|
@@ -284,12 +284,22 @@ const cmChar_t* _cmXmlAdvanceToNext( cmXml_t* p, cmChar_t* s )
|
284
|
284
|
// Return the character following the current character.
|
285
|
285
|
const cmChar_t* _cmXmlAdvanceOne( cmXml_t* p )
|
286
|
286
|
{
|
|
287
|
+ if( _cmXmlAdvance(p) )
|
|
288
|
+ return p->c;
|
|
289
|
+
|
|
290
|
+ return NULL;
|
|
291
|
+
|
|
292
|
+ /*
|
287
|
293
|
if( _cmXmlIsEof(p) )
|
288
|
294
|
return NULL;
|
289
|
295
|
|
290
|
296
|
p->c += 1;
|
291
|
297
|
|
|
298
|
+ if( *p->c == '\n' )
|
|
299
|
+ p->line += 1;
|
|
300
|
+
|
292
|
301
|
return _cmXmlIsEof(p) ? NULL : p->c;
|
|
302
|
+ */
|
293
|
303
|
}
|
294
|
304
|
|
295
|
305
|
cmXmlRC_t _cmXmlParseAttr( cmXml_t* p, cmChar_t endChar, cmXmlNode_t* np )
|
|
@@ -993,13 +1003,33 @@ cmXmlRC_t cmXmlNodeDouble(const cmXmlNode_t* np, double* retRef, ...)
|
993
|
1003
|
|
994
|
1004
|
}
|
995
|
1005
|
|
996
|
|
-bool cmXmlNodeHasChildV( const cmXmlNode_t* np, const cmChar_t* label, va_list vl )
|
|
1006
|
+unsigned _cmXmlLabelCount( const cmChar_t* firstLabel, va_list vl )
|
997
|
1007
|
{
|
998
|
|
- const cmChar_t* str = NULL;
|
|
1008
|
+ unsigned n = 0;
|
|
1009
|
+
|
|
1010
|
+ if( firstLabel != NULL )
|
|
1011
|
+ {
|
|
1012
|
+ n = 1;
|
|
1013
|
+
|
|
1014
|
+ va_list vl0;
|
|
1015
|
+ va_copy(vl0,vl);
|
|
1016
|
+ while( va_arg(vl0,const cmChar_t*) != NULL )
|
|
1017
|
+ n += 1;
|
|
1018
|
+
|
|
1019
|
+ va_end(vl0);
|
|
1020
|
+ }
|
|
1021
|
+ return n;
|
|
1022
|
+}
|
999
|
1023
|
|
|
1024
|
+const cmXmlNode_t* _cmXmlNodeHasChildV( const cmXmlNode_t* np, const cmChar_t* label, va_list vl, unsigned argN )
|
|
1025
|
+{
|
|
1026
|
+ unsigned i;
|
|
1027
|
+
|
1000
|
1028
|
// get next label to match
|
1001
|
|
- while( (str = va_arg(vl,const cmChar_t*)) == NULL )
|
|
1029
|
+ for(i=0; i<argN; ++i)
|
1002
|
1030
|
{
|
|
1031
|
+ assert( label != NULL);
|
|
1032
|
+
|
1003
|
1033
|
np = np->children;
|
1004
|
1034
|
for(; np!=NULL; np=np->sibling)
|
1005
|
1035
|
if( cmTextCmp(np->label,label) == 0 )
|
|
@@ -1007,10 +1037,18 @@ bool cmXmlNodeHasChildV( const cmXmlNode_t* np, const cmChar_t* label, va_lis
|
1007
|
1037
|
|
1008
|
1038
|
// if the end of the child list was encountered - with no match
|
1009
|
1039
|
if( np == NULL )
|
1010
|
|
- return false;
|
|
1040
|
+ return NULL;
|
|
1041
|
+
|
|
1042
|
+ label = va_arg(vl,const cmChar_t*);
|
|
1043
|
+
|
1011
|
1044
|
}
|
1012
|
1045
|
|
1013
|
|
- return true;
|
|
1046
|
+ return np;
|
|
1047
|
+}
|
|
1048
|
+
|
|
1049
|
+bool cmXmlNodeHasChildV( const cmXmlNode_t* np, const cmChar_t* label, va_list vl )
|
|
1050
|
+{
|
|
1051
|
+ return _cmXmlNodeHasChildV(np,label,vl,_cmXmlLabelCount(label,vl))!=NULL;
|
1014
|
1052
|
}
|
1015
|
1053
|
|
1016
|
1054
|
bool cmXmlNodeHasChild( const cmXmlNode_t* np, const cmChar_t* label, ... )
|
|
@@ -1022,8 +1060,73 @@ bool cmXmlNodeHasChild( const cmXmlNode_t* np, const cmChar_t* label, ... )
|
1022
|
1060
|
return fl;
|
1023
|
1061
|
}
|
1024
|
1062
|
|
|
1063
|
+bool _cmXmlNodeHasChildWithAttrAndValueV( const cmXmlNode_t* np, const cmChar_t* label, va_list vl0, bool valueFl )
|
|
1064
|
+{
|
|
1065
|
+ unsigned argN = _cmXmlLabelCount(label,vl0);
|
|
1066
|
+ unsigned n = valueFl ? 2 : 1;
|
|
1067
|
+ va_list vl1;
|
|
1068
|
+ unsigned i;
|
|
1069
|
+
|
|
1070
|
+ assert( argN > n-1 ); // an attribute label must be given.
|
1025
|
1071
|
|
|
1072
|
+ if( argN <= n-1 )
|
|
1073
|
+ return false;
|
|
1074
|
+
|
|
1075
|
+ va_copy(vl1,vl0);
|
|
1076
|
+ np = _cmXmlNodeHasChildV(np,label,vl1,argN-1);
|
|
1077
|
+ va_end(vl1);
|
1026
|
1078
|
|
|
1079
|
+ if( np == NULL )
|
|
1080
|
+ return false;
|
|
1081
|
+
|
|
1082
|
+ // advance vl0 to the attribute label
|
|
1083
|
+ for(i=0; i<argN-1; ++i)
|
|
1084
|
+ {
|
|
1085
|
+ label = va_arg(vl0,const cmChar_t*);
|
|
1086
|
+ assert( label != NULL );
|
|
1087
|
+ }
|
|
1088
|
+
|
|
1089
|
+ // get the attr label
|
|
1090
|
+ label = va_arg(vl0,const cmChar_t*);
|
|
1091
|
+
|
|
1092
|
+ const cmXmlAttr_t* a;
|
|
1093
|
+ if((a = cmXmlFindAttrib(np,label)) == NULL )
|
|
1094
|
+ return false;
|
|
1095
|
+
|
|
1096
|
+
|
|
1097
|
+ if( valueFl )
|
|
1098
|
+ {
|
|
1099
|
+ label = va_arg(vl0,const cmChar_t*);
|
|
1100
|
+ if( cmTextCmp(a->value,label) != 0 )
|
|
1101
|
+ return false;
|
|
1102
|
+ }
|
|
1103
|
+
|
|
1104
|
+ return true;
|
|
1105
|
+ }
|
|
1106
|
+
|
|
1107
|
+bool cmXmlNodeHasChildWithAttrAndValueV( const cmXmlNode_t* np, const cmChar_t* label, va_list vl )
|
|
1108
|
+{ return _cmXmlNodeHasChildWithAttrAndValueV(np,label,vl,true); }
|
|
1109
|
+
|
|
1110
|
+bool cmXmlNodeHasChildWithAttrAndValue( const cmXmlNode_t* np, const cmChar_t* label, ... )
|
|
1111
|
+{
|
|
1112
|
+ va_list vl;
|
|
1113
|
+ va_start(vl,label);
|
|
1114
|
+ bool fl = cmXmlNodeHasChildWithAttrAndValueV(np,label,vl);
|
|
1115
|
+ va_end(vl);
|
|
1116
|
+ return fl;
|
|
1117
|
+}
|
|
1118
|
+
|
|
1119
|
+bool cmXmlNodeHasChildWithAttrV( const cmXmlNode_t* np, const cmChar_t* label, va_list vl )
|
|
1120
|
+{ return _cmXmlNodeHasChildWithAttrAndValueV(np,label,vl,false); }
|
|
1121
|
+
|
|
1122
|
+bool cmXmlNodeHasChildWithAttr( const cmXmlNode_t* np, const cmChar_t* label, ... )
|
|
1123
|
+{
|
|
1124
|
+ va_list vl;
|
|
1125
|
+ va_start(vl,label);
|
|
1126
|
+ bool fl = cmXmlNodeHasChildWithAttrV(np,label,vl);
|
|
1127
|
+ va_end(vl);
|
|
1128
|
+ return fl;
|
|
1129
|
+}
|
1027
|
1130
|
|
1028
|
1131
|
cmXmlRC_t cmXmlTest( cmCtx_t* ctx, const cmChar_t* fn )
|
1029
|
1132
|
{
|