[DEV] add more test and compatibility and add a better error display
This commit is contained in:
parent
2f5856ca2f
commit
12f6785e62
@ -8,6 +8,7 @@
|
||||
|
||||
#include <exml/Attribute.h>
|
||||
#include <exml/debug.h>
|
||||
#include <exml/Document.h>
|
||||
|
||||
#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;
|
||||
|
@ -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; };
|
||||
|
@ -8,28 +8,30 @@
|
||||
|
||||
#include <exml/Comment.h>
|
||||
#include <exml/debug.h>
|
||||
#include <exml/Document.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
|
@ -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; };
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include <exml/Declaration.h>
|
||||
#include <exml/debug.h>
|
||||
#include <exml/Document.h>
|
||||
|
||||
#undef __class__
|
||||
#define __class__ "Declaration"
|
||||
@ -19,9 +20,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
*/
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -21,13 +21,10 @@ namespace exml
|
||||
*/
|
||||
Declaration(void) { };
|
||||
/**
|
||||
* @brief Constructor for the generic declaration : <?xml version="" format="UTF-8"?>
|
||||
* @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 : <?xml version="" format="UTF-8"?>
|
||||
* @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) { };
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
144
exml/Element.cpp
144
exml/Element.cpp
@ -12,6 +12,7 @@
|
||||
#include <exml/Comment.h>
|
||||
#include <exml/Attribute.h>
|
||||
#include <exml/Declaration.h>
|
||||
#include <exml/Document.h>
|
||||
|
||||
#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 '<!' chars ==> invalide XML");
|
||||
CREATE_ERROR(_doc, _data, _pos, _filePos, "End file with '<!' chars ==> invalide XML");
|
||||
return false;
|
||||
}
|
||||
if(_data[iii+white+2] == '-') {
|
||||
++tmpPos;
|
||||
if (iii+white+3>=_data.Size()) {
|
||||
EXML_ERROR(_filePos << " ==> end file with '<!-' chars ==> invalide XML");
|
||||
CREATE_ERROR(_doc, _data, _pos, _filePos, "End file with '<!-' chars ==> invalide XML");
|
||||
return false;
|
||||
}
|
||||
if(_data[iii+white+3] != '-') {
|
||||
EXML_ERROR(_filePos << " ==> element parse with '<!-" << _data[iii+3] << "' chars ==> invalide XML");
|
||||
CREATE_ERROR(_doc, _data, _pos, _filePos, etk::UString("Element parse with '<!-") + _data[iii+3] + "' chars ==> 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 '<![' chars ==> invalide XML");
|
||||
CREATE_ERROR(_doc, _data, _pos, _filePos, "End file with '<![' chars ==> 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 '<![" << _data[iii+white+3] << _data[iii+white+4] << _data[iii+white+5] << _data[iii+white+6] << _data[iii+white+7] << _data[iii+white+8] << "' chars ==> invalide XML");
|
||||
CREATE_ERROR(_doc, _data, _pos, _filePos, etk::UString("Element parse with '<![") + _data[iii+white+3] + _data[iii+white+4] + _data[iii+white+5] + _data[iii+white+6] + _data[iii+white+7] + _data[iii+white+8] + "' chars ==> 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 '<!" << _data[iii+white+2] << "' chars ==> invalide XML");
|
||||
CREATE_ERROR(_doc, _data, _pos, _filePos, etk::UString("End file with '<!") + _data[iii+white+2] + "' chars ==> 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)
|
||||
|
@ -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; };
|
||||
|
@ -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();
|
||||
}
|
||||
|
79
exml/Node.h
79
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, //!< <XXX> InsideText </XXX>
|
||||
} 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.
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include <exml/Text.h>
|
||||
#include <exml/debug.h>
|
||||
#include <exml/Document.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
};
|
||||
};
|
||||
|
||||
|
132
exml/test.cpp
132
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 = "<exemple/>\n";
|
||||
check.Set(reference,
|
||||
@ -97,9 +100,116 @@ void Init(void)
|
||||
1,
|
||||
"<exemple-->\n");
|
||||
l_list.PushBack(check);
|
||||
// ------------------------------------------------------
|
||||
check.Set("<exemple/>\n",
|
||||
1,
|
||||
"<exemple>\n</exemple sdfgsdfg>\n");
|
||||
l_list.PushBack(check);
|
||||
// ======================================================
|
||||
check.Set("", -2, "");
|
||||
check.Set("test element exml::Attribute ", -2, "");
|
||||
l_list.PushBack(check);
|
||||
// ======================================================
|
||||
check.Set("<elementtt attr=\"plop\"/>\n",
|
||||
-1,
|
||||
"<elementtt attr=\"plop\"/>\n");
|
||||
l_list.PushBack(check);
|
||||
// ------------------------------------------------------
|
||||
check.Set("<elementtt attr=\"plop\"/>\n",
|
||||
-1,
|
||||
"<elementtt attr=plop/>\n");
|
||||
l_list.PushBack(check);
|
||||
// ------------------------------------------------------
|
||||
check.Set("<elementtt attr=\"234345@3452345_.'\"/>\n",
|
||||
-1,
|
||||
"<elementtt attr=234345@3452345_.' />\n");
|
||||
l_list.PushBack(check);
|
||||
// ------------------------------------------------------
|
||||
check.Set("<elementtt attr=\"plop\"/>\n",
|
||||
-1,
|
||||
"<elementtt attr =\"plop\"/>\n");
|
||||
l_list.PushBack(check);
|
||||
// ------------------------------------------------------
|
||||
check.Set("<elementtt attr=\"plop\"/>\n",
|
||||
-1,
|
||||
"<elementtt attr= \"plop\"/>\n");
|
||||
l_list.PushBack(check);
|
||||
// ------------------------------------------------------
|
||||
check.Set("<elementtt attr=\"plop\"/>\n",
|
||||
-1,
|
||||
"<elementtt attr\n=\n\"plop\"/>\n");
|
||||
l_list.PushBack(check);
|
||||
// ------------------------------------------------------
|
||||
check.Set("<elementtt attr=\"plop\"/>\n",
|
||||
-1,
|
||||
"<elementtt attr=plop/>\n");
|
||||
l_list.PushBack(check);
|
||||
// ------------------------------------------------------
|
||||
check.Set("<elementtt attr=\"plop\"/>\n",
|
||||
-1,
|
||||
"<elementtt attr \n = \n\t plop/>\n");
|
||||
l_list.PushBack(check);
|
||||
// ------------------------------------------------------
|
||||
check.Set("<elementtt attr=\"\"/>\n",
|
||||
-1,
|
||||
"<elementtt attr=\"\"/>\n");
|
||||
l_list.PushBack(check);
|
||||
// ------------------------------------------------------
|
||||
check.Set("<elementtt attr=\"\"/>\n",
|
||||
-1,
|
||||
"<elementtt attr=/>\n");
|
||||
l_list.PushBack(check);
|
||||
// ======================================================
|
||||
check.Set("test exml::Declaration", -2, "");
|
||||
l_list.PushBack(check);
|
||||
// ======================================================
|
||||
check.Set("<?testDeclaration?>\n",
|
||||
-1,
|
||||
"<?testDeclaration?>\n");
|
||||
l_list.PushBack(check);
|
||||
// ======================================================
|
||||
check.Set("test Declaration exml::Attribute", -2, "");
|
||||
l_list.PushBack(check);
|
||||
// ======================================================
|
||||
check.Set("<?xml attr=\"plop\"?>\n",
|
||||
-1,
|
||||
"<?xml attr=\"plop\"?>\n");
|
||||
l_list.PushBack(check);
|
||||
// ------------------------------------------------------
|
||||
check.Set("<?xml attr=\"plop\"?>\n",
|
||||
-1,
|
||||
"<?xml attr=plop?>\n");
|
||||
l_list.PushBack(check);
|
||||
// ------------------------------------------------------
|
||||
check.Set("<?xml attr=\"234345@3452345_.'\"?>\n",
|
||||
-1,
|
||||
"<?xml attr=234345@3452345_.' ?>\n");
|
||||
l_list.PushBack(check);
|
||||
// ------------------------------------------------------
|
||||
check.Set("<?xml attr=\"plop\"?>\n",
|
||||
-1,
|
||||
"<?xml attr =\"plop\"?>\n");
|
||||
l_list.PushBack(check);
|
||||
// ------------------------------------------------------
|
||||
check.Set("<?xml attr=\"plop\"?>\n",
|
||||
-1,
|
||||
"<?xml attr= \"plop\"?>\n");
|
||||
l_list.PushBack(check);
|
||||
// ------------------------------------------------------
|
||||
check.Set("<?xml attr=\"plop\"?>\n",
|
||||
-1,
|
||||
"<?xml attr\n=\n\"plop\"?>\n");
|
||||
l_list.PushBack(check);
|
||||
// ------------------------------------------------------
|
||||
check.Set("<?xml attr=\"plop\"?>\n",
|
||||
-1,
|
||||
"<?xml attr=plop?>\n");
|
||||
l_list.PushBack(check);
|
||||
// ------------------------------------------------------
|
||||
check.Set("<?xml attr=\"plop\"?>\n",
|
||||
-1,
|
||||
"<?xml attr \n = \n\t plop?>\n");
|
||||
l_list.PushBack(check);
|
||||
// ======================================================
|
||||
check.Set("test exml::Comment", -2, "");
|
||||
l_list.PushBack(check);
|
||||
// ======================================================
|
||||
check.Set("<!--exemple-->\n",
|
||||
@ -142,7 +252,7 @@ void Init(void)
|
||||
"<!-- <.:!*%^$0945- '(- &<<< >>> '& ( '( '-' <elementPouris> -->\n");
|
||||
l_list.PushBack(check);
|
||||
// ======================================================
|
||||
check.Set("", -2, "");
|
||||
check.Set("test all", -2, "");
|
||||
l_list.PushBack(check);
|
||||
// ======================================================
|
||||
reference= "<exemple>\n"
|
||||
@ -157,7 +267,17 @@ void Init(void)
|
||||
" Text example ...\n"
|
||||
" </ex2>\n"
|
||||
"</exemple>\n";
|
||||
check.Set(reference, 1, input);
|
||||
check.Set(reference, -1, input);
|
||||
l_list.PushBack(check);
|
||||
// ------------------------------------------------------
|
||||
check.Set("", 1,
|
||||
"< exemple\n >\n"
|
||||
" <ex2 ploppp-plpl:erer=\"dfsdfsdfsdf\" lkmjmlk=\"156235\" sdfsdf=456321 />\n"
|
||||
" <exlkjl-_dsfg./> >\n"
|
||||
" <ex2>\n"
|
||||
" Text example ...\n"
|
||||
" </ex2>\n"
|
||||
"</exemple>\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++;
|
||||
|
Loading…
Reference in New Issue
Block a user