diff --git a/cmXml.c b/cmXml.c index c23217a..2214eb8 100644 --- a/cmXml.c +++ b/cmXml.c @@ -169,6 +169,7 @@ cmXmlNode_t* _cmXmlNodeAlloc( cmXml_t* p, unsigned flags, const cmChar_t* label, if( label != NULL ) np->label = cmLhAllocStrN(p->heapH,label,labelN); + np->line = p->line; np->flags = flags; return np; @@ -992,14 +993,33 @@ cmXmlRC_t cmXmlNodeDouble(const cmXmlNode_t* np, double* retRef, ...) } -bool cmXmlNodeHasChild( const cmXmlNode_t* np, const cmChar_t* label ) +bool cmXmlNodeHasChildV( const cmXmlNode_t* np, const cmChar_t* label, va_list vl ) { - const cmXmlNode_t* cnp = np->children; - for(; cnp!=NULL; cnp=cnp->sibling) - if( cmTextCmp(cnp->label,label) == 0 ) - return true; + const cmChar_t* str = NULL; - return false; + // get next label to match + while( (str = va_arg(vl,const cmChar_t*)) == NULL ) + { + np = np->children; + for(; np!=NULL; np=np->sibling) + if( cmTextCmp(np->label,label) == 0 ) + break; + + // if the end of the child list was encountered - with no match + if( np == NULL ) + return false; + } + + return true; +} + +bool cmXmlNodeHasChild( const cmXmlNode_t* np, const cmChar_t* label, ... ) +{ + va_list vl; + va_start(vl,label); + bool fl = cmXmlNodeHasChildV(np,label,vl); + va_end(vl); + return fl; } diff --git a/cmXml.h b/cmXml.h index a3002a4..343139f 100644 --- a/cmXml.h +++ b/cmXml.h @@ -35,6 +35,7 @@ extern "C" { typedef struct cmXmlNode_str { + unsigned line; // line number unsigned flags; // See k???XmlFl const cmChar_t* label; // node label @@ -62,26 +63,30 @@ extern "C" { const cmXmlNode_t* cmXmlRoot( cmXmlH_t h ); 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 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 + // Terminate node label list with NULL. 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 ); + // Terminate node label list with NULL. + 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 cmXmlNodeDoubleV( const cmXmlNode_t* np, double* retRef, va_list vl ); - cmXmlRC_t cmXmlNodeInt( const cmXmlNode_t* np, int* retRef, ... ); + // Terminate node label list with NULL. + cmXmlRC_t cmXmlNodeInt( const cmXmlNode_t* np, int* retRef, ... ); cmXmlRC_t cmXmlNodeUInt( const cmXmlNode_t* np, unsigned* retRef, ... ); - cmXmlRC_t cmXmlNodeDouble(const cmXmlNode_t* np, double* retRef, ...); - - bool cmXmlNodeHasChild( const cmXmlNode_t* np, const cmChar_t* label ); + cmXmlRC_t cmXmlNodeDouble(const cmXmlNode_t* np, double* retRef, ... ); + + // Terminate node label list with NULL. + bool cmXmlNodeHasChildV(const cmXmlNode_t* np, const cmChar_t* label, va_list vl ); + bool cmXmlNodeHasChild( const cmXmlNode_t* np, const cmChar_t* label, ... ); cmXmlRC_t cmXmlTest( cmCtx_t* ctx, const cmChar_t* fn );