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

📄 pattern.c

📁 xml开源解析代码.版本为libxml2-2.6.29,可支持GB3212.网络消息发送XML时很有用.
💻 C
📖 第 1 页 / 共 5 页
字号:
	    return;	} else {	    ERROR(NULL, NULL, NULL,		    "xmlCompileStepPattern : Name expected\n");	    ctxt->error = 1;	    return;	}    }    if (IS_BLANK_CH(CUR)) {	hasBlanks = 1;	SKIP_BLANKS;    }    if (CUR == ':') {	NEXT;	if (CUR != ':') {	    xmlChar *prefix = name;	    int i;	    	    if (hasBlanks || IS_BLANK_CH(CUR)) {		ERROR5(NULL, NULL, NULL, "Invalid QName.\n", NULL);		ctxt->error = 1;		goto error;	    }	    /*	     * This is a namespace match	     */	    token = xmlPatScanName(ctxt);	    if ((prefix[0] == 'x') &&		(prefix[1] == 'm') &&		(prefix[2] == 'l') &&		(prefix[3] == 0))	    {		XML_PAT_COPY_NSNAME(ctxt, URL, XML_XML_NAMESPACE)	    } else {		for (i = 0;i < ctxt->nb_namespaces;i++) {		    if (xmlStrEqual(ctxt->namespaces[2 * i + 1], prefix)) {			XML_PAT_COPY_NSNAME(ctxt, URL, ctxt->namespaces[2 * i])			break;		    }		}		if (i >= ctxt->nb_namespaces) {		    ERROR5(NULL, NULL, NULL,			"xmlCompileStepPattern : no namespace bound to prefix %s\n",			prefix);		    ctxt->error = 1;		    goto error;		}	    }	    XML_PAT_FREE_STRING(ctxt, prefix);	    if (token == NULL) {		if (CUR == '*') {		    NEXT;		    PUSH(XML_OP_NS, URL, NULL);		} else {		    ERROR(NULL, NULL, NULL,			    "xmlCompileStepPattern : Name expected\n");		    ctxt->error = 1;		    goto error;		}	    } else {		PUSH(XML_OP_ELEM, token, URL);	    }	} else {	    NEXT;	    if (xmlStrEqual(name, (const xmlChar *) "child")) {				XML_PAT_FREE_STRING(ctxt, name);		name = xmlPatScanName(ctxt);		if (name == NULL) {		    if (CUR == '*') {			NEXT;			PUSH(XML_OP_ALL, NULL, NULL);			return;		    } else {			ERROR(NULL, NULL, NULL,			    "xmlCompileStepPattern : QName expected\n");			ctxt->error = 1;			goto error;		    }		}		if (CUR == ':') {		    xmlChar *prefix = name;		    int i;		    		    NEXT;		    if (IS_BLANK_CH(CUR)) {			ERROR5(NULL, NULL, NULL, "Invalid QName.\n", NULL);			ctxt->error = 1;			goto error;		    }		    /*		    * This is a namespace match		    */		    token = xmlPatScanName(ctxt);		    if ((prefix[0] == 'x') &&			(prefix[1] == 'm') &&			(prefix[2] == 'l') &&			(prefix[3] == 0))		    {			XML_PAT_COPY_NSNAME(ctxt, URL, XML_XML_NAMESPACE)					    } else {			for (i = 0;i < ctxt->nb_namespaces;i++) {			    if (xmlStrEqual(ctxt->namespaces[2 * i + 1], prefix)) {				XML_PAT_COPY_NSNAME(ctxt, URL, ctxt->namespaces[2 * i])								break;			    }			}			if (i >= ctxt->nb_namespaces) {			    ERROR5(NULL, NULL, NULL,				"xmlCompileStepPattern : no namespace bound "				"to prefix %s\n", prefix);			    ctxt->error = 1;			    goto error;			}		    }		    XML_PAT_FREE_STRING(ctxt, prefix);		    if (token == NULL) {			if (CUR == '*') {			    NEXT;			    PUSH(XML_OP_NS, URL, NULL);			} else {			    ERROR(NULL, NULL, NULL,				"xmlCompileStepPattern : Name expected\n");			    ctxt->error = 1;			    goto error;			}		    } else {			PUSH(XML_OP_CHILD, token, URL);		    }		} else		    PUSH(XML_OP_CHILD, name, NULL);		return;	    } else if (xmlStrEqual(name, (const xmlChar *) "attribute")) {		XML_PAT_FREE_STRING(ctxt, name)		name = NULL;		if (XML_STREAM_XS_IDC_SEL(ctxt->comp)) {		    ERROR5(NULL, NULL, NULL,			"Unexpected attribute axis in '%s'.\n", ctxt->base);		    ctxt->error = 1;		    goto error;		}		xmlCompileAttributeTest(ctxt);		if (ctxt->error != 0)		    goto error;		return;	    } else {		ERROR5(NULL, NULL, NULL,		    "The 'element' or 'attribute' axis is expected.\n", NULL);		ctxt->error = 1;		goto error;	    }	    	}    } else if (CUR == '*') {        if (name != NULL) {	    ctxt->error = 1;	    goto error;	}	NEXT;	PUSH(XML_OP_ALL, token, NULL);    } else {	PUSH(XML_OP_ELEM, name, NULL);    }    return;error:    if (URL != NULL)	XML_PAT_FREE_STRING(ctxt, URL)	    if (token != NULL)	XML_PAT_FREE_STRING(ctxt, token)    if (name != NULL)	XML_PAT_FREE_STRING(ctxt, name)}/** * xmlCompilePathPattern: * @ctxt:  the compilation context * * Compile the Path Pattern and generates a precompiled * form suitable for fast matching. * * [5]    Path    ::=    ('.//')? ( Step '/' )* ( Step | '@' NameTest )  */static voidxmlCompilePathPattern(xmlPatParserContextPtr ctxt) {    SKIP_BLANKS;    if (CUR == '/') {        ctxt->comp->flags |= PAT_FROM_ROOT;    } else if ((CUR == '.') || (ctxt->comp->flags & XML_PATTERN_NOTPATTERN)) {        ctxt->comp->flags |= PAT_FROM_CUR;    }	    if ((CUR == '/') && (NXT(1) == '/')) {	PUSH(XML_OP_ANCESTOR, NULL, NULL);	NEXT;	NEXT;    } else if ((CUR == '.') && (NXT(1) == '/') && (NXT(2) == '/')) {	PUSH(XML_OP_ANCESTOR, NULL, NULL);	NEXT;	NEXT;	NEXT;	/* Check for incompleteness. */	SKIP_BLANKS;	if (CUR == 0) {	    ERROR5(NULL, NULL, NULL,	       "Incomplete expression '%s'.\n", ctxt->base);	    ctxt->error = 1;	    goto error;	}    }    if (CUR == '@') {	NEXT;	xmlCompileAttributeTest(ctxt);	SKIP_BLANKS;	/* TODO: check for incompleteness */	if (CUR != 0) {	    xmlCompileStepPattern(ctxt);	    if (ctxt->error != 0)		goto error;	}    } else {        if (CUR == '/') {	    PUSH(XML_OP_ROOT, NULL, NULL);	    NEXT;	    /* Check for incompleteness. */	    SKIP_BLANKS;	    if (CUR == 0) {		ERROR5(NULL, NULL, NULL,		    "Incomplete expression '%s'.\n", ctxt->base);		ctxt->error = 1;		goto error;	    }	}	xmlCompileStepPattern(ctxt);	if (ctxt->error != 0)	    goto error;	SKIP_BLANKS;	while (CUR == '/') {	    if (NXT(1) == '/') {	        PUSH(XML_OP_ANCESTOR, NULL, NULL);		NEXT;		NEXT;		SKIP_BLANKS;		xmlCompileStepPattern(ctxt);		if (ctxt->error != 0)		    goto error;	    } else {	        PUSH(XML_OP_PARENT, NULL, NULL);		NEXT;		SKIP_BLANKS;		if (CUR == 0) {		    ERROR5(NULL, NULL, NULL,		    "Incomplete expression '%s'.\n", ctxt->base);		    ctxt->error = 1;		    goto error;		    		}		xmlCompileStepPattern(ctxt);		if (ctxt->error != 0)		    goto error;	    }	}    }    if (CUR != 0) {	ERROR5(NULL, NULL, NULL,	       "Failed to compile pattern %s\n", ctxt->base);	ctxt->error = 1;    }error:    return;}/** * xmlCompileIDCXPathPath: * @ctxt:  the compilation context * * Compile the Path Pattern and generates a precompiled * form suitable for fast matching. * * [5]    Path    ::=    ('.//')? ( Step '/' )* ( Step | '@' NameTest )  */static voidxmlCompileIDCXPathPath(xmlPatParserContextPtr ctxt) {    SKIP_BLANKS;    if (CUR == '/') {	ERROR5(NULL, NULL, NULL,	    "Unexpected selection of the document root in '%s'.\n",	    ctxt->base);	goto error;    }    ctxt->comp->flags |= PAT_FROM_CUR;    if (CUR == '.') {	/* "." - "self::node()" */	NEXT;	SKIP_BLANKS;	if (CUR == 0) {	    /*	    * Selection of the context node.	    */	    PUSH(XML_OP_ELEM, NULL, NULL);	    return;	}	if (CUR != '/') {	    /* TODO: A more meaningful error message. */	    ERROR5(NULL, NULL, NULL,	    "Unexpected token after '.' in '%s'.\n", ctxt->base);	    goto error;	}	/* "./" - "self::node()/" */	NEXT;	SKIP_BLANKS;	if (CUR == '/') {	    if (IS_BLANK_CH(PEEKPREV(1))) {		/*		* Disallow "./ /"		*/		ERROR5(NULL, NULL, NULL,		    "Unexpected '/' token in '%s'.\n", ctxt->base);		goto error;	    }	    /* ".//" - "self:node()/descendant-or-self::node()/" */	    PUSH(XML_OP_ANCESTOR, NULL, NULL);	    NEXT;	    SKIP_BLANKS;	}	if (CUR == 0)	    goto error_unfinished;    }    /*    * Process steps.    */    do {	xmlCompileStepPattern(ctxt);	if (ctxt->error != 0) 	    goto error;	SKIP_BLANKS;	if (CUR != '/')	    break;	PUSH(XML_OP_PARENT, NULL, NULL);	NEXT;	SKIP_BLANKS;	if (CUR == '/') {	    /*	    * Disallow subsequent '//'.	    */	    ERROR5(NULL, NULL, NULL,		"Unexpected subsequent '//' in '%s'.\n",		ctxt->base);	    goto error;	}	if (CUR == 0)	    goto error_unfinished;	    } while (CUR != 0);    if (CUR != 0) {	ERROR5(NULL, NULL, NULL,	    "Failed to compile expression '%s'.\n", ctxt->base);	ctxt->error = 1;    }    return;error:    ctxt->error = 1;    return;error_unfinished:    ctxt->error = 1;    ERROR5(NULL, NULL, NULL,	"Unfinished expression '%s'.\n", ctxt->base);        return;}/************************************************************************ *									* *			The streaming code				* *									* ************************************************************************/#ifdef DEBUG_STREAMINGstatic voidxmlDebugStreamComp(xmlStreamCompPtr stream) {    int i;    if (stream == NULL) {        printf("Stream: NULL\n");	return;    }    printf("Stream: %d steps\n", stream->nbStep);    for (i = 0;i < stream->nbStep;i++) {	if (stream->steps[i].ns != NULL) {	    printf("{%s}", stream->steps[i].ns);	}        if (stream->steps[i].name == NULL) {	    printf("* ");	} else {	    printf("%s ", stream->steps[i].name);	}	if (stream->steps[i].flags & XML_STREAM_STEP_ROOT)	    printf("root ");	if (stream->steps[i].flags & XML_STREAM_STEP_DESC)	    printf("// ");	if (stream->steps[i].flags & XML_STREAM_STEP_FINAL)	    printf("final ");	printf("\n");    }}static voidxmlDebugStreamCtxt(xmlStreamCtxtPtr ctxt, int match) {    int i;    if (ctxt == NULL) {        printf("Stream: NULL\n");	return;    }    printf("Stream: level %d, %d states: ", ctxt->level, ctxt->nbState);    if (match)        printf("matches\n");    else        printf("\n");    for (i = 0;i < ctxt->nbState;i++) {        if (ctxt->states[2 * i] < 0)	    printf(" %d: free\n", i);	else {	    printf(" %d: step %d, level %d", i, ctxt->states[2 * i],	           ctxt->states[(2 * i) + 1]);            if (ctxt->comp->steps[ctxt->states[2 * i]].flags &	        XML_STREAM_STEP_DESC)	        printf(" //\n");	    else	        printf("\n");	}    }}#endif/** * xmlNewStreamComp: * @size: the number of expected steps * * build a new compiled pattern for streaming * * Returns the new structure or NULL in case of error. */static xmlStreamCompPtrxmlNewStreamComp(int size) {    xmlStreamCompPtr cur;    if (size < 4)        size  = 4;    cur = (xmlStreamCompPtr) xmlMalloc(sizeof(xmlStreamComp));    if (cur == NULL) {	ERROR(NULL, NULL, NULL,		"xmlNewStreamComp: malloc failed\n");	return(NULL);    }    memset(cur, 0, sizeof(xmlStreamComp));    cur->steps = (xmlStreamStepPtr) xmlMalloc(size * sizeof(xmlStreamStep));    if (cur->steps == NULL) {	xmlFree(cur);	ERROR(NULL, NULL, NULL,	      "xmlNewStreamComp: malloc failed\n");	return(NULL);    }    cur->nbStep = 0;    cur->maxStep = size;    return(cur);}/** * xmlFreeStreamComp: * @comp: the compiled pattern for streaming * * Free the compiled pattern for streaming */static voidxmlFreeStreamComp(xmlStreamCompPtr comp) {    if (comp != NULL) {        if (comp->steps != NULL)	    xmlFree(comp->steps);	if (comp->dict != NULL)	    xmlDictFree(comp->dict);        xmlFree(comp);    }}/** * xmlStreamCompAddStep: * @comp: the compiled pattern for streaming * @name: the first string, the name, or NULL for * * @ns: the second step, the namespace name * @flags: the flags for that step * * Add a new step to the compiled pattern * * Returns -1 in case of error or the step index if successful */static intxmlStreamCompAddStep(xmlStreamCompPtr comp, const xmlChar *name,                     const xmlChar *ns, int nodeType, int flags) {    xmlStreamStepPtr cur;    if (comp->nbStep >= comp->maxStep) {	cur = (xmlStreamStepPtr) xmlRealloc(comp->steps,				 comp->maxStep * 2 * sizeof(xmlStreamStep));	if (cur == NULL) {	    ERROR(NULL, NULL, NULL,		  "xmlNewStreamComp: malloc failed\n");	    return(-1);	}	comp->steps = cur;        comp->maxStep *= 2;    }    cur = &comp->steps[comp->nbStep++];    cur->flags = flags;    cur->name = name;    cur->ns = ns;    cur->nodeType = nodeType;    return(comp->nbStep - 1);}/** * xmlStreamCompile: * @comp: the precompiled pattern *  * Tries to stream compile a pattern

⌨️ 快捷键说明

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