Преглед на файлове

cmXml.h/c : Added cmXmlFindAttr(), cmXmlAttrInt(), cmXmlNodeValue(), cmXmlNodeInt() (and related functions.)

cmXmlAlloc() now automatically parses file if 'fn' arg. is given.
Fixed bug in cmXmlSearch() which did not return node when attribute keys were not given.
master
Kevin Larke преди 8 години
родител
ревизия
0f6bd3ea63
променени са 2 файла, в които са добавени 136 реда и са изтрити 12 реда
  1. 116
    3
      cmXml.c
  2. 20
    9
      cmXml.h

+ 116
- 3
cmXml.c Целия файл

@@ -86,6 +86,10 @@ cmXmlRC_t cmXmlAlloc( cmCtx_t* ctx, cmXmlH_t* hp, const cmChar_t* fn )
86 86
 
87 87
   hp->h = p;
88 88
 
89
+  if( fn != NULL )
90
+    if((rc = cmXmlParse(*hp,fn)) != kOkXmlRC )
91
+      hp->h = NULL;
92
+
89 93
  errLabel:
90 94
   if(rc != kOkXmlRC )
91 95
     _cmXmlFree(p);
@@ -116,7 +120,7 @@ bool      cmXmlIsValid( cmXmlH_t h )
116 120
   
117 121
 cmXmlRC_t _cmXmlSyntaxError( cmXml_t* p )
118 122
 {
119
-  return cmErrMsg(&p->err,kSyntaxErrorXmlRC,"Syntax error on line '%i.",p->line);
123
+  return cmErrMsg(&p->err,kSyntaxErrorXmlRC,"Syntax error on line %i.",p->line);
120 124
 }
121 125
 
122 126
 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
756 760
   // if the 'label' matches this node's label ...
757 761
   if( cmTextCmp(np->label,label) == 0 )
758 762
   {
763
+    if( attrN == 0 )
764
+      return np;
765
+    
759 766
     unsigned           matchN = 0;
760 767
     const cmXmlAttr_t* a      = np->attr;
761 768
     unsigned           i;
@@ -776,7 +783,8 @@ const cmXmlNode_t* cmXmlSearch( const cmXmlNode_t* np, const cmChar_t* label, co
776 783
           break;
777 784
         }
778 785
       }
779
-    }    
786
+    }
787
+
780 788
   }
781 789
 
782 790
   // 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
817 825
   return np;
818 826
 }
819 827
 
828
+const cmXmlAttr_t* cmXmlFindAttrib( const cmXmlNode_t* np, const cmChar_t* label )
829
+{
830
+  const cmXmlAttr_t* a = np->attr;
831
+  for(; a!=NULL; a=a->link)
832
+    if( cmTextCmp(a->label,label) == 0 )
833
+      return a;
834
+
835
+  return NULL;
836
+}
837
+
838
+cmXmlRC_t cmXmlAttrInt( const cmXmlNode_t* np, const cmChar_t* attrLabel, int* retRef )
839
+{
840
+  const cmXmlAttr_t* a;
841
+  if((a = cmXmlFindAttrib(np,attrLabel)) == NULL )
842
+    return kNodeNotFoundXmlRC;
843
+
844
+  assert(retRef != NULL);
845
+  
846
+  *retRef = 0;
847
+
848
+  if( a->value != NULL )
849
+  {
850
+    errno = 0;
851
+
852
+    // convert the string to an integer
853
+    *retRef = strtol(a->value,NULL,10);
854
+    
855
+    if( errno != 0 )
856
+      return kInvalidTypeXmlRC;
857
+  }
858
+  
859
+  return kOkXmlRC;
860
+  
861
+}
862
+
863
+cmXmlRC_t cmXmlAttrUInt( const cmXmlNode_t* np, const cmChar_t* attrLabel, unsigned* retRef )
864
+{ return cmXmlAttrInt(np,attrLabel,(int*)retRef); }
865
+
820 866
 cmXmlRC_t cmXmlGetInt( const cmXmlNode_t* np, int* retRef, const cmChar_t* label, const cmXmlAttr_t* attrV, unsigned attrN, ... )
821 867
 {
822 868
   cmXmlRC_t          rc = kNodeNotFoundXmlRC;
@@ -847,11 +893,78 @@ cmXmlRC_t cmXmlGetInt( const cmXmlNode_t* np, int* retRef, const cmChar_t* label
847 893
   return rc;
848 894
 }
849 895
 
896
+const cmXmlNode_t* _cmXmlNodeFindChild( const cmXmlNode_t* np, const cmChar_t* label )
897
+{
898
+  const cmXmlNode_t* cnp = np->children;
899
+  for(; cnp!=NULL; cnp=cnp->sibling)
900
+    if( cmTextCmp(cnp->label,label) == 0 )
901
+      return cnp;  
902
+  return NULL;
903
+}
904
+
905
+const cmChar_t*    cmXmlNodeValueV( const cmXmlNode_t* np, va_list vl )
906
+{
907
+  const cmChar_t* label;
908
+  
909
+  // for each node label
910
+  while( (label = va_arg(vl,const cmChar_t*)) != NULL )
911
+    if((np = _cmXmlNodeFindChild(np,label)) == NULL )
912
+      break;  
913
+  
914
+  return np==NULL ? NULL : np->dataStr;
915
+}
916
+
917
+const cmChar_t*    cmXmlNodeValue( const cmXmlNode_t* np, ... )
918
+{
919
+  va_list vl;
920
+  va_start(vl,np);
921
+  const cmChar_t* str = cmXmlNodeValueV(np,vl);
922
+  va_end(vl);
923
+  return str;
924
+}
925
+
926
+
927
+cmXmlRC_t          cmXmlNodeIntV(const cmXmlNode_t* np, int* retRef, va_list vl )
928
+{
929
+  const cmChar_t* valueStr;
930
+  if((valueStr = cmXmlNodeValueV(np,vl)) == NULL )
931
+    return kNodeNotFoundXmlRC;
932
+
933
+  errno = 0;
934
+
935
+  // convert the string to an integer
936
+  *retRef = strtol(valueStr,NULL,10);
937
+    
938
+  if( errno != 0 )
939
+    return kInvalidTypeXmlRC;
940
+  
941
+  return kOkXmlRC;
942
+}
850 943
 
851
-void _cmXmlPrintMeasure( const cmXmlNode_t* mnp )
944
+cmXmlRC_t          cmXmlNodeUIntV(const cmXmlNode_t* np, unsigned* retRef, va_list vl )
945
+{ return cmXmlNodeIntV(np,(int*)retRef,vl); }
946
+
947
+cmXmlRC_t          cmXmlNodeInt( const cmXmlNode_t* np, int* retRef, ... )
852 948
 {
949
+  cmXmlRC_t rc;
950
+  va_list vl;
951
+  va_start(vl,retRef);
952
+  rc = cmXmlNodeIntV(np,retRef,vl);
953
+  va_end(vl);
954
+  return rc;
853 955
 }
854 956
 
957
+cmXmlRC_t          cmXmlNodeUInt( const cmXmlNode_t* np, unsigned* retRef, ... )
958
+{
959
+  cmXmlRC_t rc;
960
+  va_list vl;
961
+  va_start(vl,retRef);
962
+  rc = cmXmlNodeUIntV(np,retRef,vl);
963
+  va_end(vl);
964
+  return rc;
965
+}
966
+
967
+
855 968
 cmXmlRC_t _cmXmlPrintScore( cmXmlH_t h )
856 969
 {
857 970
   cmXmlRC_t rc          = kOkXmlRC;

+ 20
- 9
cmXml.h Целия файл

@@ -35,17 +35,16 @@ extern "C" {
35 35
   
36 36
   typedef struct cmXmlNode_str
37 37
   {
38
-    unsigned              flags;
38
+    unsigned              flags;    // See k???XmlFl
39 39
     
40
-    const cmChar_t*       label;
41
-    const cmChar_t*       dataStr;
42
-    
43
-    cmXmlAttr_t*          attr;
40
+    const cmChar_t*       label;    // node label
41
+    const cmChar_t*       dataStr;  // node data string
44 42
     
45
-    struct cmXmlNode_str* parent;
46
-    struct cmXmlNode_str* children;
47
-    struct cmXmlNode_str* sibling;
43
+    cmXmlAttr_t*          attr;     // attribute list
48 44
     
45
+    struct cmXmlNode_str* parent;   // parent node
46
+    struct cmXmlNode_str* children; // first child node list
47
+    struct cmXmlNode_str* sibling;  // 
49 48
     
50 49
   } cmXmlNode_t;
51 50
 
@@ -64,10 +63,22 @@ extern "C" {
64 63
   void               cmXmlPrint( cmXmlH_t h, cmRpt_t* rpt );
65 64
 
66 65
   const cmXmlNode_t* cmXmlSearch( const cmXmlNode_t* np, const cmChar_t* label, const cmXmlAttr_t* attrV, unsigned attrN );
66
+  const cmXmlAttr_t* cmXmlFindAttrib( const cmXmlNode_t* np, const cmChar_t* label );
67 67
 
68
+  cmXmlRC_t          cmXmlAttrInt(  const cmXmlNode_t* np, const cmChar_t* attrLabel, int* retRef );
69
+  cmXmlRC_t          cmXmlAttrUInt( const cmXmlNode_t* np, const cmChar_t* attrLabel, unsigned* retRef );
68 70
   
69
-  
71
+  // Return the data value for a node or attributes.
72
+  // List Syntax: node-label-0, node-label-1, NULL, attr-label-0 attr-label-1 
73
+  const cmChar_t*    cmXmlNodeValueV( const cmXmlNode_t* np, va_list vl );
74
+  const cmChar_t*    cmXmlNodeValue( const cmXmlNode_t* np, ... );
70 75
 
76
+  cmXmlRC_t          cmXmlNodeIntV( const cmXmlNode_t* np, int* retRef, va_list vl );
77
+  cmXmlRC_t          cmXmlNodeUIntV(const cmXmlNode_t* np, unsigned* retRef, va_list vl );
78
+
79
+  cmXmlRC_t          cmXmlNodeInt(  const cmXmlNode_t* np, int* retRef, ... );
80
+  cmXmlRC_t          cmXmlNodeUInt( const cmXmlNode_t* np, unsigned* retRef, ... );
81
+  
71 82
   cmXmlRC_t cmXmlTest( cmCtx_t* ctx, const cmChar_t* fn );
72 83
   
73 84
 #ifdef __cpluspus

Loading…
Отказ
Запис