Browse Source

cmXml.h/c : Added cmXmlNodeHasChildWithAttr() and cmXmlNodeHasChildWithAttrAndValue().

master
kevin 8 years ago
parent
commit
3664ba5c76
2 changed files with 119 additions and 5 deletions
  1. 108
    5
      cmXml.c
  2. 11
    0
      cmXml.h

+ 108
- 5
cmXml.c View File

@@ -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
 {

+ 11
- 0
cmXml.h View File

@@ -88,6 +88,17 @@ extern "C" {
88 88
   bool               cmXmlNodeHasChildV(const cmXmlNode_t* np, const cmChar_t* label, va_list vl );
89 89
   bool               cmXmlNodeHasChild( const cmXmlNode_t* np, const cmChar_t* label, ... );
90 90
 
91
+  // Last label in list is an attribute label.
92
+  // Terminate the list with NULL.
93
+  bool               cmXmlNodeHasChildWithAttrV( const cmXmlNode_t* np, const cmChar_t* label, va_list vl );
94
+  bool               cmXmlNodeHasChildWithAttr(  const cmXmlNode_t* np, const cmChar_t* label, ... );
95
+
96
+  // Last second to last label in the list is an attribute label.
97
+  // THe last label in the list is an attribute value.
98
+  // Terminate the list with NULL.
99
+  bool               cmXmlNodeHasChildWithAttrAndValueV( const cmXmlNode_t* np, const cmChar_t* label, va_list vl );
100
+  bool               cmXmlNodeHasChildWithAttrAndValue(  const cmXmlNode_t* np, const cmChar_t* label, ... );
101
+  
91 102
   
92 103
   cmXmlRC_t cmXmlTest( cmCtx_t* ctx, const cmChar_t* fn );
93 104
   

Loading…
Cancel
Save