libcm is a C development framework with an emphasis on audio signal processing applications.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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. }