parser.c
上传用户:sy_wanhua
上传日期:2013-07-25
资源大小:3048k
文件大小:295k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

C/C++

  1. /*
  2.  * parser.c : an XML 1.0 non-verifying parser
  3.  *
  4.  * See Copyright for the status of this software.
  5.  *
  6.  * Daniel.Veillard@w3.org
  7.  */
  8. #ifdef WIN32
  9. #include "win32config.h"
  10. #else
  11. #include "config.h"
  12. #endif
  13. #include <stdio.h>
  14. #include <string.h> /* for memset() only */
  15. #ifdef HAVE_CTYPE_H
  16. #include <ctype.h>
  17. #endif
  18. #ifdef HAVE_STDLIB_H
  19. #include <stdlib.h>
  20. #endif
  21. #ifdef HAVE_SYS_STAT_H
  22. #include <sys/stat.h>
  23. #endif
  24. #ifdef HAVE_FCNTL_H
  25. #include <fcntl.h>
  26. #endif
  27. #ifdef HAVE_UNISTD_H
  28. #include <unistd.h>
  29. #endif
  30. #ifdef HAVE_ZLIB_H
  31. #include <zlib.h>
  32. #endif
  33. #include <libxml/xmlmemory.h>
  34. #include <libxml/tree.h>
  35. #include <libxml/parser.h>
  36. #include <libxml/entities.h>
  37. #include <libxml/encoding.h>
  38. #include <libxml/valid.h>
  39. #include <libxml/parserInternals.h>
  40. #include <libxml/xmlIO.h>
  41. #include "xml-error.h"
  42. #define XML_PARSER_BIG_BUFFER_SIZE 1000
  43. #define XML_PARSER_BUFFER_SIZE 100
  44. const char *xmlParserVersion = LIBXML_VERSION_STRING;
  45. int xmlGetWarningsDefaultValue = 1;
  46. /*
  47.  * List of XML prefixed PI allowed by W3C specs
  48.  */
  49. const char *xmlW3CPIs[] = {
  50.     "xml-stylesheet",
  51.     NULL
  52. };
  53. void xmlParserHandleReference(xmlParserCtxtPtr ctxt);
  54. void xmlParserHandlePEReference(xmlParserCtxtPtr ctxt);
  55. xmlEntityPtr xmlParseStringPEReference(xmlParserCtxtPtr ctxt,
  56.                                        const xmlChar **str);
  57. /************************************************************************
  58.  * *
  59.  *  Input handling functions for progressive parsing *
  60.  * *
  61.  ************************************************************************/
  62. /* #define DEBUG_INPUT */
  63. /* #define DEBUG_STACK */
  64. /* #define DEBUG_PUSH */
  65. #define INPUT_CHUNK 250
  66. /* we need to keep enough input to show errors in context */
  67. #define LINE_LEN        80
  68. #ifdef DEBUG_INPUT
  69. #define CHECK_BUFFER(in) check_buffer(in)
  70. void check_buffer(xmlParserInputPtr in) {
  71.     if (in->base != in->buf->buffer->content) {
  72.         fprintf(stderr, "xmlParserInput: base mismatch problemn");
  73.     }
  74.     if (in->cur < in->base) {
  75.         fprintf(stderr, "xmlParserInput: cur < base problemn");
  76.     }
  77.     if (in->cur > in->base + in->buf->buffer->use) {
  78.         fprintf(stderr, "xmlParserInput: cur > base + use problemn");
  79.     }
  80.     fprintf(stderr,"buffer %x : content %x, cur %d, use %d, size %dn",
  81.             (int) in, (int) in->buf->buffer->content, in->cur - in->base,
  82.     in->buf->buffer->use, in->buf->buffer->size);
  83. }
  84. #else
  85. #define CHECK_BUFFER(in) 
  86. #endif
  87. /**
  88.  * xmlParserInputRead:
  89.  * @in:  an XML parser input
  90.  * @len:  an indicative size for the lookahead
  91.  *
  92.  * This function refresh the input for the parser. It doesn't try to
  93.  * preserve pointers to the input buffer, and discard already read data
  94.  *
  95.  * Returns the number of xmlChars read, or -1 in case of error, 0 indicate the
  96.  * end of this entity
  97.  */
  98. int
  99. xmlParserInputRead(xmlParserInputPtr in, int len) {
  100.     int ret;
  101.     int used;
  102.     int index;
  103. #ifdef DEBUG_INPUT
  104.     fprintf(stderr, "Readn");
  105. #endif
  106.     if (in->buf == NULL) return(-1);
  107.     if (in->base == NULL) return(-1);
  108.     if (in->cur == NULL) return(-1);
  109.     if (in->buf->buffer == NULL) return(-1);
  110.     CHECK_BUFFER(in);
  111.     used = in->cur - in->buf->buffer->content;
  112.     ret = xmlBufferShrink(in->buf->buffer, used);
  113.     if (ret > 0) {
  114. in->cur -= ret;
  115. in->consumed += ret;
  116.     }
  117.     ret = xmlParserInputBufferRead(in->buf, len);
  118.     if (in->base != in->buf->buffer->content) {
  119.         /*
  120.  * the buffer has been realloced
  121.  */
  122. index = in->cur - in->base;
  123. in->base = in->buf->buffer->content;
  124. in->cur = &in->buf->buffer->content[index];
  125.     }
  126.     CHECK_BUFFER(in);
  127.     return(ret);
  128. }
  129. /**
  130.  * xmlParserInputGrow:
  131.  * @in:  an XML parser input
  132.  * @len:  an indicative size for the lookahead
  133.  *
  134.  * This function increase the input for the parser. It tries to
  135.  * preserve pointers to the input buffer, and keep already read data
  136.  *
  137.  * Returns the number of xmlChars read, or -1 in case of error, 0 indicate the
  138.  * end of this entity
  139.  */
  140. int
  141. xmlParserInputGrow(xmlParserInputPtr in, int len) {
  142.     int ret;
  143.     int index;
  144. #ifdef DEBUG_INPUT
  145.     fprintf(stderr, "Grown");
  146. #endif
  147.     if (in->buf == NULL) return(-1);
  148.     if (in->base == NULL) return(-1);
  149.     if (in->cur == NULL) return(-1);
  150.     if (in->buf->buffer == NULL) return(-1);
  151.     CHECK_BUFFER(in);
  152.     index = in->cur - in->base;
  153.     if (in->buf->buffer->use > index + INPUT_CHUNK) {
  154. CHECK_BUFFER(in);
  155.         return(0);
  156.     }
  157.     if (in->buf->readcallback != NULL)
  158. ret = xmlParserInputBufferGrow(in->buf, len);
  159.     else
  160.         return(0);
  161.     /*
  162.      * NOTE : in->base may be a "dandling" i.e. freed pointer in this
  163.      *        block, but we use it really as an integer to do some
  164.      *        pointer arithmetic. Insure will raise it as a bug but in
  165.      *        that specific case, that's not !
  166.      */
  167.     if (in->base != in->buf->buffer->content) {
  168.         /*
  169.  * the buffer has been realloced
  170.  */
  171. index = in->cur - in->base;
  172. in->base = in->buf->buffer->content;
  173. in->cur = &in->buf->buffer->content[index];
  174.     }
  175.     CHECK_BUFFER(in);
  176.     return(ret);
  177. }
  178. /**
  179.  * xmlParserInputShrink:
  180.  * @in:  an XML parser input
  181.  *
  182.  * This function removes used input for the parser.
  183.  */
  184. void
  185. xmlParserInputShrink(xmlParserInputPtr in) {
  186.     int used;
  187.     int ret;
  188.     int index;
  189. #ifdef DEBUG_INPUT
  190.     fprintf(stderr, "Shrinkn");
  191. #endif
  192.     if (in->buf == NULL) return;
  193.     if (in->base == NULL) return;
  194.     if (in->cur == NULL) return;
  195.     if (in->buf->buffer == NULL) return;
  196.     CHECK_BUFFER(in);
  197.     used = in->cur - in->buf->buffer->content;
  198.     if (used > INPUT_CHUNK) {
  199. ret = xmlBufferShrink(in->buf->buffer, used - LINE_LEN);
  200. if (ret > 0) {
  201.     in->cur -= ret;
  202.     in->consumed += ret;
  203. }
  204.     }
  205.     CHECK_BUFFER(in);
  206.     if (in->buf->buffer->use > INPUT_CHUNK) {
  207.         return;
  208.     }
  209.     xmlParserInputBufferRead(in->buf, 2 * INPUT_CHUNK);
  210.     if (in->base != in->buf->buffer->content) {
  211.         /*
  212.  * the buffer has been realloced
  213.  */
  214. index = in->cur - in->base;
  215. in->base = in->buf->buffer->content;
  216. in->cur = &in->buf->buffer->content[index];
  217.     }
  218.     CHECK_BUFFER(in);
  219. }
  220. /************************************************************************
  221.  * *
  222.  *  Parser stacks related functions and macros *
  223.  * *
  224.  ************************************************************************/
  225. int xmlSubstituteEntitiesDefaultValue = 0;
  226. int xmlDoValidityCheckingDefaultValue = 0;
  227. int xmlKeepBlanksDefaultValue = 1;
  228. xmlEntityPtr xmlParseStringEntityRef(xmlParserCtxtPtr ctxt,
  229.                                      const xmlChar ** str);
  230. /*
  231.  * Generic function for accessing stacks in the Parser Context
  232.  */
  233. #define PUSH_AND_POP(scope, type, name)
  234. scope int name##Push(xmlParserCtxtPtr ctxt, type value) {
  235.     if (ctxt->name##Nr >= ctxt->name##Max) {
  236. ctxt->name##Max *= 2;
  237.         ctxt->name##Tab = (void *) xmlRealloc(ctxt->name##Tab,
  238.              ctxt->name##Max * sizeof(ctxt->name##Tab[0]));
  239.         if (ctxt->name##Tab == NULL) {
  240.     fprintf(stderr, "realloc failed !n");
  241.     return(0);
  242. }
  243.     }
  244.     ctxt->name##Tab[ctxt->name##Nr] = value;
  245.     ctxt->name = value;
  246.     return(ctxt->name##Nr++);
  247. }
  248. scope type name##Pop(xmlParserCtxtPtr ctxt) {
  249.     type ret;
  250.     if (ctxt->name##Nr <= 0) return(0);
  251.     ctxt->name##Nr--;
  252.     if (ctxt->name##Nr > 0)
  253. ctxt->name = ctxt->name##Tab[ctxt->name##Nr - 1];
  254.     else
  255.         ctxt->name = NULL;
  256.     ret = ctxt->name##Tab[ctxt->name##Nr];
  257.     ctxt->name##Tab[ctxt->name##Nr] = 0;
  258.     return(ret);
  259. }
  260. PUSH_AND_POP(extern, xmlParserInputPtr, input)
  261. PUSH_AND_POP(extern, xmlNodePtr, node)
  262. PUSH_AND_POP(extern, xmlChar*, name)
  263. int spacePush(xmlParserCtxtPtr ctxt, int val) {
  264.     if (ctxt->spaceNr >= ctxt->spaceMax) {
  265. ctxt->spaceMax *= 2;
  266.         ctxt->spaceTab = (void *) xmlRealloc(ctxt->spaceTab,
  267.              ctxt->spaceMax * sizeof(ctxt->spaceTab[0]));
  268.         if (ctxt->spaceTab == NULL) {
  269.     fprintf(stderr, "realloc failed !n");
  270.     return(0);
  271. }
  272.     }
  273.     ctxt->spaceTab[ctxt->spaceNr] = val;
  274.     ctxt->space = &ctxt->spaceTab[ctxt->spaceNr];
  275.     return(ctxt->spaceNr++);
  276. }
  277. int spacePop(xmlParserCtxtPtr ctxt) {
  278.     int ret;
  279.     if (ctxt->spaceNr <= 0) return(0);
  280.     ctxt->spaceNr--;
  281.     if (ctxt->spaceNr > 0)
  282. ctxt->space = &ctxt->spaceTab[ctxt->spaceNr - 1];
  283.     else
  284.         ctxt->space = NULL;
  285.     ret = ctxt->spaceTab[ctxt->spaceNr];
  286.     ctxt->spaceTab[ctxt->spaceNr] = -1;
  287.     return(ret);
  288. }
  289. /*
  290.  * Macros for accessing the content. Those should be used only by the parser,
  291.  * and not exported.
  292.  *
  293.  * Dirty macros, i.e. one need to make assumption on the context to use them
  294.  *
  295.  *   CUR_PTR return the current pointer to the xmlChar to be parsed.
  296.  *           To be used with extreme caution since operations consuming
  297.  *           characters may move the input buffer to a different location !
  298.  *   CUR     returns the current xmlChar value, i.e. a 8 bit value if compiled
  299.  *           in ISO-Latin or UTF-8. 
  300.  *           This should be used internally by the parser
  301.  *           only to compare to ASCII values otherwise it would break when
  302.  *           running with UTF-8 encoding.
  303.  *   NXT(n)  returns the n'th next xmlChar. Same as CUR is should be used only
  304.  *           to compare on ASCII based substring.
  305.  *   SKIP(n) Skip n xmlChar, and must also be used only to skip ASCII defined
  306.  *           strings within the parser.
  307.  *
  308.  * Clean macros, not dependent of an ASCII context, expect UTF-8 encoding
  309.  *
  310.  *   NEXT    Skip to the next character, this does the proper decoding
  311.  *           in UTF-8 mode. It also pop-up unfinished entities on the fly.
  312.  *   COPY(to) copy one char to *to, increment CUR_PTR and to accordingly
  313.  *   CUR_CHAR Return the current char as an int as well as its lenght.
  314.  */
  315. #define RAW (ctxt->token ? -1 : (*ctxt->input->cur))
  316. #define CUR (ctxt->token ? ctxt->token : (*ctxt->input->cur))
  317. #define NXT(val) ctxt->input->cur[(val)]
  318. #define CUR_PTR ctxt->input->cur
  319. #define SKIP(val) ctxt->nbChars += (val),ctxt->input->cur += (val);
  320.     if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);
  321.     if (*ctxt->input->cur == '&') xmlParserHandleReference(ctxt);
  322.     if ((*ctxt->input->cur == 0) &&
  323.         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
  324.     xmlPopInput(ctxt)
  325. #define SHRINK  xmlParserInputShrink(ctxt->input);
  326.     if ((*ctxt->input->cur == 0) &&
  327.         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
  328.     xmlPopInput(ctxt)
  329. #define GROW  xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
  330.     if ((*ctxt->input->cur == 0) &&
  331.         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
  332.     xmlPopInput(ctxt)
  333. #define SKIP_BLANKS xmlSkipBlankChars(ctxt);
  334. #define NEXT xmlNextChar(ctxt);
  335. #define NEXTL(l)
  336.     if (*(ctxt->input->cur) == 'n') {
  337. ctxt->input->line++; ctxt->input->col = 1;
  338.     } else ctxt->input->col++;
  339.     ctxt->token = 0; ctxt->input->cur += l;
  340.     if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);
  341.     if (*ctxt->input->cur == '&') xmlParserHandleReference(ctxt);
  342. #define CUR_CHAR(l) xmlCurrentChar(ctxt, &l);
  343. #define CUR_SCHAR(s, l) xmlStringCurrentChar(ctxt, s, &l);
  344. #define COPY_BUF(l,b,i,v)
  345.     if (l == 1) b[i++] = (xmlChar) v;
  346.     else i += xmlCopyChar(l,&b[i],v);
  347. /**
  348.  * xmlNextChar:
  349.  * @ctxt:  the XML parser context
  350.  *
  351.  * Skip to the next char input char.
  352.  */
  353. void
  354. xmlNextChar(xmlParserCtxtPtr ctxt) {
  355.     /*
  356.      * TODO: 2.11 End-of-Line Handling
  357.      *   the literal two-character sequence "#xD#xA" or a standalone
  358.      *   literal #xD, an XML processor must pass to the application
  359.      *   the single character #xA. 
  360.      */
  361.     if (ctxt->token != 0) ctxt->token = 0;
  362.     else {
  363. if ((*ctxt->input->cur == 0) &&
  364.     (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0) &&
  365.     (ctxt->instate != XML_PARSER_COMMENT)) {
  366.         /*
  367.  * If we are at the end of the current entity and
  368.  * the context allows it, we pop consumed entities
  369.  * automatically.
  370.  * TODO: the auto closing should be blocked in other cases
  371.  */
  372. xmlPopInput(ctxt);
  373. } else {
  374.     if (*(ctxt->input->cur) == 'n') {
  375. ctxt->input->line++; ctxt->input->col = 1;
  376.     } else ctxt->input->col++;
  377.     if (ctxt->encoding == NULL) {
  378. /*
  379.  * We are supposed to handle UTF8, check it's valid
  380.  * From rfc2044: encoding of the Unicode values on UTF-8:
  381.  *
  382.  * UCS-4 range (hex.)           UTF-8 octet sequence (binary)
  383.  * 0000 0000-0000 007F   0xxxxxxx
  384.  * 0000 0080-0000 07FF   110xxxxx 10xxxxxx
  385.  * 0000 0800-0000 FFFF   1110xxxx 10xxxxxx 10xxxxxx 
  386.  *
  387.  * Check for the 0x110000 limit too
  388.  */
  389. const unsigned char *cur = ctxt->input->cur;
  390. unsigned char c;
  391. c = *cur;
  392. if (c & 0x80) {
  393.     if (cur[1] == 0)
  394. xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
  395.     if ((cur[1] & 0xc0) != 0x80)
  396. goto encoding_error;
  397.     if ((c & 0xe0) == 0xe0) {
  398. unsigned int val;
  399. if (cur[2] == 0)
  400.     xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
  401. if ((cur[2] & 0xc0) != 0x80)
  402.     goto encoding_error;
  403. if ((c & 0xf0) == 0xf0) {
  404.     if (cur[3] == 0)
  405. xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
  406.     if (((c & 0xf8) != 0xf0) ||
  407. ((cur[3] & 0xc0) != 0x80))
  408. goto encoding_error;
  409.     /* 4-byte code */
  410.     ctxt->input->cur += 4;
  411.     val = (cur[0] & 0x7) << 18;
  412.     val |= (cur[1] & 0x3f) << 12;
  413.     val |= (cur[2] & 0x3f) << 6;
  414.     val |= cur[3] & 0x3f;
  415. } else {
  416.   /* 3-byte code */
  417.     ctxt->input->cur += 3;
  418.     val = (cur[0] & 0xf) << 12;
  419.     val |= (cur[1] & 0x3f) << 6;
  420.     val |= cur[2] & 0x3f;
  421. }
  422. if (((val > 0xd7ff) && (val < 0xe000)) ||
  423.     ((val > 0xfffd) && (val < 0x10000)) ||
  424.     (val >= 0x110000)) {
  425.     if ((ctxt->sax != NULL) &&
  426. (ctxt->sax->error != NULL))
  427. ctxt->sax->error(ctxt->userData, 
  428.  "Char out of allowed rangen");
  429.     ctxt->errNo = XML_ERR_INVALID_ENCODING;
  430.     ctxt->wellFormed = 0;
  431.     ctxt->disableSAX = 1;
  432. }    
  433.     } else
  434.       /* 2-byte code */
  435.         ctxt->input->cur += 2;
  436. } else
  437.     /* 1-byte code */
  438.     ctxt->input->cur++;
  439.     } else {
  440. /*
  441.  * Assume it's a fixed lenght encoding (1) with
  442.  * a compatibke encoding for the ASCII set, since
  443.  * XML constructs only use < 128 chars
  444.  */
  445.         ctxt->input->cur++;
  446.     }
  447.     ctxt->nbChars++;
  448.     if (*ctxt->input->cur == 0)
  449. xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
  450. }
  451.     }
  452.     if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);
  453.     if (*ctxt->input->cur == '&') xmlParserHandleReference(ctxt);
  454.     if ((*ctxt->input->cur == 0) &&
  455.         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
  456.     xmlPopInput(ctxt);
  457.     return;
  458. encoding_error:
  459.     /*
  460.      * If we detect an UTF8 error that probably mean that the
  461.      * input encoding didn't get properly advertized in the
  462.      * declaration header. Report the error and switch the encoding
  463.      * to ISO-Latin-1 (if you don't like this policy, just declare the
  464.      * encoding !)
  465.      */
  466.     if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  467. ctxt->sax->error(ctxt->userData, 
  468.  "Input is not proper UTF-8, indicate encoding !n");
  469.     ctxt->errNo = XML_ERR_INVALID_ENCODING;
  470.     ctxt->encoding = xmlStrdup(BAD_CAST "ISO-8859-1"); 
  471.     ctxt->input->cur++;
  472.     return;
  473. }
  474. /**
  475.  * xmlCurrentChar:
  476.  * @ctxt:  the XML parser context
  477.  * @len:  pointer to the length of the char read
  478.  *
  479.  * The current char value, if using UTF-8 this may actaully span multiple
  480.  * bytes in the input buffer. Implement the end of line normalization:
  481.  * 2.11 End-of-Line Handling
  482.  * Wherever an external parsed entity or the literal entity value
  483.  * of an internal parsed entity contains either the literal two-character
  484.  * sequence "#xD#xA" or a standalone literal #xD, an XML processor
  485.  * must pass to the application the single character #xA.
  486.  * This behavior can conveniently be produced by normalizing all
  487.  * line breaks to #xA on input, before parsing.)
  488.  *
  489.  * Returns the current char value and its lenght
  490.  */
  491. int
  492. xmlCurrentChar(xmlParserCtxtPtr ctxt, int *len) {
  493.     if (ctxt->token != 0) {
  494. *len = 0;
  495. return(ctxt->token);
  496.     }
  497.     if (ctxt->encoding == NULL) {
  498. /*
  499.  * We are supposed to handle UTF8, check it's valid
  500.  * From rfc2044: encoding of the Unicode values on UTF-8:
  501.  *
  502.  * UCS-4 range (hex.)           UTF-8 octet sequence (binary)
  503.  * 0000 0000-0000 007F   0xxxxxxx
  504.  * 0000 0080-0000 07FF   110xxxxx 10xxxxxx
  505.  * 0000 0800-0000 FFFF   1110xxxx 10xxxxxx 10xxxxxx 
  506.  *
  507.  * Check for the 0x110000 limit too
  508.  */
  509. const unsigned char *cur = ctxt->input->cur;
  510. unsigned char c;
  511. unsigned int val;
  512. c = *cur;
  513. if (c & 0x80) {
  514.     if (cur[1] == 0)
  515. xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
  516.     if ((cur[1] & 0xc0) != 0x80)
  517. goto encoding_error;
  518.     if ((c & 0xe0) == 0xe0) {
  519. if (cur[2] == 0)
  520.     xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
  521. if ((cur[2] & 0xc0) != 0x80)
  522.     goto encoding_error;
  523. if ((c & 0xf0) == 0xf0) {
  524.     if (cur[3] == 0)
  525. xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
  526.     if (((c & 0xf8) != 0xf0) ||
  527. ((cur[3] & 0xc0) != 0x80))
  528. goto encoding_error;
  529.     /* 4-byte code */
  530.     *len = 4;
  531.     val = (cur[0] & 0x7) << 18;
  532.     val |= (cur[1] & 0x3f) << 12;
  533.     val |= (cur[2] & 0x3f) << 6;
  534.     val |= cur[3] & 0x3f;
  535. } else {
  536.   /* 3-byte code */
  537.     *len = 3;
  538.     val = (cur[0] & 0xf) << 12;
  539.     val |= (cur[1] & 0x3f) << 6;
  540.     val |= cur[2] & 0x3f;
  541. }
  542.     } else {
  543.       /* 2-byte code */
  544. *len = 2;
  545. val = (cur[0] & 0x1f) << 6;
  546. val |= cur[1] & 0x3f;
  547.     }
  548.     if (!IS_CHAR(val)) {
  549. if ((ctxt->sax != NULL) &&
  550.     (ctxt->sax->error != NULL))
  551.     ctxt->sax->error(ctxt->userData, 
  552.      "Char out of allowed rangen");
  553. ctxt->errNo = XML_ERR_INVALID_ENCODING;
  554. ctxt->wellFormed = 0;
  555. ctxt->disableSAX = 1;
  556.     }    
  557.     return(val);
  558. } else {
  559.     /* 1-byte code */
  560.     *len = 1;
  561.     if (*ctxt->input->cur == 0xD) {
  562. if (ctxt->input->cur[1] == 0xA) {
  563.     ctxt->nbChars++;
  564.     ctxt->input->cur++;
  565. }
  566. return(0xA);
  567.     }
  568.     return((int) *ctxt->input->cur);
  569. }
  570.     }
  571.     /*
  572.      * Assume it's a fixed lenght encoding (1) with
  573.      * a compatibke encoding for the ASCII set, since
  574.      * XML constructs only use < 128 chars
  575.      */
  576.     *len = 1;
  577.     if (*ctxt->input->cur == 0xD) {
  578. if (ctxt->input->cur[1] == 0xA) {
  579.     ctxt->nbChars++;
  580.     ctxt->input->cur++;
  581. }
  582. return(0xA);
  583.     }
  584.     return((int) *ctxt->input->cur);
  585. encoding_error:
  586.     /*
  587.      * If we detect an UTF8 error that probably mean that the
  588.      * input encoding didn't get properly advertized in the
  589.      * declaration header. Report the error and switch the encoding
  590.      * to ISO-Latin-1 (if you don't like this policy, just declare the
  591.      * encoding !)
  592.      */
  593.     if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  594. ctxt->sax->error(ctxt->userData, 
  595.  "Input is not proper UTF-8, indicate encoding !n");
  596.     ctxt->errNo = XML_ERR_INVALID_ENCODING;
  597.     ctxt->encoding = xmlStrdup(BAD_CAST "ISO-8859-1"); 
  598.     *len = 1;
  599.     return((int) *ctxt->input->cur);
  600. }
  601. /**
  602.  * xmlStringCurrentChar:
  603.  * @ctxt:  the XML parser context
  604.  * @cur:  pointer to the beginning of the char
  605.  * @len:  pointer to the length of the char read
  606.  *
  607.  * The current char value, if using UTF-8 this may actaully span multiple
  608.  * bytes in the input buffer.
  609.  *
  610.  * Returns the current char value and its lenght
  611.  */
  612. int
  613. xmlStringCurrentChar(xmlParserCtxtPtr ctxt, const xmlChar *cur, int *len) {
  614.     if (ctxt->encoding == NULL) {
  615. /*
  616.  * We are supposed to handle UTF8, check it's valid
  617.  * From rfc2044: encoding of the Unicode values on UTF-8:
  618.  *
  619.  * UCS-4 range (hex.)           UTF-8 octet sequence (binary)
  620.  * 0000 0000-0000 007F   0xxxxxxx
  621.  * 0000 0080-0000 07FF   110xxxxx 10xxxxxx
  622.  * 0000 0800-0000 FFFF   1110xxxx 10xxxxxx 10xxxxxx 
  623.  *
  624.  * Check for the 0x110000 limit too
  625.  */
  626. unsigned char c;
  627. unsigned int val;
  628. c = *cur;
  629. if (c & 0x80) {
  630.     if ((cur[1] & 0xc0) != 0x80)
  631. goto encoding_error;
  632.     if ((c & 0xe0) == 0xe0) {
  633. if ((cur[2] & 0xc0) != 0x80)
  634.     goto encoding_error;
  635. if ((c & 0xf0) == 0xf0) {
  636.     if (((c & 0xf8) != 0xf0) ||
  637. ((cur[3] & 0xc0) != 0x80))
  638. goto encoding_error;
  639.     /* 4-byte code */
  640.     *len = 4;
  641.     val = (cur[0] & 0x7) << 18;
  642.     val |= (cur[1] & 0x3f) << 12;
  643.     val |= (cur[2] & 0x3f) << 6;
  644.     val |= cur[3] & 0x3f;
  645. } else {
  646.   /* 3-byte code */
  647.     *len = 3;
  648.     val = (cur[0] & 0xf) << 12;
  649.     val |= (cur[1] & 0x3f) << 6;
  650.     val |= cur[2] & 0x3f;
  651. }
  652.     } else {
  653.       /* 2-byte code */
  654. *len = 2;
  655. val = (cur[0] & 0x1f) << 6;
  656. val |= cur[2] & 0x3f;
  657.     }
  658.     if (!IS_CHAR(val)) {
  659. if ((ctxt->sax != NULL) &&
  660.     (ctxt->sax->error != NULL))
  661.     ctxt->sax->error(ctxt->userData, 
  662.      "Char out of allowed rangen");
  663. ctxt->errNo = XML_ERR_INVALID_ENCODING;
  664. ctxt->wellFormed = 0;
  665. ctxt->disableSAX = 1;
  666.     }    
  667.     return(val);
  668. } else {
  669.     /* 1-byte code */
  670.     *len = 1;
  671.     return((int) *cur);
  672. }
  673.     }
  674.     /*
  675.      * Assume it's a fixed lenght encoding (1) with
  676.      * a compatibke encoding for the ASCII set, since
  677.      * XML constructs only use < 128 chars
  678.      */
  679.     *len = 1;
  680.     return((int) *cur);
  681. encoding_error:
  682.     /*
  683.      * If we detect an UTF8 error that probably mean that the
  684.      * input encoding didn't get properly advertized in the
  685.      * declaration header. Report the error and switch the encoding
  686.      * to ISO-Latin-1 (if you don't like this policy, just declare the
  687.      * encoding !)
  688.      */
  689.     if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  690. ctxt->sax->error(ctxt->userData, 
  691.  "Input is not proper UTF-8, indicate encoding !n");
  692.     ctxt->errNo = XML_ERR_INVALID_ENCODING;
  693.     *len = 1;
  694.     return((int) *cur);
  695. }
  696. /**
  697.  * xmlCopyChar:
  698.  * @len:  pointer to the length of the char read (or zero)
  699.  * @array:  pointer to an arry of xmlChar
  700.  * @val:  the char value
  701.  *
  702.  * append the char value in the array 
  703.  *
  704.  * Returns the number of xmlChar written
  705.  */
  706. int
  707. xmlCopyChar(int len, xmlChar *out, int val) {
  708.     /*
  709.      * We are supposed to handle UTF8, check it's valid
  710.      * From rfc2044: encoding of the Unicode values on UTF-8:
  711.      *
  712.      * UCS-4 range (hex.)           UTF-8 octet sequence (binary)
  713.      * 0000 0000-0000 007F   0xxxxxxx
  714.      * 0000 0080-0000 07FF   110xxxxx 10xxxxxx
  715.      * 0000 0800-0000 FFFF   1110xxxx 10xxxxxx 10xxxxxx 
  716.      */
  717.     if (len == 0) {
  718. if (val < 0) len = 0;
  719. else if (val < 0x80) len = 1;
  720. else if (val < 0x800) len = 2;
  721. else if (val < 0x10000) len = 3;
  722. else if (val < 0x110000) len = 4;
  723. if (len == 0) {
  724.     fprintf(stderr, "Internal error, xmlCopyChar 0x%X out of boundn",
  725.     val);
  726.     return(0);
  727. }
  728.     }
  729.     if (len > 1) {
  730. int bits; 
  731.         if      (val <    0x80) {  *out++=  val;                bits= -6; }
  732.         else if (val <   0x800) {  *out++= (val >>  6) | 0xC0;  bits=  0; }
  733.         else if (val < 0x10000) {  *out++= (val >> 12) | 0xE0;  bits=  6; }
  734.         else                  {    *out++= (val >> 18) | 0xF0;  bits= 12; }
  735.  
  736.         for ( ; bits >= 0; bits-= 6)
  737.             *out++= ((val >> bits) & 0x3F) | 0x80 ;
  738.         return(len);
  739.     }
  740.     *out = (xmlChar) val;
  741.     return(1);
  742. }
  743. /**
  744.  * xmlSkipBlankChars:
  745.  * @ctxt:  the XML parser context
  746.  *
  747.  * skip all blanks character found at that point in the input streams.
  748.  * It pops up finished entities in the process if allowable at that point.
  749.  *
  750.  * Returns the number of space chars skipped
  751.  */
  752. int
  753. xmlSkipBlankChars(xmlParserCtxtPtr ctxt) {
  754.     int cur, res = 0;
  755.     do {
  756. cur = CUR;
  757. while (IS_BLANK(cur)) {
  758.     NEXT;
  759.     cur = CUR;
  760.     res++;
  761. }
  762. while ((cur == 0) && (ctxt->inputNr > 1) &&
  763.        (ctxt->instate != XML_PARSER_COMMENT)) {
  764.     xmlPopInput(ctxt);
  765.     cur = CUR;
  766. }
  767. if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);
  768. if (*ctxt->input->cur == '&') xmlParserHandleReference(ctxt);
  769.     } while (IS_BLANK(cur));
  770.     return(res);
  771. }
  772. /************************************************************************
  773.  * *
  774.  * Commodity functions to handle entities processing *
  775.  * *
  776.  ************************************************************************/
  777. /**
  778.  * xmlPopInput:
  779.  * @ctxt:  an XML parser context
  780.  *
  781.  * xmlPopInput: the current input pointed by ctxt->input came to an end
  782.  *          pop it and return the next char.
  783.  *
  784.  * Returns the current xmlChar in the parser context
  785.  */
  786. xmlChar
  787. xmlPopInput(xmlParserCtxtPtr ctxt) {
  788.     if (ctxt->inputNr == 1) return(0); /* End of main Input */
  789.     xmlFreeInputStream(inputPop(ctxt));
  790.     if ((*ctxt->input->cur == 0) &&
  791.         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
  792.     return(xmlPopInput(ctxt));
  793.     return(CUR);
  794. }
  795. /**
  796.  * xmlPushInput:
  797.  * @ctxt:  an XML parser context
  798.  * @input:  an XML parser input fragment (entity, XML fragment ...).
  799.  *
  800.  * xmlPushInput: switch to a new input stream which is stacked on top
  801.  *               of the previous one(s).
  802.  */
  803. void
  804. xmlPushInput(xmlParserCtxtPtr ctxt, xmlParserInputPtr input) {
  805.     if (input == NULL) return;
  806.     inputPush(ctxt, input);
  807.     GROW;
  808. }
  809. /**
  810.  * xmlFreeInputStream:
  811.  * @input:  an xmlParserInputPtr
  812.  *
  813.  * Free up an input stream.
  814.  */
  815. void
  816. xmlFreeInputStream(xmlParserInputPtr input) {
  817.     if (input == NULL) return;
  818.     if (input->filename != NULL) xmlFree((char *) input->filename);
  819.     if (input->directory != NULL) xmlFree((char *) input->directory);
  820.     if (input->encoding != NULL) xmlFree((char *) input->encoding);
  821.     if (input->version != NULL) xmlFree((char *) input->version);
  822.     if ((input->free != NULL) && (input->base != NULL))
  823.         input->free((xmlChar *) input->base);
  824.     if (input->buf != NULL) 
  825.         xmlFreeParserInputBuffer(input->buf);
  826.     memset(input, -1, sizeof(xmlParserInput));
  827.     xmlFree(input);
  828. }
  829. /**
  830.  * xmlNewInputStream:
  831.  * @ctxt:  an XML parser context
  832.  *
  833.  * Create a new input stream structure
  834.  * Returns the new input stream or NULL
  835.  */
  836. xmlParserInputPtr
  837. xmlNewInputStream(xmlParserCtxtPtr ctxt) {
  838.     xmlParserInputPtr input;
  839.     input = (xmlParserInputPtr) xmlMalloc(sizeof(xmlParserInput));
  840.     if (input == NULL) {
  841. if (ctxt != NULL) {
  842.     ctxt->errNo = XML_ERR_NO_MEMORY;
  843.     if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  844. ctxt->sax->error(ctxt->userData, 
  845.  "malloc: couldn't allocate a new input streamn");
  846.     ctxt->errNo = XML_ERR_NO_MEMORY;
  847. }
  848. return(NULL);
  849.     }
  850.     memset(input, 0, sizeof(xmlParserInput));
  851.     input->line = 1;
  852.     input->col = 1;
  853.     input->standalone = -1;
  854.     return(input);
  855. }
  856. /**
  857.  * xmlNewIOInputStream:
  858.  * @ctxt:  an XML parser context
  859.  * @input:  an I/O Input
  860.  * @enc:  the charset encoding if known
  861.  *
  862.  * Create a new input stream structure encapsulating the @input into
  863.  * a stream suitable for the parser.
  864.  *
  865.  * Returns the new input stream or NULL
  866.  */
  867. xmlParserInputPtr
  868. xmlNewIOInputStream(xmlParserCtxtPtr ctxt, xmlParserInputBufferPtr input,
  869.             xmlCharEncoding enc) {
  870.     xmlParserInputPtr inputStream;
  871.     inputStream = xmlNewInputStream(ctxt);
  872.     if (inputStream == NULL) {
  873. return(NULL);
  874.     }
  875.     inputStream->filename = NULL;
  876.     inputStream->buf = input;
  877.     inputStream->base = inputStream->buf->buffer->content;
  878.     inputStream->cur = inputStream->buf->buffer->content;
  879.     if (enc != XML_CHAR_ENCODING_NONE) {
  880.         xmlSwitchEncoding(ctxt, enc);
  881.     }
  882.     return(inputStream);
  883. }
  884. /**
  885.  * xmlNewEntityInputStream:
  886.  * @ctxt:  an XML parser context
  887.  * @entity:  an Entity pointer
  888.  *
  889.  * Create a new input stream based on an xmlEntityPtr
  890.  *
  891.  * Returns the new input stream or NULL
  892.  */
  893. xmlParserInputPtr
  894. xmlNewEntityInputStream(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
  895.     xmlParserInputPtr input;
  896.     if (entity == NULL) {
  897.         ctxt->errNo = XML_ERR_INTERNAL_ERROR;
  898.         if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  899.     ctxt->sax->error(ctxt->userData,
  900.       "internal: xmlNewEntityInputStream entity = NULLn");
  901. ctxt->errNo = XML_ERR_INTERNAL_ERROR;
  902. return(NULL);
  903.     }
  904.     if (entity->content == NULL) {
  905. switch (entity->etype) {
  906.             case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
  907.         ctxt->errNo = XML_ERR_UNPARSED_ENTITY;
  908. if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  909.     ctxt->sax->error(ctxt->userData,
  910.       "xmlNewEntityInputStream unparsed entity !n");
  911.                 break;
  912.             case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
  913.             case XML_EXTERNAL_PARAMETER_ENTITY:
  914. return(xmlLoadExternalEntity((char *) entity->SystemID,
  915.        (char *) entity->ExternalID, ctxt));
  916.             case XML_INTERNAL_GENERAL_ENTITY:
  917. if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  918.     ctxt->sax->error(ctxt->userData,
  919.   "Internal entity %s without content !n", entity->name);
  920.                 break;
  921.             case XML_INTERNAL_PARAMETER_ENTITY:
  922. ctxt->errNo = XML_ERR_INTERNAL_ERROR;
  923. if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  924.     ctxt->sax->error(ctxt->userData,
  925.   "Internal parameter entity %s without content !n", entity->name);
  926.                 break;
  927.             case XML_INTERNAL_PREDEFINED_ENTITY:
  928. ctxt->errNo = XML_ERR_INTERNAL_ERROR;
  929. if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  930.     ctxt->sax->error(ctxt->userData,
  931.       "Predefined entity %s without content !n", entity->name);
  932.                 break;
  933. }
  934. return(NULL);
  935.     }
  936.     input = xmlNewInputStream(ctxt);
  937.     if (input == NULL) {
  938. return(NULL);
  939.     }
  940.     input->filename = (char *) entity->SystemID;
  941.     input->base = entity->content;
  942.     input->cur = entity->content;
  943.     input->length = entity->length;
  944.     return(input);
  945. }
  946. /**
  947.  * xmlNewStringInputStream:
  948.  * @ctxt:  an XML parser context
  949.  * @buffer:  an memory buffer
  950.  *
  951.  * Create a new input stream based on a memory buffer.
  952.  * Returns the new input stream
  953.  */
  954. xmlParserInputPtr
  955. xmlNewStringInputStream(xmlParserCtxtPtr ctxt, const xmlChar *buffer) {
  956.     xmlParserInputPtr input;
  957.     if (buffer == NULL) {
  958. ctxt->errNo = XML_ERR_INTERNAL_ERROR;
  959.         if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  960.     ctxt->sax->error(ctxt->userData,
  961.       "internal: xmlNewStringInputStream string = NULLn");
  962. return(NULL);
  963.     }
  964.     input = xmlNewInputStream(ctxt);
  965.     if (input == NULL) {
  966. return(NULL);
  967.     }
  968.     input->base = buffer;
  969.     input->cur = buffer;
  970.     input->length = xmlStrlen(buffer);
  971.     return(input);
  972. }
  973. /**
  974.  * xmlNewInputFromFile:
  975.  * @ctxt:  an XML parser context
  976.  * @filename:  the filename to use as entity
  977.  *
  978.  * Create a new input stream based on a file.
  979.  *
  980.  * Returns the new input stream or NULL in case of error
  981.  */
  982. xmlParserInputPtr
  983. xmlNewInputFromFile(xmlParserCtxtPtr ctxt, const char *filename) {
  984.     xmlParserInputBufferPtr buf;
  985.     xmlParserInputPtr inputStream;
  986.     char *directory = NULL;
  987.     if (ctxt == NULL) return(NULL);
  988.     buf = xmlParserInputBufferCreateFilename(filename, XML_CHAR_ENCODING_NONE);
  989.     if (buf == NULL) {
  990. char name[XML_PARSER_BIG_BUFFER_SIZE];
  991.         if ((ctxt->input != NULL) && (ctxt->input->directory != NULL)) {
  992. #ifdef WIN32
  993.             sprintf(name, "%s\%s", ctxt->input->directory, filename);
  994. #else
  995.             sprintf(name, "%s/%s", ctxt->input->directory, filename);
  996. #endif
  997.             buf = xmlParserInputBufferCreateFilename(name,
  998.                                              XML_CHAR_ENCODING_NONE);
  999.     if (buf != NULL)
  1000. directory = xmlParserGetDirectory(name);
  1001. }
  1002. if ((buf == NULL) && (ctxt->directory != NULL)) {
  1003. #ifdef WIN32
  1004.             sprintf(name, "%s\%s", ctxt->directory, filename);
  1005. #else
  1006.             sprintf(name, "%s/%s", ctxt->directory, filename);
  1007. #endif
  1008.             buf = xmlParserInputBufferCreateFilename(name,
  1009.                                              XML_CHAR_ENCODING_NONE);
  1010.     if (buf != NULL)
  1011. directory = xmlParserGetDirectory(name);
  1012. }
  1013. if (buf == NULL)
  1014.     return(NULL);
  1015.     }
  1016.     if (directory == NULL)
  1017.         directory = xmlParserGetDirectory(filename);
  1018.     inputStream = xmlNewInputStream(ctxt);
  1019.     if (inputStream == NULL) {
  1020. if (directory != NULL) xmlFree((char *) directory);
  1021. return(NULL);
  1022.     }
  1023.     inputStream->filename = xmlMemStrdup(filename);
  1024.     inputStream->directory = directory;
  1025.     inputStream->buf = buf;
  1026.     inputStream->base = inputStream->buf->buffer->content;
  1027.     inputStream->cur = inputStream->buf->buffer->content;
  1028.     if ((ctxt->directory == NULL) && (directory != NULL))
  1029.         ctxt->directory = (char *) xmlStrdup((const xmlChar *) directory);
  1030.     return(inputStream);
  1031. }
  1032. /************************************************************************
  1033.  * *
  1034.  * Commodity functions to handle parser contexts *
  1035.  * *
  1036.  ************************************************************************/
  1037. /**
  1038.  * xmlInitParserCtxt:
  1039.  * @ctxt:  an XML parser context
  1040.  *
  1041.  * Initialize a parser context
  1042.  */
  1043. void
  1044. xmlInitParserCtxt(xmlParserCtxtPtr ctxt)
  1045. {
  1046.     xmlSAXHandler *sax;
  1047.     xmlDefaultSAXHandlerInit();
  1048.     sax = (xmlSAXHandler *) xmlMalloc(sizeof(xmlSAXHandler));
  1049.     if (sax == NULL) {
  1050.         fprintf(stderr, "xmlInitParserCtxt: out of memoryn");
  1051.     }
  1052.     memset(sax, 0, sizeof(xmlSAXHandler));
  1053.     /* Allocate the Input stack */
  1054.     ctxt->inputTab = (xmlParserInputPtr *) xmlMalloc(5 * sizeof(xmlParserInputPtr));
  1055.     ctxt->inputNr = 0;
  1056.     ctxt->inputMax = 5;
  1057.     ctxt->input = NULL;
  1058.     ctxt->version = NULL;
  1059.     ctxt->encoding = NULL;
  1060.     ctxt->standalone = -1;
  1061.     ctxt->hasExternalSubset = 0;
  1062.     ctxt->hasPErefs = 0;
  1063.     ctxt->html = 0;
  1064.     ctxt->external = 0;
  1065.     ctxt->instate = XML_PARSER_START;
  1066.     ctxt->token = 0;
  1067.     ctxt->directory = NULL;
  1068.     /* Allocate the Node stack */
  1069.     ctxt->nodeTab = (xmlNodePtr *) xmlMalloc(10 * sizeof(xmlNodePtr));
  1070.     ctxt->nodeNr = 0;
  1071.     ctxt->nodeMax = 10;
  1072.     ctxt->node = NULL;
  1073.     /* Allocate the Name stack */
  1074.     ctxt->nameTab = (xmlChar **) xmlMalloc(10 * sizeof(xmlChar *));
  1075.     ctxt->nameNr = 0;
  1076.     ctxt->nameMax = 10;
  1077.     ctxt->name = NULL;
  1078.     /* Allocate the space stack */
  1079.     ctxt->spaceTab = (int *) xmlMalloc(10 * sizeof(int));
  1080.     ctxt->spaceNr = 1;
  1081.     ctxt->spaceMax = 10;
  1082.     ctxt->spaceTab[0] = -1;
  1083.     ctxt->space = &ctxt->spaceTab[0];
  1084.     if (sax == NULL) {
  1085. ctxt->sax = &xmlDefaultSAXHandler;
  1086.     } else {
  1087.         ctxt->sax = sax;
  1088. memcpy(sax, &xmlDefaultSAXHandler, sizeof(xmlSAXHandler));
  1089.     }
  1090.     ctxt->userData = ctxt;
  1091.     ctxt->myDoc = NULL;
  1092.     ctxt->wellFormed = 1;
  1093.     ctxt->valid = 1;
  1094.     ctxt->validate = xmlDoValidityCheckingDefaultValue;
  1095.     ctxt->keepBlanks = xmlKeepBlanksDefaultValue;
  1096.     ctxt->vctxt.userData = ctxt;
  1097.     if (ctxt->validate) {
  1098. ctxt->vctxt.error = xmlParserValidityError;
  1099. if (xmlGetWarningsDefaultValue == 0)
  1100.     ctxt->vctxt.warning = NULL;
  1101. else
  1102.     ctxt->vctxt.warning = xmlParserValidityWarning;
  1103. /* Allocate the Node stack */
  1104. ctxt->vctxt.nodeTab = (xmlNodePtr *) xmlMalloc(4 * sizeof(xmlNodePtr));
  1105. ctxt->vctxt.nodeNr = 0;
  1106. ctxt->vctxt.nodeMax = 4;
  1107. ctxt->vctxt.node = NULL;
  1108.     } else {
  1109. ctxt->vctxt.error = NULL;
  1110. ctxt->vctxt.warning = NULL;
  1111.     }
  1112.     ctxt->replaceEntities = xmlSubstituteEntitiesDefaultValue;
  1113.     ctxt->record_info = 0;
  1114.     ctxt->nbChars = 0;
  1115.     ctxt->checkIndex = 0;
  1116.     ctxt->inSubset = 0;
  1117.     ctxt->errNo = XML_ERR_OK;
  1118.     ctxt->depth = 0;
  1119.     xmlInitNodeInfoSeq(&ctxt->node_seq);
  1120. }
  1121. /**
  1122.  * xmlFreeParserCtxt:
  1123.  * @ctxt:  an XML parser context
  1124.  *
  1125.  * Free all the memory used by a parser context. However the parsed
  1126.  * document in ctxt->myDoc is not freed.
  1127.  */
  1128. void
  1129. xmlFreeParserCtxt(xmlParserCtxtPtr ctxt)
  1130. {
  1131.     xmlParserInputPtr input;
  1132.     xmlChar *oldname;
  1133.     if (ctxt == NULL) return;
  1134.     while ((input = inputPop(ctxt)) != NULL) {
  1135.         xmlFreeInputStream(input);
  1136.     }
  1137.     while ((oldname = namePop(ctxt)) != NULL) {
  1138. xmlFree(oldname);
  1139.     }
  1140.     if (ctxt->spaceTab != NULL) xmlFree(ctxt->spaceTab);
  1141.     if (ctxt->nameTab != NULL) xmlFree(ctxt->nameTab);
  1142.     if (ctxt->nodeTab != NULL) xmlFree(ctxt->nodeTab);
  1143.     if (ctxt->inputTab != NULL) xmlFree(ctxt->inputTab);
  1144.     if (ctxt->version != NULL) xmlFree((char *) ctxt->version);
  1145.     if (ctxt->encoding != NULL) xmlFree((char *) ctxt->encoding);
  1146.     if (ctxt->intSubName != NULL) xmlFree((char *) ctxt->intSubName);
  1147.     if (ctxt->extSubURI != NULL) xmlFree((char *) ctxt->extSubURI);
  1148.     if (ctxt->extSubSystem != NULL) xmlFree((char *) ctxt->extSubSystem);
  1149.     if (ctxt->vctxt.nodeTab != NULL) xmlFree(ctxt->vctxt.nodeTab);
  1150.     if ((ctxt->sax != NULL) && (ctxt->sax != &xmlDefaultSAXHandler))
  1151.         xmlFree(ctxt->sax);
  1152.     if (ctxt->directory != NULL) xmlFree((char *) ctxt->directory);
  1153.     xmlFree(ctxt);
  1154. }
  1155. /**
  1156.  * xmlNewParserCtxt:
  1157.  *
  1158.  * Allocate and initialize a new parser context.
  1159.  *
  1160.  * Returns the xmlParserCtxtPtr or NULL
  1161.  */
  1162. xmlParserCtxtPtr
  1163. xmlNewParserCtxt()
  1164. {
  1165.     xmlParserCtxtPtr ctxt;
  1166.     ctxt = (xmlParserCtxtPtr) xmlMalloc(sizeof(xmlParserCtxt));
  1167.     if (ctxt == NULL) {
  1168.         fprintf(stderr, "xmlNewParserCtxt : cannot allocate contextn");
  1169.         perror("malloc");
  1170. return(NULL);
  1171.     }
  1172.     memset(ctxt, 0, sizeof(xmlParserCtxt));
  1173.     xmlInitParserCtxt(ctxt);
  1174.     return(ctxt);
  1175. }
  1176. /**
  1177.  * xmlClearParserCtxt:
  1178.  * @ctxt:  an XML parser context
  1179.  *
  1180.  * Clear (release owned resources) and reinitialize a parser context
  1181.  */
  1182. void
  1183. xmlClearParserCtxt(xmlParserCtxtPtr ctxt)
  1184. {
  1185.   xmlClearNodeInfoSeq(&ctxt->node_seq);
  1186.   xmlInitParserCtxt(ctxt);
  1187. }
  1188. /************************************************************************
  1189.  * *
  1190.  * Commodity functions to handle entities *
  1191.  * *
  1192.  ************************************************************************/
  1193. /**
  1194.  * xmlCheckEntity:
  1195.  * @ctxt:  an XML parser context
  1196.  * @content:  the entity content string
  1197.  *
  1198.  * Parse an entity content and checks the WF constraints
  1199.  *
  1200.  */
  1201. void
  1202. xmlCheckEntity(xmlParserCtxtPtr ctxt, const xmlChar *content) {
  1203. }
  1204. /**
  1205.  * xmlParseCharRef:
  1206.  * @ctxt:  an XML parser context
  1207.  *
  1208.  * parse Reference declarations
  1209.  *
  1210.  * [66] CharRef ::= '&#' [0-9]+ ';' |
  1211.  *                  '&#x' [0-9a-fA-F]+ ';'
  1212.  *
  1213.  * [ WFC: Legal Character ]
  1214.  * Characters referred to using character references must match the
  1215.  * production for Char. 
  1216.  *
  1217.  * Returns the value parsed (as an int), 0 in case of error
  1218.  */
  1219. int
  1220. xmlParseCharRef(xmlParserCtxtPtr ctxt) {
  1221.     int val = 0;
  1222.     if (ctxt->token != 0) {
  1223. val = ctxt->token;
  1224.         ctxt->token = 0;
  1225.         return(val);
  1226.     }
  1227.     if ((RAW == '&') && (NXT(1) == '#') &&
  1228.         (NXT(2) == 'x')) {
  1229. SKIP(3);
  1230. while (RAW != ';') {
  1231.     if ((RAW >= '0') && (RAW <= '9')) 
  1232.         val = val * 16 + (CUR - '0');
  1233.     else if ((RAW >= 'a') && (RAW <= 'f'))
  1234.         val = val * 16 + (CUR - 'a') + 10;
  1235.     else if ((RAW >= 'A') && (RAW <= 'F'))
  1236.         val = val * 16 + (CUR - 'A') + 10;
  1237.     else {
  1238. ctxt->errNo = XML_ERR_INVALID_HEX_CHARREF;
  1239.         if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  1240.     ctxt->sax->error(ctxt->userData, 
  1241.          "xmlParseCharRef: invalid hexadecimal valuen");
  1242. ctxt->wellFormed = 0;
  1243. ctxt->disableSAX = 1;
  1244. val = 0;
  1245. break;
  1246.     }
  1247.     NEXT;
  1248. }
  1249. if (RAW == ';') {
  1250.     /* on purpose to avoid reentrancy problems with NEXT and SKIP */
  1251.     ctxt->nbChars ++;
  1252.     ctxt->input->cur++;
  1253. }
  1254.     } else if  ((RAW == '&') && (NXT(1) == '#')) {
  1255. SKIP(2);
  1256. while (RAW != ';') {
  1257.     if ((RAW >= '0') && (RAW <= '9')) 
  1258.         val = val * 10 + (CUR - '0');
  1259.     else {
  1260. ctxt->errNo = XML_ERR_INVALID_DEC_CHARREF;
  1261.         if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  1262.     ctxt->sax->error(ctxt->userData, 
  1263.          "xmlParseCharRef: invalid decimal valuen");
  1264. ctxt->wellFormed = 0;
  1265. ctxt->disableSAX = 1;
  1266. val = 0;
  1267. break;
  1268.     }
  1269.     NEXT;
  1270. }
  1271. if (RAW == ';') {
  1272.     /* on purpose to avoid reentrancy problems with NEXT and SKIP */
  1273.     ctxt->nbChars ++;
  1274.     ctxt->input->cur++;
  1275. }
  1276.     } else {
  1277. ctxt->errNo = XML_ERR_INVALID_CHARREF;
  1278. if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  1279.     ctxt->sax->error(ctxt->userData,
  1280.        "xmlParseCharRef: invalid valuen");
  1281. ctxt->wellFormed = 0;
  1282. ctxt->disableSAX = 1;
  1283.     }
  1284.     /*
  1285.      * [ WFC: Legal Character ]
  1286.      * Characters referred to using character references must match the
  1287.      * production for Char. 
  1288.      */
  1289.     if (IS_CHAR(val)) {
  1290.         return(val);
  1291.     } else {
  1292. ctxt->errNo = XML_ERR_INVALID_CHAR;
  1293. if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  1294.     ctxt->sax->error(ctxt->userData, "CharRef: invalid xmlChar value %dn",
  1295.                      val);
  1296. ctxt->wellFormed = 0;
  1297. ctxt->disableSAX = 1;
  1298.     }
  1299.     return(0);
  1300. }
  1301. /**
  1302.  * xmlParseStringCharRef:
  1303.  * @ctxt:  an XML parser context
  1304.  * @str:  a pointer to an index in the string
  1305.  *
  1306.  * parse Reference declarations, variant parsing from a string rather
  1307.  * than an an input flow.
  1308.  *
  1309.  * [66] CharRef ::= '&#' [0-9]+ ';' |
  1310.  *                  '&#x' [0-9a-fA-F]+ ';'
  1311.  *
  1312.  * [ WFC: Legal Character ]
  1313.  * Characters referred to using character references must match the
  1314.  * production for Char. 
  1315.  *
  1316.  * Returns the value parsed (as an int), 0 in case of error, str will be
  1317.  *         updated to the current value of the index
  1318.  */
  1319. int
  1320. xmlParseStringCharRef(xmlParserCtxtPtr ctxt, const xmlChar **str) {
  1321.     const xmlChar *ptr;
  1322.     xmlChar cur;
  1323.     int val = 0;
  1324.     if ((str == NULL) || (*str == NULL)) return(0);
  1325.     ptr = *str;
  1326.     cur = *ptr;
  1327.     if ((cur == '&') && (ptr[1] == '#') && (ptr[2] == 'x')) {
  1328. ptr += 3;
  1329. cur = *ptr;
  1330. while (cur != ';') {
  1331.     if ((cur >= '0') && (cur <= '9')) 
  1332.         val = val * 16 + (cur - '0');
  1333.     else if ((cur >= 'a') && (cur <= 'f'))
  1334.         val = val * 16 + (cur - 'a') + 10;
  1335.     else if ((cur >= 'A') && (cur <= 'F'))
  1336.         val = val * 16 + (cur - 'A') + 10;
  1337.     else {
  1338. ctxt->errNo = XML_ERR_INVALID_HEX_CHARREF;
  1339.         if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  1340.     ctxt->sax->error(ctxt->userData, 
  1341.          "xmlParseCharRef: invalid hexadecimal valuen");
  1342. ctxt->wellFormed = 0;
  1343. ctxt->disableSAX = 1;
  1344. val = 0;
  1345. break;
  1346.     }
  1347.     ptr++;
  1348.     cur = *ptr;
  1349. }
  1350. if (cur == ';')
  1351.     ptr++;
  1352.     } else if  ((cur == '&') && (ptr[1] == '#')){
  1353. ptr += 2;
  1354. cur = *ptr;
  1355. while (cur != ';') {
  1356.     if ((cur >= '0') && (cur <= '9')) 
  1357.         val = val * 10 + (cur - '0');
  1358.     else {
  1359. ctxt->errNo = XML_ERR_INVALID_DEC_CHARREF;
  1360.         if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  1361.     ctxt->sax->error(ctxt->userData, 
  1362.          "xmlParseCharRef: invalid decimal valuen");
  1363. ctxt->wellFormed = 0;
  1364. ctxt->disableSAX = 1;
  1365. val = 0;
  1366. break;
  1367.     }
  1368.     ptr++;
  1369.     cur = *ptr;
  1370. }
  1371. if (cur == ';')
  1372.     ptr++;
  1373.     } else {
  1374. ctxt->errNo = XML_ERR_INVALID_CHARREF;
  1375. if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  1376.     ctxt->sax->error(ctxt->userData,
  1377.        "xmlParseCharRef: invalid valuen");
  1378. ctxt->wellFormed = 0;
  1379. ctxt->disableSAX = 1;
  1380. return(0);
  1381.     }
  1382.     *str = ptr;
  1383.     /*
  1384.      * [ WFC: Legal Character ]
  1385.      * Characters referred to using character references must match the
  1386.      * production for Char. 
  1387.      */
  1388.     if (IS_CHAR(val)) {
  1389.         return(val);
  1390.     } else {
  1391. ctxt->errNo = XML_ERR_INVALID_CHAR;
  1392. if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  1393.     ctxt->sax->error(ctxt->userData,
  1394.              "CharRef: invalid xmlChar value %dn", val);
  1395. ctxt->wellFormed = 0;
  1396. ctxt->disableSAX = 1;
  1397.     }
  1398.     return(0);
  1399. }
  1400. /**
  1401.  * xmlParserHandleReference:
  1402.  * @ctxt:  the parser context
  1403.  * 
  1404.  * [67] Reference ::= EntityRef | CharRef
  1405.  *
  1406.  * [68] EntityRef ::= '&' Name ';'
  1407.  *
  1408.  * [ WFC: Entity Declared ]
  1409.  * the Name given in the entity reference must match that in an entity
  1410.  * declaration, except that well-formed documents need not declare any
  1411.  * of the following entities: amp, lt, gt, apos, quot. 
  1412.  *
  1413.  * [ WFC: Parsed Entity ]
  1414.  * An entity reference must not contain the name of an unparsed entity
  1415.  *
  1416.  * [66] CharRef ::= '&#' [0-9]+ ';' |
  1417.  *                  '&#x' [0-9a-fA-F]+ ';'
  1418.  *
  1419.  * A PEReference may have been detectect in the current input stream
  1420.  * the handling is done accordingly to 
  1421.  *      http://www.w3.org/TR/REC-xml#entproc
  1422.  */
  1423. void
  1424. xmlParserHandleReference(xmlParserCtxtPtr ctxt) {
  1425.     xmlParserInputPtr input;
  1426.     xmlChar *name;
  1427.     xmlEntityPtr ent = NULL;
  1428.     if (ctxt->token != 0) {
  1429.         return;
  1430.     }
  1431.     if (RAW != '&') return;
  1432.     GROW;
  1433.     if ((RAW == '&') && (NXT(1) == '#')) {
  1434. switch(ctxt->instate) {
  1435.     case XML_PARSER_ENTITY_DECL:
  1436.     case XML_PARSER_PI:
  1437.     case XML_PARSER_CDATA_SECTION:
  1438.     case XML_PARSER_COMMENT:
  1439.     case XML_PARSER_SYSTEM_LITERAL:
  1440. /* we just ignore it there */
  1441. return;
  1442.     case XML_PARSER_START_TAG:
  1443. return;
  1444.     case XML_PARSER_END_TAG:
  1445. return;
  1446.     case XML_PARSER_EOF:
  1447. ctxt->errNo = XML_ERR_CHARREF_AT_EOF;
  1448. if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  1449.     ctxt->sax->error(ctxt->userData, "CharRef at EOFn");
  1450. ctxt->wellFormed = 0;
  1451. ctxt->disableSAX = 1;
  1452. return;
  1453.     case XML_PARSER_PROLOG:
  1454.     case XML_PARSER_START:
  1455.     case XML_PARSER_MISC:
  1456. ctxt->errNo = XML_ERR_CHARREF_IN_PROLOG;
  1457. if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  1458.     ctxt->sax->error(ctxt->userData, "CharRef in prolog!n");
  1459. ctxt->wellFormed = 0;
  1460. ctxt->disableSAX = 1;
  1461. return;
  1462.     case XML_PARSER_EPILOG:
  1463. ctxt->errNo = XML_ERR_CHARREF_IN_EPILOG;
  1464. if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  1465.     ctxt->sax->error(ctxt->userData, "CharRef in epilog!n");
  1466. ctxt->wellFormed = 0;
  1467. ctxt->disableSAX = 1;
  1468. return;
  1469.     case XML_PARSER_DTD:
  1470. ctxt->errNo = XML_ERR_CHARREF_IN_DTD;
  1471. if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  1472.     ctxt->sax->error(ctxt->userData, 
  1473.            "CharRef are forbiden in DTDs!n");
  1474. ctxt->wellFormed = 0;
  1475. ctxt->disableSAX = 1;
  1476. return;
  1477.     case XML_PARSER_ENTITY_VALUE:
  1478.         /*
  1479.  * NOTE: in the case of entity values, we don't do the
  1480.  *       substitution here since we need the literal
  1481.  *       entity value to be able to save the internal
  1482.  *       subset of the document.
  1483.  *       This will be handled by xmlDecodeEntities
  1484.  */
  1485. return;
  1486.     case XML_PARSER_CONTENT:
  1487.     case XML_PARSER_ATTRIBUTE_VALUE:
  1488. ctxt->token = xmlParseCharRef(ctxt);
  1489. return;
  1490. }
  1491. return;
  1492.     }
  1493.     switch(ctxt->instate) {
  1494. case XML_PARSER_CDATA_SECTION:
  1495.     return;
  1496. case XML_PARSER_PI:
  1497.         case XML_PARSER_COMMENT:
  1498. case XML_PARSER_SYSTEM_LITERAL:
  1499.         case XML_PARSER_CONTENT:
  1500.     return;
  1501. case XML_PARSER_START_TAG:
  1502.     return;
  1503. case XML_PARSER_END_TAG:
  1504.     return;
  1505.         case XML_PARSER_EOF:
  1506.     ctxt->errNo = XML_ERR_ENTITYREF_AT_EOF;
  1507.     if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  1508.         ctxt->sax->error(ctxt->userData, "Reference at EOFn");
  1509.     ctxt->wellFormed = 0;
  1510.     ctxt->disableSAX = 1;
  1511.     return;
  1512.         case XML_PARSER_PROLOG:
  1513. case XML_PARSER_START:
  1514. case XML_PARSER_MISC:
  1515.     ctxt->errNo = XML_ERR_ENTITYREF_IN_PROLOG;
  1516.     if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  1517.         ctxt->sax->error(ctxt->userData, "Reference in prolog!n");
  1518.     ctxt->wellFormed = 0;
  1519.     ctxt->disableSAX = 1;
  1520.     return;
  1521.         case XML_PARSER_EPILOG:
  1522.     ctxt->errNo = XML_ERR_ENTITYREF_IN_EPILOG;
  1523.     if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  1524.         ctxt->sax->error(ctxt->userData, "Reference in epilog!n");
  1525.     ctxt->wellFormed = 0;
  1526.     ctxt->disableSAX = 1;
  1527.     return;
  1528. case XML_PARSER_ENTITY_VALUE:
  1529.     /*
  1530.      * NOTE: in the case of entity values, we don't do the
  1531.      *       substitution here since we need the literal
  1532.      *       entity value to be able to save the internal
  1533.      *       subset of the document.
  1534.      *       This will be handled by xmlDecodeEntities
  1535.      */
  1536.     return;
  1537.         case XML_PARSER_ATTRIBUTE_VALUE:
  1538.     /*
  1539.      * NOTE: in the case of attributes values, we don't do the
  1540.      *       substitution here unless we are in a mode where
  1541.      *       the parser is explicitely asked to substitute
  1542.      *       entities. The SAX callback is called with values
  1543.      *       without entity substitution.
  1544.      *       This will then be handled by xmlDecodeEntities
  1545.      */
  1546.     return;
  1547. case XML_PARSER_ENTITY_DECL:
  1548.     /*
  1549.      * we just ignore it there
  1550.      * the substitution will be done once the entity is referenced
  1551.      */
  1552.     return;
  1553.         case XML_PARSER_DTD:
  1554.     ctxt->errNo = XML_ERR_ENTITYREF_IN_DTD;
  1555.     if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  1556. ctxt->sax->error(ctxt->userData, 
  1557.        "Entity references are forbiden in DTDs!n");
  1558.     ctxt->wellFormed = 0;
  1559.     ctxt->disableSAX = 1;
  1560.     return;
  1561.     }
  1562.     NEXT;
  1563.     name = xmlScanName(ctxt);
  1564.     if (name == NULL) {
  1565. ctxt->errNo = XML_ERR_ENTITYREF_NO_NAME;
  1566. if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  1567.     ctxt->sax->error(ctxt->userData, "Entity reference: no namen");
  1568. ctxt->wellFormed = 0;
  1569. ctxt->disableSAX = 1;
  1570. ctxt->token = '&';
  1571. return;
  1572.     }
  1573.     if (NXT(xmlStrlen(name)) != ';') {
  1574. ctxt->errNo = XML_ERR_ENTITYREF_SEMICOL_MISSING;
  1575. if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  1576.     ctxt->sax->error(ctxt->userData, 
  1577.                      "Entity reference: ';' expectedn");
  1578. ctxt->wellFormed = 0;
  1579. ctxt->disableSAX = 1;
  1580. ctxt->token = '&';
  1581. xmlFree(name);
  1582. return;
  1583.     }
  1584.     SKIP(xmlStrlen(name) + 1);
  1585.     if (ctxt->sax != NULL) {
  1586. if (ctxt->sax->getEntity != NULL)
  1587.     ent = ctxt->sax->getEntity(ctxt->userData, name);
  1588.     }
  1589.     /*
  1590.      * [ WFC: Entity Declared ]
  1591.      * the Name given in the entity reference must match that in an entity
  1592.      * declaration, except that well-formed documents need not declare any
  1593.      * of the following entities: amp, lt, gt, apos, quot. 
  1594.      */
  1595.     if (ent == NULL)
  1596. ent = xmlGetPredefinedEntity(name);
  1597.     if (ent == NULL) {
  1598.         ctxt->errNo = XML_ERR_UNDECLARED_ENTITY;
  1599. if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  1600.     ctxt->sax->error(ctxt->userData, 
  1601.      "Entity reference: entity %s not declaredn",
  1602.      name);
  1603. ctxt->wellFormed = 0;
  1604. ctxt->disableSAX = 1;
  1605. xmlFree(name);
  1606. return;
  1607.     }
  1608.     /*
  1609.      * [ WFC: Parsed Entity ]
  1610.      * An entity reference must not contain the name of an unparsed entity
  1611.      */
  1612.     if (ent->etype == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
  1613.         ctxt->errNo = XML_ERR_UNPARSED_ENTITY;
  1614. if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  1615.     ctxt->sax->error(ctxt->userData, 
  1616.  "Entity reference to unparsed entity %sn", name);
  1617. ctxt->wellFormed = 0;
  1618. ctxt->disableSAX = 1;
  1619.     }
  1620.     if (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY) {
  1621.         ctxt->token = ent->content[0];
  1622. xmlFree(name);
  1623. return;
  1624.     }
  1625.     input = xmlNewEntityInputStream(ctxt, ent);
  1626.     xmlPushInput(ctxt, input);
  1627.     xmlFree(name);
  1628.     return;
  1629. }
  1630. /**
  1631.  * xmlParserHandlePEReference:
  1632.  * @ctxt:  the parser context
  1633.  * 
  1634.  * [69] PEReference ::= '%' Name ';'
  1635.  *
  1636.  * [ WFC: No Recursion ]
  1637.  * TODO A parsed entity must not contain a recursive
  1638.  * reference to itself, either directly or indirectly. 
  1639.  *
  1640.  * [ WFC: Entity Declared ]
  1641.  * In a document without any DTD, a document with only an internal DTD
  1642.  * subset which contains no parameter entity references, or a document
  1643.  * with "standalone='yes'", ...  ... The declaration of a parameter
  1644.  * entity must precede any reference to it...
  1645.  *
  1646.  * [ VC: Entity Declared ]
  1647.  * In a document with an external subset or external parameter entities
  1648.  * with "standalone='no'", ...  ... The declaration of a parameter entity
  1649.  * must precede any reference to it...
  1650.  *
  1651.  * [ WFC: In DTD ]
  1652.  * Parameter-entity references may only appear in the DTD.
  1653.  * NOTE: misleading but this is handled.
  1654.  *
  1655.  * A PEReference may have been detected in the current input stream
  1656.  * the handling is done accordingly to 
  1657.  *      http://www.w3.org/TR/REC-xml#entproc
  1658.  * i.e. 
  1659.  *   - Included in literal in entity values
  1660.  *   - Included as Paraemeter Entity reference within DTDs
  1661.  */
  1662. void
  1663. xmlParserHandlePEReference(xmlParserCtxtPtr ctxt) {
  1664.     xmlChar *name;
  1665.     xmlEntityPtr entity = NULL;
  1666.     xmlParserInputPtr input;
  1667.     if (ctxt->token != 0) {
  1668.         return;
  1669.     }
  1670.     if (RAW != '%') return;
  1671.     switch(ctxt->instate) {
  1672. case XML_PARSER_CDATA_SECTION:
  1673.     return;
  1674.         case XML_PARSER_COMMENT:
  1675.     return;
  1676. case XML_PARSER_START_TAG:
  1677.     return;
  1678. case XML_PARSER_END_TAG:
  1679.     return;
  1680.         case XML_PARSER_EOF:
  1681.     ctxt->errNo = XML_ERR_PEREF_AT_EOF;
  1682.     if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  1683.         ctxt->sax->error(ctxt->userData, "PEReference at EOFn");
  1684.     ctxt->wellFormed = 0;
  1685.     ctxt->disableSAX = 1;
  1686.     return;
  1687.         case XML_PARSER_PROLOG:
  1688. case XML_PARSER_START:
  1689. case XML_PARSER_MISC:
  1690.     ctxt->errNo = XML_ERR_PEREF_IN_PROLOG;
  1691.     if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  1692.         ctxt->sax->error(ctxt->userData, "PEReference in prolog!n");
  1693.     ctxt->wellFormed = 0;
  1694.     ctxt->disableSAX = 1;
  1695.     return;
  1696. case XML_PARSER_ENTITY_DECL:
  1697.         case XML_PARSER_CONTENT:
  1698.         case XML_PARSER_ATTRIBUTE_VALUE:
  1699.         case XML_PARSER_PI:
  1700. case XML_PARSER_SYSTEM_LITERAL:
  1701.     /* we just ignore it there */
  1702.     return;
  1703.         case XML_PARSER_EPILOG:
  1704.     ctxt->errNo = XML_ERR_PEREF_IN_EPILOG;
  1705.     if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  1706.         ctxt->sax->error(ctxt->userData, "PEReference in epilog!n");
  1707.     ctxt->wellFormed = 0;
  1708.     ctxt->disableSAX = 1;
  1709.     return;
  1710. case XML_PARSER_ENTITY_VALUE:
  1711.     /*
  1712.      * NOTE: in the case of entity values, we don't do the
  1713.      *       substitution here since we need the literal
  1714.      *       entity value to be able to save the internal
  1715.      *       subset of the document.
  1716.      *       This will be handled by xmlDecodeEntities
  1717.      */
  1718.     return;
  1719.         case XML_PARSER_DTD:
  1720.     /*
  1721.      * [WFC: Well-Formedness Constraint: PEs in Internal Subset]
  1722.      * In the internal DTD subset, parameter-entity references
  1723.      * can occur only where markup declarations can occur, not
  1724.      * within markup declarations.
  1725.      * In that case this is handled in xmlParseMarkupDecl
  1726.      */
  1727.     if ((ctxt->external == 0) && (ctxt->inputNr == 1))
  1728. return;
  1729.     }
  1730.     NEXT;
  1731.     name = xmlParseName(ctxt);
  1732.     if (name == NULL) {
  1733.         ctxt->errNo = XML_ERR_PEREF_NO_NAME;
  1734. if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  1735.     ctxt->sax->error(ctxt->userData, "xmlHandlePEReference: no namen");
  1736. ctxt->wellFormed = 0;
  1737. ctxt->disableSAX = 1;
  1738.     } else {
  1739. if (RAW == ';') {
  1740.     NEXT;
  1741.     if ((ctxt->sax != NULL) && (ctxt->sax->getParameterEntity != NULL))
  1742. entity = ctxt->sax->getParameterEntity(ctxt->userData, name);
  1743.     if (entity == NULL) {
  1744.         
  1745. /*
  1746.  * [ WFC: Entity Declared ]
  1747.  * In a document without any DTD, a document with only an
  1748.  * internal DTD subset which contains no parameter entity
  1749.  * references, or a document with "standalone='yes'", ...
  1750.  * ... The declaration of a parameter entity must precede
  1751.  * any reference to it...
  1752.  */
  1753. if ((ctxt->standalone == 1) ||
  1754.     ((ctxt->hasExternalSubset == 0) &&
  1755.      (ctxt->hasPErefs == 0))) {
  1756.     if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  1757. ctxt->sax->error(ctxt->userData,
  1758.  "PEReference: %%%s; not foundn", name);
  1759.     ctxt->wellFormed = 0;
  1760.     ctxt->disableSAX = 1;
  1761.         } else {
  1762.     /*
  1763.      * [ VC: Entity Declared ]
  1764.      * In a document with an external subset or external
  1765.      * parameter entities with "standalone='no'", ...
  1766.      * ... The declaration of a parameter entity must precede
  1767.      * any reference to it...
  1768.      */
  1769.     if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
  1770. ctxt->sax->warning(ctxt->userData,
  1771.  "PEReference: %%%s; not foundn", name);
  1772.     ctxt->valid = 0;
  1773. }
  1774.     } else {
  1775.         if ((entity->etype == XML_INTERNAL_PARAMETER_ENTITY) ||
  1776.     (entity->etype == XML_EXTERNAL_PARAMETER_ENTITY)) {
  1777.     /*
  1778.      * TODO !!! handle the extra spaces added before and after
  1779.      * c.f. http://www.w3.org/TR/REC-xml#as-PE
  1780.      */
  1781.     input = xmlNewEntityInputStream(ctxt, entity);
  1782.     xmlPushInput(ctxt, input);
  1783.     if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) &&
  1784. (RAW == '<') && (NXT(1) == '?') &&
  1785. (NXT(2) == 'x') && (NXT(3) == 'm') &&
  1786. (NXT(4) == 'l') && (IS_BLANK(NXT(5)))) {
  1787. xmlParseTextDecl(ctxt);
  1788.     }
  1789.     if (ctxt->token == 0)
  1790. ctxt->token = ' ';
  1791. } else {
  1792.     if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  1793. ctxt->sax->error(ctxt->userData,
  1794.  "xmlHandlePEReference: %s is not a parameter entityn",
  1795.                  name);
  1796.     ctxt->wellFormed = 0;
  1797.     ctxt->disableSAX = 1;
  1798. }
  1799.     }
  1800. } else {
  1801.     ctxt->errNo = XML_ERR_PEREF_SEMICOL_MISSING;
  1802.     if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  1803. ctxt->sax->error(ctxt->userData,
  1804.  "xmlHandlePEReference: expecting ';'n");
  1805.     ctxt->wellFormed = 0;
  1806.     ctxt->disableSAX = 1;
  1807. }
  1808. xmlFree(name);
  1809.     }
  1810. }
  1811. /*
  1812.  * Macro used to grow the current buffer.
  1813.  */
  1814. #define growBuffer(buffer) {
  1815.     buffer##_size *= 2;
  1816.     buffer = (xmlChar *)
  1817.      xmlRealloc(buffer, buffer##_size * sizeof(xmlChar));
  1818.     if (buffer == NULL) {
  1819. perror("realloc failed");
  1820. return(NULL);
  1821.     }
  1822. }
  1823. /**
  1824.  * xmlDecodeEntities:
  1825.  * @ctxt:  the parser context
  1826.  * @what:  combination of XML_SUBSTITUTE_REF and XML_SUBSTITUTE_PEREF
  1827.  * @len:  the len to decode (in bytes !), -1 for no size limit
  1828.  * @end:  an end marker xmlChar, 0 if none
  1829.  * @end2:  an end marker xmlChar, 0 if none
  1830.  * @end3:  an end marker xmlChar, 0 if none
  1831.  * 
  1832.  * [67] Reference ::= EntityRef | CharRef
  1833.  *
  1834.  * [69] PEReference ::= '%' Name ';'
  1835.  *
  1836.  * Returns A newly allocated string with the substitution done. The caller
  1837.  *      must deallocate it !
  1838.  */
  1839. xmlChar *
  1840. xmlDecodeEntities(xmlParserCtxtPtr ctxt, int len, int what,
  1841.                   xmlChar end, xmlChar  end2, xmlChar end3) {
  1842.     xmlChar *buffer = NULL;
  1843.     int buffer_size = 0;
  1844.     int nbchars = 0;
  1845.     xmlChar *current = NULL;
  1846.     xmlEntityPtr ent;
  1847.     unsigned int max = (unsigned int) len;
  1848.     int c,l;
  1849.     if (ctxt->depth > 40) {
  1850. if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  1851.     ctxt->sax->error(ctxt->userData,
  1852. "Detected entity reference loopn");
  1853. ctxt->wellFormed = 0;
  1854. ctxt->disableSAX = 1;
  1855. ctxt->errNo = XML_ERR_ENTITY_LOOP;
  1856. return(NULL);
  1857.     }
  1858.     /*
  1859.      * allocate a translation buffer.
  1860.      */
  1861.     buffer_size = XML_PARSER_BIG_BUFFER_SIZE;
  1862.     buffer = (xmlChar *) xmlMalloc(buffer_size * sizeof(xmlChar));
  1863.     if (buffer == NULL) {
  1864. perror("xmlDecodeEntities: malloc failed");
  1865. return(NULL);
  1866.     }
  1867.     /*
  1868.      * Ok loop until we reach one of the ending char or a size limit.
  1869.      */
  1870.     c = CUR_CHAR(l);
  1871.     while ((nbchars < max) && (c != end) &&
  1872.            (c != end2) && (c != end3)) {
  1873. if (c == 0) break;
  1874.         if (((c == '&') && (ctxt->token != '&')) && (NXT(1) == '#')) {
  1875.     int val = xmlParseCharRef(ctxt);
  1876.     COPY_BUF(0,buffer,nbchars,val);
  1877.     NEXTL(l);
  1878. } else if ((c == '&') && (ctxt->token != '&') &&
  1879.    (what & XML_SUBSTITUTE_REF)) {
  1880.     ent = xmlParseEntityRef(ctxt);
  1881.     if ((ent != NULL) && 
  1882. (ctxt->replaceEntities != 0)) {
  1883. current = ent->content;
  1884. while (*current != 0) {
  1885.     buffer[nbchars++] = *current++;
  1886.     if (nbchars > buffer_size - XML_PARSER_BUFFER_SIZE) {
  1887. growBuffer(buffer);
  1888.     }
  1889. }
  1890.     } else if (ent != NULL) {
  1891. const xmlChar *cur = ent->name;
  1892. buffer[nbchars++] = '&';
  1893. if (nbchars > buffer_size - XML_PARSER_BUFFER_SIZE) {
  1894.     growBuffer(buffer);
  1895. }
  1896. while (*cur != 0) {
  1897.     buffer[nbchars++] = *cur++;
  1898. }
  1899. buffer[nbchars++] = ';';
  1900.     }
  1901. } else if (c == '%' && (what & XML_SUBSTITUTE_PEREF)) {
  1902.     /*
  1903.      * a PEReference induce to switch the entity flow,
  1904.      * we break here to flush the current set of chars
  1905.      * parsed if any. We will be called back later.
  1906.      */
  1907.     if (nbchars != 0) break;
  1908.     xmlParsePEReference(ctxt);
  1909.     /*
  1910.      * Pop-up of finished entities.
  1911.      */
  1912.     while ((RAW == 0) && (ctxt->inputNr > 1))
  1913. xmlPopInput(ctxt);
  1914.     break;
  1915. } else {
  1916.     COPY_BUF(l,buffer,nbchars,c);
  1917.     NEXTL(l);
  1918.     if (nbchars > buffer_size - XML_PARSER_BUFFER_SIZE) {
  1919.       growBuffer(buffer);
  1920.     }
  1921. }
  1922. c = CUR_CHAR(l);
  1923.     }
  1924.     buffer[nbchars++] = 0;
  1925.     return(buffer);
  1926. }
  1927. /**
  1928.  * xmlStringDecodeEntities:
  1929.  * @ctxt:  the parser context
  1930.  * @str:  the input string
  1931.  * @what:  combination of XML_SUBSTITUTE_REF and XML_SUBSTITUTE_PEREF
  1932.  * @end:  an end marker xmlChar, 0 if none
  1933.  * @end2:  an end marker xmlChar, 0 if none
  1934.  * @end3:  an end marker xmlChar, 0 if none
  1935.  * 
  1936.  * [67] Reference ::= EntityRef | CharRef
  1937.  *
  1938.  * [69] PEReference ::= '%' Name ';'
  1939.  *
  1940.  * Returns A newly allocated string with the substitution done. The caller
  1941.  *      must deallocate it !
  1942.  */
  1943. xmlChar *
  1944. xmlStringDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int what,
  1945.         xmlChar end, xmlChar  end2, xmlChar end3) {
  1946.     xmlChar *buffer = NULL;
  1947.     int buffer_size = 0;
  1948.     xmlChar *current = NULL;
  1949.     xmlEntityPtr ent;
  1950.     int c,l;
  1951.     int nbchars = 0;
  1952.     if (ctxt->depth > 40) {
  1953. if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  1954.     ctxt->sax->error(ctxt->userData,
  1955. "Detected entity reference loopn");
  1956. ctxt->wellFormed = 0;
  1957. ctxt->disableSAX = 1;
  1958. ctxt->errNo = XML_ERR_ENTITY_LOOP;
  1959. return(NULL);
  1960.     }
  1961.     /*
  1962.      * allocate a translation buffer.
  1963.      */
  1964.     buffer_size = XML_PARSER_BIG_BUFFER_SIZE;
  1965.     buffer = (xmlChar *) xmlMalloc(buffer_size * sizeof(xmlChar));
  1966.     if (buffer == NULL) {
  1967. perror("xmlDecodeEntities: malloc failed");
  1968. return(NULL);
  1969.     }
  1970.     /*
  1971.      * Ok loop until we reach one of the ending char or a size limit.
  1972.      */
  1973.     c = CUR_SCHAR(str, l);
  1974.     while ((c != 0) && (c != end) && (c != end2) && (c != end3)) {
  1975. if (c == 0) break;
  1976.         if ((c == '&') && (str[1] == '#')) {
  1977.     int val = xmlParseStringCharRef(ctxt, &str);
  1978.     if (val != 0) {
  1979. COPY_BUF(0,buffer,nbchars,val);
  1980.     }
  1981. } else if ((c == '&') && (what & XML_SUBSTITUTE_REF)) {
  1982.     ent = xmlParseStringEntityRef(ctxt, &str);
  1983.     if ((ent != NULL) && (ent->content != NULL)) {
  1984. xmlChar *rep;
  1985. ctxt->depth++;
  1986. rep = xmlStringDecodeEntities(ctxt, ent->content, what,
  1987.                       0, 0, 0);
  1988. ctxt->depth--;
  1989. if (rep != NULL) {
  1990.     current = rep;
  1991.     while (*current != 0) {
  1992. buffer[nbchars++] = *current++;
  1993. if (nbchars >
  1994.             buffer_size - XML_PARSER_BUFFER_SIZE) {
  1995.     growBuffer(buffer);
  1996. }
  1997.     }
  1998.     xmlFree(rep);
  1999. }
  2000.     } else if (ent != NULL) {
  2001. int i = xmlStrlen(ent->name);
  2002. const xmlChar *cur = ent->name;
  2003. buffer[nbchars++] = '&';
  2004. if (nbchars > buffer_size - i - XML_PARSER_BUFFER_SIZE) {
  2005.     growBuffer(buffer);
  2006. }
  2007. for (;i > 0;i--)
  2008.     buffer[nbchars++] = *cur++;
  2009. buffer[nbchars++] = ';';
  2010.     }
  2011. } else if (c == '%' && (what & XML_SUBSTITUTE_PEREF)) {
  2012.     ent = xmlParseStringPEReference(ctxt, &str);
  2013.     if (ent != NULL) {
  2014. xmlChar *rep;
  2015. ctxt->depth++;
  2016. rep = xmlStringDecodeEntities(ctxt, ent->content, what,
  2017.                       0, 0, 0);
  2018. ctxt->depth--;
  2019. if (rep != NULL) {
  2020.     current = rep;
  2021.     while (*current != 0) {
  2022. buffer[nbchars++] = *current++;
  2023. if (nbchars >
  2024.             buffer_size - XML_PARSER_BUFFER_SIZE) {
  2025.     growBuffer(buffer);
  2026. }
  2027.     }
  2028.     xmlFree(rep);
  2029. }
  2030.     }
  2031. } else {
  2032.     COPY_BUF(l,buffer,nbchars,c);
  2033.     str += l;
  2034.     if (nbchars > buffer_size - XML_PARSER_BUFFER_SIZE) {
  2035.       growBuffer(buffer);
  2036.     }
  2037. }
  2038. c = CUR_SCHAR(str, l);
  2039.     }
  2040.     buffer[nbchars++] = 0;
  2041.     return(buffer);
  2042. }
  2043. /************************************************************************
  2044.  * *
  2045.  * Commodity functions to handle encodings *
  2046.  * *
  2047.  ************************************************************************/
  2048. /*
  2049.  * xmlCheckLanguageID
  2050.  * @lang:  pointer to the string value
  2051.  *
  2052.  * Checks that the value conforms to the LanguageID production:
  2053.  *
  2054.  * [33] LanguageID ::= Langcode ('-' Subcode)*
  2055.  * [34] Langcode ::= ISO639Code |  IanaCode |  UserCode
  2056.  * [35] ISO639Code ::= ([a-z] | [A-Z]) ([a-z] | [A-Z])
  2057.  * [36] IanaCode ::= ('i' | 'I') '-' ([a-z] | [A-Z])+
  2058.  * [37] UserCode ::= ('x' | 'X') '-' ([a-z] | [A-Z])+
  2059.  * [38] Subcode ::= ([a-z] | [A-Z])+
  2060.  *
  2061.  * Returns 1 if correct 0 otherwise
  2062.  **/
  2063. int
  2064. xmlCheckLanguageID(const xmlChar *lang) {
  2065.     const xmlChar *cur = lang;
  2066.     if (cur == NULL)
  2067. return(0);
  2068.     if (((cur[0] == 'i') && (cur[1] == '-')) ||
  2069. ((cur[0] == 'I') && (cur[1] == '-'))) {
  2070. /*
  2071.  * IANA code
  2072.  */
  2073. cur += 2;
  2074.         while (((cur[0] >= 'A') && (cur[0] <= 'Z')) ||
  2075.        ((cur[0] >= 'a') && (cur[0] <= 'z')))
  2076.     cur++;
  2077.     } else if (((cur[0] == 'x') && (cur[1] == '-')) ||
  2078.        ((cur[0] == 'X') && (cur[1] == '-'))) {
  2079. /*
  2080.  * User code
  2081.  */
  2082. cur += 2;
  2083.         while (((cur[0] >= 'A') && (cur[0] <= 'Z')) ||
  2084.        ((cur[0] >= 'a') && (cur[0] <= 'z')))
  2085.     cur++;
  2086.     } else if (((cur[0] >= 'A') && (cur[0] <= 'Z')) ||
  2087.        ((cur[0] >= 'a') && (cur[0] <= 'z'))) {
  2088. /*
  2089.  * ISO639
  2090.  */
  2091. cur++;
  2092.         if (((cur[0] >= 'A') && (cur[0] <= 'Z')) ||
  2093.     ((cur[0] >= 'a') && (cur[0] <= 'z')))
  2094.     cur++;
  2095. else
  2096.     return(0);
  2097.     } else
  2098. return(0);
  2099.     while (cur[0] != 0) {
  2100. if (cur[0] != '-')
  2101.     return(0);
  2102. cur++;
  2103.         if (((cur[0] >= 'A') && (cur[0] <= 'Z')) ||
  2104.     ((cur[0] >= 'a') && (cur[0] <= 'z')))
  2105.     cur++;
  2106. else
  2107.     return(0);
  2108.         while (((cur[0] >= 'A') && (cur[0] <= 'Z')) ||
  2109.        ((cur[0] >= 'a') && (cur[0] <= 'z')))
  2110.     cur++;
  2111.     }
  2112.     return(1);
  2113. }
  2114. /**
  2115.  * xmlSwitchEncoding:
  2116.  * @ctxt:  the parser context
  2117.  * @enc:  the encoding value (number)
  2118.  *
  2119.  * change the input functions when discovering the character encoding
  2120.  * of a given entity.
  2121.  */
  2122. void
  2123. xmlSwitchEncoding(xmlParserCtxtPtr ctxt, xmlCharEncoding enc)
  2124. {
  2125.     xmlCharEncodingHandlerPtr handler;
  2126.     handler = xmlGetCharEncodingHandler(enc);
  2127.     if (handler != NULL) {
  2128.         if (ctxt->input != NULL) {
  2129.     if (ctxt->input->buf != NULL) {
  2130.         if (ctxt->input->buf->encoder != NULL) {
  2131.     if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  2132. ctxt->sax->error(ctxt->userData,
  2133.      "xmlSwitchEncoding : encoder already regiteredn");
  2134.     return;
  2135. }
  2136. ctxt->input->buf->encoder = handler;
  2137.         /*
  2138.  * Is there already some content down the pipe to convert
  2139.  */
  2140.         if ((ctxt->input->buf->buffer != NULL) &&
  2141.     (ctxt->input->buf->buffer->use > 0)) {
  2142.     xmlChar *buf;
  2143.     int res, len, size;
  2144.     int processed;
  2145.     /*
  2146.      * Specific handling of the Byte Order Mark for 
  2147.      * UTF-16
  2148.      */
  2149.     if ((enc == XML_CHAR_ENCODING_UTF16LE) && 
  2150.         (ctxt->input->cur[0] == 0xFF) &&
  2151.         (ctxt->input->cur[1] == 0xFE)) {
  2152. SKIP(2);
  2153.     }
  2154.     if ((enc == XML_CHAR_ENCODING_UTF16BE) && 
  2155.         (ctxt->input->cur[0] == 0xFE) &&
  2156.         (ctxt->input->cur[1] == 0xFF)) {
  2157. SKIP(2);
  2158.     }
  2159.     /*
  2160.      * convert the non processed part
  2161.      */
  2162.     processed = ctxt->input->cur - ctxt->input->base;
  2163.                     len = ctxt->input->buf->buffer->use - processed;
  2164.     if (len <= 0) {
  2165.         return;
  2166.     }
  2167.     size = ctxt->input->buf->buffer->use * 4;
  2168.     if (size < 4000)
  2169.         size = 4000;
  2170. retry_larger:
  2171.     buf = (xmlChar *) xmlMalloc(size + 1);
  2172.     if (buf == NULL) {
  2173. if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  2174.     ctxt->sax->error(ctxt->userData,
  2175.  "xmlSwitchEncoding : out of memoryn");
  2176.         return;
  2177.     }
  2178.     /* TODO !!! Handling of buf too small */
  2179.     res = handler->input(buf, size, ctxt->input->cur, &len);
  2180.     if (res == -1) {
  2181.         size *= 2;
  2182. xmlFree(buf);
  2183. goto retry_larger;
  2184.     }
  2185.     if ((res < 0) ||
  2186.         (len != ctxt->input->buf->buffer->use - processed)) {
  2187. if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  2188.     ctxt->sax->error(ctxt->userData,
  2189.  "xmlSwitchEncoding : conversion failedn");
  2190.                         xmlFree(buf);
  2191.         return;
  2192.     }
  2193.     /*
  2194.      * Conversion succeeded, get rid of the old buffer
  2195.      */
  2196.     xmlFree(ctxt->input->buf->buffer->content);
  2197.     ctxt->input->buf->buffer->content = buf;
  2198.     ctxt->input->base = buf;
  2199.     ctxt->input->cur = buf;
  2200.     ctxt->input->buf->buffer->size = size;
  2201.     ctxt->input->buf->buffer->use = res;
  2202.                     buf[res] = 0;
  2203. }
  2204. return;
  2205.     } else {
  2206.         if (ctxt->input->length == 0) {
  2207.     /*
  2208.      * When parsing a static memory array one must know the
  2209.      * size to be able to convert the buffer.
  2210.      */
  2211.     if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  2212. ctxt->sax->error(ctxt->userData,
  2213.  "xmlSwitchEncoding : no inputn");
  2214.     return;
  2215. } else {
  2216.     xmlChar *buf;
  2217.     int res, len;
  2218.     int processed = ctxt->input->cur - ctxt->input->base;
  2219.     /*
  2220.      * convert the non processed part
  2221.      */
  2222.                     len = ctxt->input->length - processed;
  2223.     if (len <= 0) {
  2224. if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  2225.     ctxt->sax->error(ctxt->userData,
  2226.  "xmlSwitchEncoding : input fully consumed?n");
  2227.         return;
  2228.     }
  2229.     buf = (xmlChar *) xmlMalloc(ctxt->input->length * 4);
  2230.     if (buf == NULL) {
  2231. if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  2232.     ctxt->sax->error(ctxt->userData,
  2233.  "xmlSwitchEncoding : out of memoryn");
  2234.         return;
  2235.     }
  2236.     res = handler->input(buf, ctxt->input->length * 4,
  2237.                          ctxt->input->cur, &len);
  2238.     if ((res < 0) ||
  2239.         (len != ctxt->input->length - processed)) {
  2240. if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  2241.     ctxt->sax->error(ctxt->userData,
  2242.  "xmlSwitchEncoding : conversion failedn");
  2243.                         xmlFree(buf);
  2244.         return;
  2245.     }
  2246.     /*
  2247.      * Conversion succeeded, get rid of the old buffer
  2248.      */
  2249.     if ((ctxt->input->free != NULL) &&
  2250.         (ctxt->input->base != NULL))
  2251. ctxt->input->free((xmlChar *) ctxt->input->base);
  2252.     ctxt->input->base = ctxt->input->cur = buf;
  2253.     ctxt->input->length = res;
  2254. }
  2255.     }
  2256. } else {
  2257.     if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  2258.         ctxt->sax->error(ctxt->userData,
  2259.                  "xmlSwitchEncoding : no inputn");
  2260. }
  2261.     }
  2262.     switch (enc) {
  2263.         case XML_CHAR_ENCODING_ERROR:
  2264.     ctxt->errNo = XML_ERR_UNKNOWN_ENCODING;
  2265.     if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  2266.         ctxt->sax->error(ctxt->userData, "encoding unknownn");
  2267.     ctxt->wellFormed = 0;
  2268.     ctxt->disableSAX = 1;
  2269.             break;
  2270.         case XML_CHAR_ENCODING_NONE:
  2271.     /* let's assume it's UTF-8 without the XML decl */
  2272.             return;
  2273.         case XML_CHAR_ENCODING_UTF8:
  2274.     /* default encoding, no conversion should be needed */
  2275.             return;
  2276.         case XML_CHAR_ENCODING_UTF16LE:
  2277.     ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
  2278.     if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  2279.                 ctxt->sax->error(ctxt->userData,
  2280.   "char encoding UTF16 little endian not supportedn");
  2281.             break;
  2282.         case XML_CHAR_ENCODING_UTF16BE:
  2283.     ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
  2284.     if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  2285.                 ctxt->sax->error(ctxt->userData,
  2286.   "char encoding UTF16 big endian not supportedn");
  2287.             break;
  2288.         case XML_CHAR_ENCODING_UCS4LE:
  2289.     ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
  2290.     if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  2291.                 ctxt->sax->error(ctxt->userData,
  2292.   "char encoding USC4 little endian not supportedn");
  2293.             break;
  2294.         case XML_CHAR_ENCODING_UCS4BE:
  2295.     ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
  2296.     if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  2297.                 ctxt->sax->error(ctxt->userData,
  2298.   "char encoding USC4 big endian not supportedn");
  2299.             break;
  2300.         case XML_CHAR_ENCODING_EBCDIC:
  2301.     ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
  2302.     if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  2303.                 ctxt->sax->error(ctxt->userData,
  2304.   "char encoding EBCDIC not supportedn");
  2305.             break;
  2306.         case XML_CHAR_ENCODING_UCS4_2143:
  2307.     ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
  2308.     if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  2309.                 ctxt->sax->error(ctxt->userData,
  2310.   "char encoding UCS4 2143 not supportedn");
  2311.             break;
  2312.         case XML_CHAR_ENCODING_UCS4_3412:
  2313.     ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
  2314.     if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  2315.                 ctxt->sax->error(ctxt->userData,
  2316.   "char encoding UCS4 3412 not supportedn");
  2317.             break;
  2318.         case XML_CHAR_ENCODING_UCS2:
  2319.     ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
  2320.     if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  2321.                 ctxt->sax->error(ctxt->userData,
  2322.   "char encoding UCS2 not supportedn");
  2323.             break;
  2324.         case XML_CHAR_ENCODING_8859_1:
  2325.     ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
  2326.     if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  2327.                 ctxt->sax->error(ctxt->userData,
  2328.   "char encoding ISO_8859_1 ISO Latin 1 not supportedn");
  2329.             break;
  2330.         case XML_CHAR_ENCODING_8859_2:
  2331.     ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
  2332.     if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  2333.                 ctxt->sax->error(ctxt->userData,
  2334.   "char encoding ISO_8859_2 ISO Latin 2 not supportedn");
  2335.             break;
  2336.         case XML_CHAR_ENCODING_8859_3:
  2337.     ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
  2338.     if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  2339.                 ctxt->sax->error(ctxt->userData,
  2340.   "char encoding ISO_8859_3 not supportedn");
  2341.             break;
  2342.         case XML_CHAR_ENCODING_8859_4:
  2343.     ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
  2344.     if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  2345.                 ctxt->sax->error(ctxt->userData,
  2346.   "char encoding ISO_8859_4 not supportedn");
  2347.             break;
  2348.         case XML_CHAR_ENCODING_8859_5:
  2349.     ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
  2350.     if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  2351.                 ctxt->sax->error(ctxt->userData,
  2352.   "char encoding ISO_8859_5 not supportedn");
  2353.             break;
  2354.         case XML_CHAR_ENCODING_8859_6:
  2355.     ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
  2356.     if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  2357.                 ctxt->sax->error(ctxt->userData,
  2358.   "char encoding ISO_8859_6 not supportedn");
  2359.             break;
  2360.         case XML_CHAR_ENCODING_8859_7:
  2361.     ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
  2362.     if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  2363.                 ctxt->sax->error(ctxt->userData,
  2364.   "char encoding ISO_8859_7 not supportedn");
  2365.             break;
  2366.         case XML_CHAR_ENCODING_8859_8:
  2367.     ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
  2368.     if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  2369.                 ctxt->sax->error(ctxt->userData,
  2370.   "char encoding ISO_8859_8 not supportedn");
  2371.             break;
  2372.         case XML_CHAR_ENCODING_8859_9:
  2373.     ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
  2374.     if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  2375.                 ctxt->sax->error(ctxt->userData,
  2376.   "char encoding ISO_8859_9 not supportedn");
  2377.             break;
  2378.         case XML_CHAR_ENCODING_2022_JP:
  2379.     ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
  2380.             if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  2381.                 ctxt->sax->error(ctxt->userData,
  2382.                   "char encoding ISO-2022-JPnot supportedn");
  2383.             break;
  2384.         case XML_CHAR_ENCODING_SHIFT_JIS:
  2385.     ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
  2386.             if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  2387.                 ctxt->sax->error(ctxt->userData,
  2388.                   "char encoding Shift_JISnot supportedn");
  2389.             break;
  2390.         case XML_CHAR_ENCODING_EUC_JP:
  2391.     ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
  2392.             if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  2393.                 ctxt->sax->error(ctxt->userData,
  2394.                   "char encoding EUC-JPnot supportedn");
  2395.             break;
  2396.     }
  2397. }
  2398. /************************************************************************
  2399.  * *
  2400.  * Commodity functions to handle xmlChars *
  2401.  * *
  2402.  ************************************************************************/
  2403. /**
  2404.  * xmlStrndup:
  2405.  * @cur:  the input xmlChar *
  2406.  * @len:  the len of @cur
  2407.  *
  2408.  * a strndup for array of xmlChar's
  2409.  *
  2410.  * Returns a new xmlChar * or NULL
  2411.  */
  2412. xmlChar *
  2413. xmlStrndup(const xmlChar *cur, int len) {
  2414.     xmlChar *ret;
  2415.     
  2416.     if ((cur == NULL) || (len < 0)) return(NULL);
  2417.     ret = xmlMalloc((len + 1) * sizeof(xmlChar));
  2418.     if (ret == NULL) {
  2419.         fprintf(stderr, "malloc of %ld byte failedn",
  2420.         (len + 1) * (long)sizeof(xmlChar));
  2421.         return(NULL);
  2422.     }
  2423.     memcpy(ret, cur, len * sizeof(xmlChar));
  2424.     ret[len] = 0;
  2425.     return(ret);
  2426. }
  2427. /**
  2428.  * xmlStrdup:
  2429.  * @cur:  the input xmlChar *
  2430.  *
  2431.  * a strdup for array of xmlChar's. Since they are supposed to be
  2432.  * encoded in UTF-8 or an encoding with 8bit based chars, we assume
  2433.  * a termination mark of '0'.
  2434.  *
  2435.  * Returns a new xmlChar * or NULL
  2436.  */
  2437. xmlChar *
  2438. xmlStrdup(const xmlChar *cur) {
  2439.     const xmlChar *p = cur;
  2440.     if (cur == NULL) return(NULL);
  2441.     while (*p != 0) p++;
  2442.     return(xmlStrndup(cur, p - cur));
  2443. }
  2444. /**
  2445.  * xmlCharStrndup:
  2446.  * @cur:  the input char *
  2447.  * @len:  the len of @cur
  2448.  *
  2449.  * a strndup for char's to xmlChar's
  2450.  *
  2451.  * Returns a new xmlChar * or NULL
  2452.  */
  2453. xmlChar *
  2454. xmlCharStrndup(const char *cur, int len) {
  2455.     int i;
  2456.     xmlChar *ret;
  2457.     
  2458.     if ((cur == NULL) || (len < 0)) return(NULL);
  2459.     ret = xmlMalloc((len + 1) * sizeof(xmlChar));
  2460.     if (ret == NULL) {
  2461.         fprintf(stderr, "malloc of %ld byte failedn",
  2462.         (len + 1) * (long)sizeof(xmlChar));
  2463.         return(NULL);
  2464.     }
  2465.     for (i = 0;i < len;i++)
  2466.         ret[i] = (xmlChar) cur[i];
  2467.     ret[len] = 0;
  2468.     return(ret);
  2469. }
  2470. /**
  2471.  * xmlCharStrdup:
  2472.  * @cur:  the input char *
  2473.  * @len:  the len of @cur
  2474.  *
  2475.  * a strdup for char's to xmlChar's
  2476.  *
  2477.  * Returns a new xmlChar * or NULL
  2478.  */
  2479. xmlChar *
  2480. xmlCharStrdup(const char *cur) {
  2481.     const char *p = cur;
  2482.     if (cur == NULL) return(NULL);
  2483.     while (*p != '') p++;
  2484.     return(xmlCharStrndup(cur, p - cur));
  2485. }
  2486. /**
  2487.  * xmlStrcmp:
  2488.  * @str1:  the first xmlChar *
  2489.  * @str2:  the second xmlChar *
  2490.  *
  2491.  * a strcmp for xmlChar's
  2492.  *
  2493.  * Returns the integer result of the comparison
  2494.  */
  2495. int
  2496. xmlStrcmp(const xmlChar *str1, const xmlChar *str2) {
  2497.     register int tmp;
  2498.     if ((str1 == NULL) && (str2 == NULL)) return(0);
  2499.     if (str1 == NULL) return(-1);
  2500.     if (str2 == NULL) return(1);
  2501.     do {
  2502.         tmp = *str1++ - *str2++;
  2503. if (tmp != 0) return(tmp);
  2504.     } while ((*str1 != 0) && (*str2 != 0));
  2505.     return (*str1 - *str2);
  2506. }
  2507. /**
  2508.  * xmlStrncmp:
  2509.  * @str1:  the first xmlChar *
  2510.  * @str2:  the second xmlChar *
  2511.  * @len:  the max comparison length
  2512.  *
  2513.  * a strncmp for xmlChar's
  2514.  *
  2515.  * Returns the integer result of the comparison
  2516.  */
  2517. int
  2518. xmlStrncmp(const xmlChar *str1, const xmlChar *str2, int len) {
  2519.     register int tmp;
  2520.     if (len <= 0) return(0);
  2521.     if ((str1 == NULL) && (str2 == NULL)) return(0);
  2522.     if (str1 == NULL) return(-1);
  2523.     if (str2 == NULL) return(1);
  2524.     do {
  2525.         tmp = *str1++ - *str2++;
  2526. if (tmp != 0) return(tmp);
  2527. len--;
  2528.         if (len <= 0) return(0);
  2529.     } while ((*str1 != 0) && (*str2 != 0));
  2530.     return (*str1 - *str2);
  2531. }
  2532. /**
  2533.  * xmlStrchr:
  2534.  * @str:  the xmlChar * array
  2535.  * @val:  the xmlChar to search
  2536.  *
  2537.  * a strchr for xmlChar's
  2538.  *
  2539.  * Returns the xmlChar * for the first occurence or NULL.
  2540.  */
  2541. const xmlChar *
  2542. xmlStrchr(const xmlChar *str, xmlChar val) {
  2543.     if (str == NULL) return(NULL);
  2544.     while (*str != 0) {
  2545.         if (*str == val) return((xmlChar *) str);
  2546. str++;
  2547.     }
  2548.     return(NULL);
  2549. }
  2550. /**
  2551.  * xmlStrstr:
  2552.  * @str:  the xmlChar * array (haystack)
  2553.  * @val:  the xmlChar to search (needle)
  2554.  *
  2555.  * a strstr for xmlChar's
  2556.  *
  2557.  * Returns the xmlChar * for the first occurence or NULL.
  2558.  */
  2559. const xmlChar *
  2560. xmlStrstr(const xmlChar *str, xmlChar *val) {
  2561.     int n;
  2562.     
  2563.     if (str == NULL) return(NULL);
  2564.     if (val == NULL) return(NULL);
  2565.     n = xmlStrlen(val);
  2566.     if (n == 0) return(str);
  2567.     while (*str != 0) {
  2568.         if (*str == *val) {
  2569.     if (!xmlStrncmp(str, val, n)) return((const xmlChar *) str);
  2570. }
  2571. str++;
  2572.     }
  2573.     return(NULL);
  2574. }
  2575. /**
  2576.  * xmlStrsub:
  2577.  * @str:  the xmlChar * array (haystack)
  2578.  * @start:  the index of the first char (zero based)
  2579.  * @len:  the length of the substring
  2580.  *
  2581.  * Extract a substring of a given string
  2582.  *
  2583.  * Returns the xmlChar * for the first occurence or NULL.
  2584.  */
  2585. xmlChar *
  2586. xmlStrsub(const xmlChar *str, int start, int len) {
  2587.     int i;
  2588.     
  2589.     if (str == NULL) return(NULL);
  2590.     if (start < 0) return(NULL);
  2591.     if (len < 0) return(NULL);
  2592.     for (i = 0;i < start;i++) {
  2593.         if (*str == 0) return(NULL);
  2594. str++;
  2595.     }
  2596.     if (*str == 0) return(NULL);
  2597.     return(xmlStrndup(str, len));
  2598. }
  2599. /**
  2600.  * xmlStrlen:
  2601.  * @str:  the xmlChar * array
  2602.  *
  2603.  * length of a xmlChar's string
  2604.  *
  2605.  * Returns the number of xmlChar contained in the ARRAY.
  2606.  */
  2607. int
  2608. xmlStrlen(const xmlChar *str) {
  2609.     int len = 0;
  2610.     if (str == NULL) return(0);
  2611.     while (*str != 0) {
  2612. str++;
  2613. len++;
  2614.     }
  2615.     return(len);
  2616. }
  2617. /**
  2618.  * xmlStrncat:
  2619.  * @cur:  the original xmlChar * array
  2620.  * @add:  the xmlChar * array added
  2621.  * @len:  the length of @add
  2622.  *
  2623.  * a strncat for array of xmlChar's
  2624.  *
  2625.  * Returns a new xmlChar * containing the concatenated string.
  2626.  */
  2627. xmlChar *
  2628. xmlStrncat(xmlChar *cur, const xmlChar *add, int len) {
  2629.     int size;
  2630.     xmlChar *ret;
  2631.     if ((add == NULL) || (len == 0))
  2632.         return(cur);
  2633.     if (cur == NULL)
  2634.         return(xmlStrndup(add, len));
  2635.     size = xmlStrlen(cur);
  2636.     ret = xmlRealloc(cur, (size + len + 1) * sizeof(xmlChar));
  2637.     if (ret == NULL) {
  2638.         fprintf(stderr, "xmlStrncat: realloc of %ld byte failedn",
  2639.         (size + len + 1) * (long)sizeof(xmlChar));
  2640.         return(cur);
  2641.     }
  2642.     memcpy(&ret[size], add, len * sizeof(xmlChar));
  2643.     ret[size + len] = 0;
  2644.     return(ret);
  2645. }
  2646. /**
  2647.  * xmlStrcat:
  2648.  * @cur:  the original xmlChar * array
  2649.  * @add:  the xmlChar * array added
  2650.  *
  2651.  * a strcat for array of xmlChar's. Since they are supposed to be
  2652.  * encoded in UTF-8 or an encoding with 8bit based chars, we assume
  2653.  * a termination mark of '0'.
  2654.  *
  2655.  * Returns a new xmlChar * containing the concatenated string.
  2656.  */
  2657. xmlChar *
  2658. xmlStrcat(xmlChar *cur, const xmlChar *add) {
  2659.     const xmlChar *p = add;
  2660.     if (add == NULL) return(cur);
  2661.     if (cur == NULL) 
  2662.         return(xmlStrdup(add));
  2663.     while (*p != 0) p++;
  2664.     return(xmlStrncat(cur, add, p - add));
  2665. }
  2666. /************************************************************************
  2667.  * *
  2668.  * Commodity functions, cleanup needed ? *
  2669.  * *
  2670.  ************************************************************************/
  2671. /**
  2672.  * areBlanks:
  2673.  * @ctxt:  an XML parser context
  2674.  * @str:  a xmlChar *
  2675.  * @len:  the size of @str
  2676.  *
  2677.  * Is this a sequence of blank chars that one can ignore ?
  2678.  *
  2679.  * Returns 1 if ignorable 0 otherwise.
  2680.  */
  2681. static int areBlanks(xmlParserCtxtPtr ctxt, const xmlChar *str, int len) {
  2682.     int i, ret;
  2683.     xmlNodePtr lastChild;
  2684.     /*
  2685.      * Check for xml:space value.
  2686.      */
  2687.     if (*(ctxt->space) == 1)
  2688. return(0);
  2689.     /*
  2690.      * Check that the string is made of blanks
  2691.      */
  2692.     for (i = 0;i < len;i++)
  2693.         if (!(IS_BLANK(str[i]))) return(0);
  2694.     /*
  2695.      * Look if the element is mixed content in the Dtd if available
  2696.      */
  2697.     if (ctxt->myDoc != NULL) {
  2698. ret = xmlIsMixedElement(ctxt->myDoc, ctxt->node->name);
  2699.         if (ret == 0) return(1);
  2700.         if (ret == 1) return(0);
  2701.     }
  2702.     /*
  2703.      * Otherwise, heuristic :-
  2704.      */
  2705.     if (ctxt->keepBlanks)
  2706. return(0);
  2707.     if (RAW != '<') return(0);
  2708.     if (ctxt->node == NULL) return(0);
  2709.     if ((ctxt->node->children == NULL) &&
  2710. (RAW == '<') && (NXT(1) == '/')) return(0);
  2711.     lastChild = xmlGetLastChild(ctxt->node);
  2712.     if (lastChild == NULL) {
  2713.         if (ctxt->node->content != NULL) return(0);
  2714.     } else if (xmlNodeIsText(lastChild))
  2715.         return(0);
  2716.     else if ((ctxt->node->children != NULL) &&
  2717.              (xmlNodeIsText(ctxt->node->children)))
  2718.         return(0);
  2719.     return(1);
  2720. }
  2721. /**
  2722.  * xmlHandleEntity:
  2723.  * @ctxt:  an XML parser context
  2724.  * @entity:  an XML entity pointer.
  2725.  *
  2726.  * Default handling of defined entities, when should we define a new input
  2727.  * stream ? When do we just handle that as a set of chars ?
  2728.  *
  2729.  * OBSOLETE: to be removed at some point.
  2730.  */
  2731. void
  2732. xmlHandleEntity(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
  2733.     int len;
  2734.     xmlParserInputPtr input;
  2735.     if (entity->content == NULL) {
  2736. ctxt->errNo = XML_ERR_INTERNAL_ERROR;
  2737.         if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  2738.     ctxt->sax->error(ctxt->userData, "xmlHandleEntity %s: content == NULLn",
  2739.                entity->name);
  2740. ctxt->wellFormed = 0;
  2741. ctxt->disableSAX = 1;
  2742.         return;
  2743.     }
  2744.     len = xmlStrlen(entity->content);
  2745.     if (len <= 2) goto handle_as_char;
  2746.     /*
  2747.      * Redefine its content as an input stream.
  2748.      */
  2749.     input = xmlNewEntityInputStream(ctxt, entity);
  2750.     xmlPushInput(ctxt, input);
  2751.     return;
  2752. handle_as_char:
  2753.     /*
  2754.      * Just handle the content as a set of chars.
  2755.      */
  2756.     if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
  2757. (ctxt->sax->characters != NULL))
  2758. ctxt->sax->characters(ctxt->userData, entity->content, len);
  2759. }
  2760. /*
  2761.  * Forward definition for recusive behaviour.
  2762.  */
  2763. void xmlParsePEReference(xmlParserCtxtPtr ctxt);
  2764. void xmlParseReference(xmlParserCtxtPtr ctxt);
  2765. /************************************************************************
  2766.  * *
  2767.  * Extra stuff for namespace support *
  2768.  * Relates to http://www.w3.org/TR/WD-xml-names *
  2769.  * *
  2770.  ************************************************************************/
  2771. /**
  2772.  * xmlNamespaceParseNCName:
  2773.  * @ctxt:  an XML parser context
  2774.  *
  2775.  * parse an XML namespace name.
  2776.  *
  2777.  * [NS 3] NCName ::= (Letter | '_') (NCNameChar)*
  2778.  *
  2779.  * [NS 4] NCNameChar ::= Letter | Digit | '.' | '-' | '_' |
  2780.  *                       CombiningChar | Extender
  2781.  *
  2782.  * Returns the namespace name or NULL
  2783.  */
  2784. xmlChar *
  2785. xmlNamespaceParseNCName(xmlParserCtxtPtr ctxt) {
  2786.     xmlChar buf[XML_MAX_NAMELEN + 5];
  2787.     int len = 0, l;
  2788.     int cur = CUR_CHAR(l);
  2789.     /* load first the value of the char !!! */
  2790.     if (!IS_LETTER(cur) && (cur != '_')) return(NULL);
  2791.     while ((IS_LETTER(cur)) || (IS_DIGIT(cur)) ||
  2792.            (cur == '.') || (cur == '-') ||
  2793.    (cur == '_') ||
  2794.    (IS_COMBINING(cur)) ||
  2795.    (IS_EXTENDER(cur))) {
  2796. COPY_BUF(l,buf,len,cur);
  2797. NEXTL(l);
  2798. cur = CUR_CHAR(l);
  2799. if (len >= XML_MAX_NAMELEN) {
  2800.     fprintf(stderr, 
  2801.        "xmlNamespaceParseNCName: reached XML_MAX_NAMELEN limitn");
  2802.     while ((IS_LETTER(cur)) || (IS_DIGIT(cur)) ||
  2803.    (cur == '.') || (cur == '-') ||
  2804.    (cur == '_') ||
  2805.    (IS_COMBINING(cur)) ||
  2806.    (IS_EXTENDER(cur))) {
  2807. NEXTL(l);
  2808. cur = CUR_CHAR(l);
  2809.     }
  2810.     break;
  2811. }
  2812.     }
  2813.     return(xmlStrndup(buf, len));
  2814. }
  2815. /**
  2816.  * xmlNamespaceParseQName:
  2817.  * @ctxt:  an XML parser context
  2818.  * @prefix:  a xmlChar ** 
  2819.  *
  2820.  * parse an XML qualified name
  2821.  *
  2822.  * [NS 5] QName ::= (Prefix ':')? LocalPart
  2823.  *
  2824.  * [NS 6] Prefix ::= NCName
  2825.  *
  2826.  * [NS 7] LocalPart ::= NCName
  2827.  *
  2828.  * Returns the local part, and prefix is updated
  2829.  *   to get the Prefix if any.
  2830.  */
  2831. xmlChar *
  2832. xmlNamespaceParseQName(xmlParserCtxtPtr ctxt, xmlChar **prefix) {
  2833.     xmlChar *ret = NULL;
  2834.     *prefix = NULL;
  2835.     ret = xmlNamespaceParseNCName(ctxt);
  2836.     if (RAW == ':') {
  2837.         *prefix = ret;
  2838. NEXT;
  2839. ret = xmlNamespaceParseNCName(ctxt);
  2840.     }
  2841.     return(ret);
  2842. }
  2843. /**
  2844.  * xmlSplitQName:
  2845.  * @ctxt:  an XML parser context
  2846.  * @name:  an XML parser context
  2847.  * @prefix:  a xmlChar ** 
  2848.  *
  2849.  * parse an XML qualified name string
  2850.  *
  2851.  * [NS 5] QName ::= (Prefix ':')? LocalPart
  2852.  *
  2853.  * [NS 6] Prefix ::= NCName
  2854.  *
  2855.  * [NS 7] LocalPart ::= NCName
  2856.  *
  2857.  * Returns the local part, and prefix is updated
  2858.  *   to get the Prefix if any.
  2859.  */
  2860. xmlChar *
  2861. xmlSplitQName(xmlParserCtxtPtr ctxt, const xmlChar *name, xmlChar **prefix) {
  2862.     xmlChar buf[XML_MAX_NAMELEN + 5];
  2863.     int len = 0;
  2864.     xmlChar *ret = NULL;
  2865.     const xmlChar *cur = name;
  2866.     int c,l;
  2867.     *prefix = NULL;
  2868.     /* xml: prefix is not really a namespace */
  2869.     if ((cur[0] == 'x') && (cur[1] == 'm') &&
  2870.         (cur[2] == 'l') && (cur[3] == ':'))
  2871. return(xmlStrdup(name));
  2872.     /* nasty but valid */
  2873.     if (cur[0] == ':')
  2874. return(xmlStrdup(name));
  2875.     c = CUR_SCHAR(cur, l);
  2876.     if (!IS_LETTER(c) && (c != '_')) return(NULL);
  2877.     while ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
  2878.            (c == '.') || (c == '-') ||
  2879.    (c == '_') ||
  2880.    (IS_COMBINING(c)) ||
  2881.    (IS_EXTENDER(c))) {
  2882. COPY_BUF(l,buf,len,c);
  2883. cur += l;
  2884. c = CUR_SCHAR(cur, l);
  2885.     }
  2886.     
  2887.     ret = xmlStrndup(buf, len);
  2888.     if (c == ':') {
  2889. cur += l;
  2890. c = CUR_SCHAR(cur, l);
  2891. if (!IS_LETTER(c) && (c != '_')) return(ret);
  2892.         *prefix = ret;
  2893. len = 0;
  2894. while ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
  2895.        (c == '.') || (c == '-') ||
  2896.        (c == '_') ||
  2897.        (IS_COMBINING(c)) ||
  2898.        (IS_EXTENDER(c))) {
  2899.     COPY_BUF(l,buf,len,c);
  2900.     cur += l;
  2901.     c = CUR_SCHAR(cur, l);
  2902. }
  2903. ret = xmlStrndup(buf, len);
  2904.     }
  2905.     return(ret);
  2906. }
  2907. /**
  2908.  * xmlNamespaceParseNSDef:
  2909.  * @ctxt:  an XML parser context
  2910.  *
  2911.  * parse a namespace prefix declaration
  2912.  *
  2913.  * [NS 1] NSDef ::= PrefixDef Eq SystemLiteral
  2914.  *
  2915.  * [NS 2] PrefixDef ::= 'xmlns' (':' NCName)?
  2916.  *
  2917.  * Returns the namespace name
  2918.  */
  2919. xmlChar *
  2920. xmlNamespaceParseNSDef(xmlParserCtxtPtr ctxt) {
  2921.     xmlChar *name = NULL;
  2922.     if ((RAW == 'x') && (NXT(1) == 'm') &&
  2923.         (NXT(2) == 'l') && (NXT(3) == 'n') &&
  2924. (NXT(4) == 's')) {
  2925. SKIP(5);
  2926. if (RAW == ':') {
  2927.     NEXT;
  2928.     name = xmlNamespaceParseNCName(ctxt);
  2929. }
  2930.     }
  2931.     return(name);
  2932. }
  2933. /**
  2934.  * xmlParseQuotedString:
  2935.  * @ctxt:  an XML parser context
  2936.  *
  2937.  * [OLD] Parse and return a string between quotes or doublequotes
  2938.  * To be removed at next drop of binary compatibility
  2939.  *
  2940.  * Returns the string parser or NULL.
  2941.  */
  2942. xmlChar *
  2943. xmlParseQuotedString(xmlParserCtxtPtr ctxt) {
  2944.     xmlChar *buf = NULL;
  2945.     int len = 0,l;
  2946.     int size = XML_PARSER_BUFFER_SIZE;
  2947.     int c;
  2948.     buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar));
  2949.     if (buf == NULL) {
  2950. fprintf(stderr, "malloc of %d byte failedn", size);
  2951. return(NULL);
  2952.     }
  2953.     if (RAW == '"') {
  2954.         NEXT;
  2955. c = CUR_CHAR(l);
  2956. while (IS_CHAR(c) && (c != '"')) {
  2957.     if (len + 5 >= size) {
  2958. size *= 2;
  2959. buf = xmlRealloc(buf, size * sizeof(xmlChar));
  2960. if (buf == NULL) {
  2961.     fprintf(stderr, "realloc of %d byte failedn", size);
  2962.     return(NULL);
  2963. }
  2964.     }
  2965.     COPY_BUF(l,buf,len,c);
  2966.     NEXTL(l);
  2967.     c = CUR_CHAR(l);
  2968. }
  2969. if (c != '"') {
  2970.     ctxt->errNo = XML_ERR_STRING_NOT_CLOSED;
  2971.     if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  2972.         ctxt->sax->error(ctxt->userData, 
  2973.          "String not closed "%.50s"n", buf);
  2974.     ctxt->wellFormed = 0;
  2975.     ctxt->disableSAX = 1;
  2976.         } else {
  2977.     NEXT;
  2978. }
  2979.     } else if (RAW == '''){
  2980.         NEXT;
  2981. c = CUR;
  2982. while (IS_CHAR(c) && (c != ''')) {
  2983.     if (len + 1 >= size) {
  2984. size *= 2;
  2985. buf = xmlRealloc(buf, size * sizeof(xmlChar));
  2986. if (buf == NULL) {
  2987.     fprintf(stderr, "realloc of %d byte failedn", size);
  2988.     return(NULL);
  2989. }
  2990.     }
  2991.     buf[len++] = c;
  2992.     NEXT;
  2993.     c = CUR;
  2994. }
  2995. if (RAW != ''') {
  2996.     ctxt->errNo = XML_ERR_STRING_NOT_CLOSED;
  2997.     if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  2998.         ctxt->sax->error(ctxt->userData,
  2999.          "String not closed "%.50s"n", buf);
  3000.     ctxt->wellFormed = 0;
  3001.     ctxt->disableSAX = 1;
  3002.         } else {
  3003.     NEXT;
  3004. }
  3005.     }
  3006.     return(buf);
  3007. }
  3008. /**
  3009.  * xmlParseNamespace:
  3010.  * @ctxt:  an XML parser context
  3011.  *
  3012.  * [OLD] xmlParseNamespace: parse specific PI '<?namespace ...' constructs.
  3013.  *
  3014.  * This is what the older xml-name Working Draft specified, a bunch of
  3015.  * other stuff may still rely on it, so support is still here as
  3016.  * if it was declared on the root of the Tree:-(
  3017.  *
  3018.  * To be removed at next drop of binary compatibility
  3019.  */
  3020. void
  3021. xmlParseNamespace(xmlParserCtxtPtr ctxt) {
  3022.     xmlChar *href = NULL;
  3023.     xmlChar *prefix = NULL;
  3024.     int garbage = 0;
  3025.     /*
  3026.      * We just skipped "namespace" or "xml:namespace"
  3027.      */
  3028.     SKIP_BLANKS;
  3029.     while (IS_CHAR(RAW) && (RAW != '>')) {
  3030. /*
  3031.  * We can have "ns" or "prefix" attributes
  3032.  * Old encoding as 'href' or 'AS' attributes is still supported
  3033.  */
  3034. if ((RAW == 'n') && (NXT(1) == 's')) {
  3035.     garbage = 0;
  3036.     SKIP(2);
  3037.     SKIP_BLANKS;
  3038.     if (RAW != '=') continue;
  3039.     NEXT;
  3040.     SKIP_BLANKS;
  3041.     href = xmlParseQuotedString(ctxt);
  3042.     SKIP_BLANKS;
  3043. } else if ((RAW == 'h') && (NXT(1) == 'r') &&
  3044.     (NXT(2) == 'e') && (NXT(3) == 'f')) {
  3045.     garbage = 0;
  3046.     SKIP(4);
  3047.     SKIP_BLANKS;
  3048.     if (RAW != '=') continue;
  3049.     NEXT;
  3050.     SKIP_BLANKS;
  3051.     href = xmlParseQuotedString(ctxt);
  3052.     SKIP_BLANKS;
  3053. } else if ((RAW == 'p') && (NXT(1) == 'r') &&
  3054.            (NXT(2) == 'e') && (NXT(3) == 'f') &&
  3055.            (NXT(4) == 'i') && (NXT(5) == 'x')) {
  3056.     garbage = 0;
  3057.     SKIP(6);
  3058.     SKIP_BLANKS;
  3059.     if (RAW != '=') continue;
  3060.     NEXT;
  3061.     SKIP_BLANKS;
  3062.     prefix = xmlParseQuotedString(ctxt);
  3063.     SKIP_BLANKS;
  3064. } else if ((RAW == 'A') && (NXT(1) == 'S')) {
  3065.     garbage = 0;
  3066.     SKIP(2);
  3067.     SKIP_BLANKS;
  3068.     if (RAW != '=') continue;
  3069.     NEXT;
  3070.     SKIP_BLANKS;
  3071.     prefix = xmlParseQuotedString(ctxt);
  3072.     SKIP_BLANKS;
  3073. } else if ((RAW == '?') && (NXT(1) == '>')) {
  3074.     garbage = 0;
  3075.     NEXT;
  3076. } else {
  3077.             /*
  3078.      * Found garbage when parsing the namespace
  3079.      */
  3080.     if (!garbage) {
  3081. if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  3082.     ctxt->sax->error(ctxt->userData,
  3083.                      "xmlParseNamespace found garbagen");
  3084.     }
  3085.     ctxt->errNo = XML_ERR_NS_DECL_ERROR;
  3086.     ctxt->wellFormed = 0;
  3087.     ctxt->disableSAX = 1;
  3088.             NEXT;
  3089.         }
  3090.     }
  3091.     MOVETO_ENDTAG(CUR_PTR);
  3092.     NEXT;
  3093.     /*
  3094.      * Register the DTD.
  3095.     if (href != NULL)
  3096. if ((ctxt->sax != NULL) && (ctxt->sax->globalNamespace != NULL))
  3097.     ctxt->sax->globalNamespace(ctxt->userData, href, prefix);
  3098.      */
  3099.     if (prefix != NULL) xmlFree(prefix);
  3100.     if (href != NULL) xmlFree(href);
  3101. }
  3102. /************************************************************************
  3103.  * *
  3104.  * The parser itself *
  3105.  * Relates to http://www.w3.org/TR/REC-xml *
  3106.  * *
  3107.  ************************************************************************/
  3108. /**
  3109.  * xmlScanName:
  3110.  * @ctxt:  an XML parser context
  3111.  *
  3112.  * Trickery: parse an XML name but without consuming the input flow
  3113.  * Needed for rollback cases.
  3114.  *
  3115.  * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
  3116.  *                  CombiningChar | Extender
  3117.  *
  3118.  * [5] Name ::= (Letter | '_' | ':') (NameChar)*
  3119.  *
  3120.  * [6] Names ::= Name (S Name)*
  3121.  *
  3122.  * Returns the Name parsed or NULL
  3123.  */
  3124. xmlChar *
  3125. xmlScanName(xmlParserCtxtPtr ctxt) {
  3126.     xmlChar buf[XML_MAX_NAMELEN];
  3127.     int len = 0;
  3128.     GROW;
  3129.     if (!IS_LETTER(RAW) && (RAW != '_') &&
  3130.         (RAW != ':')) {
  3131. return(NULL);
  3132.     }
  3133.     while ((IS_LETTER(NXT(len))) || (IS_DIGIT(NXT(len))) ||
  3134.            (NXT(len) == '.') || (NXT(len) == '-') ||
  3135.    (NXT(len) == '_') || (NXT(len) == ':') || 
  3136.    (IS_COMBINING(NXT(len))) ||
  3137.    (IS_EXTENDER(NXT(len)))) {
  3138. buf[len] = NXT(len);
  3139. len++;
  3140. if (len >= XML_MAX_NAMELEN) {
  3141.     fprintf(stderr, 
  3142.        "xmlScanName: reached XML_MAX_NAMELEN limitn");
  3143.     while ((IS_LETTER(NXT(len))) || (IS_DIGIT(NXT(len))) ||
  3144.    (NXT(len) == '.') || (NXT(len) == '-') ||
  3145.    (NXT(len) == '_') || (NXT(len) == ':') || 
  3146.    (IS_COMBINING(NXT(len))) ||
  3147.    (IS_EXTENDER(NXT(len))))
  3148.  len++;
  3149.     break;
  3150. }
  3151.     }
  3152.     return(xmlStrndup(buf, len));
  3153. }
  3154. /**
  3155.  * xmlParseName:
  3156.  * @ctxt:  an XML parser context
  3157.  *
  3158.  * parse an XML name.
  3159.  *
  3160.  * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
  3161.  *                  CombiningChar | Extender
  3162.  *
  3163.  * [5] Name ::= (Letter | '_' | ':') (NameChar)*
  3164.  *
  3165.  * [6] Names ::= Name (S Name)*
  3166.  *
  3167.  * Returns the Name parsed or NULL
  3168.  */
  3169. xmlChar *
  3170. xmlParseName(xmlParserCtxtPtr ctxt) {
  3171.     xmlChar buf[XML_MAX_NAMELEN + 5];
  3172.     int len = 0, l;
  3173.     int c;
  3174.     GROW;
  3175.     c = CUR_CHAR(l);
  3176.     if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
  3177. (!IS_LETTER(c) && (c != '_') &&
  3178.          (c != ':'))) {
  3179. return(NULL);
  3180.     }
  3181.     while ((c != ' ') && (c != '>') && (c != '/') && /* accelerators */
  3182.    ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
  3183.             (c == '.') || (c == '-') ||
  3184.     (c == '_') || (c == ':') || 
  3185.     (IS_COMBINING(c)) ||
  3186.     (IS_EXTENDER(c)))) {
  3187. COPY_BUF(l,buf,len,c);
  3188. NEXTL(l);
  3189. c = CUR_CHAR(l);
  3190. if (len >= XML_MAX_NAMELEN) {
  3191.     fprintf(stderr, 
  3192.        "xmlParseName: reached XML_MAX_NAMELEN limitn");
  3193.     while ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
  3194.    (c == '.') || (c == '-') ||
  3195.    (c == '_') || (c == ':') || 
  3196.    (IS_COMBINING(c)) ||
  3197.    (IS_EXTENDER(c))) {
  3198. NEXTL(l);
  3199. c = CUR_CHAR(l);
  3200.     }
  3201.     break;
  3202. }
  3203.     }
  3204.     return(xmlStrndup(buf, len));
  3205. }
  3206. /**
  3207.  * xmlParseStringName:
  3208.  * @ctxt:  an XML parser context
  3209.  * @str:  a pointer to an index in the string
  3210.  *
  3211.  * parse an XML name.
  3212.  *
  3213.  * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
  3214.  *                  CombiningChar | Extender
  3215.  *
  3216.  * [5] Name ::= (Letter | '_' | ':') (NameChar)*
  3217.  *
  3218.  * [6] Names ::= Name (S Name)*
  3219.  *
  3220.  * Returns the Name parsed or NULL. The str pointer 
  3221.  * is updated to the current location in the string.
  3222.  */
  3223. xmlChar *
  3224. xmlParseStringName(xmlParserCtxtPtr ctxt, const xmlChar** str) {
  3225.     xmlChar buf[XML_MAX_NAMELEN + 5];
  3226.     const xmlChar *cur = *str;
  3227.     int len = 0, l;
  3228.     int c;
  3229.     c = CUR_SCHAR(cur, l);
  3230.     if (!IS_LETTER(c) && (c != '_') &&
  3231.         (c != ':')) {
  3232. return(NULL);
  3233.     }
  3234.     while ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
  3235.            (c == '.') || (c == '-') ||
  3236.    (c == '_') || (c == ':') || 
  3237.    (IS_COMBINING(c)) ||
  3238.    (IS_EXTENDER(c))) {
  3239. COPY_BUF(l,buf,len,c);
  3240. cur += l;
  3241. c = CUR_SCHAR(cur, l);
  3242. if (len >= XML_MAX_NAMELEN) {
  3243.     fprintf(stderr, 
  3244.        "xmlParseName: reached XML_MAX_NAMELEN limitn");
  3245.     while ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
  3246.    (c == '.') || (c == '-') ||
  3247.    (c == '_') || (c == ':') || 
  3248.    (IS_COMBINING(c)) ||
  3249.    (IS_EXTENDER(c))) {
  3250. cur += l;
  3251. c = CUR_SCHAR(cur, l);
  3252.     }
  3253.     break;
  3254. }
  3255.     }
  3256.     *str = cur;
  3257.     return(xmlStrndup(buf, len));
  3258. }
  3259. /**
  3260.  * xmlParseNmtoken:
  3261.  * @ctxt:  an XML parser context
  3262.  * 
  3263.  * parse an XML Nmtoken.
  3264.  *
  3265.  * [7] Nmtoken ::= (NameChar)+
  3266.  *
  3267.  * [8] Nmtokens ::= Nmtoken (S Nmtoken)*
  3268.  *
  3269.  * Returns the Nmtoken parsed or NULL
  3270.  */
  3271. xmlChar *
  3272. xmlParseNmtoken(xmlParserCtxtPtr ctxt) {
  3273.     xmlChar buf[XML_MAX_NAMELEN];
  3274.     int len = 0;
  3275.     int c,l;
  3276.     GROW;
  3277.     c = CUR_CHAR(l);
  3278.     while ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
  3279.            (c == '.') || (c == '-') ||
  3280.    (c == '_') || (c == ':') || 
  3281.    (IS_COMBINING(c)) ||
  3282.    (IS_EXTENDER(c))) {
  3283. COPY_BUF(l,buf,len,c);
  3284. NEXTL(l);
  3285. c = CUR_CHAR(l);
  3286. if (len >= XML_MAX_NAMELEN) {
  3287.     fprintf(stderr, 
  3288.        "xmlParseNmtoken: reached XML_MAX_NAMELEN limitn");
  3289.     while ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
  3290.    (c == '.') || (c == '-') ||
  3291.    (c == '_') || (c == ':') || 
  3292.    (IS_COMBINING(c)) ||
  3293.    (IS_EXTENDER(c))) {
  3294. NEXTL(l);
  3295. c = CUR_CHAR(l);
  3296.     }
  3297.     break;
  3298. }
  3299.     }
  3300.     if (len == 0)
  3301.         return(NULL);
  3302.     return(xmlStrndup(buf, len));
  3303. }
  3304. /**
  3305.  * xmlParseEntityValue:
  3306.  * @ctxt:  an XML parser context
  3307.  * @orig:  if non-NULL store a copy of the original entity value
  3308.  *
  3309.  * parse a value for ENTITY decl.
  3310.  *
  3311.  * [9] EntityValue ::= '"' ([^%&"] | PEReference | Reference)* '"' |
  3312.  *                "'" ([^%&'] | PEReference | Reference)* "'"
  3313.  *
  3314.  * Returns the EntityValue parsed with reference substitued or NULL
  3315.  */
  3316. xmlChar *
  3317. xmlParseEntityValue(xmlParserCtxtPtr ctxt, xmlChar **orig) {
  3318.     xmlChar *buf = NULL;
  3319.     int len = 0;
  3320.     int size = XML_PARSER_BUFFER_SIZE;
  3321.     int c, l;
  3322.     xmlChar stop;
  3323.     xmlChar *ret = NULL;
  3324.     const xmlChar *cur = NULL;
  3325.     xmlParserInputPtr input;
  3326.     if (RAW == '"') stop = '"';
  3327.     else if (RAW == ''') stop = ''';
  3328.     else {
  3329. ctxt->errNo = XML_ERR_ENTITY_NOT_STARTED;
  3330. if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
  3331.     ctxt->sax->error(ctxt->userData, "EntityValue: " or ' expectedn");
  3332. ctxt->wellFormed = 0;
  3333. ctxt->disableSAX = 1;
  3334. return(NULL);
  3335.     }