From 12f6785e62d2a8dfd8538c416d2c1d4165b0d7ac Mon Sep 17 00:00:00 2001 From: Edouard DUPIN Date: Sun, 30 Jun 2013 17:03:07 +0200 Subject: [PATCH] [DEV] add more test and compatibility and add a better error display --- exml/Attribute.cpp | 76 +++++++++++------------ exml/Attribute.h | 2 +- exml/Comment.cpp | 14 +++-- exml/Comment.h | 2 +- exml/Declaration.cpp | 26 ++++---- exml/Declaration.h | 26 +++++--- exml/Document.cpp | 66 +++++++++++++++----- exml/Document.h | 25 +++++++- exml/Element.cpp | 144 +++++++++++++++++++++++-------------------- exml/Element.h | 4 +- exml/Node.cpp | 21 +++++-- exml/Node.h | 79 ++++++++++++++++++++++-- exml/Text.cpp | 19 +++--- exml/Text.h | 4 +- exml/test.cpp | 132 +++++++++++++++++++++++++++++++++++++-- 15 files changed, 461 insertions(+), 179 deletions(-) diff --git a/exml/Attribute.cpp b/exml/Attribute.cpp index be9ddbd..f4694d3 100644 --- a/exml/Attribute.cpp +++ b/exml/Attribute.cpp @@ -8,6 +8,7 @@ #include #include +#include #undef __class__ #define __class__ "Attribute" @@ -19,22 +20,17 @@ exml::Attribute::Attribute(const etk::UString& _name, const etk::UString& _value } -bool exml::Attribute::Parse(const etk::UString& _data, int32_t& _pos, bool _caseSensitive, ivec2& _filePos) +bool exml::Attribute::Parse(const etk::UString& _data, int32_t& _pos, bool _caseSensitive, exml::filePos& _filePos, exml::Document& _doc) { EXML_VERBOSE("start parse : 'attribute'"); m_pos = _filePos; // search end of the comment : int32_t lastElementName = _pos; for (int32_t iii=_pos; iii<_data.Size(); iii++) { - _filePos += ivec2(1,0); + _filePos.Check(_data[iii]); #ifdef ENABLE_DISPLAY_PARSED_ELEMENT DrawElementParsed(_data[iii], _filePos); #endif - if (_data[iii] == '\n') { - _filePos.setValue(1, _filePos.y()+1); - EXML_ERROR("unexpected '\\n' in an attribute parsing"); - return false; - } if (true==CheckAvaillable(_data[iii], false) ) { lastElementName = iii; } else { @@ -45,64 +41,68 @@ bool exml::Attribute::Parse(const etk::UString& _data, int32_t& _pos, bool _case if (true==_caseSensitive) { m_name.Lower(); } - if (lastElementName+1>=_data.Size()) { - EXML_ERROR(" parse an xml end with an attribute parsing..."); + // count white space : + exml::filePos tmpPos; + int32_t white = CountWhiteChar(_data, lastElementName+1, tmpPos); + _filePos += tmpPos; + if (lastElementName+white+1>=_data.Size()) { + CREATE_ERROR(_doc, _data, lastElementName+white+1, _filePos, " parse an xml end with an attribute parsing..."); return false; } - if (_data[lastElementName+1] != '=') { - EXML_ERROR(" error attribute parsing ==> missing '=' ..."); + if (_data[lastElementName+white+1] != '=') { + CREATE_ERROR(_doc, _data, lastElementName+white+1, _filePos, " error attribute parsing ==> missing '=' ..."); return false; } - if (lastElementName+2>=_data.Size()) { - EXML_ERROR(" parse an xml end with an attribute parsing..."); + white += CountWhiteChar(_data, lastElementName+white+2, tmpPos); + _filePos += tmpPos; + + if (lastElementName+white+2>=_data.Size()) { + CREATE_ERROR(_doc, _data, lastElementName+white+2, _filePos, " parse an xml end with an attribute parsing..."); return false; } - if (_data[lastElementName+2] != '"') { + if (_data[lastElementName+white+2] != '"') { // parse with no element " ==> direct value separate with space ... - _filePos += ivec2(2,0); - int32_t lastAttributePos = lastElementName+3; - for (int32_t iii=lastElementName+2; iii<_data.Size(); iii++) { - _filePos += ivec2(1,0); + ++_filePos; + int32_t lastAttributePos = lastElementName+white+2; + for (int32_t iii=lastElementName+white+2; iii<_data.Size(); iii++) { #ifdef ENABLE_DISPLAY_PARSED_ELEMENT DrawElementParsed(_data[iii], _filePos); #endif - if (_data[iii] == '\n') { - _filePos.setValue(1, _filePos.y()+1); - EXML_ERROR("unexpected '\\n' in an attribute parsing"); + if (_filePos.Check(_data[iii])==true) { + CREATE_ERROR(_doc, _data, iii, _filePos, "unexpected '\\n' in an attribute parsing"); return false; } - if (_data[iii]!=' ') { - lastAttributePos = iii; + if( _data[iii]!=' ' + && _data[iii]!='/' + && _data[iii]!='?' + && _data[iii]!='>') { + lastAttributePos = iii+1; } else { break; } } - m_value = _data.Extract(lastElementName+2, lastAttributePos+1); + m_value = _data.Extract(lastElementName+white+2, lastAttributePos); - _pos = lastAttributePos+1; + EXML_PARSE_ATTRIBUTE(m_pos << " attribute : " << m_name << "=\"" << m_value << "\""); + + _pos = lastAttributePos-1; return true; } - _filePos += ivec2(2,0); - int32_t lastAttributePos = lastElementName+3; - for (int32_t iii=lastElementName+3; iii<_data.Size(); iii++) { - _filePos += ivec2(1,0); + int32_t lastAttributePos = lastElementName+white+3; + for (int32_t iii=lastElementName+white+3; iii<_data.Size(); iii++) { #ifdef ENABLE_DISPLAY_PARSED_ELEMENT DrawElementParsed(_data[iii], _filePos); #endif - if (_data[iii] == '\n') { - _filePos.setValue(1, _filePos.y()+1); - EXML_ERROR("unexpected '\\n' in an attribute parsing"); - return false; - } - if (_data[iii]!='"') { - lastAttributePos = iii; + _filePos.Check(_data[iii]); + if(_data[iii]!='"') { + lastAttributePos = iii+1; } else { break; } } - m_value = _data.Extract(lastElementName+3, lastAttributePos+1); + m_value = _data.Extract(lastElementName+white+3, lastAttributePos); - EXML_VERBOSE("attribute : " << m_name << "=\"" << m_value << "\""); + EXML_PARSE_ATTRIBUTE(m_pos << " attribute : " << m_name << "=\"" << m_value << "\""); _pos = lastAttributePos; return true; diff --git a/exml/Attribute.h b/exml/Attribute.h index eadd247..ce315be 100644 --- a/exml/Attribute.h +++ b/exml/Attribute.h @@ -46,7 +46,7 @@ namespace exml virtual const etk::UString& GetName(void) const { return m_name; }; public: // herited function: virtual nodeType_te GetType(void) const { return exml::typeAttribute; }; - virtual bool Parse(const etk::UString& _data, int32_t& _pos, bool _caseSensitive, ivec2& _filePos); + virtual bool Parse(const etk::UString& _data, int32_t& _pos, bool _caseSensitive, exml::filePos& _filePos, exml::Document& _doc); virtual bool Generate(etk::UString& _data, int32_t _indent) const; virtual exml::Attribute* ToAttribute(void) { return this; }; virtual const exml::Attribute* ToAttribute(void) const { return this; }; diff --git a/exml/Comment.cpp b/exml/Comment.cpp index bbb9046..e82c593 100644 --- a/exml/Comment.cpp +++ b/exml/Comment.cpp @@ -8,28 +8,30 @@ #include #include +#include #undef __class__ #define __class__ "Comment" -bool exml::Comment::Parse(const etk::UString& _data, int32_t& _pos, bool _caseSensitive, ivec2& _filePos) +bool exml::Comment::Parse(const etk::UString& _data, int32_t& _pos, bool _caseSensitive, exml::filePos& _filePos, exml::Document& _doc) { EXML_VERBOSE("start parse : 'comment'"); m_pos = _filePos; - int32_t white = CountWhiteChar(_data, _pos); + exml::filePos tmpPos; + int32_t white = CountWhiteChar(_data, _pos, tmpPos); + _filePos += tmpPos; // search end of the comment : for (int32_t iii=_pos+white; iii+2<_data.Size(); iii++) { - _filePos += ivec2(1,0); #ifdef ENABLE_DISPLAY_PARSED_ELEMENT DrawElementParsed(_data[iii], _filePos); #endif - if (_data[iii] == '\n') { - _filePos.setValue(1, _filePos.y()+1); + if (_filePos.Check(_data[iii]) == true) { continue; } if( _data[iii] == '-' && _data[iii+1] == '-' && _data[iii+2] == '>') { + _filePos += 2; // search whitespace : int32_t newEnd=iii; for( int32_t jjj=iii-1; jjj>_pos; jjj--) { @@ -47,7 +49,7 @@ bool exml::Comment::Parse(const etk::UString& _data, int32_t& _pos, bool _caseSe } } _pos = _data.Size(); - EXML_ERROR("comment got end of file without finding end node"); + CREATE_ERROR(_doc, _data, _pos, _filePos, "comment got end of file without finding end node"); return false; } diff --git a/exml/Comment.h b/exml/Comment.h index d63a33d..5ec18f7 100644 --- a/exml/Comment.h +++ b/exml/Comment.h @@ -32,7 +32,7 @@ namespace exml virtual ~Comment(void) { }; public: // herited function: virtual nodeType_te GetType(void) const { return typeAttribute; }; - virtual bool Parse(const etk::UString& _data, int32_t& _pos, bool _caseSensitive, ivec2& _filePos); + virtual bool Parse(const etk::UString& _data, int32_t& _pos, bool _caseSensitive, exml::filePos& _filePos, exml::Document& _doc); virtual bool Generate(etk::UString& _data, int32_t _indent) const; virtual exml::Comment* ToComment(void) { return this; }; virtual const exml::Comment* ToComment(void) const { return this; }; diff --git a/exml/Declaration.cpp b/exml/Declaration.cpp index 9391339..632961b 100644 --- a/exml/Declaration.cpp +++ b/exml/Declaration.cpp @@ -8,6 +8,7 @@ #include #include +#include #undef __class__ #define __class__ "Declaration" @@ -19,9 +20,9 @@ */ -exml::Declaration::Declaration(const etk::UString& _version, unicode::charset_te _format, bool _standalone) +exml::DeclarationXML::DeclarationXML(const etk::UString& _version, unicode::charset_te _format, bool _standalone) : + exml::Declaration("xml") { - m_value = "xml"; if (_version.Size()!=0) { SetAttribute("version", _version); } @@ -48,31 +49,28 @@ bool exml::Declaration::Generate(etk::UString& _data, int32_t _indent) const return true; } -bool exml::Declaration::Parse(const etk::UString& _data, int32_t& _pos, bool _caseSensitive, ivec2& _filePos) +bool exml::Declaration::Parse(const etk::UString& _data, int32_t& _pos, bool _caseSensitive, exml::filePos& _filePos, exml::Document& _doc) { - EXML_VERBOSE("start parse : 'declaration'"); + EXML_VERBOSE("start parse : 'declaration' : '" << m_value << "'"); m_pos = _filePos; // search end of the comment : for (int32_t iii=_pos; iii+1<_data.Size(); iii++) { - _filePos += ivec2(1,0); #ifdef ENABLE_DISPLAY_PARSED_ELEMENT DrawElementParsed(_data[iii], _filePos); #endif - if (_data[iii] == '\n') { - _filePos.setValue(1, _filePos.y()+1); + if (_filePos.Check(_data[iii])==true) { continue; } if( _data[iii] == '>' || _data[iii] == '<') { // an error occured : - EXML_ERROR(_filePos << " find '>' or '<' instead of '?>'"); + CREATE_ERROR(_doc, _data, _pos, _filePos, " find '>' or '<' instead of '?>'"); return false; } if( _data[iii] == '?' && _data[iii+1] == '>') { - // find end of value: - m_value = _data.Extract(_pos, iii-1); - EXML_DEBUG(" find declaration '" << m_value << "'"); + ++_filePos; + // find end of declaration: _pos = iii+1; return true; } @@ -80,11 +78,11 @@ bool exml::Declaration::Parse(const etk::UString& _data, int32_t& _pos, bool _ca // we find an attibute ==> create a new and parse it : exml::Attribute* attribute = new exml::Attribute(); if (NULL==attribute) { - EXML_ERROR(_filePos << " Allocation error ..."); + CREATE_ERROR(_doc, _data, _pos, _filePos, " Allocation error ..."); return false; } _pos = iii; - if (false==attribute->Parse(_data, _pos, _caseSensitive, _filePos)) { + if (false==attribute->Parse(_data, _pos, _caseSensitive, _filePos, _doc)) { delete(attribute); return false; } @@ -93,8 +91,8 @@ bool exml::Declaration::Parse(const etk::UString& _data, int32_t& _pos, bool _ca continue; } } + CREATE_ERROR(_doc, _data, _pos, _filePos, "Text got end of file without finding end node"); _pos = _data.Size(); - EXML_ERROR("Text got end of file without finding end node"); return false; } diff --git a/exml/Declaration.h b/exml/Declaration.h index 2dba554..7051fbe 100644 --- a/exml/Declaration.h +++ b/exml/Declaration.h @@ -21,13 +21,10 @@ namespace exml */ Declaration(void) { }; /** - * @brief Constructor for the generic declaration : - * @param[in] _version Xml version. - * @param[in] _format charset of the XML - * @param[in] _standalone this document is standalone + * @brief Constructor + * @param[in] _name name of the declaration (xml, xml:xxxx ...) */ - // for xml generic declaration - Declaration(const etk::UString& _version, unicode::charset_te _format=unicode::EDN_CHARSET_UTF8, bool _standalone=true); + Declaration(const etk::UString& _name) : exml::AttributeList(_name) { }; /** * @brief Destructor */ @@ -35,10 +32,25 @@ namespace exml public: // herited function: virtual nodeType_te GetType(void) const { return typeAttribute; }; virtual bool Generate(etk::UString& _data, int32_t _indent) const; - virtual bool Parse(const etk::UString& _data, int32_t& _pos, bool _caseSensitive, ivec2& _filePos); + virtual bool Parse(const etk::UString& _data, int32_t& _pos, bool _caseSensitive, exml::filePos& _filePos, exml::Document& _doc); virtual exml::Declaration* ToDeclaration(void) { return this; }; virtual const exml::Declaration* ToDeclaration(void) const { return this; }; }; + class DeclarationXML : public exml::Declaration + { + public: + /** + * @brief Constructor for the generic declaration : + * @param[in] _version Xml version. + * @param[in] _format charset of the XML + * @param[in] _standalone this document is standalone + */ + DeclarationXML(const etk::UString& _version, unicode::charset_te _format=unicode::EDN_CHARSET_UTF8, bool _standalone=true); + /** + * @brief Destructor + */ + virtual ~DeclarationXML(void) { }; + }; }; diff --git a/exml/Document.cpp b/exml/Document.cpp index c5bb56b..d2bf738 100644 --- a/exml/Document.cpp +++ b/exml/Document.cpp @@ -15,7 +15,11 @@ exml::Document::Document(void) : m_charset(unicode::EDN_CHARSET_UTF8), - m_caseSensitive(false) + m_caseSensitive(false), + m_writeErrorWhenDetexted(true), + m_comment(""), + m_Line(""), + m_filePos(0,0) { } @@ -31,25 +35,16 @@ bool exml::Document::Generate(etk::UString& _data, int32_t _indent) const return true; } - -bool exml::Document::Parse(const etk::UString& _data, int32_t& _pos, bool _caseSensitive, ivec2& _filePos) -{ - EXML_VERBOSE("start parse : 'document'"); - m_pos = _filePos; - // in this case : no main node ... - return SubParse(_data, _pos, _caseSensitive, _filePos, true); -} - - bool exml::Document::Parse(const etk::UString& _data) { EXML_VERBOSE("Start parsing document (type: string) size=" << _data.Size()); Clear(); // came from char ==> force in utf8 ... m_charset = unicode::EDN_CHARSET_UTF8; - ivec2 filePos(0,1); + exml::filePos filePos(1,0); + m_pos = filePos; int32_t parsePos = 0; - return Parse(_data, parsePos, m_caseSensitive, filePos); + return SubParse(_data, parsePos, m_caseSensitive, filePos, *this, true); } bool exml::Document::Generate(etk::UString& _data) @@ -97,9 +92,6 @@ bool exml::Document::Load(const etk::UString& _file) // parse the data : bool ret = Parse(tmpDataUnicode); //Display(); - if (0==Size()) { - EXML_CRITICAL("lkjlkj"); - } return ret; } @@ -132,3 +124,45 @@ void exml::Document::Display(void) EXML_INFO("Generated XML : \n" << tmpp); } +etk::UString CreatePosPointer(const etk::UString& _line, int32_t _pos) +{ + etk::UString out; + int32_t iii; + for (iii=0; iii<_pos && iii<_line.Size(); iii++) { + if (_line[iii] == '\t') { + out += "\t"; + } else { + out += " "; + } + } + for (; iii<_pos; iii++) { + out += " "; + } + out += "^"; + return out; +} + +void exml::Document::DisplayError(void) +{ + if (m_comment.Size()==0) { + EXML_ERROR("No error detected ???"); + return; + } + EXML_ERROR(m_filePos << " " << m_comment << "\n" + << m_Line << "\n" + << CreatePosPointer(m_Line, m_filePos.GetCol()) ); + #ifdef ENABLE_CRITICAL_WHEN_ERROR + EXML_CRITICAL("detect error"); + #endif +} + +void exml::Document::CreateError(const etk::UString& _data, int32_t _pos, const exml::filePos& _filePos, const etk::UString& _comment) +{ + m_comment = _comment; + m_Line = _data.ExtractLine(_pos); + m_filePos = _filePos; + if (true==m_writeErrorWhenDetexted) { + DisplayError(); + } +} + diff --git a/exml/Document.h b/exml/Document.h index 246d049..b87d81b 100644 --- a/exml/Document.h +++ b/exml/Document.h @@ -85,15 +85,38 @@ namespace exml * @brief Display the Document on console */ void Display(void); + private: + bool m_writeErrorWhenDetexted; + etk::UString m_comment; + etk::UString m_Line; + exml::filePos m_filePos; + public: + void DisplayErrorWhenDetected(void) { m_writeErrorWhenDetexted=true; }; + void NotDisplayErrorWhenDetected(void) { m_writeErrorWhenDetexted=false; }; + + void CreateError(const etk::UString& _data, int32_t _pos, const exml::filePos& _filePos, const etk::UString& _comment); + void DisplayError(void); public: // herited function: virtual nodeType_te GetType(void) const { return typeDocument; }; - bool Parse(const etk::UString& _data, int32_t& _pos, bool _caseSensitive, ivec2& _filePos); bool Generate(etk::UString& _data, int32_t _indent) const; virtual exml::Document* ToDocument(void) { return this; }; virtual const exml::Document* ToDocument(void) const { return this; }; }; }; +/* +#define CREATE_ERROR(doc,data,pos,filePos,comment) \ + EXML_ERROR( (pos) << " " << (comment) << "\n" \ + << (data).ExtractLine((pos)) << "\n" \ + << CreatePosPointer((filePos).GetCol()) ) +*/ +#define CREATE_ERROR(doc,data,pos,filePos,comment) \ + do { \ + EXML_ERROR(comment); \ + (doc).CreateError((data),(pos),(filePos),(comment)); \ + } while (0) + +//__LINE__, __class__, __func__ #endif diff --git a/exml/Element.cpp b/exml/Element.cpp index 8d2e2f7..69be38b 100644 --- a/exml/Element.cpp +++ b/exml/Element.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #undef __class__ #define __class__ "Element" @@ -183,31 +184,35 @@ bool exml::Element::Generate(etk::UString& _data, int32_t _indent) const } -bool exml::Element::SubParse(const etk::UString& _data, int32_t& _pos, bool _caseSensitive, ivec2& _filePos, bool _mainNode) +bool exml::Element::SubParse(const etk::UString& _data, int32_t& _pos, bool _caseSensitive, exml::filePos& _filePos, exml::Document& _doc, bool _mainNode) { - EXML_VERBOSE(" start subParse ... " << _pos << " " << _filePos); - m_pos = _filePos; + EXML_PARSE_ELEMENT(" start subParse ... " << _pos << " " << _filePos); for (int32_t iii=_pos; iii<_data.Size(); iii++) { - _filePos += ivec2(1,0); + _filePos.Check(_data[iii]); #ifdef ENABLE_DISPLAY_PARSED_ELEMENT DrawElementParsed(_data[iii], _filePos); #endif + exml::filePos tmpPos; if (_data[iii] == '<') { - int32_t white = CountWhiteChar(_data, iii+1); + int32_t white = CountWhiteChar(_data, iii+1, tmpPos); if (iii+white+1>=_data.Size()) { - EXML_ERROR(_filePos << " ==> end file with '<' char ==> invalide XML"); + _filePos+=tmpPos; + CREATE_ERROR(_doc, _data, _pos, _filePos, "End file with '<' char ==> invalide XML"); _pos = iii+white; return false; } // Detect type of the element: if(_data[iii+white+1] == '>') { - EXML_ERROR(_filePos << " find '>' with no element in the element..."); + _filePos+=tmpPos; + CREATE_ERROR(_doc, _data, _pos, _filePos, "Find '>' with no element in the element..."); _pos = iii+white+1; return false; } if(_data[iii+white+1] == '?') { + ++tmpPos; + // TODO : white space ... if( false == CheckAvaillable(_data[iii+white+2], true) ) { - EXML_ERROR(_filePos << " find unavaillable name in the Declaration node..."); + CREATE_ERROR(_doc, _data, _pos, _filePos, "Find unavaillable name in the Declaration node..."); _pos = iii+white+1; return false; } @@ -221,21 +226,21 @@ bool exml::Element::SubParse(const etk::UString& _data, int32_t& _pos, bool _cas } else { break; } + tmpPos.Check(_data[jjj]); } - etk::UString tmpname = _data.Extract(iii+white+1, endPosName+1); + etk::UString tmpname = _data.Extract(iii+white+2, endPosName+1); if (true==_caseSensitive) { tmpname.Lower(); } // Find declaration balise - exml::Declaration* declaration = new exml::Declaration(); + exml::Declaration* declaration = new exml::Declaration(tmpname); if (NULL==declaration) { - EXML_ERROR(_filePos << " Allocation error ..."); + CREATE_ERROR(_doc, _data, _pos, _filePos, "Allocation Error..."); return false; } - declaration->SetValue(tmpname); - _pos = iii+white+2; - _filePos += ivec2(3+white,0); - if (false==declaration->Parse(_data, _pos, _caseSensitive, _filePos)) { + _filePos += tmpPos; + _pos = endPosName+1; + if (false==declaration->Parse(_data, _pos, _caseSensitive, _filePos, _doc)) { delete(declaration); return false; } @@ -244,37 +249,41 @@ bool exml::Element::SubParse(const etk::UString& _data, int32_t& _pos, bool _cas continue; } if(_data[iii+white+1] == '!') { + ++tmpPos; // Find special block element if (iii+white+2>=_data.Size()) { - EXML_ERROR(_filePos << " ==> end file with ' invalide XML"); + CREATE_ERROR(_doc, _data, _pos, _filePos, "End file with ' invalide XML"); return false; } if(_data[iii+white+2] == '-') { + ++tmpPos; if (iii+white+3>=_data.Size()) { - EXML_ERROR(_filePos << " ==> end file with ' invalide XML"); + CREATE_ERROR(_doc, _data, _pos, _filePos, "End file with ' invalide XML"); return false; } if(_data[iii+white+3] != '-') { - EXML_ERROR(_filePos << " ==> element parse with ' invalide XML"); + CREATE_ERROR(_doc, _data, _pos, _filePos, etk::UString("Element parse with ' invalide XML"); return false; } + ++tmpPos; // find comment: exml::Comment* comment = new exml::Comment(); if (NULL==comment) { - EXML_ERROR(_filePos << " Allocation error ..."); + CREATE_ERROR(_doc, _data, _pos, _filePos, "Allocation error ..."); return false; } _pos = iii+white+4; - _filePos += ivec2(3+white,0); - if (false==comment->Parse(_data, _pos, _caseSensitive, _filePos)) { + _filePos += tmpPos; + if (false==comment->Parse(_data, _pos, _caseSensitive, _filePos, _doc)) { delete(comment); return false; } iii = _pos; m_listSub.PushBack(comment); } else if (_data[iii+white+2] == '[') { + ++tmpPos; if (iii+white+8>=_data.Size()) { - EXML_ERROR(_filePos << " ==> end file with ' invalide XML"); + CREATE_ERROR(_doc, _data, _pos, _filePos, "End file with ' invalide XML"); return false; } if( _data[iii+white+3] != 'C' @@ -283,31 +292,33 @@ bool exml::Element::SubParse(const etk::UString& _data, int32_t& _pos, bool _cas || _data[iii+white+6] != 'T' || _data[iii+white+7] != 'A' || _data[iii+white+8] != '[') { - EXML_ERROR(_filePos << " ==> element parse with ' invalide XML"); + CREATE_ERROR(_doc, _data, _pos, _filePos, etk::UString("Element parse with ' invalide XML"); return false; } + tmpPos+=6; // find text: exml::TextCDATA* text = new exml::TextCDATA(); if (NULL==text) { - EXML_ERROR(_filePos << " Allocation error ..."); + CREATE_ERROR(_doc, _data, _pos, _filePos, "Allocation error ..."); return false; } _pos = iii+9+white; - _filePos += ivec2(8+white,0); - if (false==text->Parse(_data, _pos, _caseSensitive, _filePos)) { + _filePos += tmpPos; + if (false==text->Parse(_data, _pos, _caseSensitive, _filePos, _doc)) { delete(text); return false; } iii = _pos; m_listSub.PushBack(text); } else { - EXML_ERROR(_filePos << " ==> end file with ' invalide XML"); + CREATE_ERROR(_doc, _data, _pos, _filePos, etk::UString("End file with ' invalide XML"); return false; } continue; } if(_data[iii+white+1] == '/') { + ++tmpPos; //EXML_DEBUG("Generate node name : '" << _data[iii+1] << "'"); int32_t endPosName = iii+white+1; // Generate element name ... @@ -318,6 +329,7 @@ bool exml::Element::SubParse(const etk::UString& _data, int32_t& _pos, bool _cas } else { break; } + tmpPos.Check(_data[jjj]); } etk::UString tmpname = _data.Extract(iii+white+2, endPosName+1); if (true==_caseSensitive) { @@ -327,36 +339,37 @@ bool exml::Element::SubParse(const etk::UString& _data, int32_t& _pos, bool _cas // find end of node : // find > element ... for (int32_t jjj=endPosName+1; jjj<_data.Size(); jjj++) { - _filePos += ivec2(1,0); #ifdef ENABLE_DISPLAY_PARSED_ELEMENT DrawElementParsed(_data[jjj], _filePos); #endif - if (_data[jjj] == '\n') { - _filePos.setValue(0, _filePos.y()+1); + if (true==tmpPos.Check(_data[jjj])) { continue; } if(_data[jjj] == '>') { _pos = jjj; + _filePos += tmpPos; return true; } else if( _data[jjj] != '\r' && _data[jjj] != ' ' && _data[jjj] != '\t') { - EXML_ERROR(_filePos << " ==> end node error : have data inside end node other than [ \\n\\t\\r] " << m_value << "'"); + _filePos += tmpPos; + CREATE_ERROR(_doc, _data, jjj, _filePos, etk::UString("End node error : have data inside end node other than [ \\n\\t\\r] ") + m_value + "'"); return false; } } } else { - EXML_ERROR(_filePos << " ==> end node error : '" << tmpname << "' != '" << m_value << "'"); + CREATE_ERROR(_doc, _data, _pos, _filePos, etk::UString("End node error : '") + tmpname + "' != '" + m_value + "'"); return false; } } if (_data[iii+white+1] == '>') { // end of something ==> this is really bad - EXML_ERROR(_filePos << " ==> find '>' chars ==> invalide XML"); + CREATE_ERROR(_doc, _data, _pos, _filePos, "Find '>' chars ==> invalide XML"); return false; } if( true == CheckAvaillable(_data[iii+white+1], true) ) { + ++tmpPos; //EXML_DEBUG("Generate node name : '" << _data[iii+1] << "'"); int32_t endPosName = iii+white+1; // Generate element name ... @@ -367,6 +380,7 @@ bool exml::Element::SubParse(const etk::UString& _data, int32_t& _pos, bool _cas } else { break; } + tmpPos.Check(_data[jjj]); } etk::UString tmpname = _data.Extract(iii+white+1, endPosName+1); if (true==_caseSensitive) { @@ -374,50 +388,46 @@ bool exml::Element::SubParse(const etk::UString& _data, int32_t& _pos, bool _cas } //EXML_INFO("find node named : '" << tmpname << "'"); // find text: - exml::Element* element = new exml::Element(); + exml::Element* element = new exml::Element(tmpname); if (NULL==element) { - EXML_ERROR(_filePos << " Allocation error ..."); + CREATE_ERROR(_doc, _data, _pos, _filePos, "Allocation error ..."); return false; } - element->SetValue(tmpname); _pos = endPosName+1; - _filePos += ivec2(endPosName,0); - if (false==element->Parse(_data, _pos, _caseSensitive, _filePos)) { + _filePos += tmpPos; + if (false==element->Parse(_data, _pos, _caseSensitive, _filePos, _doc)) { delete(element); return false; } iii = _pos; m_listSub.PushBack(element); - - continue; } + _filePos+=tmpPos; // here we have an error : - EXML_ERROR(_filePos << " find an ununderstanding element : '" << _data[iii+white+1] << "'"); + CREATE_ERROR(_doc, _data, _pos, _filePos, etk::UString("Find an ununderstanding element : '") + _data[iii+white+1] + "'"); return false; } else { if (_data[iii] == '>') { - EXML_ERROR(_filePos << " find elemement '>' ==> no reason to be here ..."); + CREATE_ERROR(_doc, _data, _pos, _filePos, "Find elemement '>' ==> no reason to be here ..."); return false; } // might to be data text ... - if (_data[iii] == '\n') { - _filePos.setValue(1, _filePos.y()+1); - }else if( _data[iii] == ' ' - || _data[iii] == '\t' - || _data[iii] == '\r') { + if( _data[iii] == '\n' + || _data[iii] == ' ' + || _data[iii] == '\t' + || _data[iii] == '\r') { // empty spaces ==> nothing to do .... - } else { // find data ==> parse it... exml::Text* text = new exml::Text(); if (NULL==text) { - EXML_ERROR(_filePos << " Allocation error ..."); + CREATE_ERROR(_doc, _data, _pos, _filePos, "Allocation error ..."); return false; } _pos = iii; - _filePos += ivec2(1,0); - if (false==text->Parse(_data, _pos, _caseSensitive, _filePos)) { + _filePos += tmpPos; + if (false==text->Parse(_data, _pos, _caseSensitive, _filePos, _doc)) { delete(text); return false; } @@ -426,32 +436,33 @@ bool exml::Element::SubParse(const etk::UString& _data, int32_t& _pos, bool _cas } } } - return true; + if (_mainNode == true) { + return true; + } + CREATE_ERROR(_doc, _data, _pos, _filePos, etk::UString("Did not find end of the exml::Element : '") + m_value + "'"); + return false; } -bool exml::Element::Parse(const etk::UString& _data, int32_t& _pos, bool _caseSensitive, ivec2& _filePos) +bool exml::Element::Parse(const etk::UString& _data, int32_t& _pos, bool _caseSensitive, exml::filePos& _filePos, exml::Document& _doc) { - EXML_VERBOSE("start parse : 'element' named='" << m_value << "'"); + EXML_PARSE_ELEMENT("start parse : 'element' named='" << m_value << "'"); // note : When start parsing the upper element must have set the value of the element and set the position after this one - + m_pos=_filePos; // find a normal node ... for (int32_t iii=_pos; iii<_data.Size(); iii++) { - _filePos += ivec2(1,0); - if (_data[iii] == '\n') { - _filePos.setValue(1, _filePos.y()+1); - } + _filePos.Check(_data[iii]); #ifdef ENABLE_DISPLAY_PARSED_ELEMENT DrawElementParsed(_data[iii], _filePos); #endif if(_data[iii] == '>') { // we find the end ... _pos = iii+1; - return exml::Element::SubParse(_data, _pos, _caseSensitive, _filePos, false); + return exml::Element::SubParse(_data, _pos, _caseSensitive, _filePos, _doc, false); } if (_data[iii] == '/') { // standalone node or error... if (iii+1>=_data.Size()) { - EXML_ERROR(_filePos << " find end of files ... ==> bad case"); + CREATE_ERROR(_doc, _data, _pos, _filePos, "Find end of files ... ==> bad case"); return false; } // TODO : Can have white spaces .... @@ -460,18 +471,18 @@ bool exml::Element::Parse(const etk::UString& _data, int32_t& _pos, bool _caseSe return true; } // error - EXML_ERROR(_filePos << "find / without > char ..."); + CREATE_ERROR(_doc, _data, _pos, _filePos, "Find / without > char ..."); return false; } if (true == CheckAvaillable(_data[iii], true)) { // we find an attibute ==> create a new and parse it : exml::Attribute* attribute = new exml::Attribute(); if (NULL==attribute) { - EXML_ERROR(_filePos << " Allocation error ..."); + CREATE_ERROR(_doc, _data, _pos, _filePos, "Allocation error ..."); return false; } _pos = iii; - if (false==attribute->Parse(_data, _pos, _caseSensitive, _filePos)) { + if (false==attribute->Parse(_data, _pos, _caseSensitive, _filePos, _doc)) { delete(attribute); return false; } @@ -480,11 +491,12 @@ bool exml::Element::Parse(const etk::UString& _data, int32_t& _pos, bool _caseSe continue; } if (false==_data[iii].IsWhiteChar()) { - EXML_ERROR(_filePos << " find an unknow element : '" << _data[iii] << "'"); + CREATE_ERROR(_doc, _data, iii, _filePos, etk::UString("Find an unknow element : '") + _data[iii] + "'"); return false; } } - return true; + CREATE_ERROR(_doc, _data, _pos, _filePos, etk::UString("Unexpecting end of parsing exml::Element : '") + m_value + "' ==> check if the '/>' is set or the end of element"); + return false; } void exml::Element::Clear(void) diff --git a/exml/Element.h b/exml/Element.h index 6d996cf..b467f4d 100644 --- a/exml/Element.h +++ b/exml/Element.h @@ -78,10 +78,10 @@ namespace exml */ etk::UString GetText(void); protected: - bool SubParse(const etk::UString& _data, int32_t& _pos, bool _caseSensitive, ivec2& _filePos, bool _mainNode=false); + bool SubParse(const etk::UString& _data, int32_t& _pos, bool _caseSensitive, exml::filePos& _filePos, exml::Document& _doc, bool _mainNode=false); public: // herited function: virtual nodeType_te GetType(void) const { return typeElement; }; - virtual bool Parse(const etk::UString& _data, int32_t& _pos, bool _caseSensitive, ivec2& _filePos); + virtual bool Parse(const etk::UString& _data, int32_t& _pos, bool _caseSensitive, exml::filePos& _filePos, exml::Document& _doc); virtual bool Generate(etk::UString& _data, int32_t _indent) const; virtual exml::Element* ToElement(void) { return this; }; virtual const exml::Element* ToElement(void) const { return this; }; diff --git a/exml/Node.cpp b/exml/Node.cpp index 10b8a74..a1a52c8 100644 --- a/exml/Node.cpp +++ b/exml/Node.cpp @@ -12,6 +12,17 @@ #undef __class__ #define __class__ "Node" + +etk::CCout& exml::operator <<(etk::CCout& _os, const exml::filePos& _obj) +{ + _os << "(l="; + _os << _obj.GetLine(); + _os << ",c="; + _os << _obj.GetCol(); + _os << ")"; + return _os; +} + exml::Node::Node(const etk::UString& _value) : m_pos(0,0), m_value(_value) @@ -26,9 +37,8 @@ void exml::Node::AddIndent(etk::UString& _data, int32_t _indent) const } } -void exml::Node::DrawElementParsed(const etk::UniChar& _val, const ivec2& _filePos) const +void exml::Node::DrawElementParsed(const etk::UniChar& _val, const exml::filePos& _filePos) const { - EXML_CRITICAL("lkjlkj"); if (_val=='\n') { EXML_DEBUG(_filePos << " Parse '\\n'"); } else if (_val=='\t') { @@ -86,21 +96,24 @@ bool exml::Node::CheckAvaillable(const etk::UniChar& _val, bool _firstChar) cons } -int32_t exml::Node::CountWhiteChar(const etk::UString& _data, int32_t _pos) const +int32_t exml::Node::CountWhiteChar(const etk::UString& _data, int32_t _pos, exml::filePos& _filePos) const { + _filePos.Clear(); int32_t white=0; for (int32_t iii=_pos; iii<_data.Size(); iii++) { + _filePos.Check(_data[iii]); if(true == _data[iii].IsWhiteChar()) { white++; } else { break; } } + --_filePos; return white; } void exml::Node::Clear(void) { m_value=""; - m_pos.setValue(0,0); + m_pos.Clear(); } diff --git a/exml/Node.h b/exml/Node.h index 05d4944..437195f 100644 --- a/exml/Node.h +++ b/exml/Node.h @@ -16,6 +16,17 @@ namespace exml { //#define ENABLE_DISPLAY_PARSED_ELEMENT + //#define ENABLE_CRITICAL_WHEN_ERROR + #if 1 + #define EXML_PARSE_ELEMENT EXML_VERBOSE + #else + #define EXML_PARSE_ELEMENT EXML_DEBUG + #endif + #if 1 + #define EXML_PARSE_ATTRIBUTE EXML_VERBOSE + #else + #define EXML_PARSE_ATTRIBUTE EXML_DEBUG + #endif class Document; class Attribute; class Comment; @@ -34,6 +45,63 @@ namespace exml typeText, //!< InsideText } nodeType_te; + class filePos + { + private: + int32_t m_col; + int32_t m_line; + public: + filePos(void) : m_col(0),m_line(0) { }; + filePos(int32_t _line, int32_t _col) : m_col(_col),m_line(_line) { }; + ~filePos(void) { }; + filePos& operator ++(void) { m_col++; return *this; }; + filePos& operator --(void) { m_col--; if(m_col<0) { m_col=0; return *this; } }; + const filePos& operator +=(const filePos& _obj) + { + if (_obj.m_line==0) { + m_col += _obj.m_col; + } else { + m_col = _obj.m_col; + m_line += _obj.m_line; + } + return *this; + }; + const filePos& operator +=(int32_t _col) + { + m_col += _col; + return *this; + }; + const filePos& operator= (const filePos& _obj ) + { + m_col = _obj.m_col; + m_line = _obj.m_line; + return *this; + } + void NewLine(void) { m_col=0; m_line++; }; + bool Check(const etk::UniChar& _val) + { + m_col++; + if (_val=='\n') { + NewLine(); + return true; + } + return false; + } + void Set(int32_t _line, int32_t _col) + { + m_col = _col; + m_line = _line; + } + void Clear(void) + { + m_col = 0; + m_line = 0; + } + int32_t GetCol(void) const { return m_col; }; + int32_t GetLine(void) const { return m_line; }; + }; + etk::CCout& operator <<(etk::CCout& _os, const filePos& _obj); + class Node { public: @@ -59,7 +127,7 @@ namespace exml * @param[in,out] file parsing position (line x col x) * @return false if an error occured. */ - virtual bool Parse(const etk::UString& _data, int32_t& _pos, bool _caseSensitive, ivec2& _filePos) = 0; + virtual bool Parse(const etk::UString& _data, int32_t& _pos, bool _caseSensitive, exml::filePos& _filePos, exml::Document& _doc) = 0; /** * @brief Generate a string with the tree of the xml * @param[in,out] _data string where to add the elements @@ -68,12 +136,12 @@ namespace exml */ virtual bool Generate(etk::UString& _data, int32_t _indent) const { return true; }; protected: - ivec2 m_pos; //!< position in the readed file ==> not correct when the file is generated + exml::filePos m_pos; //!< position in the readed file ==> not correct when the file is generated public: /** * @brief Get the current position where the element is in the file */ - const ivec2& GetPos(void) { return m_pos; }; + const exml::filePos& GetPos(void) { return m_pos; }; protected: etk::UString m_value; //!< value of the node (for element this is the name, for text it is the inside text ...) public: @@ -105,7 +173,7 @@ namespace exml * @param[in] _val Char that is parsed. * @param[in] _filePos Position of the char in the file. */ - void DrawElementParsed(const etk::UniChar& _val, const ivec2& _filePos) const; + void DrawElementParsed(const etk::UniChar& _val, const exml::filePos& _filePos) const; /** * @brief check if an element or attribute is availlable (not : !"#$%&'()*+,/;<=>?@[\]^`{|}~ \n\t\r and for first char : not -.0123456789). * @param[in] _val Value to check the conformity. @@ -116,9 +184,10 @@ namespace exml * @brief count the number of white char in the string from the specify position (stop at the first element that is not a white char) * @param[in] _data Data to parse. * @param[in] _pos Start position in the string. + * @param[out] _filePos new poistion of te file to add. * @return number of white element. */ - int32_t CountWhiteChar(const etk::UString& _data, int32_t _pos) const; + int32_t CountWhiteChar(const etk::UString& _data, int32_t _pos, exml::filePos& _filePos) const; public: /** * @brief Cast the element in a Document if it is possible. diff --git a/exml/Text.cpp b/exml/Text.cpp index 8f681f4..e4016c9 100644 --- a/exml/Text.cpp +++ b/exml/Text.cpp @@ -8,6 +8,7 @@ #include #include +#include #undef __class__ #define __class__ "Text" @@ -29,18 +30,16 @@ int32_t exml::Text::CountLines(void) const return count; } -bool exml::Text::Parse(const etk::UString& _data, int32_t& _pos, bool _caseSensitive, ivec2& _filePos) +bool exml::Text::Parse(const etk::UString& _data, int32_t& _pos, bool _caseSensitive, exml::filePos& _filePos, exml::Document& _doc) { EXML_VERBOSE("start parse : 'text'"); m_pos = _filePos; // search end of the comment : for (int32_t iii=_pos; iii<_data.Size(); iii++) { - _filePos += ivec2(1,0); #ifdef ENABLE_DISPLAY_PARSED_ELEMENT DrawElementParsed(_data[iii], _filePos); #endif - if (_data[iii] == '\n') { - _filePos.setValue(0, _filePos.y()+1); + if (_filePos.Check(_data[iii]) == true) { continue; } if( _data[iii] == '>' @@ -61,38 +60,36 @@ bool exml::Text::Parse(const etk::UString& _data, int32_t& _pos, bool _caseSensi return true; } } + CREATE_ERROR(_doc, _data, _pos, _filePos, "Text got end of file without finding end node"); _pos = _data.Size(); - EXML_ERROR("Text got end of file without finding end node"); - EXML_ERROR(" Data : " << _data); return false; } -bool exml::TextCDATA::Parse(const etk::UString& _data, int32_t& _pos, bool _caseSensitive, ivec2& _filePos) +bool exml::TextCDATA::Parse(const etk::UString& _data, int32_t& _pos, bool _caseSensitive, exml::filePos& _filePos, exml::Document& _doc) { EXML_VERBOSE("start parse : 'text::CDATA'"); m_pos = _filePos; // search end of the comment : for (int32_t iii=_pos; iii+2<_data.Size(); iii++) { - _filePos += ivec2(1,0); #ifdef ENABLE_DISPLAY_PARSED_ELEMENT DrawElementParsed(_data[iii], _filePos); #endif - if (_data[iii] == '\n') { - _filePos.setValue(1, _filePos.y()+1); + if (_filePos.Check(_data[iii]) == true) { continue; } if( _data[iii] == ']' && _data[iii+1] == ']' && _data[iii+2] == '>') { // find end of value: + _filePos += 2; m_value = _data.Extract(_pos, iii); EXML_VERBOSE(" find text CDATA '" << m_value << "'"); _pos = iii+2; return true; } } + CREATE_ERROR(_doc, _data, _pos, _filePos, "text CDATA got end of file without finding end node"); _pos = _data.Size(); - EXML_ERROR("text CDATA got end of file without finding end node"); return false; } diff --git a/exml/Text.h b/exml/Text.h index 7ef3e3b..268ef9a 100644 --- a/exml/Text.h +++ b/exml/Text.h @@ -37,7 +37,7 @@ namespace exml int32_t CountLines(void) const; public: // herited function: virtual nodeType_te GetType(void) const { return typeText; }; - virtual bool Parse(const etk::UString& _data, int32_t& _pos, bool _caseSensitive, ivec2& _filePos); + virtual bool Parse(const etk::UString& _data, int32_t& _pos, bool _caseSensitive, exml::filePos& _filePos, exml::Document& _doc); virtual bool Generate(etk::UString& _data, int32_t _indent) const; virtual exml::Text* ToText(void) { return this; }; virtual const exml::Text* ToText(void) const{ return this; }; @@ -54,7 +54,7 @@ namespace exml */ virtual ~TextCDATA(void) { }; public: // herited function: - virtual bool Parse(const etk::UString& _data, int32_t& _pos, bool _caseSensitive, ivec2& _filePos); + virtual bool Parse(const etk::UString& _data, int32_t& _pos, bool _caseSensitive, exml::filePos& _filePos, exml::Document& _doc); }; }; diff --git a/exml/test.cpp b/exml/test.cpp index 77870fa..8681970 100644 --- a/exml/test.cpp +++ b/exml/test.cpp @@ -37,6 +37,9 @@ void Init(void) etk::UString input; testCheck check; + // ====================================================== + check.Set("test exml::Element", -2, ""); + l_list.PushBack(check); // ====================================================== reference = "\n"; check.Set(reference, @@ -97,9 +100,116 @@ void Init(void) 1, "\n"); l_list.PushBack(check); - // ------------------------------------------------------ + check.Set("\n", + 1, + "\n\n"); + l_list.PushBack(check); // ====================================================== - check.Set("", -2, ""); + check.Set("test element exml::Attribute ", -2, ""); + l_list.PushBack(check); + // ====================================================== + check.Set("\n", + -1, + "\n"); + l_list.PushBack(check); + // ------------------------------------------------------ + check.Set("\n", + -1, + "\n"); + l_list.PushBack(check); + // ------------------------------------------------------ + check.Set("\n", + -1, + "\n"); + l_list.PushBack(check); + // ------------------------------------------------------ + check.Set("\n", + -1, + "\n"); + l_list.PushBack(check); + // ------------------------------------------------------ + check.Set("\n", + -1, + "\n"); + l_list.PushBack(check); + // ------------------------------------------------------ + check.Set("\n", + -1, + "\n"); + l_list.PushBack(check); + // ------------------------------------------------------ + check.Set("\n", + -1, + "\n"); + l_list.PushBack(check); + // ------------------------------------------------------ + check.Set("\n", + -1, + "\n"); + l_list.PushBack(check); + // ------------------------------------------------------ + check.Set("\n", + -1, + "\n"); + l_list.PushBack(check); + // ------------------------------------------------------ + check.Set("\n", + -1, + "\n"); + l_list.PushBack(check); + // ====================================================== + check.Set("test exml::Declaration", -2, ""); + l_list.PushBack(check); + // ====================================================== + check.Set("\n", + -1, + "\n"); + l_list.PushBack(check); + // ====================================================== + check.Set("test Declaration exml::Attribute", -2, ""); + l_list.PushBack(check); + // ====================================================== + check.Set("\n", + -1, + "\n"); + l_list.PushBack(check); + // ------------------------------------------------------ + check.Set("\n", + -1, + "\n"); + l_list.PushBack(check); + // ------------------------------------------------------ + check.Set("\n", + -1, + "\n"); + l_list.PushBack(check); + // ------------------------------------------------------ + check.Set("\n", + -1, + "\n"); + l_list.PushBack(check); + // ------------------------------------------------------ + check.Set("\n", + -1, + "\n"); + l_list.PushBack(check); + // ------------------------------------------------------ + check.Set("\n", + -1, + "\n"); + l_list.PushBack(check); + // ------------------------------------------------------ + check.Set("\n", + -1, + "\n"); + l_list.PushBack(check); + // ------------------------------------------------------ + check.Set("\n", + -1, + "\n"); + l_list.PushBack(check); + // ====================================================== + check.Set("test exml::Comment", -2, ""); l_list.PushBack(check); // ====================================================== check.Set("\n", @@ -142,7 +252,7 @@ void Init(void) "\n"); l_list.PushBack(check); // ====================================================== - check.Set("", -2, ""); + check.Set("test all", -2, ""); l_list.PushBack(check); // ====================================================== reference= "\n" @@ -157,7 +267,17 @@ void Init(void) " Text example ...\n" " \n" "\n"; - check.Set(reference, 1, input); + check.Set(reference, -1, input); + l_list.PushBack(check); + // ------------------------------------------------------ + check.Set("", 1, + "< exemple\n >\n" + " \n" + " >\n" + " \n" + " Text example ...\n" + " \n" + "\n"); l_list.PushBack(check); } @@ -173,7 +293,9 @@ int main(int argc, const char *argv[]) if (l_list[iii].m_errorPos==-2) { countSeparator++; sectionID = 0; - EXML_INFO("-----------------------------------------------------------------------------------"); + EXML_INFO("-------------------------------------------------------------"); + EXML_INFO("-- " << l_list[iii].m_ref); + EXML_INFO("-------------------------------------------------------------"); continue; } sectionID++;