⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 valid.c.svn-base

📁 这是一个用于解析xml文件的类库。使用这个类库
💻 SVN-BASE
📖 第 1 页 / 共 5 页
字号:
/* * valid.c : part of the code use to do the DTD handling and the validity *           checking * * See Copyright for the status of this software. * * daniel@veillard.com */#define IN_LIBXML#include "libxml.h"#include <string.h>#ifdef HAVE_STDLIB_H#include <stdlib.h>#endif#include <libxml/xmlmemory.h>#include <libxml/hash.h>#include <libxml/valid.h>#include <libxml/parser.h>#include <libxml/parserInternals.h>#include <libxml/xmlerror.h>#include <libxml/list.h>#include <libxml/globals.h>static xmlElementPtr xmlGetDtdElementDesc2(xmlDtdPtr dtd, const xmlChar *name,	                           int create);/* #define DEBUG_VALID_ALGO *//* #define DEBUG_REGEXP_ALGO */#define TODO 								\    xmlGenericError(xmlGenericErrorContext,				\	    "Unimplemented block at %s:%d\n",				\            __FILE__, __LINE__);/************************************************************************ *									* *			Error handling routines				* *									* ************************************************************************//** * xmlVErrMemory: * @ctxt:  an XML validation parser context * @extra:  extra informations * * Handle an out of memory error */static voidxmlVErrMemory(xmlValidCtxtPtr ctxt, const char *extra){    xmlGenericErrorFunc channel = NULL;    xmlParserCtxtPtr pctxt = NULL;    void *data = NULL;    if (ctxt != NULL) {        channel = ctxt->error;        data = ctxt->userData;	pctxt = ctxt->userData;    }    if (extra)        __xmlRaiseError(NULL, channel, data,                        pctxt, NULL, XML_FROM_VALID, XML_ERR_NO_MEMORY,                        XML_ERR_FATAL, NULL, 0, extra, NULL, NULL, 0, 0,                        "Memory allocation failed : %s\n", extra);    else        __xmlRaiseError(NULL, channel, data,                        pctxt, NULL, XML_FROM_VALID, XML_ERR_NO_MEMORY,                        XML_ERR_FATAL, NULL, 0, NULL, NULL, NULL, 0, 0,                        "Memory allocation failed\n");}/** * xmlErrValid: * @ctxt:  an XML validation parser context * @error:  the error number * @extra:  extra informations * * Handle a validation error */static voidxmlErrValid(xmlValidCtxtPtr ctxt, xmlParserErrors error,            const char *msg, const char *extra){    xmlGenericErrorFunc channel = NULL;    xmlParserCtxtPtr pctxt = NULL;    void *data = NULL;    if (ctxt != NULL) {        channel = ctxt->error;        data = ctxt->userData;	pctxt = ctxt->userData;    }    if (extra)        __xmlRaiseError(NULL, channel, data,                        pctxt, NULL, XML_FROM_VALID, error,                        XML_ERR_ERROR, NULL, 0, extra, NULL, NULL, 0, 0,                        msg, extra);    else        __xmlRaiseError(NULL, channel, data,                        pctxt, NULL, XML_FROM_VALID, error,                        XML_ERR_ERROR, NULL, 0, NULL, NULL, NULL, 0, 0,                        msg);}#if defined(LIBXML_VALID_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)/** * xmlErrValidNode: * @ctxt:  an XML validation parser context * @node:  the node raising the error * @error:  the error number * @str1:  extra informations * @str2:  extra informations * @str3:  extra informations * * Handle a validation error, provide contextual informations */static voidxmlErrValidNode(xmlValidCtxtPtr ctxt,                xmlNodePtr node, xmlParserErrors error,                const char *msg, const xmlChar * str1,                const xmlChar * str2, const xmlChar * str3){    xmlStructuredErrorFunc schannel = NULL;    xmlGenericErrorFunc channel = NULL;    xmlParserCtxtPtr pctxt = NULL;    void *data = NULL;    if (ctxt != NULL) {        channel = ctxt->error;        data = ctxt->userData;	pctxt = ctxt->userData;    }    __xmlRaiseError(schannel, channel, data, pctxt, node, XML_FROM_VALID, error,                    XML_ERR_ERROR, NULL, 0,                    (const char *) str1,                    (const char *) str1,                    (const char *) str3, 0, 0, msg, str1, str2, str3);}#endif /* LIBXML_VALID_ENABLED or LIBXML_SCHEMAS_ENABLED */#ifdef LIBXML_VALID_ENABLED/** * xmlErrValidNodeNr: * @ctxt:  an XML validation parser context * @node:  the node raising the error * @error:  the error number * @str1:  extra informations * @int2:  extra informations * @str3:  extra informations * * Handle a validation error, provide contextual informations */static voidxmlErrValidNodeNr(xmlValidCtxtPtr ctxt,                xmlNodePtr node, xmlParserErrors error,                const char *msg, const xmlChar * str1,                int int2, const xmlChar * str3){    xmlStructuredErrorFunc schannel = NULL;    xmlGenericErrorFunc channel = NULL;    xmlParserCtxtPtr pctxt = NULL;    void *data = NULL;    if (ctxt != NULL) {        channel = ctxt->error;        data = ctxt->userData;	pctxt = ctxt->userData;    }    __xmlRaiseError(schannel, channel, data, pctxt, node, XML_FROM_VALID, error,                    XML_ERR_ERROR, NULL, 0,                    (const char *) str1,                    (const char *) str3,                    NULL, int2, 0, msg, str1, int2, str3);}/** * xmlErrValidWarning: * @ctxt:  an XML validation parser context * @node:  the node raising the error * @error:  the error number * @str1:  extra information * @str2:  extra information * @str3:  extra information * * Handle a validation error, provide contextual information */static voidxmlErrValidWarning(xmlValidCtxtPtr ctxt,                xmlNodePtr node, xmlParserErrors error,                const char *msg, const xmlChar * str1,                const xmlChar * str2, const xmlChar * str3){    xmlStructuredErrorFunc schannel = NULL;    xmlGenericErrorFunc channel = NULL;    xmlParserCtxtPtr pctxt = NULL;    void *data = NULL;    if (ctxt != NULL) {        channel = ctxt->error;        data = ctxt->userData;	pctxt = ctxt->userData;    }    __xmlRaiseError(schannel, channel, data, pctxt, node, XML_FROM_VALID, error,                    XML_ERR_WARNING, NULL, 0,                    (const char *) str1,                    (const char *) str1,                    (const char *) str3, 0, 0, msg, str1, str2, str3);}#ifdef LIBXML_REGEXP_ENABLED/* * If regexp are enabled we can do continuous validation without the * need of a tree to validate the content model. this is done in each * callbacks. * Each xmlValidState represent the validation state associated to the * set of nodes currently open from the document root to the current element. */typedef struct _xmlValidState {    xmlElementPtr	 elemDecl;	/* pointer to the content model */    xmlNodePtr           node;		/* pointer to the current node */    xmlRegExecCtxtPtr    exec;		/* regexp runtime */} _xmlValidState;static intvstateVPush(xmlValidCtxtPtr ctxt, xmlElementPtr elemDecl, xmlNodePtr node) {    if ((ctxt->vstateMax == 0) || (ctxt->vstateTab == NULL)) {	ctxt->vstateMax = 10;	ctxt->vstateTab = (xmlValidState *) xmlMalloc(ctxt->vstateMax *		              sizeof(ctxt->vstateTab[0]));        if (ctxt->vstateTab == NULL) {	    xmlVErrMemory(ctxt, "malloc failed");	    return(-1);	}    }    if (ctxt->vstateNr >= ctxt->vstateMax) {        xmlValidState *tmp;	tmp = (xmlValidState *) xmlRealloc(ctxt->vstateTab,	             2 * ctxt->vstateMax * sizeof(ctxt->vstateTab[0]));        if (tmp == NULL) {	    xmlVErrMemory(ctxt, "realloc failed");	    return(-1);	}	ctxt->vstateMax *= 2;	ctxt->vstateTab = tmp;    }    ctxt->vstate = &ctxt->vstateTab[ctxt->vstateNr];    ctxt->vstateTab[ctxt->vstateNr].elemDecl = elemDecl;    ctxt->vstateTab[ctxt->vstateNr].node = node;    if ((elemDecl != NULL) && (elemDecl->etype == XML_ELEMENT_TYPE_ELEMENT)) {	if (elemDecl->contModel == NULL)	    xmlValidBuildContentModel(ctxt, elemDecl);	if (elemDecl->contModel != NULL) {	    ctxt->vstateTab[ctxt->vstateNr].exec = 		xmlRegNewExecCtxt(elemDecl->contModel, NULL, NULL);	} else {	    ctxt->vstateTab[ctxt->vstateNr].exec = NULL;	    xmlErrValidNode(ctxt, (xmlNodePtr) elemDecl,	                    XML_ERR_INTERNAL_ERROR,			    "Failed to build content model regexp for %s\n",			    node->name, NULL, NULL);	}    }    return(ctxt->vstateNr++);}static intvstateVPop(xmlValidCtxtPtr ctxt) {    xmlElementPtr elemDecl;    if (ctxt->vstateNr < 1) return(-1);    ctxt->vstateNr--;    elemDecl = ctxt->vstateTab[ctxt->vstateNr].elemDecl;    ctxt->vstateTab[ctxt->vstateNr].elemDecl = NULL;    ctxt->vstateTab[ctxt->vstateNr].node = NULL;    if ((elemDecl != NULL) && (elemDecl->etype == XML_ELEMENT_TYPE_ELEMENT)) {	xmlRegFreeExecCtxt(ctxt->vstateTab[ctxt->vstateNr].exec);    }    ctxt->vstateTab[ctxt->vstateNr].exec = NULL;    if (ctxt->vstateNr >= 1)	ctxt->vstate = &ctxt->vstateTab[ctxt->vstateNr - 1];    else	ctxt->vstate = NULL;    return(ctxt->vstateNr);}#else /* not LIBXML_REGEXP_ENABLED *//* * If regexp are not enabled, it uses a home made algorithm less * complex and easier to * debug/maintain than a generic NFA -> DFA state based algo. The * only restriction is on the deepness of the tree limited by the * size of the occurs bitfield * * this is the content of a saved state for rollbacks */#define ROLLBACK_OR	0#define ROLLBACK_PARENT	1typedef struct _xmlValidState {    xmlElementContentPtr cont;	/* pointer to the content model subtree */    xmlNodePtr           node;	/* pointer to the current node in the list */    long                 occurs;/* bitfield for multiple occurrences */    unsigned char        depth; /* current depth in the overall tree */    unsigned char        state; /* ROLLBACK_XXX */} _xmlValidState;#define MAX_RECURSE 25000#define MAX_DEPTH ((sizeof(_xmlValidState.occurs)) * 8)#define CONT ctxt->vstate->cont#define NODE ctxt->vstate->node#define DEPTH ctxt->vstate->depth#define OCCURS ctxt->vstate->occurs#define STATE ctxt->vstate->state#define OCCURRENCE (ctxt->vstate->occurs & (1 << DEPTH))#define PARENT_OCCURRENCE (ctxt->vstate->occurs & ((1 << DEPTH) - 1))#define SET_OCCURRENCE ctxt->vstate->occurs |= (1 << DEPTH)#define RESET_OCCURRENCE ctxt->vstate->occurs &= ((1 << DEPTH) - 1)static intvstateVPush(xmlValidCtxtPtr ctxt, xmlElementContentPtr cont,	    xmlNodePtr node, unsigned char depth, long occurs,	    unsigned char state) {    int i = ctxt->vstateNr - 1;    if (ctxt->vstateNr > MAX_RECURSE) {	return(-1);    }    if (ctxt->vstateTab == NULL) {	ctxt->vstateMax = 8;	ctxt->vstateTab = (xmlValidState *) xmlMalloc(		     ctxt->vstateMax * sizeof(ctxt->vstateTab[0]));	if (ctxt->vstateTab == NULL) {	    xmlVErrMemory(ctxt, "malloc failed");	    return(-1);	}    }    if (ctxt->vstateNr >= ctxt->vstateMax) {        xmlValidState *tmp;        tmp = (xmlValidState *) xmlRealloc(ctxt->vstateTab,	             2 * ctxt->vstateMax * sizeof(ctxt->vstateTab[0]));        if (tmp == NULL) {	    xmlVErrMemory(ctxt, "malloc failed");	    return(-1);	}	ctxt->vstateMax *= 2;	ctxt->vstateTab = tmp;	ctxt->vstate = &ctxt->vstateTab[0];    }    /*     * Don't push on the stack a state already here     */    if ((i >= 0) && (ctxt->vstateTab[i].cont == cont) &&	(ctxt->vstateTab[i].node == node) &&	(ctxt->vstateTab[i].depth == depth) &&	(ctxt->vstateTab[i].occurs == occurs) &&	(ctxt->vstateTab[i].state == state))	return(ctxt->vstateNr);    ctxt->vstateTab[ctxt->vstateNr].cont = cont;    ctxt->vstateTab[ctxt->vstateNr].node = node;    ctxt->vstateTab[ctxt->vstateNr].depth = depth;    ctxt->vstateTab[ctxt->vstateNr].occurs = occurs;    ctxt->vstateTab[ctxt->vstateNr].state = state;    return(ctxt->vstateNr++);}static intvstateVPop(xmlValidCtxtPtr ctxt) {    if (ctxt->vstateNr <= 1) return(-1);    ctxt->vstateNr--;    ctxt->vstate = &ctxt->vstateTab[0];    ctxt->vstate->cont =  ctxt->vstateTab[ctxt->vstateNr].cont;    ctxt->vstate->node = ctxt->vstateTab[ctxt->vstateNr].node;    ctxt->vstate->depth = ctxt->vstateTab[ctxt->vstateNr].depth;    ctxt->vstate->occurs = ctxt->vstateTab[ctxt->vstateNr].occurs;    ctxt->vstate->state = ctxt->vstateTab[ctxt->vstateNr].state;    return(ctxt->vstateNr);}#endif /* LIBXML_REGEXP_ENABLED */static intnodeVPush(xmlValidCtxtPtr ctxt, xmlNodePtr value){    if (ctxt->nodeMax <= 0) {        ctxt->nodeMax = 4;        ctxt->nodeTab =            (xmlNodePtr *) xmlMalloc(ctxt->nodeMax *                                     sizeof(ctxt->nodeTab[0]));        if (ctxt->nodeTab == NULL) {	    xmlVErrMemory(ctxt, "malloc failed");            ctxt->nodeMax = 0;            return (0);        }    }    if (ctxt->nodeNr >= ctxt->nodeMax) {        xmlNodePtr *tmp;        tmp = (xmlNodePtr *) xmlRealloc(ctxt->nodeTab,			      ctxt->nodeMax * 2 * sizeof(ctxt->nodeTab[0]));        if (tmp == NULL) {	    xmlVErrMemory(ctxt, "realloc failed");            return (0);        }        ctxt->nodeMax *= 2;	ctxt->nodeTab = tmp;    }    ctxt->nodeTab[ctxt->nodeNr] = value;    ctxt->node = value;    return (ctxt->nodeNr++);}static xmlNodePtrnodeVPop(xmlValidCtxtPtr ctxt){    xmlNodePtr ret;    if (ctxt->nodeNr <= 0)        return (0);    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] = 0;    return (ret);}#ifdef DEBUG_VALID_ALGOstatic voidxmlValidPrintNode(xmlNodePtr cur) {    if (cur == NULL) {	xmlGenericError(xmlGenericErrorContext, "null");	return;    }    switch (cur->type) {	case XML_ELEMENT_NODE:	    xmlGenericError(xmlGenericErrorContext, "%s ", cur->name);	    break;	case XML_TEXT_NODE:	    xmlGenericError(xmlGenericErrorContext, "text ");	    break;	case XML_CDATA_SECTION_NODE:	    xmlGenericError(xmlGenericErrorContext, "cdata ");	    break;	case XML_ENTITY_REF_NODE:	    xmlGenericError(xmlGenericErrorContext, "&%s; ", cur->name);	    break;	case XML_PI_NODE:	    xmlGenericError(xmlGenericErrorContext, "pi(%s) ", cur->name);	    break;	case XML_COMMENT_NODE:	    xmlGenericError(xmlGenericErrorContext, "comment ");	    break;	case XML_ATTRIBUTE_NODE:	    xmlGenericError(xmlGenericErrorContext, "?attr? ");	    break;	case XML_ENTITY_NODE:	    xmlGenericError(xmlGenericErrorContext, "?ent? ");	    break;	case XML_DOCUMENT_NODE:	    xmlGenericError(xmlGenericErrorContext, "?doc? ");	    break;	case XML_DOCUMENT_TYPE_NODE:	    xmlGenericError(xmlGenericErrorContext, "?doctype? ");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -