📄 parser.c
字号:
defaults->nbAttrs = 0; defaults->maxAttrs = 4; xmlHashUpdateEntry2(ctxt->attsDefault, name, prefix, defaults, NULL); } else if (defaults->nbAttrs >= defaults->maxAttrs) { xmlDefAttrsPtr temp; temp = (xmlDefAttrsPtr) xmlRealloc(defaults, sizeof(xmlDefAttrs) + (2 * defaults->maxAttrs * 4) * sizeof(const xmlChar *)); if (temp == NULL) goto mem_error; defaults = temp; defaults->maxAttrs *= 2; xmlHashUpdateEntry2(ctxt->attsDefault, name, prefix, defaults, NULL); } /* * Split the element name into prefix:localname , the string found * are within the DTD and hen not associated to namespace names. */ name = xmlSplitQName3(fullattr, &len); if (name == NULL) { name = xmlDictLookup(ctxt->dict, fullattr, -1); prefix = NULL; } else { name = xmlDictLookup(ctxt->dict, name, -1); prefix = xmlDictLookup(ctxt->dict, fullattr, len); } defaults->values[4 * defaults->nbAttrs] = name; defaults->values[4 * defaults->nbAttrs + 1] = prefix; /* intern the string and precompute the end */ len = xmlStrlen(value); value = xmlDictLookup(ctxt->dict, value, len); defaults->values[4 * defaults->nbAttrs + 2] = value; defaults->values[4 * defaults->nbAttrs + 3] = value + len; defaults->nbAttrs++; return;mem_error: xmlErrMemory(ctxt, NULL); return;}/** * xmlAddSpecialAttr: * @ctxt: an XML parser context * @fullname: the element fullname * @fullattr: the attribute fullname * @type: the attribute type * * Register that this attribute is not CDATA */static voidxmlAddSpecialAttr(xmlParserCtxtPtr ctxt, const xmlChar *fullname, const xmlChar *fullattr, int type){ if (ctxt->attsSpecial == NULL) { ctxt->attsSpecial = xmlHashCreateDict(10, ctxt->dict); if (ctxt->attsSpecial == NULL) goto mem_error; } xmlHashAddEntry2(ctxt->attsSpecial, fullname, fullattr, (void *) (long) type); return;mem_error: xmlErrMemory(ctxt, NULL); return;}/** * xmlCheckLanguageID: * @lang: pointer to the string value * * Checks that the value conforms to the LanguageID production: * * NOTE: this is somewhat deprecated, those productions were removed from * the XML Second edition. * * [33] LanguageID ::= Langcode ('-' Subcode)* * [34] Langcode ::= ISO639Code | IanaCode | UserCode * [35] ISO639Code ::= ([a-z] | [A-Z]) ([a-z] | [A-Z]) * [36] IanaCode ::= ('i' | 'I') '-' ([a-z] | [A-Z])+ * [37] UserCode ::= ('x' | 'X') '-' ([a-z] | [A-Z])+ * [38] Subcode ::= ([a-z] | [A-Z])+ * * Returns 1 if correct 0 otherwise **/intxmlCheckLanguageID(const xmlChar * lang){ const xmlChar *cur = lang; if (cur == NULL) return (0); if (((cur[0] == 'i') && (cur[1] == '-')) || ((cur[0] == 'I') && (cur[1] == '-'))) { /* * IANA code */ cur += 2; while (((cur[0] >= 'A') && (cur[0] <= 'Z')) || /* non input consuming */ ((cur[0] >= 'a') && (cur[0] <= 'z'))) cur++; } else if (((cur[0] == 'x') && (cur[1] == '-')) || ((cur[0] == 'X') && (cur[1] == '-'))) { /* * User code */ cur += 2; while (((cur[0] >= 'A') && (cur[0] <= 'Z')) || /* non input consuming */ ((cur[0] >= 'a') && (cur[0] <= 'z'))) cur++; } else if (((cur[0] >= 'A') && (cur[0] <= 'Z')) || ((cur[0] >= 'a') && (cur[0] <= 'z'))) { /* * ISO639 */ cur++; if (((cur[0] >= 'A') && (cur[0] <= 'Z')) || ((cur[0] >= 'a') && (cur[0] <= 'z'))) cur++; else return (0); } else return (0); while (cur[0] != 0) { /* non input consuming */ if (cur[0] != '-') return (0); cur++; if (((cur[0] >= 'A') && (cur[0] <= 'Z')) || ((cur[0] >= 'a') && (cur[0] <= 'z'))) cur++; else return (0); while (((cur[0] >= 'A') && (cur[0] <= 'Z')) || /* non input consuming */ ((cur[0] >= 'a') && (cur[0] <= 'z'))) cur++; } return (1);}/************************************************************************ * * * Parser stacks related functions and macros * * * ************************************************************************/xmlEntityPtr xmlParseStringEntityRef(xmlParserCtxtPtr ctxt, const xmlChar ** str);#ifdef SAX2/** * nsPush: * @ctxt: an XML parser context * @prefix: the namespace prefix or NULL * @URL: the namespace name * * Pushes a new parser namespace on top of the ns stack * * Returns -1 in case of error, -2 if the namespace should be discarded * and the index in the stack otherwise. */static intnsPush(xmlParserCtxtPtr ctxt, const xmlChar *prefix, const xmlChar *URL){ if (ctxt->options & XML_PARSE_NSCLEAN) { int i; for (i = 0;i < ctxt->nsNr;i += 2) { if (ctxt->nsTab[i] == prefix) { /* in scope */ if (ctxt->nsTab[i + 1] == URL) return(-2); /* out of scope keep it */ break; } } } if ((ctxt->nsMax == 0) || (ctxt->nsTab == NULL)) { ctxt->nsMax = 10; ctxt->nsNr = 0; ctxt->nsTab = (const xmlChar **) xmlMalloc(ctxt->nsMax * sizeof(xmlChar *)); if (ctxt->nsTab == NULL) { xmlErrMemory(ctxt, NULL); ctxt->nsMax = 0; return (-1); } } else if (ctxt->nsNr >= ctxt->nsMax) { ctxt->nsMax *= 2; ctxt->nsTab = (const xmlChar **) xmlRealloc((char *) ctxt->nsTab, ctxt->nsMax * sizeof(ctxt->nsTab[0])); if (ctxt->nsTab == NULL) { xmlErrMemory(ctxt, NULL); ctxt->nsMax /= 2; return (-1); } } ctxt->nsTab[ctxt->nsNr++] = prefix; ctxt->nsTab[ctxt->nsNr++] = URL; return (ctxt->nsNr);}/** * nsPop: * @ctxt: an XML parser context * @nr: the number to pop * * Pops the top @nr parser prefix/namespace from the ns stack * * Returns the number of namespaces removed */static intnsPop(xmlParserCtxtPtr ctxt, int nr){ int i; if (ctxt->nsTab == NULL) return(0); if (ctxt->nsNr < nr) { xmlGenericError(xmlGenericErrorContext, "Pbm popping %d NS\n", nr); nr = ctxt->nsNr; } if (ctxt->nsNr <= 0) return (0); for (i = 0;i < nr;i++) { ctxt->nsNr--; ctxt->nsTab[ctxt->nsNr] = NULL; } return(nr);}#endifstatic intxmlCtxtGrowAttrs(xmlParserCtxtPtr ctxt, int nr) { const xmlChar **atts; int *attallocs; int maxatts; if (ctxt->atts == NULL) { maxatts = 55; /* allow for 10 attrs by default */ atts = (const xmlChar **) xmlMalloc(maxatts * sizeof(xmlChar *)); if (atts == NULL) goto mem_error; ctxt->atts = atts; attallocs = (int *) xmlMalloc((maxatts / 5) * sizeof(int)); if (attallocs == NULL) goto mem_error; ctxt->attallocs = attallocs; ctxt->maxatts = maxatts; } else if (nr + 5 > ctxt->maxatts) { maxatts = (nr + 5) * 2; atts = (const xmlChar **) xmlRealloc((void *) ctxt->atts, maxatts * sizeof(const xmlChar *)); if (atts == NULL) goto mem_error; ctxt->atts = atts; attallocs = (int *) xmlRealloc((void *) ctxt->attallocs, (maxatts / 5) * sizeof(int)); if (attallocs == NULL) goto mem_error; ctxt->attallocs = attallocs; ctxt->maxatts = maxatts; } return(ctxt->maxatts);mem_error: xmlErrMemory(ctxt, NULL); return(-1);}/** * inputPush: * @ctxt: an XML parser context * @value: the parser input * * Pushes a new parser input on top of the input stack * * Returns 0 in case of error, the index in the stack otherwise */intinputPush(xmlParserCtxtPtr ctxt, xmlParserInputPtr value){ if ((ctxt == NULL) || (value == NULL)) return(0); if (ctxt->inputNr >= ctxt->inputMax) { ctxt->inputMax *= 2; ctxt->inputTab = (xmlParserInputPtr *) xmlRealloc(ctxt->inputTab, ctxt->inputMax * sizeof(ctxt->inputTab[0])); if (ctxt->inputTab == NULL) { xmlErrMemory(ctxt, NULL); return (0); } } ctxt->inputTab[ctxt->inputNr] = value; ctxt->input = value; return (ctxt->inputNr++);}/** * inputPop: * @ctxt: an XML parser context * * Pops the top parser input from the input stack * * Returns the input just removed */xmlParserInputPtrinputPop(xmlParserCtxtPtr ctxt){ xmlParserInputPtr ret; if (ctxt == NULL) return(NULL); if (ctxt->inputNr <= 0) return (NULL); ctxt->inputNr--; if (ctxt->inputNr > 0) ctxt->input = ctxt->inputTab[ctxt->inputNr - 1]; else ctxt->input = NULL; ret = ctxt->inputTab[ctxt->inputNr]; ctxt->inputTab[ctxt->inputNr] = NULL; return (ret);}/** * nodePush: * @ctxt: an XML parser context * @value: the element node * * Pushes a new element node on top of the node stack * * Returns 0 in case of error, the index in the stack otherwise */intnodePush(xmlParserCtxtPtr ctxt, xmlNodePtr value){ if (ctxt == NULL) return(0); if (ctxt->nodeNr >= ctxt->nodeMax) { xmlNodePtr *tmp; tmp = (xmlNodePtr *) xmlRealloc(ctxt->nodeTab, ctxt->nodeMax * 2 * sizeof(ctxt->nodeTab[0])); if (tmp == NULL) { xmlErrMemory(ctxt, NULL); return (0); } ctxt->nodeTab = tmp; ctxt->nodeMax *= 2; } if (((unsigned int) ctxt->nodeNr) > xmlParserMaxDepth) { xmlFatalErrMsgInt(ctxt, XML_ERR_INTERNAL_ERROR, "Excessive depth in document: change xmlParserMaxDepth = %d\n", xmlParserMaxDepth); ctxt->instate = XML_PARSER_EOF; return(0); } ctxt->nodeTab[ctxt->nodeNr] = value; ctxt->node = value; return (ctxt->nodeNr++);}/** * nodePop: * @ctxt: an XML parser context * * Pops the top element node from the node stack * * Returns the node just removed */xmlNodePtrnodePop(xmlParserCtxtPtr ctxt){ xmlNodePtr ret; if (ctxt == NULL) return(NULL); if (ctxt->nodeNr <= 0) return (NULL); ctxt->nodeNr--; if (ctxt->nodeNr > 0) ctxt->node = ctxt->nodeTab[ctxt->nodeNr - 1]; else ctxt->node = NULL; ret = ctxt->nodeTab[ctxt->nodeNr]; ctxt->nodeTab[ctxt->nodeNr] = NULL; return (ret);}#ifdef LIBXML_PUSH_ENABLED/** * nameNsPush: * @ctxt: an XML parser context * @value: the element name * @prefix: the element prefix * @URI: the element namespace name * * Pushes a new element name/prefix/URL on top of the name stack * * Returns -1 in case of error, the index in the stack otherwise */static intnameNsPush(xmlParserCtxtPtr ctxt, const xmlChar * value, const xmlChar *prefix, const xmlChar *URI, int nsNr){ if (ctxt->nameNr >= ctxt->nameMax) { const xmlChar * *tmp; void **tmp2; ctxt->nameMax *= 2; tmp = (const xmlChar * *) xmlRealloc((xmlChar * *)ctxt->nameTab, ctxt->nameMax * sizeof(ctxt->nameTab[0])); if (tmp == NULL) { ctxt->nameMax /= 2; goto mem_error; } ctxt->nameTab = tmp; tmp2 = (void **) xmlRealloc((void * *)ctxt->pushTab, ctxt->nameMax * 3 * sizeof(ctxt->pushTab[0])); if (tmp2 == NULL) { ctxt->nameMax /= 2; goto mem_error; } ctxt->pushTab = tmp2; } ctxt->nameTab[ctxt->nameNr] = value; ctxt->name = value; ctxt->pushTab[ctxt->nameNr * 3] = (void *) prefix; ctxt->pushTab[ctxt->nameNr * 3 + 1] = (void *) URI; ctxt->pushTab[ctxt->nameNr * 3 + 2] = (void *) (long) nsNr; return (ctxt->nameNr++);mem_error: xmlErrMemory(ctxt, NULL); return (-1);}/** * nameNsPop: * @ctxt: an XML parser context * * Pops the top element/prefix/URI name from the name stack * * Returns the name just removed */static const xmlChar *nameNsPop(xmlParserCtxtPtr ctxt){ const xmlChar *ret; if (ctxt->nameNr <= 0) return (NULL); ctxt->nameNr--; if (ctxt->nameNr > 0) ctxt->name = ctxt->nameTab[ctxt->nameNr - 1];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -