diff --git a/cmXml.c b/cmXml.c index c9c5e5d..a3a2cec 100644 --- a/cmXml.c +++ b/cmXml.c @@ -86,6 +86,10 @@ cmXmlRC_t cmXmlAlloc( cmCtx_t* ctx, cmXmlH_t* hp, const cmChar_t* fn ) hp->h = p; + if( fn != NULL ) + if((rc = cmXmlParse(*hp,fn)) != kOkXmlRC ) + hp->h = NULL; + errLabel: if(rc != kOkXmlRC ) _cmXmlFree(p); @@ -116,7 +120,7 @@ bool cmXmlIsValid( cmXmlH_t h ) cmXmlRC_t _cmXmlSyntaxError( cmXml_t* p ) { - return cmErrMsg(&p->err,kSyntaxErrorXmlRC,"Syntax error on line '%i.",p->line); + return cmErrMsg(&p->err,kSyntaxErrorXmlRC,"Syntax error on line %i.",p->line); } cmXmlNode_t* _cmXmlNodeAlloc( cmXml_t* p, unsigned flags, const cmChar_t* label, unsigned labelN ) @@ -756,6 +760,9 @@ const cmXmlNode_t* cmXmlSearch( const cmXmlNode_t* np, const cmChar_t* label, co // if the 'label' matches this node's label ... if( cmTextCmp(np->label,label) == 0 ) { + if( attrN == 0 ) + return np; + unsigned matchN = 0; const cmXmlAttr_t* a = np->attr; unsigned i; @@ -776,7 +783,8 @@ const cmXmlNode_t* cmXmlSearch( const cmXmlNode_t* np, const cmChar_t* label, co break; } } - } + } + } // this node did not match - try each of this nodes children @@ -817,6 +825,44 @@ const cmXmlNode_t* cmXmlSearchN( const cmXmlNode_t* np, const cmChar_t* label, c return np; } +const cmXmlAttr_t* cmXmlFindAttrib( const cmXmlNode_t* np, const cmChar_t* label ) +{ + const cmXmlAttr_t* a = np->attr; + for(; a!=NULL; a=a->link) + if( cmTextCmp(a->label,label) == 0 ) + return a; + + return NULL; +} + +cmXmlRC_t cmXmlAttrInt( const cmXmlNode_t* np, const cmChar_t* attrLabel, int* retRef ) +{ + const cmXmlAttr_t* a; + if((a = cmXmlFindAttrib(np,attrLabel)) == NULL ) + return kNodeNotFoundXmlRC; + + assert(retRef != NULL); + + *retRef = 0; + + if( a->value != NULL ) + { + errno = 0; + + // convert the string to an integer + *retRef = strtol(a->value,NULL,10); + + if( errno != 0 ) + return kInvalidTypeXmlRC; + } + + return kOkXmlRC; + +} + +cmXmlRC_t cmXmlAttrUInt( const cmXmlNode_t* np, const cmChar_t* attrLabel, unsigned* retRef ) +{ return cmXmlAttrInt(np,attrLabel,(int*)retRef); } + cmXmlRC_t cmXmlGetInt( const cmXmlNode_t* np, int* retRef, const cmChar_t* label, const cmXmlAttr_t* attrV, unsigned attrN, ... ) { cmXmlRC_t rc = kNodeNotFoundXmlRC; @@ -847,11 +893,78 @@ cmXmlRC_t cmXmlGetInt( const cmXmlNode_t* np, int* retRef, const cmChar_t* label return rc; } - -void _cmXmlPrintMeasure( const cmXmlNode_t* mnp ) +const cmXmlNode_t* _cmXmlNodeFindChild( const cmXmlNode_t* np, const cmChar_t* label ) { + const cmXmlNode_t* cnp = np->children; + for(; cnp!=NULL; cnp=cnp->sibling) + if( cmTextCmp(cnp->label,label) == 0 ) + return cnp; + return NULL; } +const cmChar_t* cmXmlNodeValueV( const cmXmlNode_t* np, va_list vl ) +{ + const cmChar_t* label; + + // for each node label + while( (label = va_arg(vl,const cmChar_t*)) != NULL ) + if((np = _cmXmlNodeFindChild(np,label)) == NULL ) + break; + + return np==NULL ? NULL : np->dataStr; +} + +const cmChar_t* cmXmlNodeValue( const cmXmlNode_t* np, ... ) +{ + va_list vl; + va_start(vl,np); + const cmChar_t* str = cmXmlNodeValueV(np,vl); + va_end(vl); + return str; +} + + +cmXmlRC_t cmXmlNodeIntV(const cmXmlNode_t* np, int* retRef, va_list vl ) +{ + const cmChar_t* valueStr; + if((valueStr = cmXmlNodeValueV(np,vl)) == NULL ) + return kNodeNotFoundXmlRC; + + errno = 0; + + // convert the string to an integer + *retRef = strtol(valueStr,NULL,10); + + if( errno != 0 ) + return kInvalidTypeXmlRC; + + return kOkXmlRC; +} + +cmXmlRC_t cmXmlNodeUIntV(const cmXmlNode_t* np, unsigned* retRef, va_list vl ) +{ return cmXmlNodeIntV(np,(int*)retRef,vl); } + +cmXmlRC_t cmXmlNodeInt( const cmXmlNode_t* np, int* retRef, ... ) +{ + cmXmlRC_t rc; + va_list vl; + va_start(vl,retRef); + rc = cmXmlNodeIntV(np,retRef,vl); + va_end(vl); + return rc; +} + +cmXmlRC_t cmXmlNodeUInt( const cmXmlNode_t* np, unsigned* retRef, ... ) +{ + cmXmlRC_t rc; + va_list vl; + va_start(vl,retRef); + rc = cmXmlNodeUIntV(np,retRef,vl); + va_end(vl); + return rc; +} + + cmXmlRC_t _cmXmlPrintScore( cmXmlH_t h ) { cmXmlRC_t rc = kOkXmlRC; diff --git a/cmXml.h b/cmXml.h index 2b9c97a..2ecdda8 100644 --- a/cmXml.h +++ b/cmXml.h @@ -35,17 +35,16 @@ extern "C" { typedef struct cmXmlNode_str { - unsigned flags; + unsigned flags; // See k???XmlFl - const cmChar_t* label; - const cmChar_t* dataStr; + const cmChar_t* label; // node label + const cmChar_t* dataStr; // node data string - cmXmlAttr_t* attr; - - struct cmXmlNode_str* parent; - struct cmXmlNode_str* children; - struct cmXmlNode_str* sibling; + cmXmlAttr_t* attr; // attribute list + struct cmXmlNode_str* parent; // parent node + struct cmXmlNode_str* children; // first child node list + struct cmXmlNode_str* sibling; // } cmXmlNode_t; @@ -64,10 +63,22 @@ extern "C" { void cmXmlPrint( cmXmlH_t h, cmRpt_t* rpt ); const cmXmlNode_t* cmXmlSearch( const cmXmlNode_t* np, const cmChar_t* label, const cmXmlAttr_t* attrV, unsigned attrN ); + const cmXmlAttr_t* cmXmlFindAttrib( const cmXmlNode_t* np, const cmChar_t* label ); + cmXmlRC_t cmXmlAttrInt( const cmXmlNode_t* np, const cmChar_t* attrLabel, int* retRef ); + cmXmlRC_t cmXmlAttrUInt( const cmXmlNode_t* np, const cmChar_t* attrLabel, unsigned* retRef ); - + // Return the data value for a node or attributes. + // List Syntax: node-label-0, node-label-1, NULL, attr-label-0 attr-label-1 + const cmChar_t* cmXmlNodeValueV( const cmXmlNode_t* np, va_list vl ); + const cmChar_t* cmXmlNodeValue( const cmXmlNode_t* np, ... ); + cmXmlRC_t cmXmlNodeIntV( const cmXmlNode_t* np, int* retRef, va_list vl ); + cmXmlRC_t cmXmlNodeUIntV(const cmXmlNode_t* np, unsigned* retRef, va_list vl ); + + cmXmlRC_t cmXmlNodeInt( const cmXmlNode_t* np, int* retRef, ... ); + cmXmlRC_t cmXmlNodeUInt( const cmXmlNode_t* np, unsigned* retRef, ... ); + cmXmlRC_t cmXmlTest( cmCtx_t* ctx, const cmChar_t* fn ); #ifdef __cpluspus