xmlparse.c
上传用户:hmc_gdtv
上传日期:2013-08-04
资源大小:798k
文件大小:177k
源码类别:

Windows Mobile

开发平台:

Visual C++

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