xmlparse.c
上传用户:yisoukefu
上传日期:2020-08-09
资源大小:39506k
文件大小:189k
源码类别:

其他游戏

开发平台:

Visual C++

  1.             for (;;) {
  2.               ICHAR *dataPtr = (ICHAR *)dataBuf;
  3.               XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
  4.               *eventEndPP = next;
  5.               charDataHandler(handlerArg, dataBuf,
  6.                               (int)(dataPtr - (ICHAR *)dataBuf));
  7.               if (s == next)
  8.                 break;
  9.               *eventPP = s;
  10.             }
  11.           }
  12.           else
  13.             charDataHandler(handlerArg,
  14.                             (XML_Char *)s,
  15.                             (int)((XML_Char *)next - (XML_Char *)s));
  16.         }
  17.         else if (defaultHandler)
  18.           reportDefault(parser, enc, s, next);
  19.       }
  20.       break;
  21.     case XML_TOK_INVALID:
  22.       *eventPP = next;
  23.       return XML_ERROR_INVALID_TOKEN;
  24.     case XML_TOK_PARTIAL_CHAR:
  25.       if (haveMore) {
  26.         *nextPtr = s;
  27.         return XML_ERROR_NONE;
  28.       }
  29.       return XML_ERROR_PARTIAL_CHAR;
  30.     case XML_TOK_PARTIAL:
  31.     case XML_TOK_NONE:
  32.       if (haveMore) {
  33.         *nextPtr = s;
  34.         return XML_ERROR_NONE;
  35.       }
  36.       return XML_ERROR_UNCLOSED_CDATA_SECTION;
  37.     default:
  38.       *eventPP = next;
  39.       return XML_ERROR_UNEXPECTED_STATE;
  40.     }
  41.     *eventPP = s = next;
  42.     switch (ps_parsing) {
  43.     case XML_SUSPENDED:
  44.       *nextPtr = next;
  45.       return XML_ERROR_NONE;
  46.     case XML_FINISHED:
  47.       return XML_ERROR_ABORTED;
  48.     default: ;
  49.     }
  50.   }
  51.   /* not reached */
  52. }
  53. #ifdef XML_DTD
  54. /* The idea here is to avoid using stack for each IGNORE section when
  55.    the whole file is parsed with one call.
  56. */
  57. static enum XML_Error PTRCALL
  58. ignoreSectionProcessor(XML_Parser parser,
  59.                        const char *start,
  60.                        const char *end,
  61.                        const char **endPtr)
  62. {
  63.   enum XML_Error result = doIgnoreSection(parser, encoding, &start, end, 
  64.                                           endPtr, (XML_Bool)!ps_finalBuffer);
  65.   if (result != XML_ERROR_NONE)
  66.     return result;
  67.   if (start) {
  68.     processor = prologProcessor;
  69.     return prologProcessor(parser, start, end, endPtr);
  70.   }
  71.   return result;
  72. }
  73. /* startPtr gets set to non-null is the section is closed, and to null
  74.    if the section is not yet closed.
  75. */
  76. static enum XML_Error
  77. doIgnoreSection(XML_Parser parser,
  78.                 const ENCODING *enc,
  79.                 const char **startPtr,
  80.                 const char *end,
  81.                 const char **nextPtr,
  82.                 XML_Bool haveMore)
  83. {
  84.   const char *next;
  85.   int tok;
  86.   const char *s = *startPtr;
  87.   const char **eventPP;
  88.   const char **eventEndPP;
  89.   if (enc == encoding) {
  90.     eventPP = &eventPtr;
  91.     *eventPP = s;
  92.     eventEndPP = &eventEndPtr;
  93.   }
  94.   else {
  95.     eventPP = &(openInternalEntities->internalEventPtr);
  96.     eventEndPP = &(openInternalEntities->internalEventEndPtr);
  97.   }
  98.   *eventPP = s;
  99.   *startPtr = NULL;
  100.   tok = XmlIgnoreSectionTok(enc, s, end, &next);
  101.   *eventEndPP = next;
  102.   switch (tok) {
  103.   case XML_TOK_IGNORE_SECT:
  104.     if (defaultHandler)
  105.       reportDefault(parser, enc, s, next);
  106.     *startPtr = next;
  107.     *nextPtr = next;
  108.     if (ps_parsing == XML_FINISHED)
  109.       return XML_ERROR_ABORTED;
  110.     else
  111.       return XML_ERROR_NONE;
  112.   case XML_TOK_INVALID:
  113.     *eventPP = next;
  114.     return XML_ERROR_INVALID_TOKEN;
  115.   case XML_TOK_PARTIAL_CHAR:
  116.     if (haveMore) {
  117.       *nextPtr = s;
  118.       return XML_ERROR_NONE;
  119.     }
  120.     return XML_ERROR_PARTIAL_CHAR;
  121.   case XML_TOK_PARTIAL:
  122.   case XML_TOK_NONE:
  123.     if (haveMore) {
  124.       *nextPtr = s;
  125.       return XML_ERROR_NONE;
  126.     }
  127.     return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
  128.   default:
  129.     *eventPP = next;
  130.     return XML_ERROR_UNEXPECTED_STATE;
  131.   }
  132.   /* not reached */
  133. }
  134. #endif /* XML_DTD */
  135. static enum XML_Error
  136. initializeEncoding(XML_Parser parser)
  137. {
  138.   const char *s;
  139. #ifdef XML_UNICODE
  140.   char encodingBuf[128];
  141.   if (!protocolEncodingName)
  142.     s = NULL;
  143.   else {
  144.     int i;
  145.     for (i = 0; protocolEncodingName[i]; i++) {
  146.       if (i == sizeof(encodingBuf) - 1
  147.           || (protocolEncodingName[i] & ~0x7f) != 0) {
  148.         encodingBuf[0] = '';
  149.         break;
  150.       }
  151.       encodingBuf[i] = (char)protocolEncodingName[i];
  152.     }
  153.     encodingBuf[i] = '';
  154.     s = encodingBuf;
  155.   }
  156. #else
  157.   s = protocolEncodingName;
  158. #endif
  159.   if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s))
  160.     return XML_ERROR_NONE;
  161.   return handleUnknownEncoding(parser, protocolEncodingName);
  162. }
  163. static enum XML_Error
  164. processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
  165.                const char *s, const char *next)
  166. {
  167.   const char *encodingName = NULL;
  168.   const XML_Char *storedEncName = NULL;
  169.   const ENCODING *newEncoding = NULL;
  170.   const char *version = NULL;
  171.   const char *versionend;
  172.   const XML_Char *storedversion = NULL;
  173.   int standalone = -1;
  174.   if (!(ns
  175.         ? XmlParseXmlDeclNS
  176.         : XmlParseXmlDecl)(isGeneralTextEntity,
  177.                            encoding,
  178.                            s,
  179.                            next,
  180.                            &eventPtr,
  181.                            &version,
  182.                            &versionend,
  183.                            &encodingName,
  184.                            &newEncoding,
  185.                            &standalone)) {
  186.     if (isGeneralTextEntity)
  187.       return XML_ERROR_TEXT_DECL;
  188.     else
  189.       return XML_ERROR_XML_DECL;
  190.   }
  191.   if (!isGeneralTextEntity && standalone == 1) {
  192.     _dtd->standalone = XML_TRUE;
  193. #ifdef XML_DTD
  194.     if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
  195.       paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
  196. #endif /* XML_DTD */
  197.   }
  198.   if (xmlDeclHandler) {
  199.     if (encodingName != NULL) {
  200.       storedEncName = poolStoreString(&temp2Pool,
  201.                                       encoding,
  202.                                       encodingName,
  203.                                       encodingName
  204.                                       + XmlNameLength(encoding, encodingName));
  205.       if (!storedEncName)
  206.               return XML_ERROR_NO_MEMORY;
  207.       poolFinish(&temp2Pool);
  208.     }
  209.     if (version) {
  210.       storedversion = poolStoreString(&temp2Pool,
  211.                                       encoding,
  212.                                       version,
  213.                                       versionend - encoding->minBytesPerChar);
  214.       if (!storedversion)
  215.         return XML_ERROR_NO_MEMORY;
  216.     }
  217.     xmlDeclHandler(handlerArg, storedversion, storedEncName, standalone);
  218.   }
  219.   else if (defaultHandler)
  220.     reportDefault(parser, encoding, s, next);
  221.   if (protocolEncodingName == NULL) {
  222.     if (newEncoding) {
  223.       if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) {
  224.         eventPtr = encodingName;
  225.         return XML_ERROR_INCORRECT_ENCODING;
  226.       }
  227.       encoding = newEncoding;
  228.     }
  229.     else if (encodingName) {
  230.       enum XML_Error result;
  231.       if (!storedEncName) {
  232.         storedEncName = poolStoreString(
  233.           &temp2Pool, encoding, encodingName,
  234.           encodingName + XmlNameLength(encoding, encodingName));
  235.         if (!storedEncName)
  236.           return XML_ERROR_NO_MEMORY;
  237.       }
  238.       result = handleUnknownEncoding(parser, storedEncName);
  239.       poolClear(&temp2Pool);
  240.       if (result == XML_ERROR_UNKNOWN_ENCODING)
  241.         eventPtr = encodingName;
  242.       return result;
  243.     }
  244.   }
  245.   if (storedEncName || storedversion)
  246.     poolClear(&temp2Pool);
  247.   return XML_ERROR_NONE;
  248. }
  249. static enum XML_Error
  250. handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)
  251. {
  252.   if (unknownEncodingHandler) {
  253.     XML_Encoding info;
  254.     int i;
  255.     for (i = 0; i < 256; i++)
  256.       info.map[i] = -1;
  257.     info.convert = NULL;
  258.     info.data = NULL;
  259.     info.release = NULL;
  260.     if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName,
  261.                                &info)) {
  262.       ENCODING *enc;
  263.       unknownEncodingMem = MALLOC(XmlSizeOfUnknownEncoding());
  264.       if (!unknownEncodingMem) {
  265.         if (info.release)
  266.           info.release(info.data);
  267.         return XML_ERROR_NO_MEMORY;
  268.       }
  269.       enc = (ns
  270.              ? XmlInitUnknownEncodingNS
  271.              : XmlInitUnknownEncoding)(unknownEncodingMem,
  272.                                        info.map,
  273.                                        info.convert,
  274.                                        info.data);
  275.       if (enc) {
  276.         unknownEncodingData = info.data;
  277.         unknownEncodingRelease = info.release;
  278.         encoding = enc;
  279.         return XML_ERROR_NONE;
  280.       }
  281.     }
  282.     if (info.release != NULL)
  283.       info.release(info.data);
  284.   }
  285.   return XML_ERROR_UNKNOWN_ENCODING;
  286. }
  287. static enum XML_Error PTRCALL
  288. prologInitProcessor(XML_Parser parser,
  289.                     const char *s,
  290.                     const char *end,
  291.                     const char **nextPtr)
  292. {
  293.   enum XML_Error result = initializeEncoding(parser);
  294.   if (result != XML_ERROR_NONE)
  295.     return result;
  296.   processor = prologProcessor;
  297.   return prologProcessor(parser, s, end, nextPtr);
  298. }
  299. #ifdef XML_DTD
  300. static enum XML_Error PTRCALL
  301. externalParEntInitProcessor(XML_Parser parser,
  302.                             const char *s,
  303.                             const char *end,
  304.                             const char **nextPtr)
  305. {
  306.   enum XML_Error result = initializeEncoding(parser);
  307.   if (result != XML_ERROR_NONE)
  308.     return result;
  309.   /* we know now that XML_Parse(Buffer) has been called,
  310.      so we consider the external parameter entity read */
  311.   _dtd->paramEntityRead = XML_TRUE;
  312.   if (prologState.inEntityValue) {
  313.     processor = entityValueInitProcessor;
  314.     return entityValueInitProcessor(parser, s, end, nextPtr);
  315.   }
  316.   else {
  317.     processor = externalParEntProcessor;
  318.     return externalParEntProcessor(parser, s, end, nextPtr);
  319.   }
  320. }
  321. static enum XML_Error PTRCALL
  322. entityValueInitProcessor(XML_Parser parser,
  323.                          const char *s,
  324.                          const char *end,
  325.                          const char **nextPtr)
  326. {
  327.   int tok;
  328.   const char *start = s;
  329.   const char *next = start;
  330.   eventPtr = start;
  331.   for (;;) {  
  332.     tok = XmlPrologTok(encoding, start, end, &next);
  333.     eventEndPtr = next;
  334.     if (tok <= 0) {
  335.       if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
  336.         *nextPtr = s;
  337.         return XML_ERROR_NONE;
  338.       }
  339.       switch (tok) {
  340.       case XML_TOK_INVALID:
  341.         return XML_ERROR_INVALID_TOKEN;
  342.       case XML_TOK_PARTIAL:
  343.         return XML_ERROR_UNCLOSED_TOKEN;
  344.       case XML_TOK_PARTIAL_CHAR:
  345.         return XML_ERROR_PARTIAL_CHAR;
  346.       case XML_TOK_NONE:   /* start == end */
  347.       default:
  348.         break;
  349.       }
  350.       /* found end of entity value - can store it now */
  351.       return storeEntityValue(parser, encoding, s, end);
  352.     }
  353.     else if (tok == XML_TOK_XML_DECL) {
  354.       enum XML_Error result;
  355.       result = processXmlDecl(parser, 0, start, next);
  356.       if (result != XML_ERROR_NONE)
  357.         return result;
  358.       switch (ps_parsing) {
  359.       case XML_SUSPENDED: 
  360.         *nextPtr = next;
  361.         return XML_ERROR_NONE;
  362.       case XML_FINISHED:
  363.         return XML_ERROR_ABORTED;
  364.       default:
  365.         *nextPtr = next;
  366.       }
  367.       /* stop scanning for text declaration - we found one */
  368.       processor = entityValueProcessor;
  369.       return entityValueProcessor(parser, next, end, nextPtr);
  370.     }
  371.     /* If we are at the end of the buffer, this would cause XmlPrologTok to
  372.        return XML_TOK_NONE on the next call, which would then cause the
  373.        function to exit with *nextPtr set to s - that is what we want for other
  374.        tokens, but not for the BOM - we would rather like to skip it;
  375.        then, when this routine is entered the next time, XmlPrologTok will
  376.        return XML_TOK_INVALID, since the BOM is still in the buffer
  377.     */
  378.     else if (tok == XML_TOK_BOM && next == end && !ps_finalBuffer) {
  379.       *nextPtr = next;
  380.       return XML_ERROR_NONE;
  381.     }
  382.     start = next;
  383.     eventPtr = start;
  384.   }
  385. }
  386. static enum XML_Error PTRCALL
  387. externalParEntProcessor(XML_Parser parser,
  388.                         const char *s,
  389.                         const char *end,
  390.                         const char **nextPtr)
  391. {
  392.   const char *next = s;
  393.   int tok;
  394.   tok = XmlPrologTok(encoding, s, end, &next);
  395.   if (tok <= 0) {
  396.     if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
  397.       *nextPtr = s;
  398.       return XML_ERROR_NONE;
  399.     }
  400.     switch (tok) {
  401.     case XML_TOK_INVALID:
  402.       return XML_ERROR_INVALID_TOKEN;
  403.     case XML_TOK_PARTIAL:
  404.       return XML_ERROR_UNCLOSED_TOKEN;
  405.     case XML_TOK_PARTIAL_CHAR:
  406.       return XML_ERROR_PARTIAL_CHAR;
  407.     case XML_TOK_NONE:   /* start == end */
  408.     default:
  409.       break;
  410.     }
  411.   }
  412.   /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
  413.      However, when parsing an external subset, doProlog will not accept a BOM
  414.      as valid, and report a syntax error, so we have to skip the BOM
  415.   */
  416.   else if (tok == XML_TOK_BOM) {
  417.     s = next;
  418.     tok = XmlPrologTok(encoding, s, end, &next);
  419.   }
  420.   processor = prologProcessor;
  421.   return doProlog(parser, encoding, s, end, tok, next, 
  422.                   nextPtr, (XML_Bool)!ps_finalBuffer);
  423. }
  424. static enum XML_Error PTRCALL
  425. entityValueProcessor(XML_Parser parser,
  426.                      const char *s,
  427.                      const char *end,
  428.                      const char **nextPtr)
  429. {
  430.   const char *start = s;
  431.   const char *next = s;
  432.   const ENCODING *enc = encoding;
  433.   int tok;
  434.   for (;;) {
  435.     tok = XmlPrologTok(enc, start, end, &next);
  436.     if (tok <= 0) {
  437.       if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
  438.         *nextPtr = s;
  439.         return XML_ERROR_NONE;
  440.       }
  441.       switch (tok) {
  442.       case XML_TOK_INVALID:
  443.         return XML_ERROR_INVALID_TOKEN;
  444.       case XML_TOK_PARTIAL:
  445.         return XML_ERROR_UNCLOSED_TOKEN;
  446.       case XML_TOK_PARTIAL_CHAR:
  447.         return XML_ERROR_PARTIAL_CHAR;
  448.       case XML_TOK_NONE:   /* start == end */
  449.       default:
  450.         break;
  451.       }
  452.       /* found end of entity value - can store it now */
  453.       return storeEntityValue(parser, enc, s, end);
  454.     }
  455.     start = next;
  456.   }
  457. }
  458. #endif /* XML_DTD */
  459. static enum XML_Error PTRCALL
  460. prologProcessor(XML_Parser parser,
  461.                 const char *s,
  462.                 const char *end,
  463.                 const char **nextPtr)
  464. {
  465.   const char *next = s;
  466.   int tok = XmlPrologTok(encoding, s, end, &next);
  467.   return doProlog(parser, encoding, s, end, tok, next, 
  468.                   nextPtr, (XML_Bool)!ps_finalBuffer);
  469. }
  470. static enum XML_Error
  471. doProlog(XML_Parser parser,
  472.          const ENCODING *enc,
  473.          const char *s,
  474.          const char *end,
  475.          int tok,
  476.          const char *next,
  477.          const char **nextPtr,
  478.          XML_Bool haveMore)
  479. {
  480. #ifdef XML_DTD
  481.   static const XML_Char externalSubsetName[] = { ASCII_HASH , '' };
  482. #endif /* XML_DTD */
  483.   static const XML_Char atypeCDATA[] = 
  484.       { ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '' };
  485.   static const XML_Char atypeID[] = { ASCII_I, ASCII_D, '' };
  486.   static const XML_Char atypeIDREF[] =
  487.       { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '' };
  488.   static const XML_Char atypeIDREFS[] =
  489.       { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '' };
  490.   static const XML_Char atypeENTITY[] =
  491.       { ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '' };
  492.   static const XML_Char atypeENTITIES[] = { ASCII_E, ASCII_N,
  493.       ASCII_T, ASCII_I, ASCII_T, ASCII_I, ASCII_E, ASCII_S, '' };
  494.   static const XML_Char atypeNMTOKEN[] = {
  495.       ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '' };
  496.   static const XML_Char atypeNMTOKENS[] = { ASCII_N, ASCII_M, ASCII_T,
  497.       ASCII_O, ASCII_K, ASCII_E, ASCII_N, ASCII_S, '' };
  498.   static const XML_Char notationPrefix[] = { ASCII_N, ASCII_O, ASCII_T,
  499.       ASCII_A, ASCII_T, ASCII_I, ASCII_O, ASCII_N, ASCII_LPAREN, '' };
  500.   static const XML_Char enumValueSep[] = { ASCII_PIPE, '' };
  501.   static const XML_Char enumValueStart[] = { ASCII_LPAREN, '' };
  502.   /* save one level of indirection */
  503.   DTD * const dtd = _dtd; 
  504.   const char **eventPP;
  505.   const char **eventEndPP;
  506.   enum XML_Content_Quant quant;
  507.   if (enc == encoding) {
  508.     eventPP = &eventPtr;
  509.     eventEndPP = &eventEndPtr;
  510.   }
  511.   else {
  512.     eventPP = &(openInternalEntities->internalEventPtr);
  513.     eventEndPP = &(openInternalEntities->internalEventEndPtr);
  514.   }
  515.   for (;;) {
  516.     int role;
  517.     XML_Bool handleDefault = XML_TRUE;
  518.     *eventPP = s;
  519.     *eventEndPP = next;
  520.     if (tok <= 0) {
  521.       if (haveMore && tok != XML_TOK_INVALID) {
  522.         *nextPtr = s;
  523.         return XML_ERROR_NONE;
  524.       }
  525.       switch (tok) {
  526.       case XML_TOK_INVALID:
  527.         *eventPP = next;
  528.         return XML_ERROR_INVALID_TOKEN;
  529.       case XML_TOK_PARTIAL:
  530.         return XML_ERROR_UNCLOSED_TOKEN;
  531.       case XML_TOK_PARTIAL_CHAR:
  532.         return XML_ERROR_PARTIAL_CHAR;
  533.       case XML_TOK_NONE:
  534. #ifdef XML_DTD
  535.         /* for internal PE NOT referenced between declarations */
  536.         if (enc != encoding && !openInternalEntities->betweenDecl) {
  537.           *nextPtr = s;
  538.           return XML_ERROR_NONE;
  539.         }
  540.         /* WFC: PE Between Declarations - must check that PE contains
  541.            complete markup, not only for external PEs, but also for
  542.            internal PEs if the reference occurs between declarations.
  543.         */
  544.         if (isParamEntity || enc != encoding) {
  545.           if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc)
  546.               == XML_ROLE_ERROR)
  547.             return XML_ERROR_INCOMPLETE_PE;
  548.           *nextPtr = s;
  549.           return XML_ERROR_NONE;
  550.         }
  551. #endif /* XML_DTD */
  552.         return XML_ERROR_NO_ELEMENTS;
  553.       default:
  554.         tok = -tok;
  555.         next = end;
  556.         break;
  557.       }
  558.     }
  559.     role = XmlTokenRole(&prologState, tok, s, next, enc);
  560.     switch (role) {
  561.     case XML_ROLE_XML_DECL:
  562.       {
  563.         enum XML_Error result = processXmlDecl(parser, 0, s, next);
  564.         if (result != XML_ERROR_NONE)
  565.           return result;
  566.         enc = encoding;
  567.         handleDefault = XML_FALSE;
  568.       }
  569.       break;
  570.     case XML_ROLE_DOCTYPE_NAME:
  571.       if (startDoctypeDeclHandler) {
  572.         doctypeName = poolStoreString(&tempPool, enc, s, next);
  573.         if (!doctypeName)
  574.           return XML_ERROR_NO_MEMORY;
  575.         poolFinish(&tempPool);
  576.         doctypePubid = NULL;
  577.         handleDefault = XML_FALSE;
  578.       }
  579.       doctypeSysid = NULL; /* always initialize to NULL */
  580.       break;
  581.     case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:
  582.       if (startDoctypeDeclHandler) {
  583.         startDoctypeDeclHandler(handlerArg, doctypeName, doctypeSysid,
  584.                                 doctypePubid, 1);
  585.         doctypeName = NULL;
  586.         poolClear(&tempPool);
  587.         handleDefault = XML_FALSE;
  588.       }
  589.       break;
  590. #ifdef XML_DTD
  591.     case XML_ROLE_TEXT_DECL:
  592.       {
  593.         enum XML_Error result = processXmlDecl(parser, 1, s, next);
  594.         if (result != XML_ERROR_NONE)
  595.           return result;
  596.         enc = encoding;
  597.         handleDefault = XML_FALSE;
  598.       }
  599.       break;
  600. #endif /* XML_DTD */
  601.     case XML_ROLE_DOCTYPE_PUBLIC_ID:
  602. #ifdef XML_DTD
  603.       useForeignDTD = XML_FALSE;
  604.       declEntity = (ENTITY *)lookup(&dtd->paramEntities,
  605.                                     externalSubsetName,
  606.                                     sizeof(ENTITY));
  607.       if (!declEntity)
  608.         return XML_ERROR_NO_MEMORY;
  609. #endif /* XML_DTD */
  610.       dtd->hasParamEntityRefs = XML_TRUE;
  611.       if (startDoctypeDeclHandler) {
  612.         if (!XmlIsPublicId(enc, s, next, eventPP))
  613.           return XML_ERROR_PUBLICID;
  614.         doctypePubid = poolStoreString(&tempPool, enc,
  615.                                        s + enc->minBytesPerChar,
  616.                                        next - enc->minBytesPerChar);
  617.         if (!doctypePubid)
  618.           return XML_ERROR_NO_MEMORY;
  619.         normalizePublicId((XML_Char *)doctypePubid);
  620.         poolFinish(&tempPool);
  621.         handleDefault = XML_FALSE;
  622.         goto alreadyChecked;
  623.       }
  624.       /* fall through */
  625.     case XML_ROLE_ENTITY_PUBLIC_ID:
  626.       if (!XmlIsPublicId(enc, s, next, eventPP))
  627.         return XML_ERROR_PUBLICID;
  628.     alreadyChecked:
  629.       if (dtd->keepProcessing && declEntity) {
  630.         XML_Char *tem = poolStoreString(&dtd->pool,
  631.                                         enc,
  632.                                         s + enc->minBytesPerChar,
  633.                                         next - enc->minBytesPerChar);
  634.         if (!tem)
  635.           return XML_ERROR_NO_MEMORY;
  636.         normalizePublicId(tem);
  637.         declEntity->publicId = tem;
  638.         poolFinish(&dtd->pool);
  639.         if (entityDeclHandler)
  640.           handleDefault = XML_FALSE;
  641.       }
  642.       break;
  643.     case XML_ROLE_DOCTYPE_CLOSE:
  644.       if (doctypeName) {
  645.         startDoctypeDeclHandler(handlerArg, doctypeName,
  646.                                 doctypeSysid, doctypePubid, 0);
  647.         poolClear(&tempPool);
  648.         handleDefault = XML_FALSE;
  649.       }
  650.       /* doctypeSysid will be non-NULL in the case of a previous
  651.          XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler
  652.          was not set, indicating an external subset
  653.       */
  654. #ifdef XML_DTD
  655.       if (doctypeSysid || useForeignDTD) {
  656.         XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
  657.         dtd->hasParamEntityRefs = XML_TRUE;
  658.         if (paramEntityParsing && externalEntityRefHandler) {
  659.           ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities,
  660.                                             externalSubsetName,
  661.                                             sizeof(ENTITY));
  662.           if (!entity)
  663.             return XML_ERROR_NO_MEMORY;
  664.           if (useForeignDTD)
  665.             entity->base = curBase;
  666.           dtd->paramEntityRead = XML_FALSE;
  667.           if (!externalEntityRefHandler(externalEntityRefHandlerArg,
  668.                                         0,
  669.                                         entity->base,
  670.                                         entity->systemId,
  671.                                         entity->publicId))
  672.             return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
  673.           if (dtd->paramEntityRead) {
  674.             if (!dtd->standalone && 
  675.                 notStandaloneHandler && 
  676.                 !notStandaloneHandler(handlerArg))
  677.               return XML_ERROR_NOT_STANDALONE;
  678.           }
  679.           /* if we didn't read the foreign DTD then this means that there
  680.              is no external subset and we must reset dtd->hasParamEntityRefs
  681.           */
  682.           else if (!doctypeSysid)
  683.             dtd->hasParamEntityRefs = hadParamEntityRefs;
  684.           /* end of DTD - no need to update dtd->keepProcessing */
  685.         }
  686.         useForeignDTD = XML_FALSE;
  687.       }
  688. #endif /* XML_DTD */
  689.       if (endDoctypeDeclHandler) {
  690.         endDoctypeDeclHandler(handlerArg);
  691.         handleDefault = XML_FALSE;
  692.       }
  693.       break;
  694.     case XML_ROLE_INSTANCE_START:
  695. #ifdef XML_DTD
  696.       /* if there is no DOCTYPE declaration then now is the
  697.          last chance to read the foreign DTD
  698.       */
  699.       if (useForeignDTD) {
  700.         XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
  701.         dtd->hasParamEntityRefs = XML_TRUE;
  702.         if (paramEntityParsing && externalEntityRefHandler) {
  703.           ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities,
  704.                                             externalSubsetName,
  705.                                             sizeof(ENTITY));
  706.           if (!entity)
  707.             return XML_ERROR_NO_MEMORY;
  708.           entity->base = curBase;
  709.           dtd->paramEntityRead = XML_FALSE;
  710.           if (!externalEntityRefHandler(externalEntityRefHandlerArg,
  711.                                         0,
  712.                                         entity->base,
  713.                                         entity->systemId,
  714.                                         entity->publicId))
  715.             return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
  716.           if (dtd->paramEntityRead) {
  717.             if (!dtd->standalone &&
  718.                 notStandaloneHandler &&
  719.                 !notStandaloneHandler(handlerArg))
  720.               return XML_ERROR_NOT_STANDALONE;
  721.           }
  722.           /* if we didn't read the foreign DTD then this means that there
  723.              is no external subset and we must reset dtd->hasParamEntityRefs
  724.           */
  725.           else
  726.             dtd->hasParamEntityRefs = hadParamEntityRefs;
  727.           /* end of DTD - no need to update dtd->keepProcessing */
  728.         }
  729.       }
  730. #endif /* XML_DTD */
  731.       processor = contentProcessor;
  732.       return contentProcessor(parser, s, end, nextPtr);
  733.     case XML_ROLE_ATTLIST_ELEMENT_NAME:
  734.       declElementType = getElementType(parser, enc, s, next);
  735.       if (!declElementType)
  736.         return XML_ERROR_NO_MEMORY;
  737.       goto checkAttListDeclHandler;
  738.     case XML_ROLE_ATTRIBUTE_NAME:
  739.       declAttributeId = getAttributeId(parser, enc, s, next);
  740.       if (!declAttributeId)
  741.         return XML_ERROR_NO_MEMORY;
  742.       declAttributeIsCdata = XML_FALSE;
  743.       declAttributeType = NULL;
  744.       declAttributeIsId = XML_FALSE;
  745.       goto checkAttListDeclHandler;
  746.     case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
  747.       declAttributeIsCdata = XML_TRUE;
  748.       declAttributeType = atypeCDATA;
  749.       goto checkAttListDeclHandler;
  750.     case XML_ROLE_ATTRIBUTE_TYPE_ID:
  751.       declAttributeIsId = XML_TRUE;
  752.       declAttributeType = atypeID;
  753.       goto checkAttListDeclHandler;
  754.     case XML_ROLE_ATTRIBUTE_TYPE_IDREF:
  755.       declAttributeType = atypeIDREF;
  756.       goto checkAttListDeclHandler;
  757.     case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:
  758.       declAttributeType = atypeIDREFS;
  759.       goto checkAttListDeclHandler;
  760.     case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:
  761.       declAttributeType = atypeENTITY;
  762.       goto checkAttListDeclHandler;
  763.     case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:
  764.       declAttributeType = atypeENTITIES;
  765.       goto checkAttListDeclHandler;
  766.     case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:
  767.       declAttributeType = atypeNMTOKEN;
  768.       goto checkAttListDeclHandler;
  769.     case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:
  770.       declAttributeType = atypeNMTOKENS;
  771.     checkAttListDeclHandler:
  772.       if (dtd->keepProcessing && attlistDeclHandler)
  773.         handleDefault = XML_FALSE;
  774.       break;
  775.     case XML_ROLE_ATTRIBUTE_ENUM_VALUE:
  776.     case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:
  777.       if (dtd->keepProcessing && attlistDeclHandler) {
  778.         const XML_Char *prefix;
  779.         if (declAttributeType) {
  780.           prefix = enumValueSep;
  781.         }
  782.         else {
  783.           prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE
  784.                     ? notationPrefix
  785.                     : enumValueStart);
  786.         }
  787.         if (!poolAppendString(&tempPool, prefix))
  788.           return XML_ERROR_NO_MEMORY;
  789.         if (!poolAppend(&tempPool, enc, s, next))
  790.           return XML_ERROR_NO_MEMORY;
  791.         declAttributeType = tempPool.start;
  792.         handleDefault = XML_FALSE;
  793.       }
  794.       break;
  795.     case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
  796.     case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
  797.       if (dtd->keepProcessing) {
  798.         if (!defineAttribute(declElementType, declAttributeId,
  799.                              declAttributeIsCdata, declAttributeIsId,
  800.                              0, parser))
  801.           return XML_ERROR_NO_MEMORY;
  802.         if (attlistDeclHandler && declAttributeType) {
  803.           if (*declAttributeType == XML_T(ASCII_LPAREN)
  804.               || (*declAttributeType == XML_T(ASCII_N)
  805.                   && declAttributeType[1] == XML_T(ASCII_O))) {
  806.             /* Enumerated or Notation type */
  807.             if (!poolAppendChar(&tempPool, XML_T(ASCII_RPAREN))
  808.                 || !poolAppendChar(&tempPool, XML_T('')))
  809.               return XML_ERROR_NO_MEMORY;
  810.             declAttributeType = tempPool.start;
  811.             poolFinish(&tempPool);
  812.           }
  813.           *eventEndPP = s;
  814.           attlistDeclHandler(handlerArg, declElementType->name,
  815.                              declAttributeId->name, declAttributeType,
  816.                              0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
  817.           poolClear(&tempPool);
  818.           handleDefault = XML_FALSE;
  819.         }
  820.       }
  821.       break;
  822.     case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
  823.     case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
  824.       if (dtd->keepProcessing) {
  825.         const XML_Char *attVal;
  826.         enum XML_Error result =
  827.           storeAttributeValue(parser, enc, declAttributeIsCdata,
  828.                               s + enc->minBytesPerChar,
  829.                               next - enc->minBytesPerChar,
  830.                               &dtd->pool);
  831.         if (result)
  832.           return result;
  833.         attVal = poolStart(&dtd->pool);
  834.         poolFinish(&dtd->pool);
  835.         /* ID attributes aren't allowed to have a default */
  836.         if (!defineAttribute(declElementType, declAttributeId,
  837.                              declAttributeIsCdata, XML_FALSE, attVal, parser))
  838.           return XML_ERROR_NO_MEMORY;
  839.         if (attlistDeclHandler && declAttributeType) {
  840.           if (*declAttributeType == XML_T(ASCII_LPAREN)
  841.               || (*declAttributeType == XML_T(ASCII_N)
  842.                   && declAttributeType[1] == XML_T(ASCII_O))) {
  843.             /* Enumerated or Notation type */
  844.             if (!poolAppendChar(&tempPool, XML_T(ASCII_RPAREN))
  845.                 || !poolAppendChar(&tempPool, XML_T('')))
  846.               return XML_ERROR_NO_MEMORY;
  847.             declAttributeType = tempPool.start;
  848.             poolFinish(&tempPool);
  849.           }
  850.           *eventEndPP = s;
  851.           attlistDeclHandler(handlerArg, declElementType->name,
  852.                              declAttributeId->name, declAttributeType,
  853.                              attVal,
  854.                              role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);
  855.           poolClear(&tempPool);
  856.           handleDefault = XML_FALSE;
  857.         }
  858.       }
  859.       break;
  860.     case XML_ROLE_ENTITY_VALUE:
  861.       if (dtd->keepProcessing) {
  862.         enum XML_Error result = storeEntityValue(parser, enc,
  863.                                             s + enc->minBytesPerChar,
  864.                                             next - enc->minBytesPerChar);
  865.         if (declEntity) {
  866.           declEntity->textPtr = poolStart(&dtd->entityValuePool);
  867.           declEntity->textLen = (int)(poolLength(&dtd->entityValuePool));
  868.           poolFinish(&dtd->entityValuePool);
  869.           if (entityDeclHandler) {
  870.             *eventEndPP = s;
  871.             entityDeclHandler(handlerArg,
  872.                               declEntity->name,
  873.                               declEntity->is_param,
  874.                               declEntity->textPtr,
  875.                               declEntity->textLen,
  876.                               curBase, 0, 0, 0);
  877.             handleDefault = XML_FALSE;
  878.           }
  879.         }
  880.         else
  881.           poolDiscard(&dtd->entityValuePool);
  882.         if (result != XML_ERROR_NONE)
  883.           return result;
  884.       }
  885.       break;
  886.     case XML_ROLE_DOCTYPE_SYSTEM_ID:
  887. #ifdef XML_DTD
  888.       useForeignDTD = XML_FALSE;
  889. #endif /* XML_DTD */
  890.       dtd->hasParamEntityRefs = XML_TRUE;
  891.       if (startDoctypeDeclHandler) {
  892.         doctypeSysid = poolStoreString(&tempPool, enc,
  893.                                        s + enc->minBytesPerChar,
  894.                                        next - enc->minBytesPerChar);
  895.         if (doctypeSysid == NULL)
  896.           return XML_ERROR_NO_MEMORY;
  897.         poolFinish(&tempPool);
  898.         handleDefault = XML_FALSE;
  899.       }
  900. #ifdef XML_DTD
  901.       else
  902.         /* use externalSubsetName to make doctypeSysid non-NULL
  903.            for the case where no startDoctypeDeclHandler is set */
  904.         doctypeSysid = externalSubsetName;
  905. #endif /* XML_DTD */
  906.       if (!dtd->standalone
  907. #ifdef XML_DTD
  908.           && !paramEntityParsing
  909. #endif /* XML_DTD */
  910.           && notStandaloneHandler
  911.           && !notStandaloneHandler(handlerArg))
  912.         return XML_ERROR_NOT_STANDALONE;
  913. #ifndef XML_DTD
  914.       break;
  915. #else /* XML_DTD */
  916.       if (!declEntity) {
  917.         declEntity = (ENTITY *)lookup(&dtd->paramEntities,
  918.                                       externalSubsetName,
  919.                                       sizeof(ENTITY));
  920.         if (!declEntity)
  921.           return XML_ERROR_NO_MEMORY;
  922.         declEntity->publicId = NULL;
  923.       }
  924.       /* fall through */
  925. #endif /* XML_DTD */
  926.     case XML_ROLE_ENTITY_SYSTEM_ID:
  927.       if (dtd->keepProcessing && declEntity) {
  928.         declEntity->systemId = poolStoreString(&dtd->pool, enc,
  929.                                                s + enc->minBytesPerChar,
  930.                                                next - enc->minBytesPerChar);
  931.         if (!declEntity->systemId)
  932.           return XML_ERROR_NO_MEMORY;
  933.         declEntity->base = curBase;
  934.         poolFinish(&dtd->pool);
  935.         if (entityDeclHandler)
  936.           handleDefault = XML_FALSE;
  937.       }
  938.       break;
  939.     case XML_ROLE_ENTITY_COMPLETE:
  940.       if (dtd->keepProcessing && declEntity && entityDeclHandler) {
  941.         *eventEndPP = s;
  942.         entityDeclHandler(handlerArg,
  943.                           declEntity->name,
  944.                           declEntity->is_param,
  945.                           0,0,
  946.                           declEntity->base,
  947.                           declEntity->systemId,
  948.                           declEntity->publicId,
  949.                           0);
  950.         handleDefault = XML_FALSE;
  951.       }
  952.       break;
  953.     case XML_ROLE_ENTITY_NOTATION_NAME:
  954.       if (dtd->keepProcessing && declEntity) {
  955.         declEntity->notation = poolStoreString(&dtd->pool, enc, s, next);
  956.         if (!declEntity->notation)
  957.           return XML_ERROR_NO_MEMORY;
  958.         poolFinish(&dtd->pool);
  959.         if (unparsedEntityDeclHandler) {
  960.           *eventEndPP = s;
  961.           unparsedEntityDeclHandler(handlerArg,
  962.                                     declEntity->name,
  963.                                     declEntity->base,
  964.                                     declEntity->systemId,
  965.                                     declEntity->publicId,
  966.                                     declEntity->notation);
  967.           handleDefault = XML_FALSE;
  968.         }
  969.         else if (entityDeclHandler) {
  970.           *eventEndPP = s;
  971.           entityDeclHandler(handlerArg,
  972.                             declEntity->name,
  973.                             0,0,0,
  974.                             declEntity->base,
  975.                             declEntity->systemId,
  976.                             declEntity->publicId,
  977.                             declEntity->notation);
  978.           handleDefault = XML_FALSE;
  979.         }
  980.       }
  981.       break;
  982.     case XML_ROLE_GENERAL_ENTITY_NAME:
  983.       {
  984.         if (XmlPredefinedEntityName(enc, s, next)) {
  985.           declEntity = NULL;
  986.           break;
  987.         }
  988.         if (dtd->keepProcessing) {
  989.           const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
  990.           if (!name)
  991.             return XML_ERROR_NO_MEMORY;
  992.           declEntity = (ENTITY *)lookup(&dtd->generalEntities, name,
  993.                                         sizeof(ENTITY));
  994.           if (!declEntity)
  995.             return XML_ERROR_NO_MEMORY;
  996.           if (declEntity->name != name) {
  997.             poolDiscard(&dtd->pool);
  998.             declEntity = NULL;
  999.           }
  1000.           else {
  1001.             poolFinish(&dtd->pool);
  1002.             declEntity->publicId = NULL;
  1003.             declEntity->is_param = XML_FALSE;
  1004.             /* if we have a parent parser or are reading an internal parameter
  1005.                entity, then the entity declaration is not considered "internal"
  1006.             */
  1007.             declEntity->is_internal = !(parentParser || openInternalEntities);
  1008.             if (entityDeclHandler)
  1009.               handleDefault = XML_FALSE;
  1010.           }
  1011.         }
  1012.         else {
  1013.           poolDiscard(&dtd->pool);
  1014.           declEntity = NULL;
  1015.         }
  1016.       }
  1017.       break;
  1018.     case XML_ROLE_PARAM_ENTITY_NAME:
  1019. #ifdef XML_DTD
  1020.       if (dtd->keepProcessing) {
  1021.         const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
  1022.         if (!name)
  1023.           return XML_ERROR_NO_MEMORY;
  1024.         declEntity = (ENTITY *)lookup(&dtd->paramEntities,
  1025.                                            name, sizeof(ENTITY));
  1026.         if (!declEntity)
  1027.           return XML_ERROR_NO_MEMORY;
  1028.         if (declEntity->name != name) {
  1029.           poolDiscard(&dtd->pool);
  1030.           declEntity = NULL;
  1031.         }
  1032.         else {
  1033.           poolFinish(&dtd->pool);
  1034.           declEntity->publicId = NULL;
  1035.           declEntity->is_param = XML_TRUE;
  1036.           /* if we have a parent parser or are reading an internal parameter
  1037.              entity, then the entity declaration is not considered "internal"
  1038.           */
  1039.           declEntity->is_internal = !(parentParser || openInternalEntities);
  1040.           if (entityDeclHandler)
  1041.             handleDefault = XML_FALSE;
  1042.         }
  1043.       }
  1044.       else {
  1045.         poolDiscard(&dtd->pool);
  1046.         declEntity = NULL;
  1047.       }
  1048. #else /* not XML_DTD */
  1049.       declEntity = NULL;
  1050. #endif /* XML_DTD */
  1051.       break;
  1052.     case XML_ROLE_NOTATION_NAME:
  1053.       declNotationPublicId = NULL;
  1054.       declNotationName = NULL;
  1055.       if (notationDeclHandler) {
  1056.         declNotationName = poolStoreString(&tempPool, enc, s, next);
  1057.         if (!declNotationName)
  1058.           return XML_ERROR_NO_MEMORY;
  1059.         poolFinish(&tempPool);
  1060.         handleDefault = XML_FALSE;
  1061.       }
  1062.       break;
  1063.     case XML_ROLE_NOTATION_PUBLIC_ID:
  1064.       if (!XmlIsPublicId(enc, s, next, eventPP))
  1065.         return XML_ERROR_PUBLICID;
  1066.       if (declNotationName) {  /* means notationDeclHandler != NULL */
  1067.         XML_Char *tem = poolStoreString(&tempPool,
  1068.                                         enc,
  1069.                                         s + enc->minBytesPerChar,
  1070.                                         next - enc->minBytesPerChar);
  1071.         if (!tem)
  1072.           return XML_ERROR_NO_MEMORY;
  1073.         normalizePublicId(tem);
  1074.         declNotationPublicId = tem;
  1075.         poolFinish(&tempPool);
  1076.         handleDefault = XML_FALSE;
  1077.       }
  1078.       break;
  1079.     case XML_ROLE_NOTATION_SYSTEM_ID:
  1080.       if (declNotationName && notationDeclHandler) {
  1081.         const XML_Char *systemId
  1082.           = poolStoreString(&tempPool, enc,
  1083.                             s + enc->minBytesPerChar,
  1084.                             next - enc->minBytesPerChar);
  1085.         if (!systemId)
  1086.           return XML_ERROR_NO_MEMORY;
  1087.         *eventEndPP = s;
  1088.         notationDeclHandler(handlerArg,
  1089.                             declNotationName,
  1090.                             curBase,
  1091.                             systemId,
  1092.                             declNotationPublicId);
  1093.         handleDefault = XML_FALSE;
  1094.       }
  1095.       poolClear(&tempPool);
  1096.       break;
  1097.     case XML_ROLE_NOTATION_NO_SYSTEM_ID:
  1098.       if (declNotationPublicId && notationDeclHandler) {
  1099.         *eventEndPP = s;
  1100.         notationDeclHandler(handlerArg,
  1101.                             declNotationName,
  1102.                             curBase,
  1103.                             0,
  1104.                             declNotationPublicId);
  1105.         handleDefault = XML_FALSE;
  1106.       }
  1107.       poolClear(&tempPool);
  1108.       break;
  1109.     case XML_ROLE_ERROR:
  1110.       switch (tok) {
  1111.       case XML_TOK_PARAM_ENTITY_REF:
  1112.         /* PE references in internal subset are
  1113.            not allowed within declarations. */  
  1114.         return XML_ERROR_PARAM_ENTITY_REF;
  1115.       case XML_TOK_XML_DECL:
  1116.         return XML_ERROR_MISPLACED_XML_PI;
  1117.       default:
  1118.         return XML_ERROR_SYNTAX;
  1119.       }
  1120. #ifdef XML_DTD
  1121.     case XML_ROLE_IGNORE_SECT:
  1122.       {
  1123.         enum XML_Error result;
  1124.         if (defaultHandler)
  1125.           reportDefault(parser, enc, s, next);
  1126.         handleDefault = XML_FALSE;
  1127.         result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore);
  1128.         if (result != XML_ERROR_NONE)
  1129.           return result;
  1130.         else if (!next) {
  1131.           processor = ignoreSectionProcessor;
  1132.           return result;
  1133.         }
  1134.       }
  1135.       break;
  1136. #endif /* XML_DTD */
  1137.     case XML_ROLE_GROUP_OPEN:
  1138.       if (prologState.level >= groupSize) {
  1139.         if (groupSize) {
  1140.           char *temp = (char *)REALLOC(groupConnector, groupSize *= 2);
  1141.           if (temp == NULL)
  1142.             return XML_ERROR_NO_MEMORY;
  1143.           groupConnector = temp;
  1144.           if (dtd->scaffIndex) {
  1145.             int *temp = (int *)REALLOC(dtd->scaffIndex,
  1146.                           groupSize * sizeof(int));
  1147.             if (temp == NULL)
  1148.               return XML_ERROR_NO_MEMORY;
  1149.             dtd->scaffIndex = temp;
  1150.           }
  1151.         }
  1152.         else {
  1153.           groupConnector = (char *)MALLOC(groupSize = 32);
  1154.           if (!groupConnector)
  1155.             return XML_ERROR_NO_MEMORY;
  1156.         }
  1157.       }
  1158.       groupConnector[prologState.level] = 0;
  1159.       if (dtd->in_eldecl) {
  1160.         int myindex = nextScaffoldPart(parser);
  1161.         if (myindex < 0)
  1162.           return XML_ERROR_NO_MEMORY;
  1163.         dtd->scaffIndex[dtd->scaffLevel] = myindex;
  1164.         dtd->scaffLevel++;
  1165.         dtd->scaffold[myindex].type = XML_CTYPE_SEQ;
  1166.         if (elementDeclHandler)
  1167.           handleDefault = XML_FALSE;
  1168.       }
  1169.       break;
  1170.     case XML_ROLE_GROUP_SEQUENCE:
  1171.       if (groupConnector[prologState.level] == ASCII_PIPE)
  1172.         return XML_ERROR_SYNTAX;
  1173.       groupConnector[prologState.level] = ASCII_COMMA;
  1174.       if (dtd->in_eldecl && elementDeclHandler)
  1175.         handleDefault = XML_FALSE;
  1176.       break;
  1177.     case XML_ROLE_GROUP_CHOICE:
  1178.       if (groupConnector[prologState.level] == ASCII_COMMA)
  1179.         return XML_ERROR_SYNTAX;
  1180.       if (dtd->in_eldecl
  1181.           && !groupConnector[prologState.level]
  1182.           && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
  1183.               != XML_CTYPE_MIXED)
  1184.           ) {
  1185.         dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
  1186.             = XML_CTYPE_CHOICE;
  1187.         if (elementDeclHandler)
  1188.           handleDefault = XML_FALSE;
  1189.       }
  1190.       groupConnector[prologState.level] = ASCII_PIPE;
  1191.       break;
  1192.     case XML_ROLE_PARAM_ENTITY_REF:
  1193. #ifdef XML_DTD
  1194.     case XML_ROLE_INNER_PARAM_ENTITY_REF:
  1195.       dtd->hasParamEntityRefs = XML_TRUE;
  1196.       if (!paramEntityParsing)
  1197.         dtd->keepProcessing = dtd->standalone;
  1198.       else {
  1199.         const XML_Char *name;
  1200.         ENTITY *entity;
  1201.         name = poolStoreString(&dtd->pool, enc,
  1202.                                 s + enc->minBytesPerChar,
  1203.                                 next - enc->minBytesPerChar);
  1204.         if (!name)
  1205.           return XML_ERROR_NO_MEMORY;
  1206.         entity = (ENTITY *)lookup(&dtd->paramEntities, name, 0);
  1207.         poolDiscard(&dtd->pool);
  1208.         /* first, determine if a check for an existing declaration is needed;
  1209.            if yes, check that the entity exists, and that it is internal,
  1210.            otherwise call the skipped entity handler
  1211.         */
  1212.         if (prologState.documentEntity &&
  1213.             (dtd->standalone
  1214.              ? !openInternalEntities
  1215.              : !dtd->hasParamEntityRefs)) {
  1216.           if (!entity)
  1217.             return XML_ERROR_UNDEFINED_ENTITY;
  1218.           else if (!entity->is_internal)
  1219.             return XML_ERROR_ENTITY_DECLARED_IN_PE;
  1220.         }
  1221.         else if (!entity) {
  1222.           dtd->keepProcessing = dtd->standalone;
  1223.           /* cannot report skipped entities in declarations */
  1224.           if ((role == XML_ROLE_PARAM_ENTITY_REF) && skippedEntityHandler) {
  1225.             skippedEntityHandler(handlerArg, name, 1);
  1226.             handleDefault = XML_FALSE;
  1227.           }
  1228.           break;
  1229.         }
  1230.         if (entity->open)
  1231.           return XML_ERROR_RECURSIVE_ENTITY_REF;
  1232.         if (entity->textPtr) {
  1233.           enum XML_Error result;
  1234.           XML_Bool betweenDecl = 
  1235.             (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE);
  1236.           result = processInternalEntity(parser, entity, betweenDecl);
  1237.           if (result != XML_ERROR_NONE)
  1238.             return result;
  1239.           handleDefault = XML_FALSE;
  1240.           break;
  1241.         }
  1242.         if (externalEntityRefHandler) {
  1243.           dtd->paramEntityRead = XML_FALSE;
  1244.           entity->open = XML_TRUE;
  1245.           if (!externalEntityRefHandler(externalEntityRefHandlerArg,
  1246.                                         0,
  1247.                                         entity->base,
  1248.                                         entity->systemId,
  1249.                                         entity->publicId)) {
  1250.             entity->open = XML_FALSE;
  1251.             return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
  1252.           }
  1253.           entity->open = XML_FALSE;
  1254.           handleDefault = XML_FALSE;
  1255.           if (!dtd->paramEntityRead) {
  1256.             dtd->keepProcessing = dtd->standalone;
  1257.             break;
  1258.           }
  1259.         }
  1260.         else {
  1261.           dtd->keepProcessing = dtd->standalone;
  1262.           break;
  1263.         }
  1264.       }
  1265. #endif /* XML_DTD */
  1266.       if (!dtd->standalone &&
  1267.           notStandaloneHandler &&
  1268.           !notStandaloneHandler(handlerArg))
  1269.         return XML_ERROR_NOT_STANDALONE;
  1270.       break;
  1271.     /* Element declaration stuff */
  1272.     case XML_ROLE_ELEMENT_NAME:
  1273.       if (elementDeclHandler) {
  1274.         declElementType = getElementType(parser, enc, s, next);
  1275.         if (!declElementType)
  1276.           return XML_ERROR_NO_MEMORY;
  1277.         dtd->scaffLevel = 0;
  1278.         dtd->scaffCount = 0;
  1279.         dtd->in_eldecl = XML_TRUE;
  1280.         handleDefault = XML_FALSE;
  1281.       }
  1282.       break;
  1283.     case XML_ROLE_CONTENT_ANY:
  1284.     case XML_ROLE_CONTENT_EMPTY:
  1285.       if (dtd->in_eldecl) {
  1286.         if (elementDeclHandler) {
  1287.           XML_Content * content = (XML_Content *) MALLOC(sizeof(XML_Content));
  1288.           if (!content)
  1289.             return XML_ERROR_NO_MEMORY;
  1290.           content->quant = XML_CQUANT_NONE;
  1291.           content->name = NULL;
  1292.           content->numchildren = 0;
  1293.           content->children = NULL;
  1294.           content->type = ((role == XML_ROLE_CONTENT_ANY) ?
  1295.                            XML_CTYPE_ANY :
  1296.                            XML_CTYPE_EMPTY);
  1297.           *eventEndPP = s;
  1298.           elementDeclHandler(handlerArg, declElementType->name, content);
  1299.           handleDefault = XML_FALSE;
  1300.         }
  1301.         dtd->in_eldecl = XML_FALSE;
  1302.       }
  1303.       break;
  1304.     case XML_ROLE_CONTENT_PCDATA:
  1305.       if (dtd->in_eldecl) {
  1306.         dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
  1307.             = XML_CTYPE_MIXED;
  1308.         if (elementDeclHandler)
  1309.           handleDefault = XML_FALSE;
  1310.       }
  1311.       break;
  1312.     case XML_ROLE_CONTENT_ELEMENT:
  1313.       quant = XML_CQUANT_NONE;
  1314.       goto elementContent;
  1315.     case XML_ROLE_CONTENT_ELEMENT_OPT:
  1316.       quant = XML_CQUANT_OPT;
  1317.       goto elementContent;
  1318.     case XML_ROLE_CONTENT_ELEMENT_REP:
  1319.       quant = XML_CQUANT_REP;
  1320.       goto elementContent;
  1321.     case XML_ROLE_CONTENT_ELEMENT_PLUS:
  1322.       quant = XML_CQUANT_PLUS;
  1323.     elementContent:
  1324.       if (dtd->in_eldecl) {
  1325.         ELEMENT_TYPE *el;
  1326.         const XML_Char *name;
  1327.         int nameLen;
  1328.         const char *nxt = (quant == XML_CQUANT_NONE
  1329.                            ? next
  1330.                            : next - enc->minBytesPerChar);
  1331.         int myindex = nextScaffoldPart(parser);
  1332.         if (myindex < 0)
  1333.           return XML_ERROR_NO_MEMORY;
  1334.         dtd->scaffold[myindex].type = XML_CTYPE_NAME;
  1335.         dtd->scaffold[myindex].quant = quant;
  1336.         el = getElementType(parser, enc, s, nxt);
  1337.         if (!el)
  1338.           return XML_ERROR_NO_MEMORY;
  1339.         name = el->name;
  1340.         dtd->scaffold[myindex].name = name;
  1341.         nameLen = 0;
  1342.         for (; name[nameLen++]; );
  1343.         dtd->contentStringLen +=  nameLen;
  1344.         if (elementDeclHandler)
  1345.           handleDefault = XML_FALSE;
  1346.       }
  1347.       break;
  1348.     case XML_ROLE_GROUP_CLOSE:
  1349.       quant = XML_CQUANT_NONE;
  1350.       goto closeGroup;
  1351.     case XML_ROLE_GROUP_CLOSE_OPT:
  1352.       quant = XML_CQUANT_OPT;
  1353.       goto closeGroup;
  1354.     case XML_ROLE_GROUP_CLOSE_REP:
  1355.       quant = XML_CQUANT_REP;
  1356.       goto closeGroup;
  1357.     case XML_ROLE_GROUP_CLOSE_PLUS:
  1358.       quant = XML_CQUANT_PLUS;
  1359.     closeGroup:
  1360.       if (dtd->in_eldecl) {
  1361.         if (elementDeclHandler)
  1362.           handleDefault = XML_FALSE;
  1363.         dtd->scaffLevel--;
  1364.         dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant;
  1365.         if (dtd->scaffLevel == 0) {
  1366.           if (!handleDefault) {
  1367.             XML_Content *model = build_model(parser);
  1368.             if (!model)
  1369.               return XML_ERROR_NO_MEMORY;
  1370.             *eventEndPP = s;
  1371.             elementDeclHandler(handlerArg, declElementType->name, model);
  1372.           }
  1373.           dtd->in_eldecl = XML_FALSE;
  1374.           dtd->contentStringLen = 0;
  1375.         }
  1376.       }
  1377.       break;
  1378.       /* End element declaration stuff */
  1379.     case XML_ROLE_PI:
  1380.       if (!reportProcessingInstruction(parser, enc, s, next))
  1381.         return XML_ERROR_NO_MEMORY;
  1382.       handleDefault = XML_FALSE;
  1383.       break;
  1384.     case XML_ROLE_COMMENT:
  1385.       if (!reportComment(parser, enc, s, next))
  1386.         return XML_ERROR_NO_MEMORY;
  1387.       handleDefault = XML_FALSE;
  1388.       break;
  1389.     case XML_ROLE_NONE:
  1390.       switch (tok) {
  1391.       case XML_TOK_BOM:
  1392.         handleDefault = XML_FALSE;
  1393.         break;
  1394.       }
  1395.       break;
  1396.     case XML_ROLE_DOCTYPE_NONE:
  1397.       if (startDoctypeDeclHandler)
  1398.         handleDefault = XML_FALSE;
  1399.       break;
  1400.     case XML_ROLE_ENTITY_NONE:
  1401.       if (dtd->keepProcessing && entityDeclHandler)
  1402.         handleDefault = XML_FALSE;
  1403.       break;
  1404.     case XML_ROLE_NOTATION_NONE:
  1405.       if (notationDeclHandler)
  1406.         handleDefault = XML_FALSE;
  1407.       break;
  1408.     case XML_ROLE_ATTLIST_NONE:
  1409.       if (dtd->keepProcessing && attlistDeclHandler)
  1410.         handleDefault = XML_FALSE;
  1411.       break;
  1412.     case XML_ROLE_ELEMENT_NONE:
  1413.       if (elementDeclHandler)
  1414.         handleDefault = XML_FALSE;
  1415.       break;
  1416.     } /* end of big switch */
  1417.     if (handleDefault && defaultHandler)
  1418.       reportDefault(parser, enc, s, next);
  1419.     switch (ps_parsing) {
  1420.     case XML_SUSPENDED: 
  1421.       *nextPtr = next;
  1422.       return XML_ERROR_NONE;
  1423.     case XML_FINISHED:
  1424.       return XML_ERROR_ABORTED;
  1425.     default:
  1426.       s = next;
  1427.       tok = XmlPrologTok(enc, s, end, &next);
  1428.     }
  1429.   }
  1430.   /* not reached */
  1431. }
  1432. static enum XML_Error PTRCALL
  1433. epilogProcessor(XML_Parser parser,
  1434.                 const char *s,
  1435.                 const char *end,
  1436.                 const char **nextPtr)
  1437. {
  1438.   processor = epilogProcessor;
  1439.   eventPtr = s;
  1440.   for (;;) {
  1441.     const char *next = NULL;
  1442.     int tok = XmlPrologTok(encoding, s, end, &next);
  1443.     eventEndPtr = next;
  1444.     switch (tok) {
  1445.     /* report partial linebreak - it might be the last token */
  1446.     case -XML_TOK_PROLOG_S:
  1447.       if (defaultHandler) {
  1448.         reportDefault(parser, encoding, s, next);
  1449.         if (ps_parsing == XML_FINISHED)
  1450.           return XML_ERROR_ABORTED;
  1451.       }
  1452.       *nextPtr = next;
  1453.       return XML_ERROR_NONE;
  1454.     case XML_TOK_NONE:
  1455.       *nextPtr = s;
  1456.       return XML_ERROR_NONE;
  1457.     case XML_TOK_PROLOG_S:
  1458.       if (defaultHandler)
  1459.         reportDefault(parser, encoding, s, next);
  1460.       break;
  1461.     case XML_TOK_PI:
  1462.       if (!reportProcessingInstruction(parser, encoding, s, next))
  1463.         return XML_ERROR_NO_MEMORY;
  1464.       break;
  1465.     case XML_TOK_COMMENT:
  1466.       if (!reportComment(parser, encoding, s, next))
  1467.         return XML_ERROR_NO_MEMORY;
  1468.       break;
  1469.     case XML_TOK_INVALID:
  1470.       eventPtr = next;
  1471.       return XML_ERROR_INVALID_TOKEN;
  1472.     case XML_TOK_PARTIAL:
  1473.       if (!ps_finalBuffer) {
  1474.         *nextPtr = s;
  1475.         return XML_ERROR_NONE;
  1476.       }
  1477.       return XML_ERROR_UNCLOSED_TOKEN;
  1478.     case XML_TOK_PARTIAL_CHAR:
  1479.       if (!ps_finalBuffer) {
  1480.         *nextPtr = s;
  1481.         return XML_ERROR_NONE;
  1482.       }
  1483.       return XML_ERROR_PARTIAL_CHAR;
  1484.     default:
  1485.       return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
  1486.     }
  1487.     eventPtr = s = next;
  1488.     switch (ps_parsing) {
  1489.     case XML_SUSPENDED: 
  1490.       *nextPtr = next;
  1491.       return XML_ERROR_NONE;
  1492.     case XML_FINISHED:
  1493.       return XML_ERROR_ABORTED;
  1494.     default: ;
  1495.     }
  1496.   }
  1497. }
  1498. static enum XML_Error
  1499. processInternalEntity(XML_Parser parser, ENTITY *entity,
  1500.                       XML_Bool betweenDecl)
  1501. {
  1502.   const char *textStart, *textEnd;
  1503.   const char *next;
  1504.   enum XML_Error result;
  1505.   OPEN_INTERNAL_ENTITY *openEntity;
  1506.   if (freeInternalEntities) {
  1507.     openEntity = freeInternalEntities;
  1508.     freeInternalEntities = openEntity->next;
  1509.   }
  1510.   else {
  1511.     openEntity = (OPEN_INTERNAL_ENTITY *)MALLOC(sizeof(OPEN_INTERNAL_ENTITY));
  1512.     if (!openEntity)
  1513.       return XML_ERROR_NO_MEMORY;
  1514.   }
  1515.   entity->open = XML_TRUE;
  1516.   entity->processed = 0;
  1517.   openEntity->next = openInternalEntities;
  1518.   openInternalEntities = openEntity;
  1519.   openEntity->entity = entity;
  1520.   openEntity->startTagLevel = tagLevel;
  1521.   openEntity->betweenDecl = betweenDecl;
  1522.   openEntity->internalEventPtr = NULL;
  1523.   openEntity->internalEventEndPtr = NULL;
  1524.   textStart = (char *)entity->textPtr;
  1525.   textEnd = (char *)(entity->textPtr + entity->textLen);
  1526. #ifdef XML_DTD
  1527.   if (entity->is_param) {
  1528.     int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);
  1529.     result = doProlog(parser, internalEncoding, textStart, textEnd, tok, 
  1530.                       next, &next, XML_FALSE);
  1531.   }
  1532.   else 
  1533. #endif /* XML_DTD */
  1534.     result = doContent(parser, tagLevel, internalEncoding, textStart, 
  1535.                        textEnd, &next, XML_FALSE);
  1536.   if (result == XML_ERROR_NONE) {
  1537.     if (textEnd != next && ps_parsing == XML_SUSPENDED) {
  1538.       entity->processed = (int)(next - textStart);
  1539.       processor = internalEntityProcessor;
  1540.     }
  1541.     else {
  1542.       entity->open = XML_FALSE;
  1543.       openInternalEntities = openEntity->next;
  1544.       /* put openEntity back in list of free instances */
  1545.       openEntity->next = freeInternalEntities;
  1546.       freeInternalEntities = openEntity;
  1547.     }
  1548.   }
  1549.   return result;
  1550. }
  1551. static enum XML_Error PTRCALL
  1552. internalEntityProcessor(XML_Parser parser,
  1553.                         const char *s,
  1554.                         const char *end,
  1555.                         const char **nextPtr)
  1556. {
  1557.   ENTITY *entity;
  1558.   const char *textStart, *textEnd;
  1559.   const char *next;
  1560.   enum XML_Error result;
  1561.   OPEN_INTERNAL_ENTITY *openEntity = openInternalEntities;
  1562.   if (!openEntity)
  1563.     return XML_ERROR_UNEXPECTED_STATE;
  1564.   entity = openEntity->entity;
  1565.   textStart = ((char *)entity->textPtr) + entity->processed;
  1566.   textEnd = (char *)(entity->textPtr + entity->textLen);
  1567. #ifdef XML_DTD
  1568.   if (entity->is_param) {
  1569.     int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);
  1570.     result = doProlog(parser, internalEncoding, textStart, textEnd, tok, 
  1571.                       next, &next, XML_FALSE);
  1572.   }
  1573.   else
  1574. #endif /* XML_DTD */
  1575.     result = doContent(parser, openEntity->startTagLevel, internalEncoding, 
  1576.                        textStart, textEnd, &next, XML_FALSE);  
  1577.   if (result != XML_ERROR_NONE)
  1578.     return result;
  1579.   else if (textEnd != next && ps_parsing == XML_SUSPENDED) {
  1580.     entity->processed = (int)(next - (char *)entity->textPtr);
  1581.     return result;
  1582.   }
  1583.   else {
  1584.     entity->open = XML_FALSE;
  1585.     openInternalEntities = openEntity->next;
  1586.     /* put openEntity back in list of free instances */
  1587.     openEntity->next = freeInternalEntities;
  1588.     freeInternalEntities = openEntity;
  1589.   }
  1590. #ifdef XML_DTD
  1591.   if (entity->is_param) {
  1592.     int tok;
  1593.     processor = prologProcessor;
  1594.     tok = XmlPrologTok(encoding, s, end, &next);
  1595.     return doProlog(parser, encoding, s, end, tok, next, nextPtr, 
  1596.                     (XML_Bool)!ps_finalBuffer);
  1597.   }
  1598.   else
  1599. #endif /* XML_DTD */
  1600.   {
  1601.     processor = contentProcessor;
  1602.     /* see externalEntityContentProcessor vs contentProcessor */
  1603.     return doContent(parser, parentParser ? 1 : 0, encoding, s, end,
  1604.                      nextPtr, (XML_Bool)!ps_finalBuffer); 
  1605.   }  
  1606. }
  1607. static enum XML_Error PTRCALL
  1608. errorProcessor(XML_Parser parser,
  1609.                const char *s,
  1610.                const char *end,
  1611.                const char **nextPtr)
  1612. {
  1613.   return errorCode;
  1614. }
  1615. static enum XML_Error
  1616. storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
  1617.                     const char *ptr, const char *end,
  1618.                     STRING_POOL *pool)
  1619. {
  1620.   enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr,
  1621.                                                end, pool);
  1622.   if (result)
  1623.     return result;
  1624.   if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
  1625.     poolChop(pool);
  1626.   if (!poolAppendChar(pool, XML_T('')))
  1627.     return XML_ERROR_NO_MEMORY;
  1628.   return XML_ERROR_NONE;
  1629. }
  1630. static enum XML_Error
  1631. appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
  1632.                      const char *ptr, const char *end,
  1633.                      STRING_POOL *pool)
  1634. {
  1635.   DTD * const dtd = _dtd;  /* save one level of indirection */
  1636.   for (;;) {
  1637.     const char *next;
  1638.     int tok = XmlAttributeValueTok(enc, ptr, end, &next);
  1639.     switch (tok) {
  1640.     case XML_TOK_NONE:
  1641.       return XML_ERROR_NONE;
  1642.     case XML_TOK_INVALID:
  1643.       if (enc == encoding)
  1644.         eventPtr = next;
  1645.       return XML_ERROR_INVALID_TOKEN;
  1646.     case XML_TOK_PARTIAL:
  1647.       if (enc == encoding)
  1648.         eventPtr = ptr;
  1649.       return XML_ERROR_INVALID_TOKEN;
  1650.     case XML_TOK_CHAR_REF:
  1651.       {
  1652.         XML_Char buf[XML_ENCODE_MAX];
  1653.         int i;
  1654.         int n = XmlCharRefNumber(enc, ptr);
  1655.         if (n < 0) {
  1656.           if (enc == encoding)
  1657.             eventPtr = ptr;
  1658.           return XML_ERROR_BAD_CHAR_REF;
  1659.         }
  1660.         if (!isCdata
  1661.             && n == 0x20 /* space */
  1662.             && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
  1663.           break;
  1664.         n = XmlEncode(n, (ICHAR *)buf);
  1665.         if (!n) {
  1666.           if (enc == encoding)
  1667.             eventPtr = ptr;
  1668.           return XML_ERROR_BAD_CHAR_REF;
  1669.         }
  1670.         for (i = 0; i < n; i++) {
  1671.           if (!poolAppendChar(pool, buf[i]))
  1672.             return XML_ERROR_NO_MEMORY;
  1673.         }
  1674.       }
  1675.       break;
  1676.     case XML_TOK_DATA_CHARS:
  1677.       if (!poolAppend(pool, enc, ptr, next))
  1678.         return XML_ERROR_NO_MEMORY;
  1679.       break;
  1680.     case XML_TOK_TRAILING_CR:
  1681.       next = ptr + enc->minBytesPerChar;
  1682.       /* fall through */
  1683.     case XML_TOK_ATTRIBUTE_VALUE_S:
  1684.     case XML_TOK_DATA_NEWLINE:
  1685.       if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
  1686.         break;
  1687.       if (!poolAppendChar(pool, 0x20))
  1688.         return XML_ERROR_NO_MEMORY;
  1689.       break;
  1690.     case XML_TOK_ENTITY_REF:
  1691.       {
  1692.         const XML_Char *name;
  1693.         ENTITY *entity;
  1694.         char checkEntityDecl;
  1695.         XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
  1696.                                               ptr + enc->minBytesPerChar,
  1697.                                               next - enc->minBytesPerChar);
  1698.         if (ch) {
  1699.           if (!poolAppendChar(pool, ch))
  1700.                 return XML_ERROR_NO_MEMORY;
  1701.           break;
  1702.         }
  1703.         name = poolStoreString(&temp2Pool, enc,
  1704.                                ptr + enc->minBytesPerChar,
  1705.                                next - enc->minBytesPerChar);
  1706.         if (!name)
  1707.           return XML_ERROR_NO_MEMORY;
  1708.         entity = (ENTITY *)lookup(&dtd->generalEntities, name, 0);
  1709.         poolDiscard(&temp2Pool);
  1710.         /* First, determine if a check for an existing declaration is needed;
  1711.            if yes, check that the entity exists, and that it is internal.
  1712.         */
  1713.         if (pool == &dtd->pool)  /* are we called from prolog? */
  1714.           checkEntityDecl =
  1715. #ifdef XML_DTD
  1716.               prologState.documentEntity &&
  1717. #endif /* XML_DTD */
  1718.               (dtd->standalone
  1719.                ? !openInternalEntities
  1720.                : !dtd->hasParamEntityRefs);
  1721.         else /* if (pool == &tempPool): we are called from content */
  1722.           checkEntityDecl = !dtd->hasParamEntityRefs || dtd->standalone;
  1723.         if (checkEntityDecl) {
  1724.           if (!entity)
  1725.             return XML_ERROR_UNDEFINED_ENTITY;
  1726.           else if (!entity->is_internal)
  1727.             return XML_ERROR_ENTITY_DECLARED_IN_PE;
  1728.         }
  1729.         else if (!entity) {
  1730.           /* Cannot report skipped entity here - see comments on
  1731.              skippedEntityHandler.
  1732.           if (skippedEntityHandler)
  1733.             skippedEntityHandler(handlerArg, name, 0);
  1734.           */
  1735.           /* Cannot call the default handler because this would be
  1736.              out of sync with the call to the startElementHandler.
  1737.           if ((pool == &tempPool) && defaultHandler)
  1738.             reportDefault(parser, enc, ptr, next);
  1739.           */
  1740.           break;
  1741.         }
  1742.         if (entity->open) {
  1743.           if (enc == encoding)
  1744.             eventPtr = ptr;
  1745.           return XML_ERROR_RECURSIVE_ENTITY_REF;
  1746.         }
  1747.         if (entity->notation) {
  1748.           if (enc == encoding)
  1749.             eventPtr = ptr;
  1750.           return XML_ERROR_BINARY_ENTITY_REF;
  1751.         }
  1752.         if (!entity->textPtr) {
  1753.           if (enc == encoding)
  1754.             eventPtr = ptr;
  1755.               return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
  1756.         }
  1757.         else {
  1758.           enum XML_Error result;
  1759.           const XML_Char *textEnd = entity->textPtr + entity->textLen;
  1760.           entity->open = XML_TRUE;
  1761.           result = appendAttributeValue(parser, internalEncoding, isCdata,
  1762.                                         (char *)entity->textPtr,
  1763.                                         (char *)textEnd, pool);
  1764.           entity->open = XML_FALSE;
  1765.           if (result)
  1766.             return result;
  1767.         }
  1768.       }
  1769.       break;
  1770.     default:
  1771.       if (enc == encoding)
  1772.         eventPtr = ptr;
  1773.       return XML_ERROR_UNEXPECTED_STATE;
  1774.     }
  1775.     ptr = next;
  1776.   }
  1777.   /* not reached */
  1778. }
  1779. static enum XML_Error
  1780. storeEntityValue(XML_Parser parser,
  1781.                  const ENCODING *enc,
  1782.                  const char *entityTextPtr,
  1783.                  const char *entityTextEnd)
  1784. {
  1785.   DTD * const dtd = _dtd;  /* save one level of indirection */
  1786.   STRING_POOL *pool = &(dtd->entityValuePool);
  1787.   enum XML_Error result = XML_ERROR_NONE;
  1788. #ifdef XML_DTD
  1789.   int oldInEntityValue = prologState.inEntityValue;
  1790.   prologState.inEntityValue = 1;
  1791. #endif /* XML_DTD */
  1792.   /* never return Null for the value argument in EntityDeclHandler,
  1793.      since this would indicate an external entity; therefore we
  1794.      have to make sure that entityValuePool.start is not null */
  1795.   if (!pool->blocks) {
  1796.     if (!poolGrow(pool))
  1797.       return XML_ERROR_NO_MEMORY;
  1798.   }
  1799.   for (;;) {
  1800.     const char *next;
  1801.     int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
  1802.     switch (tok) {
  1803.     case XML_TOK_PARAM_ENTITY_REF:
  1804. #ifdef XML_DTD
  1805.       if (isParamEntity || enc != encoding) {
  1806.         const XML_Char *name;
  1807.         ENTITY *entity;
  1808.         name = poolStoreString(&tempPool, enc,
  1809.                                entityTextPtr + enc->minBytesPerChar,
  1810.                                next - enc->minBytesPerChar);
  1811.         if (!name) {
  1812.           result = XML_ERROR_NO_MEMORY;
  1813.           goto endEntityValue;
  1814.         }
  1815.         entity = (ENTITY *)lookup(&dtd->paramEntities, name, 0);
  1816.         poolDiscard(&tempPool);
  1817.         if (!entity) {
  1818.           /* not a well-formedness error - see XML 1.0: WFC Entity Declared */
  1819.           /* cannot report skipped entity here - see comments on
  1820.              skippedEntityHandler
  1821.           if (skippedEntityHandler)
  1822.             skippedEntityHandler(handlerArg, name, 0);
  1823.           */
  1824.           dtd->keepProcessing = dtd->standalone;
  1825.           goto endEntityValue;
  1826.         }
  1827.         if (entity->open) {
  1828.           if (enc == encoding)
  1829.             eventPtr = entityTextPtr;
  1830.           result = XML_ERROR_RECURSIVE_ENTITY_REF;
  1831.           goto endEntityValue;
  1832.         }
  1833.         if (entity->systemId) {
  1834.           if (externalEntityRefHandler) {
  1835.             dtd->paramEntityRead = XML_FALSE;
  1836.             entity->open = XML_TRUE;
  1837.             if (!externalEntityRefHandler(externalEntityRefHandlerArg,
  1838.                                           0,
  1839.                                           entity->base,
  1840.                                           entity->systemId,
  1841.                                           entity->publicId)) {
  1842.               entity->open = XML_FALSE;
  1843.               result = XML_ERROR_EXTERNAL_ENTITY_HANDLING;
  1844.               goto endEntityValue;
  1845.             }
  1846.             entity->open = XML_FALSE;
  1847.             if (!dtd->paramEntityRead)
  1848.               dtd->keepProcessing = dtd->standalone;
  1849.           }
  1850.           else
  1851.             dtd->keepProcessing = dtd->standalone;
  1852.         }
  1853.         else {
  1854.           entity->open = XML_TRUE;
  1855.           result = storeEntityValue(parser,
  1856.                                     internalEncoding,
  1857.                                     (char *)entity->textPtr,
  1858.                                     (char *)(entity->textPtr
  1859.                                              + entity->textLen));
  1860.           entity->open = XML_FALSE;
  1861.           if (result)
  1862.             goto endEntityValue;
  1863.         }
  1864.         break;
  1865.       }
  1866. #endif /* XML_DTD */
  1867.       /* In the internal subset, PE references are not legal
  1868.          within markup declarations, e.g entity values in this case. */
  1869.       eventPtr = entityTextPtr;
  1870.       result = XML_ERROR_PARAM_ENTITY_REF;
  1871.       goto endEntityValue;
  1872.     case XML_TOK_NONE:
  1873.       result = XML_ERROR_NONE;
  1874.       goto endEntityValue;
  1875.     case XML_TOK_ENTITY_REF:
  1876.     case XML_TOK_DATA_CHARS:
  1877.       if (!poolAppend(pool, enc, entityTextPtr, next)) {
  1878.         result = XML_ERROR_NO_MEMORY;
  1879.         goto endEntityValue;
  1880.       }
  1881.       break;
  1882.     case XML_TOK_TRAILING_CR:
  1883.       next = entityTextPtr + enc->minBytesPerChar;
  1884.       /* fall through */
  1885.     case XML_TOK_DATA_NEWLINE:
  1886.       if (pool->end == pool->ptr && !poolGrow(pool)) {
  1887.               result = XML_ERROR_NO_MEMORY;
  1888.         goto endEntityValue;
  1889.       }
  1890.       *(pool->ptr)++ = 0xA;
  1891.       break;
  1892.     case XML_TOK_CHAR_REF:
  1893.       {
  1894.         XML_Char buf[XML_ENCODE_MAX];
  1895.         int i;
  1896.         int n = XmlCharRefNumber(enc, entityTextPtr);
  1897.         if (n < 0) {
  1898.           if (enc == encoding)
  1899.             eventPtr = entityTextPtr;
  1900.           result = XML_ERROR_BAD_CHAR_REF;
  1901.           goto endEntityValue;
  1902.         }
  1903.         n = XmlEncode(n, (ICHAR *)buf);
  1904.         if (!n) {
  1905.           if (enc == encoding)
  1906.             eventPtr = entityTextPtr;
  1907.           result = XML_ERROR_BAD_CHAR_REF;
  1908.           goto endEntityValue;
  1909.         }
  1910.         for (i = 0; i < n; i++) {
  1911.           if (pool->end == pool->ptr && !poolGrow(pool)) {
  1912.             result = XML_ERROR_NO_MEMORY;
  1913.             goto endEntityValue;
  1914.           }
  1915.           *(pool->ptr)++ = buf[i];
  1916.         }
  1917.       }
  1918.       break;
  1919.     case XML_TOK_PARTIAL:
  1920.       if (enc == encoding)
  1921.         eventPtr = entityTextPtr;
  1922.       result = XML_ERROR_INVALID_TOKEN;
  1923.       goto endEntityValue;
  1924.     case XML_TOK_INVALID:
  1925.       if (enc == encoding)
  1926.         eventPtr = next;
  1927.       result = XML_ERROR_INVALID_TOKEN;
  1928.       goto endEntityValue;
  1929.     default:
  1930.       if (enc == encoding)
  1931.         eventPtr = entityTextPtr;
  1932.       result = XML_ERROR_UNEXPECTED_STATE;
  1933.       goto endEntityValue;
  1934.     }
  1935.     entityTextPtr = next;
  1936.   }
  1937. endEntityValue:
  1938. #ifdef XML_DTD
  1939.   prologState.inEntityValue = oldInEntityValue;
  1940. #endif /* XML_DTD */
  1941.   return result;
  1942. }
  1943. static void FASTCALL
  1944. normalizeLines(XML_Char *s)
  1945. {
  1946.   XML_Char *p;
  1947.   for (;; s++) {
  1948.     if (*s == XML_T(''))
  1949.       return;
  1950.     if (*s == 0xD)
  1951.       break;
  1952.   }
  1953.   p = s;
  1954.   do {
  1955.     if (*s == 0xD) {
  1956.       *p++ = 0xA;
  1957.       if (*++s == 0xA)
  1958.         s++;
  1959.     }
  1960.     else
  1961.       *p++ = *s++;
  1962.   } while (*s);
  1963.   *p = XML_T('');
  1964. }
  1965. static int
  1966. reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
  1967.                             const char *start, const char *end)
  1968. {
  1969.   const XML_Char *target;
  1970.   XML_Char *data;
  1971.   const char *tem;
  1972.   if (!processingInstructionHandler) {
  1973.     if (defaultHandler)
  1974.       reportDefault(parser, enc, start, end);
  1975.     return 1;
  1976.   }
  1977.   start += enc->minBytesPerChar * 2;
  1978.   tem = start + XmlNameLength(enc, start);
  1979.   target = poolStoreString(&tempPool, enc, start, tem);
  1980.   if (!target)
  1981.     return 0;
  1982.   poolFinish(&tempPool);
  1983.   data = poolStoreString(&tempPool, enc,
  1984.                         XmlSkipS(enc, tem),
  1985.                         end - enc->minBytesPerChar*2);
  1986.   if (!data)
  1987.     return 0;
  1988.   normalizeLines(data);
  1989.   processingInstructionHandler(handlerArg, target, data);
  1990.   poolClear(&tempPool);
  1991.   return 1;
  1992. }
  1993. static int
  1994. reportComment(XML_Parser parser, const ENCODING *enc,
  1995.               const char *start, const char *end)
  1996. {
  1997.   XML_Char *data;
  1998.   if (!commentHandler) {
  1999.     if (defaultHandler)
  2000.       reportDefault(parser, enc, start, end);
  2001.     return 1;
  2002.   }
  2003.   data = poolStoreString(&tempPool,
  2004.                          enc,
  2005.                          start + enc->minBytesPerChar * 4,
  2006.                          end - enc->minBytesPerChar * 3);
  2007.   if (!data)
  2008.     return 0;
  2009.   normalizeLines(data);
  2010.   commentHandler(handlerArg, data);
  2011.   poolClear(&tempPool);
  2012.   return 1;
  2013. }
  2014. static void
  2015. reportDefault(XML_Parser parser, const ENCODING *enc,
  2016.               const char *s, const char *end)
  2017. {
  2018.   if (MUST_CONVERT(enc, s)) {
  2019.     const char **eventPP;
  2020.     const char **eventEndPP;
  2021.     if (enc == encoding) {
  2022.       eventPP = &eventPtr;
  2023.       eventEndPP = &eventEndPtr;
  2024.     }
  2025.     else {
  2026.       eventPP = &(openInternalEntities->internalEventPtr);
  2027.       eventEndPP = &(openInternalEntities->internalEventEndPtr);
  2028.     }
  2029.     do {
  2030.       ICHAR *dataPtr = (ICHAR *)dataBuf;
  2031.       XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
  2032.       *eventEndPP = s;
  2033.       defaultHandler(handlerArg, dataBuf, (int)(dataPtr - (ICHAR *)dataBuf));
  2034.       *eventPP = s;
  2035.     } while (s != end);
  2036.   }
  2037.   else
  2038.     defaultHandler(handlerArg, (XML_Char *)s, (int)((XML_Char *)end - (XML_Char *)s));
  2039. }
  2040. static int
  2041. defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,
  2042.                 XML_Bool isId, const XML_Char *value, XML_Parser parser)
  2043. {
  2044.   DEFAULT_ATTRIBUTE *att;
  2045.   if (value || isId) {
  2046.     /* The handling of default attributes gets messed up if we have
  2047.        a default which duplicates a non-default. */
  2048.     int i;
  2049.     for (i = 0; i < type->nDefaultAtts; i++)
  2050.       if (attId == type->defaultAtts[i].id)
  2051.         return 1;
  2052.     if (isId && !type->idAtt && !attId->xmlns)
  2053.       type->idAtt = attId;
  2054.   }
  2055.   if (type->nDefaultAtts == type->allocDefaultAtts) {
  2056.     if (type->allocDefaultAtts == 0) {
  2057.       type->allocDefaultAtts = 8;
  2058.       type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(type->allocDefaultAtts
  2059.                             * sizeof(DEFAULT_ATTRIBUTE));
  2060.       if (!type->defaultAtts)
  2061.         return 0;
  2062.     }
  2063.     else {
  2064.       DEFAULT_ATTRIBUTE *temp;
  2065.       int count = type->allocDefaultAtts * 2;
  2066.       temp = (DEFAULT_ATTRIBUTE *)
  2067.         REALLOC(type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE)));
  2068.       if (temp == NULL)
  2069.         return 0;
  2070.       type->allocDefaultAtts = count;
  2071.       type->defaultAtts = temp;
  2072.     }
  2073.   }
  2074.   att = type->defaultAtts + type->nDefaultAtts;
  2075.   att->id = attId;
  2076.   att->value = value;
  2077.   att->isCdata = isCdata;
  2078.   if (!isCdata)
  2079.     attId->maybeTokenized = XML_TRUE;
  2080.   type->nDefaultAtts += 1;
  2081.   return 1;
  2082. }
  2083. static int
  2084. setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)
  2085. {
  2086.   DTD * const dtd = _dtd;  /* save one level of indirection */
  2087.   const XML_Char *name;
  2088.   for (name = elementType->name; *name; name++) {
  2089.     if (*name == XML_T(ASCII_COLON)) {
  2090.       PREFIX *prefix;
  2091.       const XML_Char *s;
  2092.       for (s = elementType->name; s != name; s++) {
  2093.         if (!poolAppendChar(&dtd->pool, *s))
  2094.           return 0;
  2095.       }
  2096.       if (!poolAppendChar(&dtd->pool, XML_T('')))
  2097.         return 0;
  2098.       prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool),
  2099.                                 sizeof(PREFIX));
  2100.       if (!prefix)
  2101.         return 0;
  2102.       if (prefix->name == poolStart(&dtd->pool))
  2103.         poolFinish(&dtd->pool);
  2104.       else
  2105.         poolDiscard(&dtd->pool);
  2106.       elementType->prefix = prefix;
  2107.     }
  2108.   }
  2109.   return 1;
  2110. }
  2111. static ATTRIBUTE_ID *
  2112. getAttributeId(XML_Parser parser, const ENCODING *enc,
  2113.                const char *start, const char *end)
  2114. {
  2115.   DTD * const dtd = _dtd;  /* save one level of indirection */
  2116.   ATTRIBUTE_ID *id;
  2117.   const XML_Char *name;
  2118.   if (!poolAppendChar(&dtd->pool, XML_T('')))
  2119.     return NULL;
  2120.   name = poolStoreString(&dtd->pool, enc, start, end);
  2121.   if (!name)
  2122.     return NULL;
  2123.   /* skip quotation mark - its storage will be re-used (like in name[-1]) */
  2124.   ++name;
  2125.   id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, name, sizeof(ATTRIBUTE_ID));
  2126.   if (!id)
  2127.     return NULL;
  2128.   if (id->name != name)
  2129.     poolDiscard(&dtd->pool);
  2130.   else {
  2131.     poolFinish(&dtd->pool);
  2132.     if (!ns)
  2133.       ;
  2134.     else if (name[0] == XML_T(ASCII_x)
  2135.         && name[1] == XML_T(ASCII_m)
  2136.         && name[2] == XML_T(ASCII_l)
  2137.         && name[3] == XML_T(ASCII_n)
  2138.         && name[4] == XML_T(ASCII_s)
  2139.         && (name[5] == XML_T('') || name[5] == XML_T(ASCII_COLON))) {
  2140.       if (name[5] == XML_T(''))
  2141.         id->prefix = &dtd->defaultPrefix;
  2142.       else
  2143.         id->prefix = (PREFIX *)lookup(&dtd->prefixes, name + 6, sizeof(PREFIX));
  2144.       id->xmlns = XML_TRUE;
  2145.     }
  2146.     else {
  2147.       int i;
  2148.       for (i = 0; name[i]; i++) {
  2149.         /* attributes without prefix are *not* in the default namespace */
  2150.         if (name[i] == XML_T(ASCII_COLON)) {
  2151.           int j;
  2152.           for (j = 0; j < i; j++) {
  2153.             if (!poolAppendChar(&dtd->pool, name[j]))
  2154.               return NULL;
  2155.           }
  2156.           if (!poolAppendChar(&dtd->pool, XML_T('')))
  2157.             return NULL;
  2158.           id->prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool),
  2159.                                         sizeof(PREFIX));
  2160.           if (id->prefix->name == poolStart(&dtd->pool))
  2161.             poolFinish(&dtd->pool);
  2162.           else
  2163.             poolDiscard(&dtd->pool);
  2164.           break;
  2165.         }
  2166.       }
  2167.     }
  2168.   }
  2169.   return id;
  2170. }
  2171. #define CONTEXT_SEP XML_T(ASCII_FF)
  2172. static const XML_Char *
  2173. getContext(XML_Parser parser)
  2174. {
  2175.   DTD * const dtd = _dtd;  /* save one level of indirection */
  2176.   HASH_TABLE_ITER iter;
  2177.   XML_Bool needSep = XML_FALSE;
  2178.   if (dtd->defaultPrefix.binding) {
  2179.     int i;
  2180.     int len;
  2181.     if (!poolAppendChar(&tempPool, XML_T(ASCII_EQUALS)))
  2182.       return NULL;
  2183.     len = dtd->defaultPrefix.binding->uriLen;
  2184.     if (namespaceSeparator)
  2185.       len--;
  2186.     for (i = 0; i < len; i++)
  2187.       if (!poolAppendChar(&tempPool, dtd->defaultPrefix.binding->uri[i]))
  2188.         return NULL;
  2189.     needSep = XML_TRUE;
  2190.   }
  2191.   hashTableIterInit(&iter, &(dtd->prefixes));
  2192.   for (;;) {
  2193.     int i;
  2194.     int len;
  2195.     const XML_Char *s;
  2196.     PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);
  2197.     if (!prefix)
  2198.       break;
  2199.     if (!prefix->binding)
  2200.       continue;
  2201.     if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
  2202.       return NULL;
  2203.     for (s = prefix->name; *s; s++)
  2204.       if (!poolAppendChar(&tempPool, *s))
  2205.         return NULL;
  2206.     if (!poolAppendChar(&tempPool, XML_T(ASCII_EQUALS)))
  2207.       return NULL;
  2208.     len = prefix->binding->uriLen;
  2209.     if (namespaceSeparator)
  2210.       len--;
  2211.     for (i = 0; i < len; i++)
  2212.       if (!poolAppendChar(&tempPool, prefix->binding->uri[i]))
  2213.         return NULL;
  2214.     needSep = XML_TRUE;
  2215.   }
  2216.   hashTableIterInit(&iter, &(dtd->generalEntities));
  2217.   for (;;) {
  2218.     const XML_Char *s;
  2219.     ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
  2220.     if (!e)
  2221.       break;
  2222.     if (!e->open)
  2223.       continue;
  2224.     if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
  2225.       return NULL;
  2226.     for (s = e->name; *s; s++)
  2227.       if (!poolAppendChar(&tempPool, *s))
  2228.         return 0;
  2229.     needSep = XML_TRUE;
  2230.   }
  2231.   if (!poolAppendChar(&tempPool, XML_T('')))
  2232.     return NULL;
  2233.   return tempPool.start;
  2234. }
  2235. static XML_Bool
  2236. setContext(XML_Parser parser, const XML_Char *context)
  2237. {
  2238.   DTD * const dtd = _dtd;  /* save one level of indirection */
  2239.   const XML_Char *s = context;
  2240.   while (*context != XML_T('')) {
  2241.     if (*s == CONTEXT_SEP || *s == XML_T('')) {
  2242.       ENTITY *e;
  2243.       if (!poolAppendChar(&tempPool, XML_T('')))
  2244.         return XML_FALSE;
  2245.       e = (ENTITY *)lookup(&dtd->generalEntities, poolStart(&tempPool), 0);
  2246.       if (e)
  2247.         e->open = XML_TRUE;
  2248.       if (*s != XML_T(''))
  2249.         s++;
  2250.       context = s;
  2251.       poolDiscard(&tempPool);
  2252.     }
  2253.     else if (*s == XML_T(ASCII_EQUALS)) {
  2254.       PREFIX *prefix;
  2255.       if (poolLength(&tempPool) == 0)
  2256.         prefix = &dtd->defaultPrefix;
  2257.       else {
  2258.         if (!poolAppendChar(&tempPool, XML_T('')))
  2259.           return XML_FALSE;
  2260.         prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&tempPool),
  2261.                                   sizeof(PREFIX));
  2262.         if (!prefix)
  2263.           return XML_FALSE;
  2264.         if (prefix->name == poolStart(&tempPool)) {
  2265.           prefix->name = poolCopyString(&dtd->pool, prefix->name);
  2266.           if (!prefix->name)
  2267.             return XML_FALSE;
  2268.         }
  2269.         poolDiscard(&tempPool);
  2270.       }
  2271.       for (context = s + 1;
  2272.            *context != CONTEXT_SEP && *context != XML_T('');
  2273.            context++)
  2274.         if (!poolAppendChar(&tempPool, *context))
  2275.           return XML_FALSE;
  2276.       if (!poolAppendChar(&tempPool, XML_T('')))
  2277.         return XML_FALSE;
  2278.       if (addBinding(parser, prefix, NULL, poolStart(&tempPool),
  2279.                      &inheritedBindings) != XML_ERROR_NONE)
  2280.         return XML_FALSE;
  2281.       poolDiscard(&tempPool);
  2282.       if (*context != XML_T(''))
  2283.         ++context;
  2284.       s = context;
  2285.     }
  2286.     else {
  2287.       if (!poolAppendChar(&tempPool, *s))
  2288.         return XML_FALSE;
  2289.       s++;
  2290.     }
  2291.   }
  2292.   return XML_TRUE;
  2293. }
  2294. static void FASTCALL
  2295. normalizePublicId(XML_Char *publicId)
  2296. {
  2297.   XML_Char *p = publicId;
  2298.   XML_Char *s;
  2299.   for (s = publicId; *s; s++) {
  2300.     switch (*s) {
  2301.     case 0x20:
  2302.     case 0xD:
  2303.     case 0xA:
  2304.       if (p != publicId && p[-1] != 0x20)
  2305.         *p++ = 0x20;
  2306.       break;
  2307.     default:
  2308.       *p++ = *s;
  2309.     }
  2310.   }
  2311.   if (p != publicId && p[-1] == 0x20)
  2312.     --p;
  2313.   *p = XML_T('');
  2314. }
  2315. static DTD *
  2316. dtdCreate(const XML_Memory_Handling_Suite *ms)
  2317. {
  2318.   DTD *p = (DTD *)ms->malloc_fcn(sizeof(DTD));
  2319.   if (p == NULL)
  2320.     return p;
  2321.   poolInit(&(p->pool), ms);
  2322.   poolInit(&(p->entityValuePool), ms);
  2323.   hashTableInit(&(p->generalEntities), ms);
  2324.   hashTableInit(&(p->elementTypes), ms);
  2325.   hashTableInit(&(p->attributeIds), ms);
  2326.   hashTableInit(&(p->prefixes), ms);
  2327. #ifdef XML_DTD
  2328.   p->paramEntityRead = XML_FALSE;
  2329.   hashTableInit(&(p->paramEntities), ms);
  2330. #endif /* XML_DTD */
  2331.   p->defaultPrefix.name = NULL;
  2332.   p->defaultPrefix.binding = NULL;
  2333.   p->in_eldecl = XML_FALSE;
  2334.   p->scaffIndex = NULL;
  2335.   p->scaffold = NULL;
  2336.   p->scaffLevel = 0;
  2337.   p->scaffSize = 0;
  2338.   p->scaffCount = 0;
  2339.   p->contentStringLen = 0;
  2340.   p->keepProcessing = XML_TRUE;
  2341.   p->hasParamEntityRefs = XML_FALSE;
  2342.   p->standalone = XML_FALSE;
  2343.   return p;
  2344. }
  2345. static void
  2346. dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms)
  2347. {
  2348.   HASH_TABLE_ITER iter;
  2349.   hashTableIterInit(&iter, &(p->elementTypes));
  2350.   for (;;) {
  2351.     ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
  2352.     if (!e)
  2353.       break;
  2354.     if (e->allocDefaultAtts != 0)
  2355.       ms->free_fcn(e->defaultAtts);
  2356.   }
  2357.   hashTableClear(&(p->generalEntities));
  2358. #ifdef XML_DTD
  2359.   p->paramEntityRead = XML_FALSE;
  2360.   hashTableClear(&(p->paramEntities));
  2361. #endif /* XML_DTD */
  2362.   hashTableClear(&(p->elementTypes));
  2363.   hashTableClear(&(p->attributeIds));
  2364.   hashTableClear(&(p->prefixes));
  2365.   poolClear(&(p->pool));
  2366.   poolClear(&(p->entityValuePool));
  2367.   p->defaultPrefix.name = NULL;
  2368.   p->defaultPrefix.binding = NULL;
  2369.   p->in_eldecl = XML_FALSE;
  2370.   ms->free_fcn(p->scaffIndex);
  2371.   p->scaffIndex = NULL;
  2372.   ms->free_fcn(p->scaffold);
  2373.   p->scaffold = NULL;
  2374.   p->scaffLevel = 0;
  2375.   p->scaffSize = 0;
  2376.   p->scaffCount = 0;
  2377.   p->contentStringLen = 0;
  2378.   p->keepProcessing = XML_TRUE;
  2379.   p->hasParamEntityRefs = XML_FALSE;
  2380.   p->standalone = XML_FALSE;
  2381. }
  2382. static void
  2383. dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms)
  2384. {
  2385.   HASH_TABLE_ITER iter;
  2386.   hashTableIterInit(&iter, &(p->elementTypes));
  2387.   for (;;) {
  2388.     ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
  2389.     if (!e)
  2390.       break;
  2391.     if (e->allocDefaultAtts != 0)
  2392.       ms->free_fcn(e->defaultAtts);
  2393.   }
  2394.   hashTableDestroy(&(p->generalEntities));
  2395. #ifdef XML_DTD
  2396.   hashTableDestroy(&(p->paramEntities));
  2397. #endif /* XML_DTD */
  2398.   hashTableDestroy(&(p->elementTypes));
  2399.   hashTableDestroy(&(p->attributeIds));
  2400.   hashTableDestroy(&(p->prefixes));
  2401.   poolDestroy(&(p->pool));
  2402.   poolDestroy(&(p->entityValuePool));
  2403.   if (isDocEntity) {
  2404.     ms->free_fcn(p->scaffIndex);
  2405.     ms->free_fcn(p->scaffold);
  2406.   }
  2407.   ms->free_fcn(p);
  2408. }
  2409. /* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.
  2410.    The new DTD has already been initialized.
  2411. */
  2412. static int
  2413. dtdCopy(DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms)
  2414. {
  2415.   HASH_TABLE_ITER iter;
  2416.   /* Copy the prefix table. */
  2417.   hashTableIterInit(&iter, &(oldDtd->prefixes));
  2418.   for (;;) {
  2419.     const XML_Char *name;
  2420.     const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);
  2421.     if (!oldP)
  2422.       break;
  2423.     name = poolCopyString(&(newDtd->pool), oldP->name);
  2424.     if (!name)
  2425.       return 0;
  2426.     if (!lookup(&(newDtd->prefixes), name, sizeof(PREFIX)))
  2427.       return 0;
  2428.   }
  2429.   hashTableIterInit(&iter, &(oldDtd->attributeIds));
  2430.   /* Copy the attribute id table. */
  2431.   for (;;) {
  2432.     ATTRIBUTE_ID *newA;
  2433.     const XML_Char *name;
  2434.     const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);
  2435.     if (!oldA)
  2436.       break;
  2437.     /* Remember to allocate the scratch byte before the name. */
  2438.     if (!poolAppendChar(&(newDtd->pool), XML_T('')))
  2439.       return 0;
  2440.     name = poolCopyString(&(newDtd->pool), oldA->name);
  2441.     if (!name)
  2442.       return 0;
  2443.     ++name;
  2444.     newA = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), name,
  2445.                                   sizeof(ATTRIBUTE_ID));
  2446.     if (!newA)
  2447.       return 0;
  2448.     newA->maybeTokenized = oldA->maybeTokenized;
  2449.     if (oldA->prefix) {
  2450.       newA->xmlns = oldA->xmlns;
  2451.       if (oldA->prefix == &oldDtd->defaultPrefix)
  2452.         newA->prefix = &newDtd->defaultPrefix;
  2453.       else
  2454.         newA->prefix = (PREFIX *)lookup(&(newDtd->prefixes),
  2455.                                         oldA->prefix->name, 0);
  2456.     }
  2457.   }
  2458.   /* Copy the element type table. */
  2459.   hashTableIterInit(&iter, &(oldDtd->elementTypes));
  2460.   for (;;) {
  2461.     int i;
  2462.     ELEMENT_TYPE *newE;
  2463.     const XML_Char *name;
  2464.     const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);
  2465.     if (!oldE)
  2466.       break;
  2467.     name = poolCopyString(&(newDtd->pool), oldE->name);
  2468.     if (!name)
  2469.       return 0;
  2470.     newE = (ELEMENT_TYPE *)lookup(&(newDtd->elementTypes), name,
  2471.                                   sizeof(ELEMENT_TYPE));
  2472.     if (!newE)
  2473.       return 0;
  2474.     if (oldE->nDefaultAtts) {
  2475.       newE->defaultAtts = (DEFAULT_ATTRIBUTE *)
  2476.           ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
  2477.       if (!newE->defaultAtts) {
  2478.         ms->free_fcn(newE);
  2479.         return 0;
  2480.       }
  2481.     }
  2482.     if (oldE->idAtt)
  2483.       newE->idAtt = (ATTRIBUTE_ID *)
  2484.           lookup(&(newDtd->attributeIds), oldE->idAtt->name, 0);
  2485.     newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
  2486.     if (oldE->prefix)
  2487.       newE->prefix = (PREFIX *)lookup(&(newDtd->prefixes),
  2488.                                       oldE->prefix->name, 0);
  2489.     for (i = 0; i < newE->nDefaultAtts; i++) {
  2490.       newE->defaultAtts[i].id = (ATTRIBUTE_ID *)
  2491.           lookup(&(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
  2492.       newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
  2493.       if (oldE->defaultAtts[i].value) {
  2494.         newE->defaultAtts[i].value
  2495.             = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
  2496.         if (!newE->defaultAtts[i].value)
  2497.           return 0;
  2498.       }
  2499.       else
  2500.         newE->defaultAtts[i].value = NULL;
  2501.     }
  2502.   }
  2503.   /* Copy the entity tables. */
  2504.   if (!copyEntityTable(&(newDtd->generalEntities),
  2505.                        &(newDtd->pool),
  2506.                        &(oldDtd->generalEntities)))
  2507.       return 0;
  2508. #ifdef XML_DTD
  2509.   if (!copyEntityTable(&(newDtd->paramEntities),
  2510.                        &(newDtd->pool),
  2511.                        &(oldDtd->paramEntities)))
  2512.       return 0;
  2513.   newDtd->paramEntityRead = oldDtd->paramEntityRead;
  2514. #endif /* XML_DTD */
  2515.   newDtd->keepProcessing = oldDtd->keepProcessing;
  2516.   newDtd->hasParamEntityRefs = oldDtd->hasParamEntityRefs;
  2517.   newDtd->standalone = oldDtd->standalone;
  2518.   /* Don't want deep copying for scaffolding */
  2519.   newDtd->in_eldecl = oldDtd->in_eldecl;
  2520.   newDtd->scaffold = oldDtd->scaffold;
  2521.   newDtd->contentStringLen = oldDtd->contentStringLen;
  2522.   newDtd->scaffSize = oldDtd->scaffSize;
  2523.   newDtd->scaffLevel = oldDtd->scaffLevel;
  2524.   newDtd->scaffIndex = oldDtd->scaffIndex;
  2525.   return 1;
  2526. }  /* End dtdCopy */
  2527. static int
  2528. copyEntityTable(HASH_TABLE *newTable,
  2529.                 STRING_POOL *newPool,
  2530.                 const HASH_TABLE *oldTable)
  2531. {
  2532.   HASH_TABLE_ITER iter;
  2533.   const XML_Char *cachedOldBase = NULL;
  2534.   const XML_Char *cachedNewBase = NULL;
  2535.   hashTableIterInit(&iter, oldTable);
  2536.   for (;;) {
  2537.     ENTITY *newE;
  2538.     const XML_Char *name;
  2539.     const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);
  2540.     if (!oldE)
  2541.       break;
  2542.     name = poolCopyString(newPool, oldE->name);
  2543.     if (!name)
  2544.       return 0;
  2545.     newE = (ENTITY *)lookup(newTable, name, sizeof(ENTITY));
  2546.     if (!newE)
  2547.       return 0;
  2548.     if (oldE->systemId) {
  2549.       const XML_Char *tem = poolCopyString(newPool, oldE->systemId);
  2550.       if (!tem)
  2551.         return 0;
  2552.       newE->systemId = tem;
  2553.       if (oldE->base) {
  2554.         if (oldE->base == cachedOldBase)
  2555.           newE->base = cachedNewBase;
  2556.         else {
  2557.           cachedOldBase = oldE->base;
  2558.           tem = poolCopyString(newPool, cachedOldBase);
  2559.           if (!tem)
  2560.             return 0;
  2561.           cachedNewBase = newE->base = tem;
  2562.         }
  2563.       }
  2564.       if (oldE->publicId) {
  2565.         tem = poolCopyString(newPool, oldE->publicId);
  2566.         if (!tem)
  2567.           return 0;
  2568.         newE->publicId = tem;
  2569.       }
  2570.     }
  2571.     else {
  2572.       const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr,
  2573.                                             oldE->textLen);
  2574.       if (!tem)
  2575.         return 0;
  2576.       newE->textPtr = tem;
  2577.       newE->textLen = oldE->textLen;
  2578.     }
  2579.     if (oldE->notation) {
  2580.       const XML_Char *tem = poolCopyString(newPool, oldE->notation);
  2581.       if (!tem)
  2582.         return 0;
  2583.       newE->notation = tem;
  2584.     }
  2585.     newE->is_param = oldE->is_param;
  2586.     newE->is_internal = oldE->is_internal;
  2587.   }
  2588.   return 1;
  2589. }
  2590. #define INIT_POWER 6
  2591. static XML_Bool FASTCALL
  2592. keyeq(KEY s1, KEY s2)
  2593. {
  2594.   for (; *s1 == *s2; s1++, s2++)
  2595.     if (*s1 == 0)
  2596.       return XML_TRUE;
  2597.   return XML_FALSE;
  2598. }
  2599. static unsigned long FASTCALL
  2600. hash(KEY s)
  2601. {
  2602.   unsigned long h = 0;
  2603.   while (*s)
  2604.     h = CHAR_HASH(h, *s++);
  2605.   return h;
  2606. }
  2607. static NAMED *
  2608. lookup(HASH_TABLE *table, KEY name, size_t createSize)
  2609. {
  2610.   size_t i;
  2611.   if (table->size == 0) {
  2612.     size_t tsize;
  2613.     if (!createSize)
  2614.       return NULL;
  2615.     table->power = INIT_POWER;
  2616.     /* table->size is a power of 2 */
  2617.     table->size = (size_t)1 << INIT_POWER;
  2618.     tsize = table->size * sizeof(NAMED *);
  2619.     table->v = (NAMED **)table->mem->malloc_fcn(tsize);
  2620.     if (!table->v) {
  2621.       table->size = 0;
  2622.       return NULL;
  2623.     }
  2624.     memset(table->v, 0, tsize);
  2625.     i = hash(name) & ((unsigned long)table->size - 1);
  2626.   }
  2627.   else {
  2628.     unsigned long h = hash(name);
  2629.     unsigned long mask = (unsigned long)table->size - 1;
  2630.     unsigned char step = 0;
  2631.     i = h & mask;
  2632.     while (table->v[i]) {
  2633.       if (keyeq(name, table->v[i]->name))
  2634.         return table->v[i];
  2635.       if (!step)
  2636.         step = PROBE_STEP(h, mask, table->power);
  2637.       i < step ? (i += table->size - step) : (i -= step);
  2638.     }
  2639.     if (!createSize)
  2640.       return NULL;
  2641.     /* check for overflow (table is half full) */
  2642.     if (table->used >> (table->power - 1)) {
  2643.       unsigned char newPower = table->power + 1;
  2644.       size_t newSize = (size_t)1 << newPower;
  2645.       unsigned long newMask = (unsigned long)newSize - 1;
  2646.       size_t tsize = newSize * sizeof(NAMED *);
  2647.       NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize);
  2648.       if (!newV)
  2649.         return NULL;
  2650.       memset(newV, 0, tsize);
  2651.       for (i = 0; i < table->size; i++)
  2652.         if (table->v[i]) {
  2653.           unsigned long newHash = hash(table->v[i]->name);
  2654.           size_t j = newHash & newMask;
  2655.           step = 0;
  2656.           while (newV[j]) {
  2657.             if (!step)
  2658.               step = PROBE_STEP(newHash, newMask, newPower);
  2659.             j < step ? (j += newSize - step) : (j -= step);
  2660.           }
  2661.           newV[j] = table->v[i];
  2662.         }
  2663.       table->mem->free_fcn(table->v);
  2664.       table->v = newV;
  2665.       table->power = newPower;
  2666.       table->size = newSize;
  2667.       i = h & newMask;
  2668.       step = 0;
  2669.       while (table->v[i]) {
  2670.         if (!step)
  2671.           step = PROBE_STEP(h, newMask, newPower);
  2672.         i < step ? (i += newSize - step) : (i -= step);
  2673.       }
  2674.     }
  2675.   }
  2676.   table->v[i] = (NAMED *)table->mem->malloc_fcn(createSize);
  2677.   if (!table->v[i])
  2678.     return NULL;
  2679.   memset(table->v[i], 0, createSize);
  2680.   table->v[i]->name = name;
  2681.   (table->used)++;
  2682.   return table->v[i];
  2683. }
  2684. static void FASTCALL
  2685. hashTableClear(HASH_TABLE *table)
  2686. {
  2687.   size_t i;
  2688.   for (i = 0; i < table->size; i++) {
  2689.     table->mem->free_fcn(table->v[i]);
  2690.     table->v[i] = NULL;
  2691.   }
  2692.   table->used = 0;
  2693. }
  2694. static void FASTCALL
  2695. hashTableDestroy(HASH_TABLE *table)
  2696. {
  2697.   size_t i;
  2698.   for (i = 0; i < table->size; i++)
  2699.     table->mem->free_fcn(table->v[i]);
  2700.   table->mem->free_fcn(table->v);
  2701. }
  2702. static void FASTCALL
  2703. hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms)
  2704. {
  2705.   p->power = 0;
  2706.   p->size = 0;
  2707.   p->used = 0;
  2708.   p->v = NULL;
  2709.   p->mem = ms;
  2710. }
  2711. static void FASTCALL
  2712. hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table)
  2713. {
  2714.   iter->p = table->v;
  2715.   iter->end = iter->p + table->size;
  2716. }
  2717. static NAMED * FASTCALL
  2718. hashTableIterNext(HASH_TABLE_ITER *iter)
  2719. {
  2720.   while (iter->p != iter->end) {
  2721.     NAMED *tem = *(iter->p)++;
  2722.     if (tem)
  2723.       return tem;
  2724.   }
  2725.   return NULL;
  2726. }
  2727. static void FASTCALL
  2728. poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms)
  2729. {
  2730.   pool->blocks = NULL;
  2731.   pool->freeBlocks = NULL;
  2732.   pool->start = NULL;
  2733.   pool->ptr = NULL;
  2734.   pool->end = NULL;
  2735.   pool->mem = ms;
  2736. }
  2737. static void FASTCALL
  2738. poolClear(STRING_POOL *pool)
  2739. {
  2740.   if (!pool->freeBlocks)
  2741.     pool->freeBlocks = pool->blocks;
  2742.   else {
  2743.     BLOCK *p = pool->blocks;
  2744.     while (p) {
  2745.       BLOCK *tem = p->next;
  2746.       p->next = pool->freeBlocks;
  2747.       pool->freeBlocks = p;
  2748.       p = tem;
  2749.     }
  2750.   }
  2751.   pool->blocks = NULL;
  2752.   pool->start = NULL;
  2753.   pool->ptr = NULL;
  2754.   pool->end = NULL;
  2755. }
  2756. static void FASTCALL
  2757. poolDestroy(STRING_POOL *pool)
  2758. {
  2759.   BLOCK *p = pool->blocks;
  2760.   while (p) {
  2761.     BLOCK *tem = p->next;
  2762.     pool->mem->free_fcn(p);
  2763.     p = tem;
  2764.   }
  2765.   p = pool->freeBlocks;
  2766.   while (p) {
  2767.     BLOCK *tem = p->next;
  2768.     pool->mem->free_fcn(p);
  2769.     p = tem;
  2770.   }
  2771. }
  2772. static XML_Char *
  2773. poolAppend(STRING_POOL *pool, const ENCODING *enc,
  2774.            const char *ptr, const char *end)
  2775. {
  2776.   if (!pool->ptr && !poolGrow(pool))
  2777.     return NULL;
  2778.   for (;;) {
  2779.     XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
  2780.     if (ptr == end)
  2781.       break;
  2782.     if (!poolGrow(pool))
  2783.       return NULL;
  2784.   }
  2785.   return pool->start;
  2786. }
  2787. static const XML_Char * FASTCALL
  2788. poolCopyString(STRING_POOL *pool, const XML_Char *s)
  2789. {
  2790.   do {
  2791.     if (!poolAppendChar(pool, *s))
  2792.       return NULL;
  2793.   } while (*s++);
  2794.   s = pool->start;
  2795.   poolFinish(pool);
  2796.   return s;
  2797. }
  2798. static const XML_Char *
  2799. poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)
  2800. {
  2801.   if (!pool->ptr && !poolGrow(pool))
  2802.     return NULL;
  2803.   for (; n > 0; --n, s++) {
  2804.     if (!poolAppendChar(pool, *s))
  2805.       return NULL;
  2806.   }
  2807.   s = pool->start;
  2808.   poolFinish(pool);
  2809.   return s;
  2810. }
  2811. static const XML_Char * FASTCALL
  2812. poolAppendString(STRING_POOL *pool, const XML_Char *s)
  2813. {
  2814.   while (*s) {
  2815.     if (!poolAppendChar(pool, *s))
  2816.       return NULL;
  2817.     s++;
  2818.   }
  2819.   return pool->start;
  2820. }
  2821. static XML_Char *
  2822. poolStoreString(STRING_POOL *pool, const ENCODING *enc,
  2823.                 const char *ptr, const char *end)
  2824. {
  2825.   if (!poolAppend(pool, enc, ptr, end))
  2826.     return NULL;
  2827.   if (pool->ptr == pool->end && !poolGrow(pool))
  2828.     return NULL;
  2829.   *(pool->ptr)++ = 0;
  2830.   return pool->start;
  2831. }
  2832. static XML_Bool FASTCALL
  2833. poolGrow(STRING_POOL *pool)
  2834. {
  2835.   if (pool->freeBlocks) {
  2836.     if (pool->start == 0) {
  2837.       pool->blocks = pool->freeBlocks;
  2838.       pool->freeBlocks = pool->freeBlocks->next;
  2839.       pool->blocks->next = NULL;
  2840.       pool->start = pool->blocks->s;
  2841.       pool->end = pool->start + pool->blocks->size;
  2842.       pool->ptr = pool->start;
  2843.       return XML_TRUE;
  2844.     }
  2845.     if (pool->end - pool->start < pool->freeBlocks->size) {
  2846.       BLOCK *tem = pool->freeBlocks->next;
  2847.       pool->freeBlocks->next = pool->blocks;
  2848.       pool->blocks = pool->freeBlocks;
  2849.       pool->freeBlocks = tem;
  2850.       memcpy(pool->blocks->s, pool->start,
  2851.              (pool->end - pool->start) * sizeof(XML_Char));
  2852.       pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
  2853.       pool->start = pool->blocks->s;
  2854.       pool->end = pool->start + pool->blocks->size;
  2855.       return XML_TRUE;
  2856.     }
  2857.   }
  2858.   if (pool->blocks && pool->start == pool->blocks->s) {
  2859.     int blockSize = (int)(pool->end - pool->start)*2;
  2860.     pool->blocks = (BLOCK *)
  2861.       pool->mem->realloc_fcn(pool->blocks,
  2862.                              (offsetof(BLOCK, s)
  2863.                               + blockSize * sizeof(XML_Char)));
  2864.     if (pool->blocks == NULL)
  2865.       return XML_FALSE;
  2866.     pool->blocks->size = blockSize;
  2867.     pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
  2868.     pool->start = pool->blocks->s;
  2869.     pool->end = pool->start + blockSize;
  2870.   }
  2871.   else {
  2872.     BLOCK *tem;
  2873.     int blockSize = (int)(pool->end - pool->start);
  2874.     if (blockSize < INIT_BLOCK_SIZE)
  2875.       blockSize = INIT_BLOCK_SIZE;
  2876.     else
  2877.       blockSize *= 2;
  2878.     tem = (BLOCK *)pool->mem->malloc_fcn(offsetof(BLOCK, s)
  2879.                                         + blockSize * sizeof(XML_Char));
  2880.     if (!tem)
  2881.       return XML_FALSE;
  2882.     tem->size = blockSize;
  2883.     tem->next = pool->blocks;
  2884.     pool->blocks = tem;
  2885.     if (pool->ptr != pool->start)
  2886.       memcpy(tem->s, pool->start,
  2887.              (pool->ptr - pool->start) * sizeof(XML_Char));
  2888.     pool->ptr = tem->s + (pool->ptr - pool->start);
  2889.     pool->start = tem->s;
  2890.     pool->end = tem->s + blockSize;
  2891.   }
  2892.   return XML_TRUE;
  2893. }
  2894. static int FASTCALL
  2895. nextScaffoldPart(XML_Parser parser)
  2896. {
  2897.   DTD * const dtd = _dtd;  /* save one level of indirection */
  2898.   CONTENT_SCAFFOLD * me;
  2899.   int next;
  2900.   if (!dtd->scaffIndex) {
  2901.     dtd->scaffIndex = (int *)MALLOC(groupSize * sizeof(int));
  2902.     if (!dtd->scaffIndex)
  2903.       return -1;
  2904.     dtd->scaffIndex[0] = 0;
  2905.   }
  2906.   if (dtd->scaffCount >= dtd->scaffSize) {
  2907.     CONTENT_SCAFFOLD *temp;
  2908.     if (dtd->scaffold) {
  2909.       temp = (CONTENT_SCAFFOLD *)
  2910.         REALLOC(dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD));
  2911.       if (temp == NULL)
  2912.         return -1;
  2913.       dtd->scaffSize *= 2;
  2914.     }
  2915.     else {
  2916.       temp = (CONTENT_SCAFFOLD *)MALLOC(INIT_SCAFFOLD_ELEMENTS
  2917.                                         * sizeof(CONTENT_SCAFFOLD));
  2918.       if (temp == NULL)
  2919.         return -1;
  2920.       dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS;
  2921.     }
  2922.     dtd->scaffold = temp;
  2923.   }
  2924.   next = dtd->scaffCount++;
  2925.   me = &dtd->scaffold[next];
  2926.   if (dtd->scaffLevel) {
  2927.     CONTENT_SCAFFOLD *parent = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel-1]];
  2928.     if (parent->lastchild) {
  2929.       dtd->scaffold[parent->lastchild].nextsib = next;
  2930.     }
  2931.     if (!parent->childcnt)
  2932.       parent->firstchild = next;
  2933.     parent->lastchild = next;
  2934.     parent->childcnt++;
  2935.   }
  2936.   me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0;
  2937.   return next;
  2938. }
  2939. static void
  2940. build_node(XML_Parser parser,
  2941.            int src_node,
  2942.            XML_Content *dest,
  2943.            XML_Content **contpos,
  2944.            XML_Char **strpos)
  2945. {
  2946.   DTD * const dtd = _dtd;  /* save one level of indirection */
  2947.   dest->type = dtd->scaffold[src_node].type;
  2948.   dest->quant = dtd->scaffold[src_node].quant;
  2949.   if (dest->type == XML_CTYPE_NAME) {
  2950.     const XML_Char *src;
  2951.     dest->name = *strpos;
  2952.     src = dtd->scaffold[src_node].name;
  2953.     for (;;) {
  2954.       *(*strpos)++ = *src;
  2955.       if (!*src)
  2956.         break;
  2957.       src++;
  2958.     }
  2959.     dest->numchildren = 0;
  2960.     dest->children = NULL;
  2961.   }
  2962.   else {
  2963.     unsigned int i;
  2964.     int cn;
  2965.     dest->numchildren = dtd->scaffold[src_node].childcnt;
  2966.     dest->children = *contpos;
  2967.     *contpos += dest->numchildren;
  2968.     for (i = 0, cn = dtd->scaffold[src_node].firstchild;
  2969.          i < dest->numchildren;
  2970.          i++, cn = dtd->scaffold[cn].nextsib) {
  2971.       build_node(parser, cn, &(dest->children[i]), contpos, strpos);
  2972.     }
  2973.     dest->name = NULL;
  2974.   }
  2975. }
  2976. static XML_Content *
  2977. build_model (XML_Parser parser)
  2978. {
  2979.   DTD * const dtd = _dtd;  /* save one level of indirection */
  2980.   XML_Content *ret;
  2981.   XML_Content *cpos;
  2982.   XML_Char * str;
  2983.   int allocsize = (dtd->scaffCount * sizeof(XML_Content)
  2984.                    + (dtd->contentStringLen * sizeof(XML_Char)));
  2985.   ret = (XML_Content *)MALLOC(allocsize);
  2986.   if (!ret)
  2987.     return NULL;
  2988.   str =  (XML_Char *) (&ret[dtd->scaffCount]);
  2989.   cpos = &ret[1];
  2990.   build_node(parser, 0, ret, &cpos, &str);
  2991.   return ret;
  2992. }
  2993. static ELEMENT_TYPE *
  2994. getElementType(XML_Parser parser,
  2995.                const ENCODING *enc,
  2996.                const char *ptr,
  2997.                const char *end)
  2998. {
  2999.   DTD * const dtd = _dtd;  /* save one level of indirection */
  3000.   const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end);
  3001.   ELEMENT_TYPE *ret;
  3002.   if (!name)
  3003.     return NULL;
  3004.   ret = (ELEMENT_TYPE *) lookup(&dtd->elementTypes, name, sizeof(ELEMENT_TYPE));
  3005.   if (!ret)
  3006.     return NULL;
  3007.   if (ret->name != name)
  3008.     poolDiscard(&dtd->pool);
  3009.   else {
  3010.     poolFinish(&dtd->pool);
  3011.     if (!setElementTypePrefix(parser, ret))
  3012.       return NULL;
  3013.   }
  3014.   return ret;
  3015. }