libcm is a C development framework with an emphasis on audio signal processing applications.
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

cmXml.c 4.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. #include "cmPrefix.h"
  2. #include "cmGlobal.h"
  3. #include "cmFloatTypes.h"
  4. #include "cmRpt.h"
  5. #include "cmErr.h"
  6. #include "cmCtx.h"
  7. #include "cmJson.h"
  8. #include "cmMem.h"
  9. #include "cmMallocDebug.h"
  10. #include "cmLex.h"
  11. #include "cmLinkedHeap.h"
  12. #include "cmFile.h"
  13. #include "cmXml.h"
  14. /*
  15. file -> decl doctype node
  16. decl -> "<?" attr-list "?>"
  17. doctype -> "<!DOCTYPE" dt-text ">"
  18. node -> beg-node node-body end-node
  19. | "<!--" cmmt-text "-->"
  20. node-body -> data-text
  21. | node
  22. beg-node -> "<" tag-label attr-list ">"
  23. end-node -> "<" tag-label "/>"
  24. attr-list -> attr*
  25. attr -> attr-label "=" qstring
  26. attr-label -> A string of characters ending with an '=' or <space>.
  27. Attribute labels may not contain '<' or '>'.
  28. tag-label -> A string of characters ending with:
  29. <space>, '>' or '/>'.
  30. Tag labels may not contain '<' or '>'.
  31. data-text -> A string of characters ending with '<'.
  32. dt-text -> A string of characters beginning with a non-whitespace
  33. and ending with '>'
  34. cmmt-text -> A string of characters ending with '-->'
  35. */
  36. cmXmlH_t cmXmlNullHandle = cmSTATIC_NULL_HANDLE;
  37. typedef struct
  38. {
  39. cmErr_t err; //
  40. cmLHeapH_t heapH; // linked heap stores all node memory
  41. cmLexH lexH;
  42. cmXmlNode_t* root;
  43. } cmXml_t;
  44. enum
  45. {
  46. kTagBegLexTId = kUserLexTId+1,
  47. kTagEndLexTId,
  48. kDeclBegLexTId,
  49. kDeclEndLexTId,
  50. kSpclBegLexTId,
  51. kDocTypeLexTId,
  52. kCmmtBegLexTId,
  53. kCmmtEndLexTId,
  54. kEqualLexTId
  55. };
  56. cmXmlToken_t _cmXmlTokenArray[] =
  57. {
  58. { kTagBegLexTId = kUserLexId+1, "<" },
  59. { kTagEndLexTid, ">" },
  60. { kDeclBegLexTId, "<?" },
  61. { kDeclEndLexTid, "?>" },
  62. { kSpclBegLexTId, "<!" },
  63. { kDocTypeLexTId, "<!DOCTYPE" },
  64. { kCmmtBegLexTId, "<!--" },
  65. { kCmmtEndLexTid, "-->" },
  66. { kEqualLexTid, "=" },
  67. { kErrorLexTId,""}
  68. };
  69. // Match a tag label.
  70. // A string ending with a <space> or '>'
  71. unsigned cmLexTagLabelMatcher( const cmChar_t* cp, unsigned cn )
  72. {
  73. for(i=0; i<cn; ++i)
  74. if( cp[i] == '>' || isspace(cp[i]) )
  75. break;
  76. return i>0 ? i-1 : 0;
  77. }
  78. unsigned cmLexStringMatcher( const cmChar_t* cp, unsigned cn )
  79. {
  80. for(i=0; i<cn; ++i)
  81. {
  82. if( cp[i] == ' ')
  83. break;
  84. if( cp[i] == '<' )
  85. break;
  86. }
  87. return i>0 ?
  88. }
  89. cmXml_t* _cmXmlHandleToPtr( cmXmlH_t h )
  90. {
  91. cmXml_t* p = (cmXml_t*)h.h;
  92. assert( p != NULL );
  93. return p;
  94. }
  95. cmXmlRC_t _cmXmlFree( cmXml_t* p )
  96. {
  97. cmLHeapDestroy( &p->heapH );
  98. cmLexDestroy( &p->lexH );
  99. }
  100. cmXmlRC_t _cmXmlParse( cmXml_t* p, const cmChar_t* fn )
  101. {
  102. cmXmlRC_t rc = kOkXmlRC;
  103. if( cmLexReset( p->lexH ) != kOkLexRC )
  104. {
  105. rc = cmErrMsg(&p->err,kLexErrXmlRC,"Lexer reset failed.");
  106. goto errLabel:
  107. }
  108. if( cmLexSetFile( p->lexH, fn ) != kOkLexRC )
  109. {
  110. rc = cmErrMsg(&p->err,kLexErrXmlRC,"Lexer parse failed on '%s'.",cmStringNullGuard(fn));
  111. goto errLabel;
  112. }
  113. unsigned tokId;
  114. while((tokId = cmLexGetNextToken( cmLexH h )) != kEofRC && tokId != kErrorLexTId )
  115. {
  116. switch(tokId)
  117. {
  118. case kTagBegLexTId:
  119. case kTagEndLexTid:
  120. case kEqualLexTId:
  121. case kQStrLexTId:
  122. }
  123. }
  124. errLabel:
  125. return rc;
  126. }
  127. cmXmlRC_t cmXmlAlloc( cmCtx_t* ctx, cmXmlH_t* hp, const cmChar_t* fn )
  128. {
  129. cmXmlRC_t rc = kOkXmlRC;
  130. cmXml_t* p = NULL;
  131. // finalize before initialize
  132. if((rc = cmXmlFree(hp)) != kOkXmlRC )
  133. return rc;
  134. // allocate the main object record
  135. if((p = cmMemAllocZ( cmXml_t, 1 )) == NULL )
  136. return cmErrMsg(&ctx->err,kMemAllocErrXmlRC,"Object memory allocation failed.");
  137. cmErrSetup(&p->err,&ctx->rpt,"XML Parser");
  138. // allocate the linked heap mgr
  139. if( cmLHeapIsValid(p->heapH = cmLHeapCreate(1024,ctx)) == false )
  140. {
  141. rc = cmErrMsg(&p->err,kMemAllocErrXmlRC,"Linked heap object allocation failed.");
  142. goto errLabel;
  143. }
  144. // allocate the lexer
  145. if(cmLexIsValid(p->lexH = cmLexInit(NULL,0,0,&ctx->rpt)) == false )
  146. {
  147. rc = cmErrMsg(&p->err,kLexErrXmlRC,"Lex allocation failed.");
  148. goto errLabel;
  149. }
  150. // register xml specific tokens with the lexer
  151. for(i=0; _cmXmlTokenArray[i].id != kErrorLexTId; ++i)
  152. {
  153. cmRC_t lexRC;
  154. if( (lexRC = cmLexRegisterToken(p->lexH, _cmXmlTokenArray[i].id, _cmXmlTokenArray[i].text )) != kOkLexRC )
  155. {
  156. rc = cmErrMsg(&p->err,kLexErrXmlRC,"Lex token registration failed for:'%s'.",_cmXmlTokenArray[i].text );
  157. goto errLabel;
  158. }
  159. }
  160. hp->h = p;
  161. errLabel:
  162. if(rc != kOkXmlRC )
  163. _cmXmlFree(p);
  164. return rc;
  165. }
  166. cmXmlRC_t cmXmlFree( cmXmlH_t* hp )
  167. {
  168. cmXmlRC_t rc = kOkXmlRC;
  169. if( hp!=NULL || cmXmlIsValid(*hp)==false )
  170. return kOkXmlRC;
  171. cmXml_t* p = _cmXmlHandleToPtr(*hp);
  172. if((rc = _cmXmlFree(p)) != kOkXmlRC )
  173. return rc;
  174. hp->h = NULL;
  175. return rc;
  176. }
  177. bool cmXmlIsValid( cmXmlH_t h )
  178. { return h.h != NULL; }
  179. cmXmlRC_t cmXmlParse( cmXmlH_t h, const cmChar_t* fn )
  180. {
  181. }
  182. cmXmlRC_t cmXmlClear( cmXmlH_t h )
  183. {
  184. }