📄 relaxng.c.svn-base
字号:
if (ret == NULL) { xmlRngVErrMemory(ctxt, "allocating states\n"); return (NULL); } memset(ret, 0, sizeof(xmlRelaxNGValidState)); } attrs = ret->attrs; maxAttrs = ret->maxAttrs; memcpy(ret, state, sizeof(xmlRelaxNGValidState)); ret->attrs = attrs; ret->maxAttrs = maxAttrs; if (state->nbAttrs > 0) { if (ret->attrs == NULL) { ret->maxAttrs = state->maxAttrs; ret->attrs = (xmlAttrPtr *) xmlMalloc(ret->maxAttrs * sizeof(xmlAttrPtr)); if (ret->attrs == NULL) { xmlRngVErrMemory(ctxt, "allocating states\n"); ret->nbAttrs = 0; return (ret); } } else if (ret->maxAttrs < state->nbAttrs) { xmlAttrPtr *tmp; tmp = (xmlAttrPtr *) xmlRealloc(ret->attrs, state->maxAttrs * sizeof(xmlAttrPtr)); if (tmp == NULL) { xmlRngVErrMemory(ctxt, "allocating states\n"); ret->nbAttrs = 0; return (ret); } ret->maxAttrs = state->maxAttrs; ret->attrs = tmp; } memcpy(ret->attrs, state->attrs, state->nbAttrs * sizeof(xmlAttrPtr)); } return (ret);}/** * xmlRelaxNGEqualValidState: * @ctxt: a Relax-NG validation context * @state1: a validation state * @state2: a validation state * * Compare the validation states for equality * * Returns 1 if equald, 0 otherwise */static intxmlRelaxNGEqualValidState(xmlRelaxNGValidCtxtPtr ctxt ATTRIBUTE_UNUSED, xmlRelaxNGValidStatePtr state1, xmlRelaxNGValidStatePtr state2){ int i; if ((state1 == NULL) || (state2 == NULL)) return (0); if (state1 == state2) return (1); if (state1->node != state2->node) return (0); if (state1->seq != state2->seq) return (0); if (state1->nbAttrLeft != state2->nbAttrLeft) return (0); if (state1->nbAttrs != state2->nbAttrs) return (0); if (state1->endvalue != state2->endvalue) return (0); if ((state1->value != state2->value) && (!xmlStrEqual(state1->value, state2->value))) return (0); for (i = 0; i < state1->nbAttrs; i++) { if (state1->attrs[i] != state2->attrs[i]) return (0); } return (1);}/** * xmlRelaxNGFreeValidState: * @state: a validation state structure * * Deallocate a RelaxNG validation state structure. */static voidxmlRelaxNGFreeValidState(xmlRelaxNGValidCtxtPtr ctxt, xmlRelaxNGValidStatePtr state){ if (state == NULL) return; if ((ctxt != NULL) && (ctxt->freeState == NULL)) { ctxt->freeState = xmlRelaxNGNewStates(ctxt, 40); } if ((ctxt == NULL) || (ctxt->freeState == NULL)) { if (state->attrs != NULL) xmlFree(state->attrs); xmlFree(state); } else { xmlRelaxNGAddStatesUniq(ctxt, ctxt->freeState, state); }}/************************************************************************ * * * Semi internal functions * * * ************************************************************************//** * xmlRelaxParserSetFlag: * @ctxt: a RelaxNG parser context * @flags: a set of flags values * * Semi private function used to pass informations to a parser context * which are a combination of xmlRelaxNGParserFlag . * * Returns 0 if success and -1 in case of error */intxmlRelaxParserSetFlag(xmlRelaxNGParserCtxtPtr ctxt, int flags){ if (ctxt == NULL) return(-1); if (flags & XML_RELAXNGP_FREE_DOC) { ctxt->crng |= XML_RELAXNGP_FREE_DOC; flags -= XML_RELAXNGP_FREE_DOC; } if (flags & XML_RELAXNGP_CRNG) { ctxt->crng |= XML_RELAXNGP_CRNG; flags -= XML_RELAXNGP_CRNG; } if (flags != 0) return(-1); return(0);}/************************************************************************ * * * Document functions * * * ************************************************************************/static xmlDocPtr xmlRelaxNGCleanupDoc(xmlRelaxNGParserCtxtPtr ctxt, xmlDocPtr doc);/** * xmlRelaxNGIncludePush: * @ctxt: the parser context * @value: the element doc * * Pushes a new include on top of the include stack * * Returns 0 in case of error, the index in the stack otherwise */static intxmlRelaxNGIncludePush(xmlRelaxNGParserCtxtPtr ctxt, xmlRelaxNGIncludePtr value){ if (ctxt->incTab == NULL) { ctxt->incMax = 4; ctxt->incNr = 0; ctxt->incTab = (xmlRelaxNGIncludePtr *) xmlMalloc(ctxt->incMax * sizeof(ctxt->incTab[0])); if (ctxt->incTab == NULL) { xmlRngPErrMemory(ctxt, "allocating include\n"); return (0); } } if (ctxt->incNr >= ctxt->incMax) { ctxt->incMax *= 2; ctxt->incTab = (xmlRelaxNGIncludePtr *) xmlRealloc(ctxt->incTab, ctxt->incMax * sizeof(ctxt->incTab[0])); if (ctxt->incTab == NULL) { xmlRngPErrMemory(ctxt, "allocating include\n"); return (0); } } ctxt->incTab[ctxt->incNr] = value; ctxt->inc = value; return (ctxt->incNr++);}/** * xmlRelaxNGIncludePop: * @ctxt: the parser context * * Pops the top include from the include stack * * Returns the include just removed */static xmlRelaxNGIncludePtrxmlRelaxNGIncludePop(xmlRelaxNGParserCtxtPtr ctxt){ xmlRelaxNGIncludePtr ret; if (ctxt->incNr <= 0) return (0); ctxt->incNr--; if (ctxt->incNr > 0) ctxt->inc = ctxt->incTab[ctxt->incNr - 1]; else ctxt->inc = NULL; ret = ctxt->incTab[ctxt->incNr]; ctxt->incTab[ctxt->incNr] = 0; return (ret);}/** * xmlRelaxNGRemoveRedefine: * @ctxt: the parser context * @URL: the normalized URL * @target: the included target * @name: the define name to eliminate * * Applies the elimination algorithm of 4.7 * * Returns 0 in case of error, 1 in case of success. */static intxmlRelaxNGRemoveRedefine(xmlRelaxNGParserCtxtPtr ctxt, const xmlChar * URL ATTRIBUTE_UNUSED, xmlNodePtr target, const xmlChar * name){ int found = 0; xmlNodePtr tmp, tmp2; xmlChar *name2;#ifdef DEBUG_INCLUDE if (name == NULL) xmlGenericError(xmlGenericErrorContext, "Elimination of <include> start from %s\n", URL); else xmlGenericError(xmlGenericErrorContext, "Elimination of <include> define %s from %s\n", name, URL);#endif tmp = target; while (tmp != NULL) { tmp2 = tmp->next; if ((name == NULL) && (IS_RELAXNG(tmp, "start"))) { found = 1; xmlUnlinkNode(tmp); xmlFreeNode(tmp); } else if ((name != NULL) && (IS_RELAXNG(tmp, "define"))) { name2 = xmlGetProp(tmp, BAD_CAST "name"); xmlRelaxNGNormExtSpace(name2); if (name2 != NULL) { if (xmlStrEqual(name, name2)) { found = 1; xmlUnlinkNode(tmp); xmlFreeNode(tmp); } xmlFree(name2); } } else if (IS_RELAXNG(tmp, "include")) { xmlChar *href = NULL; xmlRelaxNGDocumentPtr inc = tmp->psvi; if ((inc != NULL) && (inc->doc != NULL) && (inc->doc->children != NULL)) { if (xmlStrEqual (inc->doc->children->name, BAD_CAST "grammar")) {#ifdef DEBUG_INCLUDE href = xmlGetProp(tmp, BAD_CAST "href");#endif if (xmlRelaxNGRemoveRedefine(ctxt, href, inc->doc->children-> children, name) == 1) { found = 1; } if (href != NULL) xmlFree(href); } } } tmp = tmp2; } return (found);}/** * xmlRelaxNGLoadInclude: * @ctxt: the parser context * @URL: the normalized URL * @node: the include node. * @ns: the namespace passed from the context. * * First lookup if the document is already loaded into the parser context, * check against recursion. If not found the resource is loaded and * the content is preprocessed before being returned back to the caller. * * Returns the xmlRelaxNGIncludePtr or NULL in case of error */static xmlRelaxNGIncludePtrxmlRelaxNGLoadInclude(xmlRelaxNGParserCtxtPtr ctxt, const xmlChar * URL, xmlNodePtr node, const xmlChar * ns){ xmlRelaxNGIncludePtr ret = NULL; xmlDocPtr doc; int i; xmlNodePtr root, cur;#ifdef DEBUG_INCLUDE xmlGenericError(xmlGenericErrorContext, "xmlRelaxNGLoadInclude(%s)\n", URL);#endif /* * check against recursion in the stack */ for (i = 0; i < ctxt->incNr; i++) { if (xmlStrEqual(ctxt->incTab[i]->href, URL)) { xmlRngPErr(ctxt, NULL, XML_RNGP_INCLUDE_RECURSE, "Detected an Include recursion for %s\n", URL, NULL); return (NULL); } } /* * load the document */ doc = xmlReadFile((const char *) URL,NULL,0); if (doc == NULL) { xmlRngPErr(ctxt, node, XML_RNGP_PARSE_ERROR, "xmlRelaxNG: could not load %s\n", URL, NULL); return (NULL); }#ifdef DEBUG_INCLUDE xmlGenericError(xmlGenericErrorContext, "Parsed %s Okay\n", URL);#endif /* * Allocate the document structures and register it first. */ ret = (xmlRelaxNGIncludePtr) xmlMalloc(sizeof(xmlRelaxNGInclude)); if (ret == NULL) { xmlRngPErrMemory(ctxt, "allocating include\n"); xmlFreeDoc(doc); return (NULL); } memset(ret, 0, sizeof(xmlRelaxNGInclude)); ret->doc = doc; ret->href = xmlStrdup(URL); ret->next = ctxt->includes; ctxt->includes = ret; /* * transmit the ns if needed */ if (ns != NULL) { root = xmlDocGetRootElement(doc); if (root != NULL) { if (xmlHasProp(root, BAD_CAST "ns") == NULL) { xmlSetProp(root, BAD_CAST "ns", ns); } } } /* * push it on the stack */ xmlRelaxNGIncludePush(ctxt, ret); /* * Some preprocessing of the document content, this include recursing * in the include stack. */#ifdef DEBUG_INCLUDE xmlGenericError(xmlGenericErrorContext, "cleanup of %s\n", URL);#endif doc = xmlRelaxNGCleanupDoc(ctxt, doc); if (doc == NULL) { ctxt->inc = NULL; return (NULL); } /* * Pop up the include from the stack */ xmlRelaxNGIncludePop(ctxt);#ifdef DEBUG_INCLUDE xmlGenericError(xmlGenericErrorContext, "Checking of %s\n", URL);#endif /* * Check that the top element is a grammar */ root = xmlDocGetRootElement(doc); if (root == NULL) { xmlRngPErr(ctxt, node, XML_RNGP_EMPTY, "xmlRelaxNG: included document is empty %s\n", URL, NULL); return (NULL); } if (!IS_RELAXNG(root, "grammar")) { xmlRngPErr(ctxt, node, XML_RNGP_GRAMMAR_MISSING, "xmlRelaxNG: included document %s root is not a grammar\n", URL, NULL); return (NULL); } /* * Elimination of redefined rules in the include. */ cur = node->children; while (cur != NULL) { if (IS_RELAXNG(cur, "start")) { int found = 0; found = xmlRelaxNGRemoveRedefine(ctxt, URL, root->children, NULL); if (!found) { xmlRngPErr(ctxt, node, XML_RNGP_START_MISSING, "xmlRelaxNG: include %s has a start but not the included grammar\n", URL, NULL); } } else if (IS_RELAXNG(cur, "define")) { xmlChar *name;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -