From: <re...@us...> - 2007-09-18 15:04:57
|
Revision: 27680 http://crystal.svn.sourceforge.net/crystal/?rev=27680&view=rev Author: res2002 Date: 2007-09-18 07:54:31 -0700 (Tue, 18 Sep 2007) Log Message: ----------- res added the line number + column reporting to the TinyXML and xmlread error strings. Addresses trac #123. Modified Paths: -------------- CS/trunk/docs/history.txt CS/trunk/libs/csutil/tinypars.cpp CS/trunk/libs/csutil/tinystr.cpp CS/trunk/libs/csutil/tinystr.h CS/trunk/libs/csutil/tinyxml.cpp CS/trunk/libs/csutil/tinyxml.h CS/trunk/libs/csutil/xmltiny.cpp CS/trunk/libs/csutil/xmltinyp.h CS/trunk/plugins/documentsystem/xmlread/xr.cpp CS/trunk/plugins/documentsystem/xmlread/xr.h CS/trunk/plugins/documentsystem/xmlread/xrimp.cpp CS/trunk/plugins/documentsystem/xmlread/xrparse.cpp Modified: CS/trunk/docs/history.txt =================================================================== --- CS/trunk/docs/history.txt 2007-09-18 13:46:30 UTC (rev 27679) +++ CS/trunk/docs/history.txt 2007-09-18 14:54:31 UTC (rev 27680) @@ -16,6 +16,8 @@ select the appropriate variant. Fixes trac #361. - res fixed "fake relay stub" generation for when relaytool is not available. + - res added the line number + column reporting to the TinyXML and + xmlread error strings. Addresses trac #123. 17-Sep-2007 - res added a driver DB tweak to disable EXT_framebuffer_object for (now rather old) ATI drivers (see trac #261). Modified: CS/trunk/libs/csutil/tinypars.cpp =================================================================== --- CS/trunk/libs/csutil/tinypars.cpp 2007-09-18 13:46:30 UTC (rev 27679) +++ CS/trunk/libs/csutil/tinypars.cpp 2007-09-18 14:54:31 UTC (rev 27680) @@ -29,6 +29,10 @@ namespace CS { +namespace Implementation +{ +namespace TinyXml +{ // Note tha "PutString" hardcodes the same list. This // is less flexible than it appears. Changing the entries @@ -43,13 +47,21 @@ }; -const char* TiXmlBase::SkipWhiteSpace( const char* p ) +const char* TiXmlBase::SkipWhiteSpace( ParseInfo& parse, const char* p ) { if ( !p || !*p ) { return 0; } - while ( isspace (*p)) p++; + while ( isspace (*p)) + { + if (*p == '\n') + { + parse.linenum++; + parse.startOfLine = p + 1; + } + p++; + } return p; } @@ -187,17 +199,22 @@ }; -const char* TiXmlBase::ReadText(const char* p, +const char* TiXmlBase::ReadText(ParseInfo& parse, const char* p, GrowString& buf, bool trimWhiteSpace, const char* endTag) { if (!trimWhiteSpace // certain tags always keep whitespace - || !condenseWhiteSpace ) // if true, whitespace is always kept + || !parse.condenseWhiteSpace ) // if true, whitespace is always kept { // Keep all the white space. while (*p && !StringEqual ( p, endTag)) { + if (*p == '\n') + { + parse.linenum++; + parse.startOfLine = p + 1; + } char c; p = GetChar( p, &c ); buf.AddChar (c); @@ -208,9 +225,14 @@ bool whitespace = false; // Remove leading white space: - p = SkipWhiteSpace( p ); + p = SkipWhiteSpace( parse, p ); while ( *p && !StringEqual ( p, endTag) ) { + if (*p == '\n') + { + parse.linenum++; + parse.startOfLine = p + 1; + } if ( isspace( *p ) ) { whitespace = true; @@ -235,31 +257,31 @@ return p + strlen( endTag ); } -const char* TiDocumentNode::Parse( TiDocument* document, const char* p ) +const char* TiDocumentNode::Parse( ParseInfo& parse, const char* p ) { switch (type) { case DOCUMENT: - return static_cast<TiDocument*> (this)->Parse (document, p); + return static_cast<TiDocument*> (this)->Parse (parse, p); case ELEMENT: - return static_cast<TiXmlElement*> (this)->Parse (document, p); + return static_cast<TiXmlElement*> (this)->Parse (parse, p); case COMMENT: - return static_cast<TiXmlComment*> (this)->Parse (document, p); + return static_cast<TiXmlComment*> (this)->Parse (parse, p); case UNKNOWN: - return static_cast<TiXmlUnknown*> (this)->Parse (document, p); + return static_cast<TiXmlUnknown*> (this)->Parse (parse, p); case TEXT: - return static_cast<TiXmlText*> (this)->Parse (document, p); + return static_cast<TiXmlText*> (this)->Parse (parse, p); case CDATA: - return static_cast<TiXmlCData*> (this)->Parse (document, p); + return static_cast<TiXmlCData*> (this)->Parse (parse, p); case DECLARATION: - return static_cast<TiXmlDeclaration*> (this)->Parse (document, p); + return static_cast<TiXmlDeclaration*> (this)->Parse (parse, p); default: CS_ASSERT(false); return 0; } } -const char* TiDocument::Parse( TiDocument*, const char* p ) +const char* TiDocument::Parse( ParseInfo& parse, const char* p ) { // Parse away, at the document level. Since a document // contains nothing but other tags, most of what happens @@ -271,24 +293,24 @@ if ( !p || !*p ) { - SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0 ); + SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, p ); return 0; } - p = SkipWhiteSpace( p ); + p = SkipWhiteSpace( parse, p ); if ( !p ) { - SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0 ); + SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, p ); return 0; } TiDocumentNode* lastChild = 0; while ( p && *p ) { - csRef<TiDocumentNode> node (Identify( this, p )); + csRef<TiDocumentNode> node (Identify( parse, p )); if ( node ) { - p = node->Parse( this, p ); + p = node->Parse( parse, p ); InsertAfterChild (lastChild, node); lastChild = node; } @@ -296,35 +318,35 @@ { break; } - p = SkipWhiteSpace( p ); + p = SkipWhiteSpace( parse, p ); } // All is well. return p; } -const char* TiXmlElement::Parse( TiDocument* document, const char* p ) +const char* TiXmlElement::Parse( ParseInfo& parse, const char* p ) { - p = SkipWhiteSpace( p ); + p = SkipWhiteSpace( parse, p ); if ( !p || !*p || *p != '<' ) { - document->SetError( TIXML_ERROR_PARSING_ELEMENT, this ); + parse.document->SetError( TIXML_ERROR_PARSING_ELEMENT, this, p ); return 0; } - p = SkipWhiteSpace( p+1 ); + p = SkipWhiteSpace( parse, p+1 ); // Read the name. - csString inname; + csString inname; p = ReadName( p, inname ); if ( inname.IsEmpty() ) { - document->SetError( TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME, this ); + parse.document->SetError( TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME, this, p ); return 0; } - csStringID name_id = document->strings.Request (inname); - const char* reg_name = document->strings.Request (name_id); + csStringID name_id = parse.document->strings.Request (inname); + const char* reg_name = parse.document->strings.Request (name_id); SetValueRegistered (reg_name); TiXmlString endTag ("</"); @@ -335,10 +357,10 @@ // tag or an end tag. while ( p && *p ) { - p = SkipWhiteSpace( p ); + p = SkipWhiteSpace( parse, p ); if ( !p || !*p ) { - document->SetError( TIXML_ERROR_READING_ATTRIBUTES, this ); + parse.document->SetError( TIXML_ERROR_READING_ATTRIBUTES, this, p ); return 0; } if ( *p == '/' ) @@ -347,7 +369,7 @@ // Empty tag. if ( *p != '>' ) { - document->SetError( TIXML_ERROR_PARSING_EMPTY, this ); + parse.document->SetError( TIXML_ERROR_PARSING_EMPTY, this, p ); return 0; } attributeSet.set.ShrinkBestFit (); @@ -359,7 +381,7 @@ // Read the value -- which can include other // elements -- read the end tag, and return. ++p; - p = ReadValue( document, p ); // Note this is an Element method, + p = ReadValue( parse, p ); // Note this is an Element method, // and will set the error if one happens. if ( !p || !*p ) { @@ -376,7 +398,7 @@ } else { - document->SetError( TIXML_ERROR_READING_END_TAG, this ); + parse.document->SetError( TIXML_ERROR_READING_END_TAG, this, p ); return 0; } } @@ -385,11 +407,11 @@ // Try to read an element: TiDocumentAttribute attrib; // @@@ OPTIMIZE - p = attrib.Parse( document, this, p ); + p = attrib.Parse( parse, this, p ); if ( !p || !*p ) { - document->SetError( TIXML_ERROR_PARSING_ELEMENT, this ); + parse.document->SetError( TIXML_ERROR_PARSING_ELEMENT, this, p ); return 0; } GetAttributeRegistered (attrib.Name()). @@ -402,7 +424,7 @@ } -const char* TiXmlElement::ReadValue( TiDocument* document, const char* p ) +const char* TiXmlElement::ReadValue( ParseInfo& parse, const char* p ) { char const* orig_p; @@ -412,23 +434,23 @@ TiDocumentNode* lastChild = 0; // Read in text and elements in any order. - p = SkipWhiteSpace( p ); + p = SkipWhiteSpace( parse, p ); while ( p && *p ) { if ( *p != '<' ) { // Take what we have, make a text element. - void* ptr = document->blk_text.Alloc (sizeof (TiXmlText)); + void* ptr = parse.document->blk_text.Alloc (sizeof (TiXmlText)); csRef<TiXmlText> textNode; textNode.AttachNew (new (ptr) TiXmlText ()); if ( !textNode ) { - document->SetError( TIXML_ERROR_OUT_OF_MEMORY, this ); + parse.document->SetError( TIXML_ERROR_OUT_OF_MEMORY, this, p ); return 0; } - p = textNode->Parse( document, orig_p ); + p = textNode->Parse( parse, orig_p ); if ( !textNode->Blank() ) { @@ -436,21 +458,21 @@ lastChild = textNode; } else - document->DeleteNode (textNode); + parse.document->DeleteNode (textNode); } else if ( StringEqual(p, "<![CDATA[") ) { csRef<TiXmlCData> cdataNode; - void* ptr = document->docHeap.Alloc (sizeof (TiXmlCData)); + void* ptr = parse.document->docHeap.Alloc (sizeof (TiXmlCData)); cdataNode.AttachNew (new (ptr) TiXmlCData( )); if ( !cdataNode ) { - document->SetError( TIXML_ERROR_OUT_OF_MEMORY, this ); + parse.document->SetError( TIXML_ERROR_OUT_OF_MEMORY, this, p ); return 0; } - p = cdataNode->Parse( document, p ); + p = cdataNode->Parse( parse, p ); // don't care about whitespace before <![CDATA[ -> don't use orig_p if ( !cdataNode->Blank() ) @@ -469,10 +491,10 @@ } else { - csRef<TiDocumentNode> node (Identify( document, p )); + csRef<TiDocumentNode> node (Identify( parse, p )); if ( node ) { - p = node->Parse( document, p ); + p = node->Parse( parse, p ); InsertAfterChild (lastChild, node); if (!p) return 0; lastChild = node; @@ -488,23 +510,23 @@ // themselves if leading whitespace should be stripped. orig_p = p; - p = SkipWhiteSpace( p ); + p = SkipWhiteSpace( parse, p ); } if ( !p ) { - document->SetError( TIXML_ERROR_READING_ELEMENT_VALUE, this ); + parse.document->SetError( TIXML_ERROR_READING_ELEMENT_VALUE, this, p ); } return p; } -const char* TiXmlUnknown::Parse( TiDocument* document, const char* p ) +const char* TiXmlUnknown::Parse( ParseInfo& parse, const char* p ) { - p = SkipWhiteSpace( p ); + p = SkipWhiteSpace( parse, p ); if ( !p || !*p || *p != '<' ) { - document->SetError( TIXML_ERROR_PARSING_UNKNOWN, this ); + parse.document->SetError( TIXML_ERROR_PARSING_UNKNOWN, this, p ); return 0; } ++p; @@ -518,37 +540,37 @@ if ( !p ) { - document->SetError( TIXML_ERROR_PARSING_UNKNOWN, this ); + parse.document->SetError( TIXML_ERROR_PARSING_UNKNOWN, this, p ); } if ( *p == '>' ) return p+1; return p; } -const char* TiXmlComment::Parse( TiDocument* document, const char* p ) +const char* TiXmlComment::Parse( ParseInfo& parse, const char* p ) { - p = SkipWhiteSpace( p ); + p = SkipWhiteSpace( parse, p ); const char* startTag = "<!--"; const char* endTag = "-->"; if ( !StringEqual ( p, startTag) ) { - document->SetError( TIXML_ERROR_PARSING_COMMENT, this ); + parse.document->SetError( TIXML_ERROR_PARSING_COMMENT, this, p ); return 0; } p += strlen( startTag ); cs_free (value); GrowString buf; - p = ReadText( p, buf, false, endTag); + p = ReadText( parse, p, buf, false, endTag); value = buf.GetNewCopy (); return p; } -const char* TiDocumentAttribute::Parse( TiDocument* document, TiDocumentNode* node, +const char* TiDocumentAttribute::Parse( ParseInfo& parse, TiDocumentNode* node, const char* p ) { - p = TiXmlBase::SkipWhiteSpace( p ); + p = TiXmlBase::SkipWhiteSpace( parse, p ); if ( !p || !*p ) return 0; // Read the name, the '=' and the value. @@ -557,25 +579,25 @@ if ( inname.IsEmpty() ) { - document->SetError( TIXML_ERROR_READING_ATTRIBUTES, node ); + parse.document->SetError( TIXML_ERROR_READING_ATTRIBUTES, node, p ); return 0; } - csStringID name_id = document->strings.Request (inname); - name = document->strings.Request (name_id); + csStringID name_id = parse.document->strings.Request (inname); + name = parse.document->strings.Request (name_id); - p = TiXmlBase::SkipWhiteSpace( p ); + p = TiXmlBase::SkipWhiteSpace( parse, p ); if ( !p || !*p || *p != '=' ) { - document->SetError( TIXML_ERROR_READING_ATTRIBUTES, node ); + parse.document->SetError( TIXML_ERROR_READING_ATTRIBUTES, node, p ); return 0; } ++p; // skip '=' - p = TiXmlBase::SkipWhiteSpace( p ); + p = TiXmlBase::SkipWhiteSpace( parse, p ); if ( !p || !*p ) { - document->SetError( TIXML_ERROR_READING_ATTRIBUTES, node ); + parse.document->SetError( TIXML_ERROR_READING_ATTRIBUTES, node, p ); return 0; } @@ -587,24 +609,24 @@ { ++p; end = "\'"; - p = TiXmlBase::ReadText( p, buf, false, end); + p = TiXmlBase::ReadText( parse, p, buf, false, end); } else if ( *p == '"' ) { ++p; end = "\""; - p = TiXmlBase::ReadText( p, buf, false, end); + p = TiXmlBase::ReadText( parse, p, buf, false, end); } else { - document->SetError( TIXML_ERROR_READING_ATTRIBUTES, node ); + parse.document->SetError( TIXML_ERROR_READING_ATTRIBUTES, node, p ); return 0; } value = buf.GetNewCopy (); return p; } -const char* TiXmlText::Parse( TiDocument* document, const char* p ) +const char* TiXmlText::Parse( ParseInfo& parse, const char* p ) { //TiDocument* doc = GetDocument(); bool ignoreWhite = true; @@ -612,10 +634,10 @@ const char* end = "<"; GrowString buf; - p = ReadText( p, buf, ignoreWhite, end); + p = ReadText( parse, p, buf, ignoreWhite, end); - csStringID value_id = document->strings.Request (buf.GetThisCopy ()); - const char* reg_value = document->strings.Request (value_id); + csStringID value_id = parse.document->strings.Request (buf.GetThisCopy ()); + const char* reg_value = parse.document->strings.Request (value_id); SetValueRegistered (reg_value); if ( p ) @@ -623,7 +645,7 @@ return 0; } -const char* TiXmlCData::Parse( TiDocument* document, const char* p ) +const char* TiXmlCData::Parse( ParseInfo& parse, const char* p ) { //TiDocument* doc = GetDocument(); bool ignoreWhite = false; @@ -632,10 +654,10 @@ p += 9; const char* end = "]]>"; GrowString buf; - p = ReadText( p, buf, ignoreWhite, end); + p = ReadText( parse, p, buf, ignoreWhite, end); - csStringID value_id = document->strings.Request (buf.GetThisCopy ()); - const char* reg_value = document->strings.Request (value_id); + csStringID value_id = parse.document->strings.Request (buf.GetThisCopy ()); + const char* reg_value = parse.document->strings.Request (value_id); SetValueRegistered (reg_value); if ( p ) @@ -643,14 +665,14 @@ return 0; } -const char* TiXmlDeclaration::Parse( TiDocument* document, const char* p ) +const char* TiXmlDeclaration::Parse( ParseInfo& parse, const char* p ) { - p = SkipWhiteSpace( p ); + p = SkipWhiteSpace( parse, p ); // Find the beginning, find the end, and look for // the stuff in-between. if ( !p || !*p || !StringEqual( p, "<?xml") ) { - document->SetError( TIXML_ERROR_PARSING_DECLARATION, this ); + parse.document->SetError( TIXML_ERROR_PARSING_DECLARATION, this, p ); return 0; } @@ -670,26 +692,26 @@ return p; } - p = SkipWhiteSpace( p ); + p = SkipWhiteSpace( parse, p ); if ( StringEqual( p, "version") ) { // p += 7; TiDocumentAttribute attrib; - p = attrib.Parse( document, this, p ); + p = attrib.Parse( parse, this, p ); version = attrib.Value(); } else if ( StringEqual( p, "encoding") ) { // p += 8; TiDocumentAttribute attrib; - p = attrib.Parse( document, this, p ); + p = attrib.Parse( parse, this, p ); encoding = attrib.Value(); } else if ( StringEqual( p, "standalone") ) { // p += 10; TiDocumentAttribute attrib; - p = attrib.Parse( document, this, p ); + p = attrib.Parse( parse, this, p ); standalone = attrib.Value(); } else @@ -711,4 +733,6 @@ return true; } +} // namespace TinyXml +} // namespace Implementation } // namespace CS Modified: CS/trunk/libs/csutil/tinystr.cpp =================================================================== --- CS/trunk/libs/csutil/tinystr.cpp 2007-09-18 13:46:30 UTC (rev 27679) +++ CS/trunk/libs/csutil/tinystr.cpp 2007-09-18 14:54:31 UTC (rev 27680) @@ -33,6 +33,10 @@ namespace CS { +namespace Implementation +{ +namespace TinyXml +{ // TiXmlString constructor, based on a C string TiXmlString::TiXmlString (const char* instring) @@ -264,4 +268,6 @@ return false; } +} // namespace TinyXml +} // namespace Implementation } // namespace CS Modified: CS/trunk/libs/csutil/tinystr.h =================================================================== --- CS/trunk/libs/csutil/tinystr.h 2007-09-18 13:46:30 UTC (rev 27679) +++ CS/trunk/libs/csutil/tinystr.h 2007-09-18 14:54:31 UTC (rev 27680) @@ -36,6 +36,10 @@ namespace CS { +namespace Implementation +{ +namespace TinyXml +{ /* TiXmlString is an emulation of the std::string template. @@ -204,6 +208,8 @@ } ; +} // namespace TinyXml +} // namespace Implementation } // namespace CS #endif // TIXML_STRING_INCLUDED Modified: CS/trunk/libs/csutil/tinyxml.cpp =================================================================== --- CS/trunk/libs/csutil/tinyxml.cpp 2007-09-18 13:46:30 UTC (rev 27679) +++ CS/trunk/libs/csutil/tinyxml.cpp 2007-09-18 14:54:31 UTC (rev 27680) @@ -29,6 +29,10 @@ namespace CS { +namespace Implementation +{ +namespace TinyXml +{ const char* const TiXmlBase::errorString[ TIXML_ERROR_STRING_COUNT ] = { @@ -48,8 +52,6 @@ "Error document empty." }; -bool TiXmlBase::condenseWhiteSpace = true; - void TiXmlBase::PutString( const TiXmlString& str, TiXmlString* outString ) { int i=0; @@ -256,18 +258,18 @@ } -csPtr<TiDocumentNode> TiDocumentNodeChildren::Identify( TiDocument* document, +csPtr<TiDocumentNode> TiDocumentNodeChildren::Identify( ParseInfo& parse, const char* p ) { TiDocumentNode* returnNode = 0; - p = SkipWhiteSpace( p ); + p = SkipWhiteSpace( parse, p ); if( !p || !*p || *p != '<' ) { return 0; } - p = SkipWhiteSpace( p ); + p = SkipWhiteSpace( parse, p ); if ( !p || !*p ) { @@ -286,22 +288,22 @@ if ( StringEqual( p, xmlHeader) ) { - void* ptr = document->docHeap.Alloc (sizeof (TiXmlDeclaration)); + void* ptr = parse.document->docHeap.Alloc (sizeof (TiXmlDeclaration)); returnNode = new (ptr) TiXmlDeclaration(); } else if ( isalpha( *(p+1) ) || *(p+1) == '_' ) { - void* p = document->blk_element.Alloc (sizeof (TiXmlElement)); + void* p = parse.document->blk_element.Alloc (sizeof (TiXmlElement)); returnNode = new (p) TiXmlElement (); } else if ( StringEqual ( p, commentHeader) ) { - void* ptr = document->docHeap.Alloc (sizeof (TiXmlComment)); + void* ptr = parse.document->docHeap.Alloc (sizeof (TiXmlComment)); returnNode = new (ptr) TiXmlComment(); } else { - void* ptr = document->docHeap.Alloc (sizeof (TiXmlUnknown)); + void* ptr = parse.document->docHeap.Alloc (sizeof (TiXmlUnknown)); returnNode = new (ptr) TiXmlUnknown(); } @@ -313,7 +315,7 @@ } else { - document->SetError( TIXML_ERROR_OUT_OF_MEMORY, this ); + parse.document->SetError( TIXML_ERROR_OUT_OF_MEMORY, this, p ); } return returnNode; } @@ -687,6 +689,7 @@ errorId = TIXML_NO_ERROR; // ignoreWhiteSpace = true; type = DOCUMENT; + parse.document = this; } TiDocument::TiDocument( const char * documentName ) : @@ -699,6 +702,7 @@ value = documentName; errorId = TIXML_NO_ERROR; type = DOCUMENT; + parse.document = this; } TiDocument::~TiDocument () @@ -934,4 +938,6 @@ return (size_t)-1; } +} +} } // namespace CS Modified: CS/trunk/libs/csutil/tinyxml.h =================================================================== --- CS/trunk/libs/csutil/tinyxml.h 2007-09-18 13:46:30 UTC (rev 27679) +++ CS/trunk/libs/csutil/tinyxml.h 2007-09-18 14:54:31 UTC (rev 27680) @@ -50,6 +50,10 @@ namespace CS { +namespace Implementation +{ +namespace TinyXml +{ class TiDocument; class TiDocumentNodeChildren; @@ -81,6 +85,18 @@ TIXML_ERROR_STRING_COUNT }; +struct ParseInfo +{ + TiDocument* document; + bool condenseWhiteSpace; + + const char* startOfLine; + int linenum; + + void BeginParse (const char* p) + { startOfLine = p; linenum = 1; } +}; + /** * TiXmlBase is a base class for every class in TinyXml. * It does little except to establish that TinyXml classes @@ -114,22 +130,8 @@ TiXmlBase () {} ~TiXmlBase () {} - /** - * The world does not agree on whether white space should be kept or - * not. In order to make everyone happy, these global, static functions - * are provided to set whether or not TinyXml will condense all white space - * into a single space or not. The default is to condense. Note changing these - * values is not thread safe. - */ - static void SetCondenseWhiteSpace( bool condense ) - { condenseWhiteSpace = condense; } + static const char* SkipWhiteSpace( ParseInfo& parse, const char* ); - /// Return the current white space setting. - static bool IsWhiteSpaceCondensed() - { return condenseWhiteSpace; } - - static const char* SkipWhiteSpace( const char* ); - /** * Reads an XML name into the string provided. Returns * a pointer just past the last character of the name, @@ -141,7 +143,8 @@ * Reads text. Returns a pointer past the given end tag. * Wickedly complex options, but it keeps the (sensitive) code in one place. */ - static const char* ReadText( const char* in, GrowString& buf, + static const char* ReadText( ParseInfo& parse, + const char* in, GrowString& buf, bool ignoreWhiteSpace, const char* endTag); @@ -190,7 +193,6 @@ MAX_ENTITY_LENGTH = 6 }; static const Entity entity[ NUM_ENTITY ]; - static bool condenseWhiteSpace; }; @@ -233,7 +235,7 @@ * (For an unformatted stream, use the << operator.) */ void Print( iString* cfile, int depth ) const; - const char* Parse( TiDocument* document, const char* p ); + const char* Parse( ParseInfo& parse, const char* p ); /** * The meaning of 'value' changes for the specific type of @@ -354,7 +356,7 @@ protected: // Figure out what is at *p, and parse it. Returns null if it is not an xml // node. - csPtr<TiDocumentNode> Identify( TiDocument* document, const char* start ); + csPtr<TiDocumentNode> Identify( ParseInfo& parse, const char* start ); /** * Add a new node related to this. Adds a child past afterThis. @@ -422,7 +424,7 @@ * Attribute parsing starts: first letter of the name * returns: the next char after the value end quote */ - const char* Parse( TiDocument* document, TiDocumentNode* node, const char* p ); + const char* Parse( ParseInfo& parse, TiDocumentNode* node, const char* p ); private: friend class TiXmlElement; @@ -538,13 +540,13 @@ * Attribtue parsing starts: next char past '<' * returns: next char past '>' */ - const char* Parse( TiDocument* document, const char* p ); + const char* Parse( ParseInfo& parse, const char* p ); /* [internal use] * Reads the "value" of the element -- another element, or text. * This should terminate with the current end tag. */ - const char* ReadValue( TiDocument* document, const char* in ); + const char* ReadValue( ParseInfo& parse, const char* in ); private: TiDocumentAttributeSet attributeSet; @@ -581,7 +583,7 @@ * Attribtue parsing starts: at the ! of the !-- * returns: next char past '>' */ - const char* Parse( TiDocument* document, const char* p ); + const char* Parse( ParseInfo& parse, const char* p ); char* value; }; @@ -623,7 +625,7 @@ * Attribtue parsing starts: First char of the text * returns: next char past '>' */ - const char* Parse( TiDocument* document, const char* p ); + const char* Parse( ParseInfo& parse, const char* p ); const char* value; }; @@ -647,7 +649,7 @@ protected : friend class TiDocumentNode; - const char* Parse( TiDocument* document, const char* p ); + const char* Parse( ParseInfo& parse, const char* p ); }; /** @@ -697,7 +699,7 @@ // [internal use] // Attribtue parsing starts: next char past '<' // returns: next char past '>' - const char* Parse( TiDocument* document, const char* p ); + const char* Parse( ParseInfo& parse, const char* p ); private: TiXmlString version; @@ -733,7 +735,7 @@ * Attribute parsing starts: First char of the text * returns: next char past '>' */ - const char* Parse( TiDocument* document, const char* p ); + const char* Parse( ParseInfo& parse, const char* p ); TiXmlString value; }; @@ -744,7 +746,7 @@ * XML pieces. It can be saved, loaded, and printed to the screen. * The 'value' of a document node is the xml file name. */ -class TiDocument : public TiDocumentNodeChildren + class TiDocument : public TiDocumentNodeChildren { /* When e.g. the root node is deleted with DeleteNode() an avalanche of node releases may follow, even to the extent that the stack is blown. @@ -894,8 +896,15 @@ const char * Value () const { return value.c_str (); } void SetValue (const char * _value) { value = _value;} +private: /// Parse the given null terminated block of xml data. - const char* Parse( TiDocument* document, const char* p ); + const char* Parse( ParseInfo& parse, const char* p ); +public: + const char* Parse( const char* p ) + { + parse.BeginParse (p); + return Parse (parse, p); + } /// If, during parsing, a error occurs, Error will be set to true. bool Error() const { return errorId != TIXML_NO_ERROR; } @@ -915,7 +924,7 @@ // [internal use] void Print( iString* cfile, int depth = 0 ) const; // [internal use] - void SetError( int err, TiDocumentNode* errorNode ) + void SetError( int err, TiDocumentNode* errorNode, const char* errorPos ) { errorId = err; errorDesc = errorString[ errorId ]; @@ -937,11 +946,33 @@ } errorDesc += " (in: "; - errorDesc += errorPath.GetDataSafe(); + csString location; + location.Format ("line %d", parse.linenum); + if (errorPos != 0) + location.AppendFmt (":%zu", errorPos - parse.startOfLine + 1); + errorDesc += location.GetDataSafe(); + if (!errorPath.IsEmpty()) + { + errorDesc += "; "; + errorDesc += errorPath.GetDataSafe(); + } errorDesc += ")"; } } + + /** + * The world does not agree on whether white space should be kept or + * not. In order to make everyone happy, these functions are provided + * to set whether or not TinyXml will condense all white space into a + * single space or not. The default is to condense. + */ + void SetCondenseWhiteSpace( bool condense ) + { parse.condenseWhiteSpace = condense; } + + /// Return the current white space setting. + bool IsWhiteSpaceCondensed() + { return parse.condenseWhiteSpace; } protected : friend class TiDocumentNode; @@ -950,10 +981,13 @@ private: int errorId; + ParseInfo parse; TiXmlString errorDesc; TiXmlString value; }; +} // namespace TinyXml +} // namespace Implementation } // namespace CS #endif Modified: CS/trunk/libs/csutil/xmltiny.cpp =================================================================== --- CS/trunk/libs/csutil/xmltiny.cpp 2007-09-18 13:46:30 UTC (rev 27679) +++ CS/trunk/libs/csutil/xmltiny.cpp 2007-09-18 14:54:31 UTC (rev 27680) @@ -29,6 +29,8 @@ #include "iutil/databuff.h" #include "tinyxml.h" +using namespace CS; + //------------------------------------------------------------------------ @@ -50,7 +52,7 @@ //------------------------------------------------------------------------ -csTinyXmlAttributeIterator::csTinyXmlAttributeIterator (CS::TiDocumentNode* parent) +csTinyXmlAttributeIterator::csTinyXmlAttributeIterator (TiDocumentNode* parent) : scfImplementationType (this) { csTinyXmlAttributeIterator::parent = parent->ToElement (); @@ -100,12 +102,12 @@ : scfImplementationType (this), doc (doc), parent (parent), currentPos (0), endPos ((size_t)~0) { - csTinyXmlNodeIterator::value = value ? CS::StrDup (value) : 0; + csTinyXmlNodeIterator::value = value ? StrDup (value) : 0; - CS::TiDocumentNodeChildren* node_children = 0; + TiDocumentNodeChildren* node_children = 0; if (parent && - ((parent->GetTiNode()->Type() == CS::TiDocumentNode::ELEMENT) - || (parent->GetTiNode()->Type() == CS::TiDocumentNode::DOCUMENT))) + ((parent->GetTiNode()->Type() == TiDocumentNode::ELEMENT) + || (parent->GetTiNode()->Type() == TiDocumentNode::DOCUMENT))) node_children = parent->GetTiNodeChildren (); if (!node_children) current = 0; @@ -145,7 +147,7 @@ if (endPos == (size_t)~0) { endPos = currentPos; - CS::TiDocumentNode* node = current; + TiDocumentNode* node = current; while (node != 0) { endPos++; @@ -178,13 +180,13 @@ { switch (node->Type ()) { - case CS::TiDocumentNode::DOCUMENT: return CS_NODE_DOCUMENT; - case CS::TiDocumentNode::ELEMENT: return CS_NODE_ELEMENT; - case CS::TiDocumentNode::COMMENT: return CS_NODE_COMMENT; - case CS::TiDocumentNode::CDATA: - case CS::TiDocumentNode::TEXT: + case TiDocumentNode::DOCUMENT: return CS_NODE_DOCUMENT; + case TiDocumentNode::ELEMENT: return CS_NODE_ELEMENT; + case TiDocumentNode::COMMENT: return CS_NODE_COMMENT; + case TiDocumentNode::CDATA: + case TiDocumentNode::TEXT: return CS_NODE_TEXT; - case CS::TiDocumentNode::DECLARATION: return CS_NODE_DECLARATION; + case TiDocumentNode::DECLARATION: return CS_NODE_DECLARATION; default: return CS_NODE_UNKNOWN; } } @@ -237,27 +239,27 @@ csRef<iDocumentNode> csTinyXmlNode::GetNode (const char* value) { - if ((node->Type() != CS::TiDocumentNode::ELEMENT) - && (node->Type() != CS::TiDocumentNode::DOCUMENT)) return 0; - CS::TiDocumentNodeChildren* node_children = GetTiNodeChildren (); + if ((node->Type() != TiDocumentNode::ELEMENT) + && (node->Type() != TiDocumentNode::DOCUMENT)) return 0; + TiDocumentNodeChildren* node_children = GetTiNodeChildren (); csRef<iDocumentNode> child; - CS::TiDocumentNode* c = node_children->FirstChild (value); + TiDocumentNode* c = node_children->FirstChild (value); if (c) child = csPtr<iDocumentNode> (doc->Alloc (c)); return child; } void csTinyXmlNode::RemoveNode (const csRef<iDocumentNode>& child) { - if ((node->Type() != CS::TiDocumentNode::ELEMENT) - && (node->Type() != CS::TiDocumentNode::DOCUMENT)) return; - CS::TiDocumentNodeChildren* node_children = GetTiNodeChildren (); + if ((node->Type() != TiDocumentNode::ELEMENT) + && (node->Type() != TiDocumentNode::DOCUMENT)) return; + TiDocumentNodeChildren* node_children = GetTiNodeChildren (); //CS_ASSERT (child.IsValid ()); if (node_children) { csTinyXmlNode* tinyChild = static_cast<csTinyXmlNode*>((iDocumentNode*)child); - CS::TiDocumentNode* tiNode = tinyChild->GetTiNode (); + TiDocumentNode* tiNode = tinyChild->GetTiNode (); node_children->RemoveChild (tiNode); if (tiNode == lastChild) lastChild = 0; } @@ -265,9 +267,9 @@ void csTinyXmlNode::RemoveNodes (csRef<iDocumentNodeIterator> children) { - if ((node->Type() != CS::TiDocumentNode::ELEMENT) - && (node->Type() != CS::TiDocumentNode::DOCUMENT)) return; - CS::TiDocumentNodeChildren* node_children = GetTiNodeChildren (); + if ((node->Type() != TiDocumentNode::ELEMENT) + && (node->Type() != TiDocumentNode::DOCUMENT)) return; + TiDocumentNodeChildren* node_children = GetTiNodeChildren (); while (children->HasNext ()) { @@ -280,9 +282,9 @@ void csTinyXmlNode::RemoveNodes () { - if ((node->Type() != CS::TiDocumentNode::ELEMENT) - && (node->Type() != CS::TiDocumentNode::DOCUMENT)) return; - CS::TiDocumentNodeChildren* node_children = GetTiNodeChildren (); + if ((node->Type() != TiDocumentNode::ELEMENT) + && (node->Type() != TiDocumentNode::DOCUMENT)) return; + TiDocumentNodeChildren* node_children = GetTiNodeChildren (); node_children->Clear (); lastChild = 0; @@ -291,19 +293,19 @@ csRef<iDocumentNode> csTinyXmlNode::CreateNodeBefore (csDocumentNodeType type, iDocumentNode* before) { - if ((node->Type() != CS::TiDocumentNode::ELEMENT) - && (node->Type() != CS::TiDocumentNode::DOCUMENT)) return 0; - CS::TiDocumentNodeChildren* node_children = GetTiNodeChildren (); + if ((node->Type() != TiDocumentNode::ELEMENT) + && (node->Type() != TiDocumentNode::DOCUMENT)) return 0; + TiDocumentNodeChildren* node_children = GetTiNodeChildren (); csRef<iDocumentNode> n; - CS::TiDocumentNode* child = 0; + TiDocumentNode* child = 0; switch (type) { case CS_NODE_DOCUMENT: break; case CS_NODE_ELEMENT: { - CS::TiXmlElement el; + TiXmlElement el; if (before) child = node_children->InsertBeforeChild ( static_cast<csTinyXmlNode*> (before)->GetTiNode (), @@ -318,7 +320,7 @@ break; case CS_NODE_COMMENT: { - CS::TiXmlComment el; + TiXmlComment el; if (before) child = node_children->InsertBeforeChild ( static_cast<csTinyXmlNode*> (before)->GetTiNode (), @@ -333,7 +335,7 @@ break; case CS_NODE_TEXT: { - CS::TiXmlText el; + TiXmlText el; if (before) child = node_children->InsertBeforeChild ( static_cast<csTinyXmlNode*> (before)->GetTiNode (), @@ -348,7 +350,7 @@ break; case CS_NODE_DECLARATION: { - CS::TiXmlDeclaration el; + TiXmlDeclaration el; if (before) child = node_children->InsertBeforeChild ( static_cast<csTinyXmlNode*> (before)->GetTiNode (), @@ -363,7 +365,7 @@ break; case CS_NODE_UNKNOWN: { - CS::TiXmlUnknown el; + TiXmlUnknown el; if (before) child = node_children->InsertBeforeChild ( static_cast<csTinyXmlNode*> (before)->GetTiNode (), @@ -386,15 +388,15 @@ const char* csTinyXmlNode::GetContentsValue () { - if ((node->Type() != CS::TiDocumentNode::ELEMENT) - && (node->Type() != CS::TiDocumentNode::DOCUMENT)) return 0; - CS::TiDocumentNodeChildren* node_children = GetTiNodeChildren (); + if ((node->Type() != TiDocumentNode::ELEMENT) + && (node->Type() != TiDocumentNode::DOCUMENT)) return 0; + TiDocumentNodeChildren* node_children = GetTiNodeChildren (); - CS::TiDocumentNode* child = node_children->FirstChild (); + TiDocumentNode* child = node_children->FirstChild (); while (child) { - if ((child->Type () == CS::TiDocumentNode::TEXT) - || (child->Type () == CS::TiDocumentNode::CDATA)) + if ((child->Type () == TiDocumentNode::TEXT) + || (child->Type () == TiDocumentNode::CDATA)) { return child->Value (); } @@ -429,15 +431,15 @@ return it; } -CS::TiDocumentAttribute* csTinyXmlNode::GetAttributeInternal (const char* name) +TiDocumentAttribute* csTinyXmlNode::GetAttributeInternal (const char* name) { - CS::TiXmlElement* element = node->ToElement (); + TiXmlElement* element = node->ToElement (); if (!element) return 0; size_t count = element->GetAttributeCount (); size_t i; for (i = 0 ; i < count ; i++) { - CS::TiDocumentAttribute& attrib = node->ToElement ()->GetAttribute (i); + TiDocumentAttribute& attrib = node->ToElement ()->GetAttribute (i); if (strcmp (name, attrib.Name ()) == 0) return &attrib; } @@ -448,7 +450,7 @@ csRef<iDocumentAttribute> csTinyXmlNode::GetAttribute (const char* name) { csRef<iDocumentAttribute> attr; - CS::TiDocumentAttribute* a = GetAttributeInternal (name); + TiDocumentAttribute* a = GetAttributeInternal (name); if (a) { attr = csPtr<iDocumentAttribute> (new csTinyXmlAttribute (a)); @@ -458,21 +460,21 @@ const char* csTinyXmlNode::GetAttributeValue (const char* name) { - CS::TiXmlElement* el = node->ToElement (); + TiXmlElement* el = node->ToElement (); if (el) return el->Attribute (name); else return 0; } int csTinyXmlNode::GetAttributeValueAsInt (const char* name) { - CS::TiDocumentAttribute* a = GetAttributeInternal (name); + TiDocumentAttribute* a = GetAttributeInternal (name); if (!a) return 0; return a->IntValue (); } float csTinyXmlNode::GetAttributeValueAsFloat (const char* name) { - CS::TiDocumentAttribute* a = GetAttributeInternal (name); + TiDocumentAttribute* a = GetAttributeInternal (name); if (!a) return 0; float f; sscanf (a->Value (), "%f", &f); @@ -482,7 +484,7 @@ bool csTinyXmlNode::GetAttributeValueAsBool(const char* name, bool defaultvalue) { - CS::TiDocumentAttribute* a = GetAttributeInternal (name); + TiDocumentAttribute* a = GetAttributeInternal (name); if (!a || !a->Value () ) return defaultvalue; if (strcasecmp(a->Value(),"true")==0 || strcasecmp(a->Value(),"yes")==0 || @@ -506,19 +508,19 @@ void csTinyXmlNode::SetAttribute (const char* name, const char* value) { - CS::TiXmlElement* el = node->ToElement (); + TiXmlElement* el = node->ToElement (); if (el) el->SetAttribute (el->GetDocument (), name, value); } void csTinyXmlNode::SetAttributeAsInt (const char* name, int value) { - CS::TiXmlElement* el = node->ToElement (); + TiXmlElement* el = node->ToElement (); if (el) el->SetAttribute (el->GetDocument (), name, value); } void csTinyXmlNode::SetAttributeAsFloat (const char* name, float value) { - CS::TiXmlElement* el = node->ToElement (); + TiXmlElement* el = node->ToElement (); if (el) { csString v; @@ -548,7 +550,7 @@ csRef<iDocumentNode> csTinyXmlDocument::CreateRoot () { Clear (); - root.AttachNew (new CS::TiDocument ()); + root.AttachNew (new TiDocument ()); return csPtr<iDocumentNode> (Alloc (root)); } @@ -593,10 +595,8 @@ const char* csTinyXmlDocument::Parse (const char* buf, bool collapse) { CreateRoot (); - bool const old_collapse = root->IsWhiteSpaceCondensed(); root->SetCondenseWhiteSpace(collapse); - root->Parse (root, buf); - root->SetCondenseWhiteSpace(old_collapse); + root->Parse (buf); if (root->Error ()) return root->ErrorDesc (); return 0; @@ -639,7 +639,7 @@ return new (pool) csTinyXmlNode (this); } -csTinyXmlNode* csTinyXmlDocument::Alloc (CS::TiDocumentNode* node) +csTinyXmlNode* csTinyXmlDocument::Alloc (TiDocumentNode* node) { csTinyXmlNode* n = Alloc (); n->SetTiNode (node); Modified: CS/trunk/libs/csutil/xmltinyp.h =================================================================== --- CS/trunk/libs/csutil/xmltinyp.h 2007-09-18 13:46:30 UTC (rev 27679) +++ CS/trunk/libs/csutil/xmltinyp.h 2007-09-18 14:54:31 UTC (rev 27680) @@ -28,6 +28,8 @@ class csTinyXmlDocument; struct csTinyXmlNode; +using namespace CS::Implementation::TinyXml; + /** * This is an SCF compatible wrapper for an attribute iterator. */ @@ -38,10 +40,10 @@ private: size_t current; size_t count; - csRef<CS::TiXmlElement> parent; + csRef<TiXmlElement> parent; public: - csTinyXmlAttributeIterator (CS::TiDocumentNode* parent); + csTinyXmlAttributeIterator (TiDocumentNode* parent); virtual ~csTinyXmlAttributeIterator (); virtual bool HasNext (); @@ -55,7 +57,7 @@ public scfImplementation1<csTinyXmlAttribute, iDocumentAttribute> { private: - CS::TiDocumentAttribute* attr; + TiDocumentAttribute* attr; public: csTinyXmlAttribute () @@ -63,7 +65,7 @@ { } - csTinyXmlAttribute (CS::TiDocumentAttribute* attr) + csTinyXmlAttribute (TiDocumentAttribute* attr) : scfImplementationType (this), attr (attr) { } @@ -140,7 +142,7 @@ { private: csTinyXmlDocument* doc; - csRef<CS::TiDocumentNode> current; + csRef<TiDocumentNode> current; csRef<csTinyXmlNode> parent; char* value; @@ -166,15 +168,15 @@ { private: friend class csTinyXmlDocument; - csRef<CS::TiDocumentNode> node; - csRef<CS::TiDocumentNode> lastChild; + csRef<TiDocumentNode> node; + csRef<TiDocumentNode> lastChild; // We keep a reference to 'doc' to avoid it being cleaned up too early. // We need 'doc' for the pool. csRef<csTinyXmlDocument> doc; csTinyXmlNode (csTinyXmlDocument* doc); - CS::TiDocumentAttribute* GetAttributeInternal (const char* name); + TiDocumentAttribute* GetAttributeInternal (const char* name); public: virtual ~csTinyXmlNode (); @@ -190,10 +192,10 @@ scfPooledImplementationType::DecRef(); } - CS::TiDocumentNode* GetTiNode () { return node; } - CS::TiDocumentNodeChildren* GetTiNodeChildren () - { return static_cast<CS::TiDocumentNodeChildren*> (GetTiNode ()); } - void SetTiNode (CS::TiDocumentNode* node) + TiDocumentNode* GetTiNode () { return node; } + TiDocumentNodeChildren* GetTiNodeChildren () + { return static_cast<TiDocumentNodeChildren*> (GetTiNode ()); } + void SetTiNode (TiDocumentNode* node) { csTinyXmlNode::node = node; lastChild = 0; @@ -246,7 +248,7 @@ private: friend struct csTinyXmlNode; friend struct csTinyXmlNodeIterator; - csRef<CS::TiDocument> root; + csRef<TiDocument> root; // We keep a reference to 'sys' to avoid it being cleaned up too early. csRef<csTinyDocumentSystem> sys; @@ -255,7 +257,7 @@ /// Allocate a node instance csTinyXmlNode* Alloc (); /// Allocate a node instance - csTinyXmlNode* Alloc (CS::TiDocumentNode*); + csTinyXmlNode* Alloc (TiDocumentNode*); public: csTinyXmlDocument (csTinyDocumentSystem* sys); virtual ~csTinyXmlDocument (); Modified: CS/trunk/plugins/documentsystem/xmlread/xr.cpp =================================================================== --- CS/trunk/plugins/documentsystem/xmlread/xr.cpp 2007-09-18 13:46:30 UTC (rev 27679) +++ CS/trunk/plugins/documentsystem/xmlread/xr.cpp 2007-09-18 14:54:31 UTC (rev 27680) @@ -73,18 +73,18 @@ } -TrDocumentNode* TrDocumentNodeChildren::Identify (const ParseInfo& parse, +TrDocumentNode* TrDocumentNodeChildren::Identify (ParseInfo& parse, const char* p) { TrDocumentNode* returnNode = 0; - p = SkipWhiteSpace( p ); + p = SkipWhiteSpace( parse, p ); if( !p || !*p || *p != '<' ) { return 0; } - p = SkipWhiteSpace( p ); + p = SkipWhiteSpace( parse, p ); if ( !p || !*p ) { @@ -126,7 +126,7 @@ } else { - parse.document->SetError( TIXML_ERROR_OUT_OF_MEMORY, this ); + parse.document->SetError( TIXML_ERROR_OUT_OF_MEMORY, this, p ); } return returnNode; } Modified: CS/trunk/plugins/documentsystem/xmlread/xr.h =================================================================== --- CS/trunk/plugins/documentsystem/xmlread/xr.h 2007-09-18 13:46:30 UTC (rev 27679) +++ CS/trunk/plugins/documentsystem/xmlread/xr.h 2007-09-18 14:54:31 UTC (rev 27680) @@ -84,6 +84,12 @@ ReadNameFunc* ReadName; IsNameStartFunc* IsNameStart; + + const char* startOfLine; + int linenum; + + void BeginParse (const char* p) + { startOfLine = p; linenum = 1; } }; /** @@ -119,8 +125,8 @@ TrXmlBase () {} virtual ~TrXmlBase () {} - static const char* SkipWhiteSpace( const char* ); - static char* SkipWhiteSpace( char* ); + static const char* SkipWhiteSpace( ParseInfo& parse, const char* ); + static char* SkipWhiteSpace( ParseInfo& parse, char* ); /** * Reads an XML name into the string provided. Returns @@ -135,11 +141,11 @@ * This version parses in place (i.e. it modifies the in buffer and * returns a pointer inside that). */ - static char* ReadText(char* in, char*& buf, + static char* ReadText(ParseInfo& parse, char* in, char*& buf, int& buflen, bool ignoreWhiteSpace, const char* endTag); protected: - virtual char* Parse( const ParseInfo& parse, char* p ) = 0; + virtual char* Parse( ParseInfo& parse, char* p ) = 0; // If an entity has been found, transform it into a character. static char* GetEntity( char* in, char* value ); @@ -293,7 +299,7 @@ protected: // Figure out what is at *p, and parse it. Returns null if it is not an xml // node. - TrDocumentNode* Identify( const ParseInfo& parse, const char* start ); + TrDocumentNode* Identify( ParseInfo& parse, const char* start ); // The node is passed in by ownership. This object will delete it. TrDocumentNode* LinkEndChild( TrDocumentNode* lastChild, @@ -351,7 +357,7 @@ * Attribute parsing starts: first letter of the name * returns: the next char after the value end quote */ - char* Parse( const ParseInfo& parse, TrDocumentNode* node, char* p ); + char* Parse( ParseInfo& parse, TrDocumentNode* node, char* p ); private: const char* name; @@ -440,13 +446,13 @@ * Attribtue parsing starts: next char past '<' * returns: next char past '>' */ - virtual char* Parse( const ParseInfo& parse, char* p ); + virtual char* Parse( ParseInfo& parse, char* p ); /* [internal use] * Reads the "value" of the element -- another element, or text. * This should terminate with the current end tag. */ - char* ReadValue( const ParseInfo& parse, char* in ); + char* ReadValue( ParseInfo& parse, char* in ); private: TrDocumentAttributeSet attributeSet; @@ -476,7 +482,7 @@ * Attribtue parsing starts: at the ! of the !-- * returns: next char past '>' */ - virtual char* Parse( const ParseInfo& parse, char* p ); + virtual char* Parse( ParseInfo& parse, char* p ); char* value; int vallen; @@ -508,7 +514,7 @@ * Attribtue parsing starts: First char of the text * returns: next char past '>' */ - virtual char* Parse( const ParseInfo& parse, char* p ); + virtual char* Parse( ParseInfo& parse, char* p ); char* value; int vallen; @@ -531,7 +537,7 @@ virtual ~TrXmlCData() {} protected : - virtual char* Parse( const ParseInfo& parse, char* p ); + virtual char* Parse( ParseInfo& parse, char* p ); }; /** @@ -580,7 +586,7 @@ // [internal use] // Attribtue parsing starts: next char past '<' // returns: next char past '>' - virtual char* Parse( const ParseInfo& parse, char* p ); + virtual char* Parse( ParseInfo& parse, char* p ); private: const char* version; @@ -608,7 +614,7 @@ * Attribute parsing starts: First char of the text * returns: next char past '>' */ - virtual char* Parse( const ParseInfo& parse, char* p ); + virtual char* Parse( ParseInfo& parse, char* p ); char* value; int vallen; @@ -651,8 +657,15 @@ virtual const char * Value () { return 0; } +private: /// Parse the given null terminated block of xml data. - virtual char* Parse( const ParseInfo& parse, char* p ); + virtual char* Parse( ParseInfo& parse, char* p ); +public: + char* Parse( char* p ) + { + parse.BeginParse (p); + return Parse (parse, p); + } /// If, during parsing, a error occurs, Error will be set to true. bool Error() const { return errorId != TIXML_NO_ERROR; } @@ -670,7 +683,7 @@ void ClearError() { errorId = TIXML_NO_ERROR; errorDesc = ""; } // [internal use] - void SetError( int err, TrDocumentNode* errorNode ) + void SetError( int err, TrDocumentNode* errorNode, const char* errorPos ) { errorId = err; errorDesc = errorString[ errorId ]; @@ -692,7 +705,16 @@ } errorDesc += " (in: "; - errorDesc += errorPath.GetDataSafe(); + csString location; + location.Format ("line %d", parse.linenum); + if (errorPos != 0) + location.AppendFmt (":%zu", errorPos - parse.startOfLine + 1); + errorDesc += location.GetDataSafe(); + if (!errorPath.IsEmpty()) + { + errorDesc += "; "; + errorDesc += errorPath.GetDataSafe(); + } errorDesc += ")"; } } Modified: CS/trunk/plugins/documentsystem/xmlread/xrimp.cpp =================================================================== --- CS/trunk/plugins/documentsystem/xmlread/xrimp.cpp 2007-09-18 13:46:30 UTC (rev 27679) +++ CS/trunk/plugins/documentsystem/xmlread/xrimp.cpp 2007-09-18 14:54:31 UTC (rev 27680) @@ -483,8 +483,7 @@ { CreateRoot (CS::StrDup (buf)); root->SetCondenseWhiteSpace(collapse); - ParseInfo parse; - root->Parse (parse, root->input_data); + root->Parse (root->input_data); if (root->Error ()) return root->ErrorDesc (); return 0; @@ -494,8 +493,7 @@ { CreateRoot (buf); root->SetCondenseWhiteSpace(collapse); - ParseInfo parse; - root->Parse (parse, root->input_data); + root->Parse (root->input_data); if (root->Error ()) return root->ErrorDesc (); return 0; Modified: CS/trunk/plugins/documentsystem/xmlread/xrparse.cpp =================================================================== --- CS/trunk/plugins/documentsystem/xmlread/xrparse.cpp 2007-09-18 13:46:30 UTC (rev 27679) +++ CS/trunk/plugins/documentsystem/xmlread/xrparse.cpp 2007-09-18 14:54:31 UTC (rev 27680) @@ -46,23 +46,39 @@ return (c == 0x20) || (c == 0x0a) || (c == 0x0d) || (c == 0x09); } -char* TrXmlBase::SkipWhiteSpace( char* p ) +char* TrXmlBase::SkipWhiteSpace( ParseInfo& parse, char* p ) { if ( !p || !*p ) { return 0; } - while ( IsSpace (*p)) p++; + while ( IsSpace (*p)) + { + if (*p == '\n') + { + parse.linenum++; + parse.startOfLine = p + 1; + } + p++; + } return p; } -const char* TrXmlBase::SkipWhiteSpace( const char* p ) +const char* TrXmlBase::SkipWhiteSpace( ParseInfo& parse, const char* p ) { if ( !p || !*p ) { return 0; } - while ( IsSpace (*p)) p++; + while ( IsSpace (*p)) + { + if (*p == '\n') + { + parse.linenum++; + parse.startOfLine = p + 1; + } + p++; + } return p; } @@ -148,7 +164,7 @@ return false; } -char* TrXmlBase::ReadText(char* p, +char* TrXmlBase::ReadText(ParseInfo& parse, char* p, char*& buf, int& buflen, bool trimWhiteSpace, const char* endTag) @@ -164,6 +180,11 @@ // Keep all the white space. while (*p && (*p != tagStart)) { + if (*p == '\n') + { + parse.linenum++; + parse.startOfLine = p + 1; + } char c; p = GetChar( p, &c ); *out++ = c; @@ -179,13 +200,18 @@ bool first = true; // Remove leading white space: - p = SkipWhiteSpace( p ); + p = SkipWhiteSpace( parse, p ); buf = p; out = p; while (true) { while ( *p && (*p != tagStart)) { + if (*p == '\n') + { + parse.linenum++; + parse.startOfLine = p + 1; + } if ( IsSpace( *p ) ) { whitespace = true; @@ -220,7 +246,7 @@ return p; } -char* TrDocument::Parse( const ParseInfo&, char* p ) +char* TrDocument::Parse( ParseInfo& parse, char* p ) { // Parse away, at the document level. Since a document // contains nothing but other tags, most of what happens @@ -232,14 +258,14 @@ if ( !p || !*p ) { - SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0 ); + SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0 ); return 0; } - p = SkipWhiteSpace( p ); + p = SkipWhiteSpace( parse, p ); if ( !p ) { - SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0 ); + SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0 ); return 0; } @@ -260,24 +286,24 @@ { break; } - p = SkipWhiteSpace( p ); + p = SkipWhiteSpace( parse, p ); } // All is well. return p; } -char* TrXmlElement::Parse( const ParseInfo& parse, char* p ) +char* TrXmlElement::Parse( ParseInfo& parse, char* p ) { - p = SkipWhiteSpace( p ); + p = SkipWhiteSpace( parse, p ); if ( !p || !*p || *p != '<' ) { - parse.document->SetError( TIXML_ERROR_PARSING_ELEMENT, this ); + parse.document->SetError( TIXML_ERROR_PARSING_ELEMENT, this, p ); return 0; } - p = SkipWhiteSpace( p+1 ); + p = SkipWhiteSpace( parse, p+1 ); // Read the name. value = p; @@ -286,7 +312,8 @@ if ( !p || !*p ) { - parse.document->SetError( TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME, this ); + *endp = 0; + parse.document->SetError( TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME, this, p ); return 0; } @@ -306,10 +333,11 @@ // tag or an end tag. while ( p && *p ) { - p = SkipWhiteSpace( p ); + p = SkipWhiteSpace( parse, p ); if ( !p || !*p ) { - parse.document->SetError( TIXML_ERROR_READING_ATTRIBUTES, this ); + *endp = 0; + parse.document->SetError( TIXML_ERROR_READING_ATTRIBUTES, this, p ); return 0; } if ( *p == '/' ) @@ -318,7 +346,8 @@ // Empty tag. if ( *p != '>' ) { - parse.document->SetError( TIXML_ERROR_PARSING_EMPTY, this ); + *endp = 0; + parse.document->SetError( TIXML_ERROR_PARSING_EMPTY, this, p ); return 0; } attributeSet.set.ShrinkBestFit (); @@ -330,7 +359,7 @@ // Done with attributes (if there were any.) // Read the value -- which can include other // elements -- read the end tag, and return. - ++p; + ++p; *endp = 0; p = ReadValue( parse, p ); // Note this is an Element method, and will set the error if one happens. if ( !p || !*p ) { @@ -343,12 +372,11 @@ { p += endTaglen; attributeSet.set.ShrinkBestFit (); - *endp = 0; return p; } else { - parse.document->SetError( TIXML_ERROR_READING_END_TAG, this ); + parse.document->SetError( TIXML_ERROR_READING_END_TAG, this, p ); return 0; } } @@ -361,7 +389,8 @@ if ( !p || !*p ) { - parse.document->SetError( TIXML_ERROR_PARSING_ELEMENT, this ); + *endp = 0; + parse.document->SetError( TIXML_ERROR_PARSING_ELEMENT, this, p ); return 0; } GetAttributeRegistered (attrib.Name()). @@ -375,14 +404,14 @@ } -char* TrXmlElement::ReadValue( const ParseInfo& parse, char* p ) +char* TrXmlElement::ReadValue( ParseInfo& parse, char* p ) { // Remember original location in stream because text and CDATA nodes decide // themselves if leading whitespace should be stripped. char* orig_p = p; // Read in text and elements in any order. - p = SkipWhiteSpace( p ); + p = SkipWhiteSpace( parse, p ); bool first_text = false; TrDocumentNode* lastChild = 0; while ( p && *p ) @@ -395,7 +424,7 @@ { first_text = true; const char* end = "<"; - p = ReadText( orig_p, contentsvalue, contentsvalue_len, + p = ReadText( parse, orig_p, contentsvalue, contentsvalue_len, parse.condenseWhiteSpace, end); if ( p ) p--; } @@ -405,7 +434,7 @@ TrXmlText* textNode = parse.document->blk_text.Alloc (); if ( !textNode ) { - parse.document->SetError( TIXML_ERROR_OUT_OF_MEMORY, this ); + parse.document->SetError( TIXML_ERROR_OUT_OF_MEMORY, this, p ); return 0; } p = textNode->Parse( parse, orig_p ); @@ -418,7 +447,7 @@ if ( !cdataNode ) { - parse.document->SetError( TIXML_ERROR_OUT_OF_MEMORY, this ); + parse.document->SetError( TIXML_ERROR_OUT_OF_MEMORY, this, p ); return 0; } @@ -456,24 +485,24 @@ orig_p = p; - p = SkipWhiteSpace( p ); + p = SkipWhiteSpace( parse, p ); } if ( !p ) { - parse.document->SetError( TIXML_ERROR_READING_ELEMENT_VALUE, this ); + parse.document->SetError( TIXML_ERROR_READING_ELEMENT_VALUE, this, p ); } return p; } -char* TrXmlUnknown::Parse( const ParseInfo& parse, char* p ) +char* TrXmlUnknown::Parse( ParseInfo& parse, char* p ) { - p = SkipWhiteSpace( p ); + p = SkipWhiteSpace( parse, p ); if ( !p || !*p || *p != '<' ) { - parse.document->SetError( TIXML_ERROR_PARSING_UNKNOWN, this ); + parse.document->SetError( TIXML_ERROR_PARSING_UNKNOWN, this, p ); return 0; } ++p; @@ -487,33 +516,33 @@ if ( !p ) { - parse.document->SetError( TIXML_ERROR_PARSING_UNKNOWN, this ); + parse.document->SetError( TIXML_ERROR_PARSING_UNKNOWN, this, p ); } if ( *p == '>' ) return p+1; return p; } -char* TrXmlComment::Parse( const ParseInfo& parse, char* p ) +char* TrXmlComment::Parse( ParseInfo& parse, char* p ) { - p = SkipWhiteSpace( p ); + p = SkipWhiteSpace( parse, p ); const char* startTag = "<!--"; const char* endTag = "-->"; if ( !StringEqual ( p, startTag) ) { - parse.document->SetError( TIXML_ERROR_PARSING_COMMENT, this ); + parse.document->SetError( TIXML_ERROR_PARSING_COMMENT, this, p ); return 0; } p += strlen( startTag ); - p = ReadText( p, value, vallen, false, endTag); + p = ReadText( parse, p, value, vallen, false, endTag); return p; } -char* TrDocumentAttribute::Parse( const ParseInfo& parse, TrDocumentNode* node, char* p ) +char* TrDocumentAttribute::Parse( ParseInfo& parse, TrDocumentNode* node, char* p ) { - p = TrXmlBase::SkipWhiteSpace( p ); + p = TrXmlBase::SkipWhiteSpace( parse, p ); if ( !p || !*p ) return 0; // Read the name, the '=' and the value. @@ -523,23 +552,23 @@ if ( !p || !*p ) { - parse.document->SetError( TIXML_ERROR_READING_ATTRIBUTES, node ); + parse.document->SetError( TIXML_ERROR_READING_ATTRIBUTES, node, p ); return 0; } - p = TrXmlBase::SkipWhiteSpace( p ); + p = TrXmlBase::SkipWhiteSpace( parse, p ); if ( !p || !*p || *p != '=' ) { - parse.document->SetError( TIXML_ERROR_READING_ATTRIBUTES, node ); + parse.document->SetError( TIXML_ERROR_READING_ATTRIBUTES, node, p ); return 0; } ++p; // skip '=' *endp = 0; // End the name field. - p = TrXmlBase::SkipWhiteSpace( p ); + p = TrXmlBase::SkipWhiteSpace( parse, p ); if ( !p || !*p ) { - parse.document->SetError( TIXML_ERROR_READING_ATTRIBUTES, node ); + parse.document->SetError( TIXML_ERROR_READING_ATTRIBUTES, node, p ); return 0; } @@ -551,17 +580,17 @@ { ++p; end = "\'"; - p = TrXmlBase::ReadText( p, buf, buflen, false, end); + p = TrXmlBase::ReadText( parse, p, buf, buflen, false, end); } else if ( *p == '"' ) { ++p; end = "\""; - p = TrXmlBase::ReadText( p, buf, buflen, false, end); + p = TrXmlBase::ReadText( parse, p, buf, buflen, false, end); } else { - parse.document->SetError( TIXML_ERROR_READING_ATTRIBUTES, node ); + parse.document->SetError( TIXML_ERROR_READING_ATTRIBUTES, node, p ); return 0; } value = buf; @@ -569,40 +598,40 @@ return p; } -char* TrXmlText::Parse( const ParseInfo& parse, char* p ) +char* TrXmlText::Parse( ParseInfo& parse, char* p ) { //TrDocument* doc = GetDocument(); //bool ignoreWhite = true; //if ( doc && !doc->IgnoreWhiteSpace() ) ignoreWhite = false; const char* end = "<"; - p = ReadText( p, value, vallen, parse.condenseWhiteSpace, end); + p = ReadText( parse, p, value, vallen, parse.condenseWhiteSpace, end); if ( p ) return p-1; // don't truncate the '<' return 0; } -char* TrXmlCData::Parse( const ParseInfo& parse, char* p ) +char* TrXmlCData::Parse( ParseInfo& parse, ch... [truncated message content] |