📄 valid.c.svn-base
字号:
break; case XML_DOCUMENT_FRAG_NODE: xmlGenericError(xmlGenericErrorContext, "?frag? "); break; case XML_NOTATION_NODE: xmlGenericError(xmlGenericErrorContext, "?nota? "); break; case XML_HTML_DOCUMENT_NODE: xmlGenericError(xmlGenericErrorContext, "?html? "); break;#ifdef LIBXML_DOCB_ENABLED case XML_DOCB_DOCUMENT_NODE: xmlGenericError(xmlGenericErrorContext, "?docb? "); break;#endif case XML_DTD_NODE: xmlGenericError(xmlGenericErrorContext, "?dtd? "); break; case XML_ELEMENT_DECL: xmlGenericError(xmlGenericErrorContext, "?edecl? "); break; case XML_ATTRIBUTE_DECL: xmlGenericError(xmlGenericErrorContext, "?adecl? "); break; case XML_ENTITY_DECL: xmlGenericError(xmlGenericErrorContext, "?entdecl? "); break; case XML_NAMESPACE_DECL: xmlGenericError(xmlGenericErrorContext, "?nsdecl? "); break; case XML_XINCLUDE_START: xmlGenericError(xmlGenericErrorContext, "incstart "); break; case XML_XINCLUDE_END: xmlGenericError(xmlGenericErrorContext, "incend "); break; }}static voidxmlValidPrintNodeList(xmlNodePtr cur) { if (cur == NULL) xmlGenericError(xmlGenericErrorContext, "null "); while (cur != NULL) { xmlValidPrintNode(cur); cur = cur->next; }}static voidxmlValidDebug(xmlNodePtr cur, xmlElementContentPtr cont) { char expr[5000]; expr[0] = 0; xmlGenericError(xmlGenericErrorContext, "valid: "); xmlValidPrintNodeList(cur); xmlGenericError(xmlGenericErrorContext, "against "); xml_snprintfElementContent(expr, 5000, cont, 1); xmlGenericError(xmlGenericErrorContext, "%s\n", expr);}static voidxmlValidDebugState(xmlValidStatePtr state) { xmlGenericError(xmlGenericErrorContext, "("); if (state->cont == NULL) xmlGenericError(xmlGenericErrorContext, "null,"); else switch (state->cont->type) { case XML_ELEMENT_CONTENT_PCDATA: xmlGenericError(xmlGenericErrorContext, "pcdata,"); break; case XML_ELEMENT_CONTENT_ELEMENT: xmlGenericError(xmlGenericErrorContext, "%s,", state->cont->name); break; case XML_ELEMENT_CONTENT_SEQ: xmlGenericError(xmlGenericErrorContext, "seq,"); break; case XML_ELEMENT_CONTENT_OR: xmlGenericError(xmlGenericErrorContext, "or,"); break; } xmlValidPrintNode(state->node); xmlGenericError(xmlGenericErrorContext, ",%d,%X,%d)", state->depth, state->occurs, state->state);}static voidxmlValidStateDebug(xmlValidCtxtPtr ctxt) { int i, j; xmlGenericError(xmlGenericErrorContext, "state: "); xmlValidDebugState(ctxt->vstate); xmlGenericError(xmlGenericErrorContext, " stack: %d ", ctxt->vstateNr - 1); for (i = 0, j = ctxt->vstateNr - 1;(i < 3) && (j > 0);i++,j--) xmlValidDebugState(&ctxt->vstateTab[j]); xmlGenericError(xmlGenericErrorContext, "\n");}/*****#define DEBUG_VALID_STATE(n,c) xmlValidDebug(n,c); *****/#define DEBUG_VALID_STATE(n,c) xmlValidStateDebug(ctxt);#define DEBUG_VALID_MSG(m) \ xmlGenericError(xmlGenericErrorContext, "%s\n", m); #else#define DEBUG_VALID_STATE(n,c)#define DEBUG_VALID_MSG(m)#endif/* TODO: use hash table for accesses to elem and attribute definitions */#define CHECK_DTD \ if (doc == NULL) return(0); \ else if ((doc->intSubset == NULL) && \ (doc->extSubset == NULL)) return(0)xmlAttributePtr xmlScanAttributeDecl(xmlDtdPtr dtd, const xmlChar *elem);#ifdef LIBXML_REGEXP_ENABLED/************************************************************************ * * * Content model validation based on the regexps * * * ************************************************************************//** * xmlValidBuildAContentModel: * @content: the content model * @ctxt: the schema parser context * @name: the element name whose content is being built * * Generate the automata sequence needed for that type * * Returns 1 if successful or 0 in case of error. */static intxmlValidBuildAContentModel(xmlElementContentPtr content, xmlValidCtxtPtr ctxt, const xmlChar *name) { if (content == NULL) { xmlErrValidNode(ctxt, NULL, XML_ERR_INTERNAL_ERROR, "Found NULL content in content model of %s\n", name, NULL, NULL); return(0); } switch (content->type) { case XML_ELEMENT_CONTENT_PCDATA: xmlErrValidNode(ctxt, NULL, XML_ERR_INTERNAL_ERROR, "Found PCDATA in content model of %s\n", name, NULL, NULL); return(0); break; case XML_ELEMENT_CONTENT_ELEMENT: { xmlAutomataStatePtr oldstate = ctxt->state; xmlChar fn[50]; xmlChar *fullname; fullname = xmlBuildQName(content->name, content->prefix, fn, 50); if (fullname == NULL) { xmlVErrMemory(ctxt, "Building content model"); return(0); } switch (content->ocur) { case XML_ELEMENT_CONTENT_ONCE: ctxt->state = xmlAutomataNewTransition(ctxt->am, ctxt->state, NULL, fullname, NULL); break; case XML_ELEMENT_CONTENT_OPT: ctxt->state = xmlAutomataNewTransition(ctxt->am, ctxt->state, NULL, fullname, NULL); xmlAutomataNewEpsilon(ctxt->am, oldstate, ctxt->state); break; case XML_ELEMENT_CONTENT_PLUS: ctxt->state = xmlAutomataNewTransition(ctxt->am, ctxt->state, NULL, fullname, NULL); xmlAutomataNewTransition(ctxt->am, ctxt->state, ctxt->state, fullname, NULL); break; case XML_ELEMENT_CONTENT_MULT: ctxt->state = xmlAutomataNewEpsilon(ctxt->am, ctxt->state, NULL); xmlAutomataNewTransition(ctxt->am, ctxt->state, ctxt->state, fullname, NULL); break; } if ((fullname != fn) && (fullname != content->name)) xmlFree(fullname); break; } case XML_ELEMENT_CONTENT_SEQ: { xmlAutomataStatePtr oldstate, oldend; xmlElementContentOccur ocur; /* * Simply iterate over the content */ oldstate = ctxt->state; ocur = content->ocur; if (ocur != XML_ELEMENT_CONTENT_ONCE) { ctxt->state = xmlAutomataNewEpsilon(ctxt->am, oldstate, NULL); oldstate = ctxt->state; } do { xmlValidBuildAContentModel(content->c1, ctxt, name); content = content->c2; } while ((content->type == XML_ELEMENT_CONTENT_SEQ) && (content->ocur == XML_ELEMENT_CONTENT_ONCE)); xmlValidBuildAContentModel(content, ctxt, name); oldend = ctxt->state; ctxt->state = xmlAutomataNewEpsilon(ctxt->am, oldend, NULL); switch (ocur) { case XML_ELEMENT_CONTENT_ONCE: break; case XML_ELEMENT_CONTENT_OPT: xmlAutomataNewEpsilon(ctxt->am, oldstate, ctxt->state); break; case XML_ELEMENT_CONTENT_MULT: xmlAutomataNewEpsilon(ctxt->am, oldstate, ctxt->state); xmlAutomataNewEpsilon(ctxt->am, oldend, oldstate); break; case XML_ELEMENT_CONTENT_PLUS: xmlAutomataNewEpsilon(ctxt->am, oldend, oldstate); break; } break; } case XML_ELEMENT_CONTENT_OR: { xmlAutomataStatePtr oldstate, oldend; xmlElementContentOccur ocur; ocur = content->ocur; if ((ocur == XML_ELEMENT_CONTENT_PLUS) || (ocur == XML_ELEMENT_CONTENT_MULT)) { ctxt->state = xmlAutomataNewEpsilon(ctxt->am, ctxt->state, NULL); } oldstate = ctxt->state; oldend = xmlAutomataNewState(ctxt->am); /* * iterate over the subtypes and remerge the end with an * epsilon transition */ do { ctxt->state = oldstate; xmlValidBuildAContentModel(content->c1, ctxt, name); xmlAutomataNewEpsilon(ctxt->am, ctxt->state, oldend); content = content->c2; } while ((content->type == XML_ELEMENT_CONTENT_OR) && (content->ocur == XML_ELEMENT_CONTENT_ONCE)); ctxt->state = oldstate; xmlValidBuildAContentModel(content, ctxt, name); xmlAutomataNewEpsilon(ctxt->am, ctxt->state, oldend); ctxt->state = xmlAutomataNewEpsilon(ctxt->am, oldend, NULL); switch (ocur) { case XML_ELEMENT_CONTENT_ONCE: break; case XML_ELEMENT_CONTENT_OPT: xmlAutomataNewEpsilon(ctxt->am, oldstate, ctxt->state); break; case XML_ELEMENT_CONTENT_MULT: xmlAutomataNewEpsilon(ctxt->am, oldstate, ctxt->state); xmlAutomataNewEpsilon(ctxt->am, oldend, oldstate); break; case XML_ELEMENT_CONTENT_PLUS: xmlAutomataNewEpsilon(ctxt->am, oldend, oldstate); break; } break; } default: xmlErrValid(ctxt, XML_ERR_INTERNAL_ERROR, "ContentModel broken for element %s\n", (const char *) name); return(0); } return(1);}/** * xmlValidBuildContentModel: * @ctxt: a validation context * @elem: an element declaration node * * (Re)Build the automata associated to the content model of this * element * * Returns 1 in case of success, 0 in case of error */intxmlValidBuildContentModel(xmlValidCtxtPtr ctxt, xmlElementPtr elem) { if ((ctxt == NULL) || (elem == NULL)) return(0); if (elem->type != XML_ELEMENT_DECL) return(0); if (elem->etype != XML_ELEMENT_TYPE_ELEMENT) return(1); /* TODO: should we rebuild in this case ? */ if (elem->contModel != NULL) { if (!xmlRegexpIsDeterminist(elem->contModel)) { ctxt->valid = 0; return(0); } return(1); } ctxt->am = xmlNewAutomata(); if (ctxt->am == NULL) { xmlErrValidNode(ctxt, (xmlNodePtr) elem, XML_ERR_INTERNAL_ERROR, "Cannot create automata for element %s\n", elem->name, NULL, NULL); return(0); } ctxt->state = xmlAutomataGetInitState(ctxt->am); xmlValidBuildAContentModel(elem->content, ctxt, elem->name); xmlAutomataSetFinalState(ctxt->am, ctxt->state); elem->contModel = xmlAutomataCompile(ctxt->am); if (xmlRegexpIsDeterminist(elem->contModel) != 1) { char expr[5000]; expr[0] = 0; xml_snprintfElementContent(expr, 5000, elem->content, 1); xmlErrValidNode(ctxt, (xmlNodePtr) elem, XML_DTD_CONTENT_NOT_DETERMINIST, "Content model of %s is not determinist: %s\n", elem->name, BAD_CAST expr, NULL);#ifdef DEBUG_REGEXP_ALGO xmlRegexpPrint(stderr, elem->contModel);#endif ctxt->valid = 0; ctxt->state = NULL; xmlFreeAutomata(ctxt->am); ctxt->am = NULL; return(0); } ctxt->state = NULL; xmlFreeAutomata(ctxt->am); ctxt->am = NULL; return(1);}#endif /* LIBXML_REGEXP_ENABLED *//**************************************************************** * * * Util functions for data allocation/deallocation * * * ****************************************************************//** * xmlNewValidCtxt: * * Allocate a validation context structure. * * Returns NULL if not, otherwise the new validation context structure */xmlValidCtxtPtr xmlNewValidCtxt(void) { xmlValidCtxtPtr ret; if ((ret = xmlMalloc(sizeof (xmlValidCtxt))) == NULL) { xmlVErrMemory(NULL, "malloc failed"); return (NULL); } (void) memset(ret, 0, sizeof (xmlValidCtxt)); return (ret);}/** * xmlFreeValidCtxt: * @cur: the validation context to free * * Free a validation context structure. */voidxmlFreeValidCtxt(xmlValidCtxtPtr cur) { xmlFree(cur);}#endif /* LIBXML_VALID_ENABLED *//** * xmlNewElementContent: * @name: the subelement name or NULL * @type: the type of element content decl * * Allocate an element content structure. * * Returns NULL if not, otherwise the new element content structure */xmlElementContentPtrxmlNewElementContent(const xmlChar *name, xmlElementContentType type) { xmlElementContentPtr ret; switch(type) { case XML_ELEMENT_CONTENT_ELEMENT: if (name == NULL) { xmlErrValid(NULL, XML_ERR_INTERNAL_ERROR, "xmlNewElementContent : name == NULL !\n", NULL); } break; case XML_ELEMENT_CONTENT_PCDATA: case XML_ELEMENT_CONTENT_SEQ: case XML_ELEMENT_CONTENT_OR: if (name != NULL) { xmlErrValid(NULL, XML_ERR_INTERNAL_ERROR, "xmlNewElementContent : name != NULL !\n", NULL); } break; default: xmlErrValid(NULL, XML_ERR_INTERNAL_ERROR, "Internal: ELEMENT content corrupted invalid type\n", NULL); return(NULL); } ret = (xmlElementContentPtr) xmlMalloc(sizeof(xmlElementContent)); if (ret == NULL) { xmlVErrMemory(NULL, "malloc failed"); return(NULL); } memset(ret, 0, sizeof(xmlElementContent)); ret->type = type; ret->ocur = XML_ELEMENT_CONTENT_ONCE; if (name != NULL) { xmlChar *prefix = NULL; ret->name = xmlSplitQName2(name, &prefix); if (ret->name == NULL) ret->name = xmlStrdup(name); ret->prefix = prefix; } else { ret->name = NULL; ret->prefix = NULL; } ret->c1 = ret->c2 = ret->parent = NULL; return(ret);}/** * xmlCopyElementContent: * @cur: An element content pointer. * * Build a copy of an element content description. * * Returns the new xmlElementContentPtr or NULL in case of error. */xmlElementContentPtrxmlCopyElementContent(xmlElementContentPtr cur) { xmlElementContentPtr ret; if (cur == NULL) return(NULL); ret = xmlNewElementContent((xmlChar *) cur->name, cur->type); if (ret == NULL) { xmlVErrMemory(NULL, "malloc failed"); return(NULL); } if (cur->prefix != NULL) ret->prefix = xmlStrdup(cur->prefix); ret->ocur = cur->ocur; if (cur->c1 != NULL) ret->c1 = xmlCopyElementContent(cur->c1); if (ret->c1 != NULL) ret->c1->parent = ret; if (cur->c2 != NULL) ret->c2 = xmlCopyElementContent(cur->c2); if (ret->c2 != NULL) ret->c2->parent = ret; return(ret);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -