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

📄 valid.c

📁 Vovida 社区开源的 SIP 协议源码
💻 C
📖 第 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@w3.org */#ifdef WIN32#include "win32config.h"#else#include "config.h"#endif#include <stdio.h>#include <string.h>#ifdef HAVE_STDLIB_H#include <stdlib.h>#endif#include <libxml/xmlmemory.h>#include <libxml/valid.h>#include <libxml/parser.h>#include <libxml/parserInternals.h>/* * Generic function for accessing stacks in the Validity Context */#define PUSH_AND_POP(scope, type, name)					\scope int name##VPush(xmlValidCtxtPtr ctxt, type value) {		\    if (ctxt->name##Nr >= ctxt->name##Max) {				\	ctxt->name##Max *= 2;						\        ctxt->name##Tab = (void *) xmlRealloc(ctxt->name##Tab,		\	             ctxt->name##Max * sizeof(ctxt->name##Tab[0]));	\        if (ctxt->name##Tab == NULL) {					\	    fprintf(stderr, "realloc failed !\n");			\	    return(0);							\	}								\    }									\    ctxt->name##Tab[ctxt->name##Nr] = value;				\    ctxt->name = value;							\    return(ctxt->name##Nr++);						\}									\scope type name##VPop(xmlValidCtxtPtr ctxt) {				\    type ret;								\    if (ctxt->name##Nr <= 0) return(0);					\    ctxt->name##Nr--;							\    if (ctxt->name##Nr > 0)						\	ctxt->name = ctxt->name##Tab[ctxt->name##Nr - 1];		\    else								\        ctxt->name = NULL;						\    ret = ctxt->name##Tab[ctxt->name##Nr];				\    ctxt->name##Tab[ctxt->name##Nr] = 0;				\    return(ret);							\}									\PUSH_AND_POP(static, xmlNodePtr, node)/* #define DEBUG_VALID_ALGO */#ifdef DEBUG_VALID_ALGOvoid xmlValidPrintNodeList(xmlNodePtr cur) {    if (cur == NULL)	fprintf(stderr, "null ");    while (cur != NULL) {	switch (cur->type) {	    case XML_ELEMENT_NODE:		fprintf(stderr, "%s ", cur->name);		break;	    case XML_TEXT_NODE:		fprintf(stderr, "text ");		break;	    case XML_CDATA_SECTION_NODE:		fprintf(stderr, "cdata ");		break;	    case XML_ENTITY_REF_NODE:		fprintf(stderr, "&%s; ", cur->name);		break;	    case XML_PI_NODE:		fprintf(stderr, "pi(%s) ", cur->name);		break;	    case XML_COMMENT_NODE:		fprintf(stderr, "comment ");		break;	    case XML_ATTRIBUTE_NODE:		fprintf(stderr, "?attr? ");		break;	    case XML_ENTITY_NODE:		fprintf(stderr, "?ent? ");		break;	    case XML_DOCUMENT_NODE:		fprintf(stderr, "?doc? ");		break;	    case XML_DOCUMENT_TYPE_NODE:		fprintf(stderr, "?doctype? ");		break;	    case XML_DOCUMENT_FRAG_NODE:		fprintf(stderr, "?frag? ");		break;	    case XML_NOTATION_NODE:		fprintf(stderr, "?nota? ");		break;	    case XML_HTML_DOCUMENT_NODE:		fprintf(stderr, "?html? ");		break;	    case XML_DTD_NODE:		fprintf(stderr, "?dtd? ");		break;	    case XML_ELEMENT_DECL:		fprintf(stderr, "?edecl? ");		break;	    case XML_ATTRIBUTE_DECL:		fprintf(stderr, "?adecl? ");		break;	    case XML_ENTITY_DECL:		fprintf(stderr, "?entdecl? ");		break;	}	cur = cur->next;    }}void xmlValidDebug(xmlNodePtr cur, xmlElementContentPtr cont) {    char expr[1000];    expr[0] = 0;    fprintf(stderr, "valid: ");    xmlValidPrintNodeList(cur);    fprintf(stderr, "against ");    xmlSprintfElementContent(expr, cont, 0);    fprintf(stderr, "%s\n", expr);}#define DEBUG_VALID_STATE(n,c) xmlValidDebug(n,c);#else#define DEBUG_VALID_STATE(n,c)#endif/* TODO: use hash table for accesses to elem and attribute dedinitions */#define VERROR							\   if ((ctxt != NULL) && (ctxt->error != NULL)) ctxt->error#define VWARNING						\   if ((ctxt != NULL) && (ctxt->warning != NULL)) ctxt->warning#define CHECK_DTD						\   if (doc == NULL) return(0);					\   else if (doc->intSubset == NULL) return(0)xmlElementPtr xmlGetDtdElementDesc(xmlDtdPtr dtd, const xmlChar *name);xmlAttributePtr xmlScanAttributeDecl(xmlDtdPtr dtd, const xmlChar *elem);/**************************************************************** *								* *	Util functions for data allocation/deallocation		* *								* ****************************************************************//** * xmlNewElementContent: * @name:  the subelement name or NULL * @type:  the type of element content decl * * Allocate an element content structure. * * Returns NULL if not, othervise the new element content structure */xmlElementContentPtrxmlNewElementContent(xmlChar *name, xmlElementContentType type) {    xmlElementContentPtr ret;    switch(type) {	case XML_ELEMENT_CONTENT_ELEMENT:	    if (name == NULL) {	        fprintf(stderr, "xmlNewElementContent : name == NULL !\n");	    }	    break;        case XML_ELEMENT_CONTENT_PCDATA:	case XML_ELEMENT_CONTENT_SEQ:	case XML_ELEMENT_CONTENT_OR:	    if (name != NULL) {	        fprintf(stderr, "xmlNewElementContent : name != NULL !\n");	    }	    break;	default:	    fprintf(stderr, "xmlNewElementContent: unknown type %d\n", type);	    return(NULL);    }    ret = (xmlElementContentPtr) xmlMalloc(sizeof(xmlElementContent));    if (ret == NULL) {	fprintf(stderr, "xmlNewElementContent : out of memory!\n");	return(NULL);    }    ret->type = type;    ret->ocur = XML_ELEMENT_CONTENT_ONCE;    if (name != NULL)        ret->name = xmlStrdup(name);    else        ret->name = NULL;    ret->c1 = ret->c2 = NULL;    return(ret);}/** * xmlCopyElementContent: * @content:  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) {        fprintf(stderr, "xmlCopyElementContent : out of memory\n");	return(NULL);    }    ret->ocur = cur->ocur;    if (cur->c1 != NULL) ret->c1 = xmlCopyElementContent(cur->c1);    if (cur->c2 != NULL) ret->c2 = xmlCopyElementContent(cur->c2);    return(ret);}/** * xmlFreeElementContent: * @cur:  the element content tree to free * * Free an element content structure. This is a recursive call ! */voidxmlFreeElementContent(xmlElementContentPtr cur) {    if (cur == NULL) return;    if (cur->c1 != NULL) xmlFreeElementContent(cur->c1);    if (cur->c2 != NULL) xmlFreeElementContent(cur->c2);    if (cur->name != NULL) xmlFree((xmlChar *) cur->name);    memset(cur, -1, sizeof(xmlElementContent));    xmlFree(cur);}/** * xmlDumpElementContent: * @buf:  An XML buffer * @content:  An element table * @glob: 1 if one must print the englobing parenthesis, 0 otherwise * * This will dump the content of the element table as an XML DTD definition */voidxmlDumpElementContent(xmlBufferPtr buf, xmlElementContentPtr content, int glob) {    if (content == NULL) return;    if (glob) xmlBufferWriteChar(buf, "(");    switch (content->type) {        case XML_ELEMENT_CONTENT_PCDATA:            xmlBufferWriteChar(buf, "#PCDATA");	    break;	case XML_ELEMENT_CONTENT_ELEMENT:	    xmlBufferWriteCHAR(buf, content->name);	    break;	case XML_ELEMENT_CONTENT_SEQ:	    if ((content->c1->type == XML_ELEMENT_CONTENT_OR) ||	        (content->c1->type == XML_ELEMENT_CONTENT_SEQ))		xmlDumpElementContent(buf, content->c1, 1);	    else		xmlDumpElementContent(buf, content->c1, 0);            xmlBufferWriteChar(buf, " , ");	    if (content->c2->type == XML_ELEMENT_CONTENT_OR)		xmlDumpElementContent(buf, content->c2, 1);	    else		xmlDumpElementContent(buf, content->c2, 0);	    break;	case XML_ELEMENT_CONTENT_OR:	    if ((content->c1->type == XML_ELEMENT_CONTENT_OR) ||	        (content->c1->type == XML_ELEMENT_CONTENT_SEQ))		xmlDumpElementContent(buf, content->c1, 1);	    else		xmlDumpElementContent(buf, content->c1, 0);            xmlBufferWriteChar(buf, " | ");	    if (content->c2->type == XML_ELEMENT_CONTENT_SEQ)		xmlDumpElementContent(buf, content->c2, 1);	    else		xmlDumpElementContent(buf, content->c2, 0);	    break;	default:	    fprintf(stderr, "xmlDumpElementContent: unknown type %d\n",	            content->type);    }    if (glob)        xmlBufferWriteChar(buf, ")");    switch (content->ocur) {        case XML_ELEMENT_CONTENT_ONCE:	    break;        case XML_ELEMENT_CONTENT_OPT:	    xmlBufferWriteChar(buf, "?");	    break;        case XML_ELEMENT_CONTENT_MULT:	    xmlBufferWriteChar(buf, "*");	    break;        case XML_ELEMENT_CONTENT_PLUS:	    xmlBufferWriteChar(buf, "+");	    break;    }}/** * xmlSprintfElementContent: * @buf:  an output buffer * @content:  An element table * @glob: 1 if one must print the englobing parenthesis, 0 otherwise * * This will dump the content of the element content definition * Intended just for the debug routine */voidxmlSprintfElementContent(char *buf, xmlElementContentPtr content, int glob) {    if (content == NULL) return;    if (glob) strcat(buf, "(");    switch (content->type) {        case XML_ELEMENT_CONTENT_PCDATA:            strcat(buf, "#PCDATA");	    break;	case XML_ELEMENT_CONTENT_ELEMENT:	    strcat(buf, (char *) content->name);	    break;	case XML_ELEMENT_CONTENT_SEQ:	    if ((content->c1->type == XML_ELEMENT_CONTENT_OR) ||	        (content->c1->type == XML_ELEMENT_CONTENT_SEQ))		xmlSprintfElementContent(buf, content->c1, 1);	    else		xmlSprintfElementContent(buf, content->c1, 0);            strcat(buf, " , ");	    if (content->c2->type == XML_ELEMENT_CONTENT_OR)		xmlSprintfElementContent(buf, content->c2, 1);	    else		xmlSprintfElementContent(buf, content->c2, 0);	    break;	case XML_ELEMENT_CONTENT_OR:	    if ((content->c1->type == XML_ELEMENT_CONTENT_OR) ||	        (content->c1->type == XML_ELEMENT_CONTENT_SEQ))		xmlSprintfElementContent(buf, content->c1, 1);	    else		xmlSprintfElementContent(buf, content->c1, 0);            strcat(buf, " | ");	    if (content->c2->type == XML_ELEMENT_CONTENT_SEQ)		xmlSprintfElementContent(buf, content->c2, 1);	    else		xmlSprintfElementContent(buf, content->c2, 0);	    break;    }    if (glob)        strcat(buf, ")");    switch (content->ocur) {        case XML_ELEMENT_CONTENT_ONCE:	    break;        case XML_ELEMENT_CONTENT_OPT:	    strcat(buf, "?");	    break;        case XML_ELEMENT_CONTENT_MULT:	    strcat(buf, "*");	    break;        case XML_ELEMENT_CONTENT_PLUS:	    strcat(buf, "+");	    break;    }}/**************************************************************** *								* *	Registration of DTD declarations			* *								* ****************************************************************//** * xmlCreateElementTable: * * create and initialize an empty element hash table. * * Returns the xmlElementTablePtr just created or NULL in case of error. */xmlElementTablePtrxmlCreateElementTable(void) {    xmlElementTablePtr ret;    ret = (xmlElementTablePtr)          xmlMalloc(sizeof(xmlElementTable));    if (ret == NULL) {        fprintf(stderr, "xmlCreateElementTable : xmlMalloc(%ld) failed\n",	        (long)sizeof(xmlElementTable));        return(NULL);    }    ret->max_elements = XML_MIN_ELEMENT_TABLE;    ret->nb_elements = 0;    ret->table = (xmlElementPtr *)          xmlMalloc(ret->max_elements * sizeof(xmlElementPtr));    if (ret == NULL) {        fprintf(stderr, "xmlCreateElementTable : xmlMalloc(%ld) failed\n",	        ret->max_elements * (long)sizeof(xmlElement));	xmlFree(ret);        return(NULL);    }    return(ret);}/** * xmlAddElementDecl: * @ctxt:  the validation context * @dtd:  pointer to the DTD * @name:  the entity name * @type:  the element type * @content:  the element content tree or NULL * * Register a new element declaration * * Returns NULL if not, othervise the entity */xmlElementPtrxmlAddElementDecl(xmlValidCtxtPtr ctxt, xmlDtdPtr dtd, const xmlChar *name,                  xmlElementTypeVal type,		  xmlElementContentPtr content) {    xmlElementPtr ret, cur;    xmlElementTablePtr table;    int i;    if (dtd == NULL) {        fprintf(stderr, "xmlAddElementDecl: dtd == NULL\n");	return(NULL);    }    if (name == NULL) {        fprintf(stderr, "xmlAddElementDecl: name == NULL\n");	return(NULL);    }    switch (type) {        case XML_ELEMENT_TYPE_EMPTY:	    if (content != NULL) {	        fprintf(stderr,		        "xmlAddElementDecl: content != NULL for EMPTY\n");		return(NULL);	    }	    break;	case XML_ELEMENT_TYPE_ANY:	    if (content != NULL) {	        fprintf(stderr,		        "xmlAddElementDecl: content != NULL for ANY\n");		return(NULL);	    }	    break;	case XML_ELEMENT_TYPE_MIXED:	    if (content == NULL) {	        fprintf(stderr,		        "xmlAddElementDecl: content == NULL for MIXED\n");		return(NULL);	    }	    break;	case XML_ELEMENT_TYPE_ELEMENT:	    if (content == NULL) {	        fprintf(stderr,		        "xmlAddElementDecl: content == NULL for ELEMENT\n");		return(NULL);	    }	    break;	default:	    fprintf(stderr, "xmlAddElementDecl: unknown type %d\n", type);	    return(NULL);    }    /*     * Create the Element table if needed.     */    table = dtd->elements;    if (table == NULL)         table = dtd->elements = xmlCreateElementTable();    if (table == NULL) {	fprintf(stderr, "xmlAddElementDecl: Table creation failed!\n");        return(NULL);    }    /*     * Validity Check:     * Search the DTD for previous declarations of the ELEMENT     */    for (i = 0;i < table->nb_elements;i++) {        cur = table->table[i];	if (!xmlStrcmp(cur->name, name)) {	    /*	     * The element is already defined in this Dtd.	     */	    VERROR(ctxt->userData, "Redefinition of element %s\n", name);	    return(NULL);	}    }    /*     * Grow the table, if needed.     */    if (table->nb_elements >= table->max_elements) {        /*	 * need more elements.	 */	table->max_elements *= 2;	table->table = (xmlElementPtr *) 	    xmlRealloc(table->table, table->max_elements * sizeof(xmlElementPtr));	if (table->table == NULL) {	    fprintf(stderr, "xmlAddElementDecl: out of memory\n");	    return(NULL);	}    }    ret = (xmlElementPtr) xmlMalloc(sizeof(xmlElement));

⌨️ 快捷键说明

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