[DEV] add comment and basic tests
This commit is contained in:
parent
5fce0e9ef2
commit
2f5856ca2f
@ -19,7 +19,6 @@ 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)
|
||||
{
|
||||
EXML_VERBOSE("start parse : 'attribute'");
|
||||
@ -43,7 +42,9 @@ bool exml::Attribute::Parse(const etk::UString& _data, int32_t& _pos, bool _case
|
||||
}
|
||||
}
|
||||
m_name = _data.Extract(_pos, lastElementName+1);
|
||||
|
||||
if (true==_caseSensitive) {
|
||||
m_name.Lower();
|
||||
}
|
||||
if (lastElementName+1>=_data.Size()) {
|
||||
EXML_ERROR(" parse an xml end with an attribute parsing...");
|
||||
return false;
|
||||
@ -115,4 +116,12 @@ bool exml::Attribute::Generate(etk::UString& _data, int32_t _indent) const
|
||||
_data += m_value;
|
||||
_data += "\"";
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void exml::Attribute::Clear(void)
|
||||
{
|
||||
m_name="";
|
||||
}
|
||||
|
||||
|
@ -17,19 +17,40 @@ namespace exml
|
||||
class Attribute : public Node
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
Attribute(void) { };
|
||||
/**
|
||||
* @brief Constructor
|
||||
* @param[in] _name Name of the attribute.
|
||||
* @param[in] _value Value of the attribute.
|
||||
*/
|
||||
Attribute(const etk::UString& _name, const etk::UString& _value);
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
virtual ~Attribute(void) { };
|
||||
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 Generate(etk::UString& _data, int32_t _indent) const;
|
||||
protected:
|
||||
etk::UString m_name;
|
||||
public:
|
||||
/**
|
||||
* @brief Set the name of the attribute
|
||||
* @param[in] _name New name of the attribute
|
||||
*/
|
||||
virtual void SetName(etk::UString _name) { m_name = _name; };
|
||||
/**
|
||||
* @brief Get the current name of the Attribute
|
||||
* @return String of the attribute
|
||||
*/
|
||||
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 Generate(etk::UString& _data, int32_t _indent) const;
|
||||
virtual exml::Attribute* ToAttribute(void) { return this; };
|
||||
virtual const exml::Attribute* ToAttribute(void) const { return this; };
|
||||
virtual void Clear(void);
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -12,6 +12,17 @@
|
||||
#undef __class__
|
||||
#define __class__ "AttributeList"
|
||||
|
||||
exml::AttributeList::~AttributeList(void)
|
||||
{
|
||||
for (int32_t iii=0; iii<m_listAttribute.Size(); iii++) {
|
||||
if (NULL!=m_listAttribute[iii]) {
|
||||
delete(m_listAttribute[iii]);
|
||||
m_listAttribute[iii]=NULL;
|
||||
}
|
||||
}
|
||||
m_listAttribute.Clear();
|
||||
}
|
||||
|
||||
exml::Attribute* exml::AttributeList::GetAttr(int32_t _id)
|
||||
{
|
||||
if (_id <0 || _id>m_listAttribute.Size()) {
|
||||
@ -28,19 +39,19 @@ const exml::Attribute* exml::AttributeList::GetAttr(int32_t _id) const
|
||||
return m_listAttribute[_id];
|
||||
}
|
||||
|
||||
void exml::AttributeList::AppendAttribute(exml::Attribute* _node)
|
||||
void exml::AttributeList::AppendAttribute(exml::Attribute* _attr)
|
||||
{
|
||||
if (_node == NULL) {
|
||||
if (_attr == NULL) {
|
||||
EXML_ERROR("Try to set an empty node");
|
||||
return;
|
||||
}
|
||||
for (int32_t iii=0; iii<m_listAttribute.Size(); iii++) {
|
||||
if (m_listAttribute[iii] == _node) {
|
||||
if (m_listAttribute[iii] == _attr) {
|
||||
EXML_ERROR("Try to add a node that is already added befor !!!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
m_listAttribute.PushBack(_node);
|
||||
m_listAttribute.PushBack(_attr);
|
||||
}
|
||||
|
||||
const etk::UString& exml::AttributeList::GetAttribute(const etk::UString& _name) const
|
||||
@ -58,6 +69,20 @@ const etk::UString& exml::AttributeList::GetAttribute(const etk::UString& _name)
|
||||
return errorReturn;
|
||||
}
|
||||
|
||||
bool exml::AttributeList::ExistAttribute(const etk::UString& _name) const
|
||||
{
|
||||
if (_name.Size()==0) {
|
||||
return false;
|
||||
}
|
||||
for (int32_t iii=0; iii<m_listAttribute.Size(); iii++) {
|
||||
if( NULL != m_listAttribute[iii]
|
||||
&& m_listAttribute[iii]->GetName() == _name) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void exml::AttributeList::SetAttribute(const etk::UString& _name, const etk::UString& _value)
|
||||
{
|
||||
// check if attribute already det :
|
||||
@ -85,3 +110,17 @@ bool exml::AttributeList::Generate(etk::UString& _data, int32_t _indent) const
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void exml::AttributeList::Clear(void)
|
||||
{
|
||||
exml::Node::Clear();
|
||||
for (int32_t iii=0; iii<m_listAttribute.Size(); iii++) {
|
||||
if (NULL!=m_listAttribute[iii]) {
|
||||
delete(m_listAttribute[iii]);
|
||||
m_listAttribute[iii]=NULL;
|
||||
}
|
||||
}
|
||||
m_listAttribute.Clear();
|
||||
}
|
||||
|
||||
|
||||
|
@ -18,20 +18,60 @@ namespace exml
|
||||
class AttributeList : public Node
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
AttributeList(void) { };
|
||||
virtual ~AttributeList(void) { };
|
||||
/**
|
||||
* @brief Constructor
|
||||
* @param[in] _value Node value;
|
||||
*/
|
||||
AttributeList(const etk::UString& _value) : exml::Node(_value) { };
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
virtual ~AttributeList(void);
|
||||
protected:
|
||||
etk::Vector<exml::Attribute*> m_listAttribute;
|
||||
etk::Vector<exml::Attribute*> m_listAttribute; //!< list of all attribute
|
||||
public:
|
||||
/**
|
||||
* @brief Get the number of attribute in the Node
|
||||
* @return Nulber of attribute >=0
|
||||
*/
|
||||
int32_t SizeAttribute(void) const { return m_listAttribute.Size(); };
|
||||
void AppendAttribute(Attribute* _node);
|
||||
/**
|
||||
* @brief Add attribute on the List
|
||||
* @param[in] _attr Pointer on the attribute
|
||||
*/
|
||||
void AppendAttribute(exml::Attribute* _attr);
|
||||
/**
|
||||
* @brief Get attribute whith his ID
|
||||
* @param[in] _id Identifier of the attribute 0<= _id < SizeAttribute()
|
||||
* @return Pointer on the attribute or NULL
|
||||
*/
|
||||
Attribute* GetAttr(int32_t _id);
|
||||
const Attribute* GetAttr(int32_t _id) const;
|
||||
/**
|
||||
* @brief Get the attribute value with searching in the List with his name
|
||||
* @param[in] _name Attribute Name.
|
||||
* @return Value of the attribute or no data in the string
|
||||
*/
|
||||
const etk::UString& GetAttribute(const etk::UString& _name) const;
|
||||
/**
|
||||
* @brief Check if an attribute Exist or not with his name.
|
||||
* @param[in] _name Attribute Name.
|
||||
* @return true if the attribute exist or False
|
||||
*/
|
||||
bool ExistAttribute(const etk::UString& _name) const;
|
||||
/**
|
||||
* @brief Sen A new attribute or replace data of the previous one
|
||||
* @param[in] _name Name of the attribute
|
||||
* @param[in] _value Value of the attribute
|
||||
*/
|
||||
void SetAttribute(const etk::UString& _name, const etk::UString& _value);
|
||||
public:
|
||||
// herited function:
|
||||
public: // herited function:
|
||||
bool Generate(etk::UString& _data, int32_t _indent) const;
|
||||
virtual void Clear(void);
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -16,8 +16,9 @@ bool exml::Comment::Parse(const etk::UString& _data, int32_t& _pos, bool _caseSe
|
||||
{
|
||||
EXML_VERBOSE("start parse : 'comment'");
|
||||
m_pos = _filePos;
|
||||
int32_t white = CountWhiteChar(_data, _pos);
|
||||
// search end of the comment :
|
||||
for (int32_t iii=_pos; iii+2<_data.Size(); iii++) {
|
||||
for (int32_t iii=_pos+white; iii+2<_data.Size(); iii++) {
|
||||
_filePos += ivec2(1,0);
|
||||
#ifdef ENABLE_DISPLAY_PARSED_ELEMENT
|
||||
DrawElementParsed(_data[iii], _filePos);
|
||||
@ -29,8 +30,17 @@ bool exml::Comment::Parse(const etk::UString& _data, int32_t& _pos, bool _caseSe
|
||||
if( _data[iii] == '-'
|
||||
&& _data[iii+1] == '-'
|
||||
&& _data[iii+2] == '>') {
|
||||
// search whitespace :
|
||||
int32_t newEnd=iii;
|
||||
for( int32_t jjj=iii-1; jjj>_pos; jjj--) {
|
||||
if(true==_data[jjj].IsWhiteChar()) {
|
||||
newEnd = jjj;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// find end of value:
|
||||
m_value = _data.Extract(_pos, iii-1);
|
||||
m_value = _data.Extract(_pos+white, newEnd);
|
||||
EXML_VERBOSE(" find comment '" << m_value << "'");
|
||||
_pos = iii+2;
|
||||
return true;
|
||||
|
@ -17,8 +17,20 @@ namespace exml
|
||||
class Comment : public Node
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
Comment(void) { };
|
||||
/**
|
||||
* @brief Constructor
|
||||
* @param[in] _value comment value
|
||||
*/
|
||||
Comment(const etk::UString& _value) : exml::Node(_value) { };
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
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 Generate(etk::UString& _data, int32_t _indent) const;
|
||||
|
@ -19,7 +19,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
*/
|
||||
|
||||
exml::Declaration::Declaration(const etk::UString& _version, unicode::charset_te _format, const etk::UString& _standalone)
|
||||
exml::Declaration::Declaration(const etk::UString& _version, unicode::charset_te _format, bool _standalone)
|
||||
{
|
||||
m_value = "xml";
|
||||
if (_version.Size()!=0) {
|
||||
@ -31,8 +31,10 @@ exml::Declaration::Declaration(const etk::UString& _version, unicode::charset_te
|
||||
EXML_ERROR("Actually does not supported other charset than UTF8");
|
||||
SetAttribute("encoding", "UTF-8");
|
||||
}
|
||||
if (_standalone.Size()!=0) {
|
||||
SetAttribute("standalone", _standalone);
|
||||
if (_standalone==true) {
|
||||
SetAttribute("standalone", "true");
|
||||
} else {
|
||||
SetAttribute("standalone", "true");
|
||||
}
|
||||
}
|
||||
|
||||
@ -74,6 +76,22 @@ bool exml::Declaration::Parse(const etk::UString& _data, int32_t& _pos, bool _ca
|
||||
_pos = iii+1;
|
||||
return true;
|
||||
}
|
||||
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 ...");
|
||||
return false;
|
||||
}
|
||||
_pos = iii;
|
||||
if (false==attribute->Parse(_data, _pos, _caseSensitive, _filePos)) {
|
||||
delete(attribute);
|
||||
return false;
|
||||
}
|
||||
iii = _pos;
|
||||
m_listAttribute.PushBack(attribute);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
_pos = _data.Size();
|
||||
EXML_ERROR("Text got end of file without finding end node");
|
||||
|
@ -16,10 +16,23 @@ namespace exml
|
||||
class Declaration : public exml::AttributeList
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
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
|
||||
*/
|
||||
// for xml generic declaration
|
||||
Declaration(const etk::UString& _version, unicode::charset_te _format, const etk::UString& _standalone);
|
||||
Declaration(const etk::UString& _version, unicode::charset_te _format=unicode::EDN_CHARSET_UTF8, bool _standalone=true);
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
virtual ~Declaration(void) { };
|
||||
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);
|
||||
|
@ -37,14 +37,14 @@ bool exml::Document::Parse(const etk::UString& _data, int32_t& _pos, bool _caseS
|
||||
EXML_VERBOSE("start parse : 'document'");
|
||||
m_pos = _filePos;
|
||||
// in this case : no main node ...
|
||||
SubParse(_data, _pos, _caseSensitive, _filePos, true);
|
||||
return true;
|
||||
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);
|
||||
@ -62,6 +62,7 @@ bool exml::Document::Load(const etk::UString& _file)
|
||||
{
|
||||
// Start loading the XML :
|
||||
EXML_VERBOSE("open file (xml) \"" << _file << "\"");
|
||||
Clear();
|
||||
etk::FSNode tmpFile(_file);
|
||||
if (false == tmpFile.Exist()) {
|
||||
EXML_ERROR("File Does not exist : " << _file);
|
||||
|
@ -18,18 +18,39 @@ namespace exml
|
||||
class Document : public exml::Element
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
Document(void);
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
virtual ~Document(void) { };
|
||||
virtual nodeType_te GetType(void) const { return typeDocument; };
|
||||
private:
|
||||
unicode::charset_te m_charset;
|
||||
public:
|
||||
/**
|
||||
* @brief Get the current charset of the Parsing
|
||||
* @param[in] _charset The new charset
|
||||
*/
|
||||
virtual void SetCharset(unicode::charset_te _charset) { m_charset = _charset; };
|
||||
/**
|
||||
* @brief Get the current charset of the Parsing
|
||||
* @return The current charset
|
||||
*/
|
||||
virtual unicode::charset_te GetCharset(void) const { return m_charset; };
|
||||
private:
|
||||
bool m_caseSensitive;
|
||||
bool m_caseSensitive; // check the case sensitive of the nodes and attribute
|
||||
public:
|
||||
/**
|
||||
* @brief Enable or diasable the case sensitive (must be done before the call of parsing)
|
||||
* @param[in] _val true if enable; false else.
|
||||
*/
|
||||
virtual void SetCaseSensitive(bool _val) { m_caseSensitive = _val; };
|
||||
/**
|
||||
* @brief Get the status of case sensitive mode.
|
||||
* @return true if case sensitive is active
|
||||
*/
|
||||
virtual bool GetCaseSensitive(void) const { return m_caseSensitive; };
|
||||
public:
|
||||
/**
|
||||
@ -60,8 +81,12 @@ namespace exml
|
||||
* @return true : Parsing is OK
|
||||
*/
|
||||
bool Store(const etk::UString& _file);
|
||||
|
||||
/**
|
||||
* @brief Display the Document on console
|
||||
*/
|
||||
void Display(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; };
|
||||
|
@ -16,6 +16,20 @@
|
||||
#undef __class__
|
||||
#define __class__ "Element"
|
||||
|
||||
|
||||
exml::Element::~Element(void)
|
||||
{
|
||||
for (int32_t iii=0; iii<m_listSub.Size(); iii++) {
|
||||
if (NULL!=m_listSub[iii]) {
|
||||
delete(m_listSub[iii]);
|
||||
m_listSub[iii]=NULL;
|
||||
}
|
||||
}
|
||||
m_listSub.Clear();
|
||||
}
|
||||
|
||||
|
||||
|
||||
exml::nodeType_te exml::Element::GetType(int32_t _id)
|
||||
{
|
||||
exml::Node* tmpp = GetNode(_id);
|
||||
@ -109,9 +123,13 @@ void exml::Element::Append(exml::Node* _node)
|
||||
EXML_ERROR("Try to set an empty node");
|
||||
return;
|
||||
}
|
||||
if (_node->GetType()==exml::typeAttribute) {
|
||||
AppendAttribute(_node->ToAttribute());
|
||||
return;
|
||||
}
|
||||
for (int32_t iii=0; iii<m_listSub.Size(); iii++) {
|
||||
if (m_listSub[iii] == _node) {
|
||||
EXML_ERROR("Try to add a node that is already added befor !!!");
|
||||
EXML_ERROR("Try to add a node that is already added before !!!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -188,12 +206,33 @@ bool exml::Element::SubParse(const etk::UString& _data, int32_t& _pos, bool _cas
|
||||
return false;
|
||||
}
|
||||
if(_data[iii+white+1] == '?') {
|
||||
if( false == CheckAvaillable(_data[iii+white+2], true) ) {
|
||||
EXML_ERROR(_filePos << " find unavaillable name in the Declaration node...");
|
||||
_pos = iii+white+1;
|
||||
return false;
|
||||
}
|
||||
//EXML_DEBUG("Generate node name : '" << _data[iii+1] << "'");
|
||||
int32_t endPosName = iii+white+1;
|
||||
// Generate element name ...
|
||||
for (int32_t jjj=iii+white+2; jjj<_data.Size(); jjj++) {
|
||||
if(true == CheckAvaillable(_data[jjj], false) ) {
|
||||
// we find the end ...
|
||||
endPosName = jjj;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
etk::UString tmpname = _data.Extract(iii+white+1, endPosName+1);
|
||||
if (true==_caseSensitive) {
|
||||
tmpname.Lower();
|
||||
}
|
||||
// Find declaration balise
|
||||
exml::Declaration* declaration = new exml::Declaration();
|
||||
if (NULL==declaration) {
|
||||
EXML_ERROR(_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)) {
|
||||
@ -281,6 +320,9 @@ bool exml::Element::SubParse(const etk::UString& _data, int32_t& _pos, bool _cas
|
||||
}
|
||||
}
|
||||
etk::UString tmpname = _data.Extract(iii+white+2, endPosName+1);
|
||||
if (true==_caseSensitive) {
|
||||
tmpname.Lower();
|
||||
}
|
||||
if( tmpname == m_value) {
|
||||
// find end of node :
|
||||
// find > element ...
|
||||
@ -327,6 +369,9 @@ bool exml::Element::SubParse(const etk::UString& _data, int32_t& _pos, bool _cas
|
||||
}
|
||||
}
|
||||
etk::UString tmpname = _data.Extract(iii+white+1, endPosName+1);
|
||||
if (true==_caseSensitive) {
|
||||
tmpname.Lower();
|
||||
}
|
||||
//EXML_INFO("find node named : '" << tmpname << "'");
|
||||
// find text:
|
||||
exml::Element* element = new exml::Element();
|
||||
@ -347,6 +392,9 @@ bool exml::Element::SubParse(const etk::UString& _data, int32_t& _pos, bool _cas
|
||||
|
||||
continue;
|
||||
}
|
||||
// here we have an error :
|
||||
EXML_ERROR(_filePos << " find an ununderstanding element : '" << _data[iii+white+1] << "'");
|
||||
return false;
|
||||
} else {
|
||||
if (_data[iii] == '>') {
|
||||
EXML_ERROR(_filePos << " find elemement '>' ==> no reason to be here ...");
|
||||
@ -378,7 +426,7 @@ bool exml::Element::SubParse(const etk::UString& _data, int32_t& _pos, bool _cas
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool exml::Element::Parse(const etk::UString& _data, int32_t& _pos, bool _caseSensitive, ivec2& _filePos)
|
||||
@ -403,15 +451,16 @@ bool exml::Element::Parse(const etk::UString& _data, int32_t& _pos, bool _caseSe
|
||||
if (_data[iii] == '/') {
|
||||
// standalone node or error...
|
||||
if (iii+1>=_data.Size()) {
|
||||
EXML_ERROR(" find end of files ... ==> bad case");
|
||||
EXML_ERROR(_filePos << " find end of files ... ==> bad case");
|
||||
return false;
|
||||
}
|
||||
// TODO : Can have white spaces ....
|
||||
if (_data[iii+1] == '>') {
|
||||
_pos = iii+1;
|
||||
return true;
|
||||
}
|
||||
// error
|
||||
EXML_ERROR("find / without > char ...");
|
||||
EXML_ERROR(_filePos << "find / without > char ...");
|
||||
return false;
|
||||
}
|
||||
if (true == CheckAvaillable(_data[iii], true)) {
|
||||
@ -430,9 +479,24 @@ bool exml::Element::Parse(const etk::UString& _data, int32_t& _pos, bool _caseSe
|
||||
m_listAttribute.PushBack(attribute);
|
||||
continue;
|
||||
}
|
||||
// TODO : Else ==> if not white ==> create an error ...
|
||||
if (false==_data[iii].IsWhiteChar()) {
|
||||
EXML_ERROR(_filePos << " find an unknow element : '" << _data[iii] << "'");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void exml::Element::Clear(void)
|
||||
{
|
||||
exml::AttributeList::Clear();
|
||||
for (int32_t iii=0; iii<m_listSub.Size(); iii++) {
|
||||
if (NULL!=m_listSub[iii]) {
|
||||
delete(m_listSub[iii]);
|
||||
m_listSub[iii]=NULL;
|
||||
}
|
||||
}
|
||||
m_listSub.Clear();
|
||||
}
|
||||
|
||||
|
||||
|
@ -18,33 +18,74 @@ namespace exml
|
||||
class Element : public AttributeList
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
Element(void) { };
|
||||
Element(const etk::UString& _value) { m_value = _value; };
|
||||
virtual ~Element(void) { };
|
||||
virtual nodeType_te GetType(void) const { return typeElement; };
|
||||
/**
|
||||
* @brief Constructor
|
||||
* @param[in] _value Element name;
|
||||
*/
|
||||
Element(const etk::UString& _value) : exml::AttributeList(_value) { };
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
virtual ~Element(void);
|
||||
protected:
|
||||
etk::Vector<exml::Node*> m_listSub;
|
||||
public:
|
||||
/**
|
||||
* @brief Get the number of sub element in the node (can be exml::Comment ; exml::Element ; exml::Text :exml::Declaration).
|
||||
* @return a number >=0.
|
||||
*/
|
||||
int32_t Size(void) const { return m_listSub.Size(); };
|
||||
/**
|
||||
* @brief Add a node at the element (not exml::Attribute (move in the attribute automaticly).
|
||||
* @param[in] _node Pointer of the node to add.
|
||||
*/
|
||||
void Append(Node* _node);
|
||||
|
||||
/**
|
||||
* @brief Get the type of the element id.
|
||||
* @param[in] _id Id of the element.
|
||||
* @return the Current type of the element or exml::typeUnknow.
|
||||
*/
|
||||
nodeType_te GetType(int32_t _id);
|
||||
const nodeType_te GetType(int32_t _id) const;
|
||||
/**
|
||||
* @brief Get the Node pointer of the element id.
|
||||
* @param[in] _id Id of the element.
|
||||
* @return Pointer on node.
|
||||
*/
|
||||
Node* GetNode(int32_t _id);
|
||||
const Node* GetNode(int32_t _id) const;
|
||||
/**
|
||||
* @brief Get the element casted in Element (if the node is not an element return NULL).
|
||||
* @param[in] _id Id of the element.
|
||||
* @return Pointer on the element or NULL.
|
||||
*/
|
||||
Element* GetElement(int32_t _id);
|
||||
const Element* GetElement(int32_t _id) const;
|
||||
/**
|
||||
* @brief Get an element with his name (work only with exml::Element)
|
||||
* @param[in] _name Name of the element that is requested
|
||||
* @return Pointer on the element or NULL.
|
||||
*/
|
||||
Element* GetNamed(const etk::UString& _name);
|
||||
const Element* GetNamed(const etk::UString& _name) const;
|
||||
public:
|
||||
/**
|
||||
* @brief Get the internal data of the element (if the element has some sub node thay are converted in xml string ==> like this it is not needed to use <![CDATA[...]]>
|
||||
* @return the curent data string.
|
||||
*/
|
||||
etk::UString GetText(void);
|
||||
public:
|
||||
virtual bool Parse(const etk::UString& _data, int32_t& _pos, bool _caseSensitive, ivec2& _filePos);
|
||||
virtual bool Generate(etk::UString& _data, int32_t _indent) const;
|
||||
protected:
|
||||
bool SubParse(const etk::UString& _data, int32_t& _pos, bool _caseSensitive, ivec2& _filePos, 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 Generate(etk::UString& _data, int32_t _indent) const;
|
||||
virtual exml::Element* ToElement(void) { return this; };
|
||||
virtual const exml::Element* ToElement(void) const { return this; };
|
||||
virtual void Clear(void);
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -16,7 +16,7 @@ exml::Node::Node(const etk::UString& _value) :
|
||||
m_pos(0,0),
|
||||
m_value(_value)
|
||||
{
|
||||
|
||||
// nothing to do.
|
||||
}
|
||||
|
||||
void exml::Node::AddIndent(etk::UString& _data, int32_t _indent) const
|
||||
@ -38,8 +38,6 @@ void exml::Node::DrawElementParsed(const etk::UniChar& _val, const ivec2& _fileP
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// !"#$%&'()*+,/;<=>?@[\]^`{|}~ ou une espace et ne peut pas commencer par -. ou un chiffre.
|
||||
bool exml::Node::CheckAvaillable(const etk::UniChar& _val, bool _firstChar) const
|
||||
{
|
||||
if( _val == '!'
|
||||
@ -87,14 +85,12 @@ bool exml::Node::CheckAvaillable(const etk::UniChar& _val, bool _firstChar) cons
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
int32_t exml::Node::CountWhiteChar(const etk::UString& _data, int32_t _pos) const
|
||||
{
|
||||
int32_t white=0;
|
||||
for (int32_t iii=_pos; iii<_data.Size(); iii++) {
|
||||
if( _data[iii] == ' '
|
||||
|| _data[iii] == '\t'
|
||||
|| _data[iii] == '\n'
|
||||
|| _data[iii] == '\r') {
|
||||
if(true == _data[iii].IsWhiteChar()) {
|
||||
white++;
|
||||
} else {
|
||||
break;
|
||||
@ -103,3 +99,8 @@ int32_t exml::Node::CountWhiteChar(const etk::UString& _data, int32_t _pos) cons
|
||||
return white;
|
||||
}
|
||||
|
||||
void exml::Node::Clear(void)
|
||||
{
|
||||
m_value="";
|
||||
m_pos.setValue(0,0);
|
||||
}
|
||||
|
123
exml/Node.h
123
exml/Node.h
@ -37,52 +37,161 @@ namespace exml
|
||||
class Node
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief basic element of a xml structure
|
||||
*/
|
||||
Node(void) : m_pos(0,0) { };
|
||||
/**
|
||||
* @brief basic element of a xml structure
|
||||
* @param[in] value of the node
|
||||
*/
|
||||
Node(const etk::UString& _value);
|
||||
/**
|
||||
* @brief destructor
|
||||
*/
|
||||
virtual ~Node(void) { };
|
||||
protected:
|
||||
void AddIndent(etk::UString& _data, int32_t _indent) const;
|
||||
public:
|
||||
/**
|
||||
* Parse the sub nodes and current nodes ...
|
||||
* @brief Parse the Current node [pure VIRUAL]
|
||||
* @param[in] _data data string to parse.
|
||||
* @param[in,out] _pos position in the string to start parse, return the position end of parsing.
|
||||
* @param[in] _caseSensitive Request a parsion of element that is not case sensitive (all element is in low case)
|
||||
* @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;
|
||||
/**
|
||||
* @brief Generate a string with the tree of the xml
|
||||
* @param[in,out] _data string where to add the elements
|
||||
* @param[in] current indentation of the file
|
||||
* @return false if an error occured.
|
||||
*/
|
||||
virtual bool Generate(etk::UString& _data, int32_t _indent) const { return true; };
|
||||
protected:
|
||||
ivec2 m_pos; // position in the readed file
|
||||
ivec2 m_pos; //!< position in the readed file ==> not correct when the file is generated
|
||||
public:
|
||||
const ivec2& Pos(void) { return m_pos; };
|
||||
/**
|
||||
* @brief Get the current position where the element is in the file
|
||||
*/
|
||||
const ivec2& GetPos(void) { return m_pos; };
|
||||
protected:
|
||||
etk::UString m_value;
|
||||
etk::UString m_value; //!< value of the node (for element this is the name, for text it is the inside text ...)
|
||||
public:
|
||||
/**
|
||||
* @brief Set the value of the node.
|
||||
* @param[in] _value New value of the node.
|
||||
*/
|
||||
virtual void SetValue(etk::UString _value) { m_value = _value; };
|
||||
/**
|
||||
* @brief Get the current element Value.
|
||||
* @return the reference of the string value.
|
||||
*/
|
||||
virtual const etk::UString& GetValue(void) const { return m_value; };
|
||||
public:
|
||||
/**
|
||||
* @brief Get the node type.
|
||||
* @return the type of the Node.
|
||||
*/
|
||||
virtual nodeType_te GetType(void) const { return typeNode; };
|
||||
protected:
|
||||
void DrawElementParsed(const etk::UniChar& _val, const ivec2& _firstChar) const;
|
||||
/**
|
||||
* @brief Add indentation of the string input.
|
||||
* @param[in,out] _data String where the indentation is done.
|
||||
* @param[in] _indent Number of tab to add at the string.
|
||||
*/
|
||||
void AddIndent(etk::UString& _data, int32_t _indent) const;
|
||||
/**
|
||||
* @brief Display the cuurent element that is curently parse.
|
||||
* @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;
|
||||
/**
|
||||
* @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.
|
||||
* @param[in] _firstChar True if the element check is the first char.
|
||||
*/
|
||||
bool CheckAvaillable(const etk::UniChar& _val, bool _firstChar) const;
|
||||
/**
|
||||
* @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.
|
||||
* @return number of white element.
|
||||
*/
|
||||
int32_t CountWhiteChar(const etk::UString& _data, int32_t _pos) const;
|
||||
public:
|
||||
/**
|
||||
* @brief Cast the element in a Document if it is possible.
|
||||
* @return pointer on the class or NULL.
|
||||
*/
|
||||
virtual exml::Document* ToDocument(void) { return NULL; };
|
||||
virtual const exml::Document* ToDocument(void) const { return NULL; };
|
||||
/**
|
||||
* @brief Cast the element in a Attribute if it is possible.
|
||||
* @return pointer on the class or NULL.
|
||||
*/
|
||||
virtual exml::Attribute* ToAttribute(void) { return NULL; };
|
||||
virtual const exml::Attribute* ToAttribute(void) const { return NULL; };
|
||||
/**
|
||||
* @brief Cast the element in a Comment if it is possible.
|
||||
* @return pointer on the class or NULL.
|
||||
*/
|
||||
virtual exml::Comment* ToComment(void) { return NULL; };
|
||||
virtual const exml::Comment* ToComment(void) const { return NULL; };
|
||||
/**
|
||||
* @brief Cast the element in a Declaration if it is possible.
|
||||
* @return pointer on the class or NULL.
|
||||
*/
|
||||
virtual exml::Declaration* ToDeclaration(void) { return NULL; };
|
||||
virtual const exml::Declaration* ToDeclaration(void) const { return NULL; };
|
||||
/**
|
||||
* @brief Cast the element in a Element if it is possible.
|
||||
* @return pointer on the class or NULL.
|
||||
*/
|
||||
virtual exml::Element* ToElement(void) { return NULL; };
|
||||
virtual const exml::Element* ToElement(void) const { return NULL; };
|
||||
/**
|
||||
* @brief Cast the element in a Text if it is possible.
|
||||
* @return pointer on the class or NULL.
|
||||
*/
|
||||
virtual exml::Text* ToText(void) { return NULL; };
|
||||
virtual const exml::Text* ToText(void) const{ return NULL; };
|
||||
|
||||
/**
|
||||
* @brief Check if the node is a exml::Document
|
||||
* @return true if the node is a exml::Document
|
||||
*/
|
||||
bool IsDocument(void) const { return GetType()==exml::typeDocument; };
|
||||
/**
|
||||
* @brief Check if the node is a exml::Attribute
|
||||
* @return true if the node is a exml::Attribute
|
||||
*/
|
||||
bool IsAttribute(void) const { return GetType()==exml::typeAttribute; };
|
||||
/**
|
||||
* @brief Check if the node is a exml::Comment
|
||||
* @return true if the node is a exml::Comment
|
||||
*/
|
||||
bool IsComment(void) const { return GetType()==exml::typeComment; };
|
||||
/**
|
||||
* @brief Check if the node is a exml::Declaration
|
||||
* @return true if the node is a exml::Declaration
|
||||
*/
|
||||
bool IsDeclaration(void) const { return GetType()==exml::typeDeclaration; };
|
||||
/**
|
||||
* @brief Check if the node is a exml::Element
|
||||
* @return true if the node is a exml::Element
|
||||
*/
|
||||
bool IsElement(void) const { return GetType()==exml::typeElement; };
|
||||
/**
|
||||
* @brief Check if the node is a exml::Text
|
||||
* @return true if the node is a exml::Text
|
||||
*/
|
||||
bool IsText(void) const { return GetType()==exml::typeText; };
|
||||
|
||||
/**
|
||||
* @brief Clear the Node
|
||||
*/
|
||||
virtual void Clear(void);
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -48,10 +48,7 @@ bool exml::Text::Parse(const etk::UString& _data, int32_t& _pos, bool _caseSensi
|
||||
// search whitespace :
|
||||
int32_t newEnd=iii;
|
||||
for( int32_t jjj=iii-1; jjj>_pos; jjj--) {
|
||||
if( _data[jjj] == ' '
|
||||
|| _data[jjj] == '\n'
|
||||
|| _data[jjj] == '\r'
|
||||
|| _data[jjj] == '\t') {
|
||||
if(true==_data[jjj].IsWhiteChar()) {
|
||||
newEnd = jjj;
|
||||
} else {
|
||||
break;
|
||||
|
27
exml/Text.h
27
exml/Text.h
@ -17,22 +17,43 @@ namespace exml
|
||||
class Text : public Node
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
Text(void) { };
|
||||
Text(const etk::UString& _data) { m_value=_data; };
|
||||
/**
|
||||
* @brief Constructor
|
||||
* @param[in] _data String data of the current Text
|
||||
*/
|
||||
Text(const etk::UString& _data) : exml::Node(_data) { };
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
virtual ~Text(void) { };
|
||||
/**
|
||||
* @brief Count the number of line in the current text
|
||||
* @return The number of lines
|
||||
*/
|
||||
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 Generate(etk::UString& _data, int32_t _indent) const;
|
||||
int32_t CountLines(void) const;
|
||||
virtual exml::Text* ToText(void) { return this; };
|
||||
virtual const exml::Text* ToText(void) const{ return this; };
|
||||
};
|
||||
class TextCDATA : public Text
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
TextCDATA(void) { };
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
virtual ~TextCDATA(void) { };
|
||||
virtual nodeType_te GetType(void) { return typeText; };
|
||||
public: // herited function:
|
||||
virtual bool Parse(const etk::UString& _data, int32_t& _pos, bool _caseSensitive, ivec2& _filePos);
|
||||
};
|
||||
};
|
||||
|
@ -11,5 +11,6 @@
|
||||
|
||||
#include <exml/Document.h>
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
237
exml/test.cpp
237
exml/test.cpp
@ -8,28 +8,235 @@
|
||||
|
||||
#include <exml/test.h>
|
||||
#include <etk/Debug.h>
|
||||
#include <etk/Vector.h>
|
||||
#include <exml/debug.h>
|
||||
|
||||
#undef __class__
|
||||
#define __class__ "test"
|
||||
|
||||
class testCheck
|
||||
{
|
||||
public:
|
||||
etk::UString m_ref;
|
||||
etk::UString m_input;
|
||||
int32_t m_errorPos; // -1 : no error , 1 : parsing error, 2 generation error, 3 comparaison error ????
|
||||
testCheck(void) {};
|
||||
void Set(const etk::UString& _ref, int32_t _pos, const etk::UString& _input)
|
||||
{
|
||||
m_ref = _ref;
|
||||
m_input = _input;
|
||||
m_errorPos = _pos;
|
||||
}
|
||||
};
|
||||
|
||||
etk::Vector<testCheck> l_list;
|
||||
|
||||
void Init(void)
|
||||
{
|
||||
etk::UString reference;
|
||||
etk::UString input;
|
||||
testCheck check;
|
||||
|
||||
// ======================================================
|
||||
reference = "<exemple/>\n";
|
||||
check.Set(reference,
|
||||
-1,
|
||||
"<exemple/>\n");
|
||||
l_list.PushBack(check);
|
||||
// ------------------------------------------------------
|
||||
check.Set(reference,
|
||||
-1,
|
||||
"< \t\r exemple/>\n");
|
||||
l_list.PushBack(check);
|
||||
// ------------------------------------------------------
|
||||
check.Set(reference,
|
||||
-1,
|
||||
"< \t\r exemple \t\r\r\r\n \t\t />\n");
|
||||
l_list.PushBack(check);
|
||||
// ------------------------------------------------------
|
||||
check.Set(reference,
|
||||
1,
|
||||
"< exemple < >\n");
|
||||
l_list.PushBack(check);
|
||||
// ------------------------------------------------------
|
||||
check.Set(reference,
|
||||
1,
|
||||
"< exemple / />\n");
|
||||
l_list.PushBack(check);
|
||||
// ------------------------------------------------------
|
||||
check.Set(reference,
|
||||
1,
|
||||
"< exemple ? />\n");
|
||||
l_list.PushBack(check);
|
||||
// ------------------------------------------------------
|
||||
check.Set(reference,
|
||||
1,
|
||||
"< exemple * />\n");
|
||||
l_list.PushBack(check);
|
||||
// ------------------------------------------------------
|
||||
check.Set(reference,
|
||||
1,
|
||||
"< . exemple < />\n");
|
||||
l_list.PushBack(check);
|
||||
// ------------------------------------------------------
|
||||
check.Set(reference,
|
||||
1,
|
||||
"<! exemple < />\n");
|
||||
l_list.PushBack(check);
|
||||
// ------------------------------------------------------
|
||||
check.Set(reference,
|
||||
1,
|
||||
"<!- exemple < />\n");
|
||||
l_list.PushBack(check);
|
||||
// ------------------------------------------------------
|
||||
check.Set(reference,
|
||||
1,
|
||||
"< exemple < />\n");
|
||||
l_list.PushBack(check);
|
||||
check.Set("<exemple--/>\n",
|
||||
1,
|
||||
"<exemple-->\n");
|
||||
l_list.PushBack(check);
|
||||
// ------------------------------------------------------
|
||||
// ======================================================
|
||||
check.Set("", -2, "");
|
||||
l_list.PushBack(check);
|
||||
// ======================================================
|
||||
check.Set("<!--exemple-->\n",
|
||||
-1,
|
||||
"<!--exemple-->\n");
|
||||
l_list.PushBack(check);
|
||||
// ------------------------------------------------------
|
||||
check.Set("<!--exemple-->\n",
|
||||
-1,
|
||||
"<!-- \t \t\t exemple \n\n\n\t-->\n");
|
||||
l_list.PushBack(check);
|
||||
// ------------------------------------------------------
|
||||
check.Set("<!---- exemple-->\n",
|
||||
-1,
|
||||
"<!-- -- exemple -->\n");
|
||||
l_list.PushBack(check);
|
||||
// ------------------------------------------------------
|
||||
check.Set("<!--> exemple-->\n",
|
||||
-1,
|
||||
"<!--> exemple -->\n");
|
||||
l_list.PushBack(check);
|
||||
// ------------------------------------------------------
|
||||
check.Set("<!--exemple-->\n",
|
||||
1,
|
||||
"<!-- ---> exemple -->\n");
|
||||
l_list.PushBack(check);
|
||||
// ------------------------------------------------------
|
||||
check.Set("<!--exemple-->\n",
|
||||
1,
|
||||
"<!-- ssdfgdfg >\n");
|
||||
l_list.PushBack(check);
|
||||
// ------------------------------------------------------
|
||||
check.Set("<!---->\n",
|
||||
-1,
|
||||
"<!---->\n");
|
||||
l_list.PushBack(check);
|
||||
// ------------------------------------------------------
|
||||
check.Set("<!--<.:!*%^$0945- '(- &<<< >>> '& ( '( '-' <elementPouris>-->\n",
|
||||
-1,
|
||||
"<!-- <.:!*%^$0945- '(- &<<< >>> '& ( '( '-' <elementPouris> -->\n");
|
||||
l_list.PushBack(check);
|
||||
// ======================================================
|
||||
check.Set("", -2, "");
|
||||
l_list.PushBack(check);
|
||||
// ======================================================
|
||||
reference= "<exemple>\n"
|
||||
" <ex2 ploppp-plpl:erer=\"dfsdfsdfsdf\" lkmjmlk=\"156235\" sdfsdf=\"456321\"/>\n"
|
||||
" <exlkjl-_dsfg./>\n"
|
||||
" <ex2>Text example ...</ex2>\n"
|
||||
"</exemple>\n";
|
||||
input ="< 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";
|
||||
check.Set(reference, 1, input);
|
||||
l_list.PushBack(check);
|
||||
}
|
||||
|
||||
int main(int argc, const char *argv[])
|
||||
{
|
||||
GeneralDebugSetLevel(etk::LOG_LEVEL_VERBOSE);
|
||||
exml::Document doc;
|
||||
etk::UString testString = ""
|
||||
"< exemple\n >\n"
|
||||
" <ex2 ploppp-plpl:erer=\"dfsdfsdfsdf\" lkmjmlk=\"156235\" sdfsdf=456321 />\n"
|
||||
" <exlkjl-_dsfg./>\n"
|
||||
" <ex2>\n"
|
||||
" Text example ...\n"
|
||||
// " <!--a really simple comment -- !!! [[] ] < exemple\n -->\n"
|
||||
// " <![CDATA[CDATA_EXEMPLE slkdjf l ksjdflks fsd s,dn fsfn > < < S!! ]]>\n"
|
||||
" </ex2>\n"
|
||||
"</exemple>\n";
|
||||
EXML_DEBUG("start parsing : \n" << testString);
|
||||
doc.Parse(testString);
|
||||
doc.Display();
|
||||
return false;
|
||||
Init();
|
||||
int32_t countError = 0;
|
||||
int32_t countSeparator = 0;
|
||||
int32_t sectionID = 0;
|
||||
for (int32_t iii=0 ; iii<l_list.Size() ; iii++) {
|
||||
int32_t jjj= iii-countSeparator+1;
|
||||
if (l_list[iii].m_errorPos==-2) {
|
||||
countSeparator++;
|
||||
sectionID = 0;
|
||||
EXML_INFO("-----------------------------------------------------------------------------------");
|
||||
continue;
|
||||
}
|
||||
sectionID++;
|
||||
exml::Document doc;
|
||||
etk::UString out("");
|
||||
//EXML_DEBUG("parse : \n" << l_list[iii].m_input);
|
||||
if (false==doc.Parse(l_list[iii].m_input)) {
|
||||
if (l_list[iii].m_errorPos==1) {
|
||||
EXML_INFO("[TEST] " << sectionID << ":" << jjj << " { OK } Parsing in error (correct result)");
|
||||
} else {
|
||||
EXML_ERROR("[TEST] " << sectionID << ":" << jjj << " {ERROR } Parsing might be OK");
|
||||
EXML_ERROR("parse : \n" << l_list[iii].m_input);
|
||||
countError++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (l_list[iii].m_errorPos==1) {
|
||||
EXML_ERROR("[TEST] " << sectionID << ":" << jjj << " {ERROR } Parsing might be in error ...");
|
||||
EXML_ERROR("parse : \n" << l_list[iii].m_input);
|
||||
doc.Display();
|
||||
countError++;
|
||||
continue;
|
||||
}
|
||||
if (false == doc.Generate(out)) {
|
||||
if (l_list[iii].m_errorPos==2) {
|
||||
EXML_INFO("[TEST] " << sectionID << ":" << jjj << " { OK } generate in error (correct result)");
|
||||
} else {
|
||||
EXML_ERROR("[TEST] " << sectionID << ":" << jjj << " {ERROR } Generate output might be OK");
|
||||
EXML_ERROR("generate : \n" << out);
|
||||
countError++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (l_list[iii].m_errorPos==2) {
|
||||
EXML_ERROR("[TEST] " << sectionID << ":" << jjj << " {ERROR } Generating might be in error ...");
|
||||
countError++;
|
||||
continue;
|
||||
}
|
||||
if (l_list[iii].m_ref != out) {
|
||||
if (l_list[iii].m_errorPos==3) {
|
||||
EXML_INFO("[TEST] " << sectionID << ":" << jjj << " { OK } Result in error (normal case)");
|
||||
} else {
|
||||
EXML_ERROR("[TEST] " << sectionID << ":" << jjj << " {ERROR } different output");
|
||||
EXML_ERROR("generate : \n" << out);
|
||||
EXML_ERROR("reference : \n" << l_list[iii].m_ref);
|
||||
countError++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (l_list[iii].m_errorPos==3) {
|
||||
EXML_ERROR("[TEST] " << sectionID << ":" << jjj << " {ERROR} checking result might be in error...");
|
||||
EXML_ERROR("generate : \n" << out);
|
||||
EXML_ERROR("reference : \n" << l_list[iii].m_ref);
|
||||
countError++;
|
||||
continue;
|
||||
}
|
||||
EXML_INFO("[TEST] " << sectionID << ":" << jjj << " { OK }");
|
||||
}
|
||||
if (countError>0) {
|
||||
EXML_ERROR("[TEST] produce " << countError << " error on " << l_list.Size()-countSeparator << " test");
|
||||
} else {
|
||||
EXML_INFO("[TEST] produce " << countError << " error on " << l_list.Size()-countSeparator << " test");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user