📄 xpath.c.svn-base
字号:
} if (comp->steps != NULL) { xmlFree(comp->steps); }#ifdef DEBUG_EVAL_COUNTS if (comp->string != NULL) { xmlFree(comp->string); }#endif if (comp->expr != NULL) { xmlFree(comp->expr); } xmlFree(comp);}/** * xmlXPathCompExprAdd: * @comp: the compiled expression * @ch1: first child index * @ch2: second child index * @op: an op * @value: the first int value * @value2: the second int value * @value3: the third int value * @value4: the first string value * @value5: the second string value * * Add a step to an XPath Compiled Expression * * Returns -1 in case of failure, the index otherwise */static intxmlXPathCompExprAdd(xmlXPathCompExprPtr comp, int ch1, int ch2, xmlXPathOp op, int value, int value2, int value3, void *value4, void *value5) { if (comp->nbStep >= comp->maxStep) { xmlXPathStepOp *real; comp->maxStep *= 2; real = (xmlXPathStepOp *) xmlRealloc(comp->steps, comp->maxStep * sizeof(xmlXPathStepOp)); if (real == NULL) { comp->maxStep /= 2; xmlXPathErrMemory(NULL, "adding step\n"); return(-1); } comp->steps = real; } comp->last = comp->nbStep; comp->steps[comp->nbStep].ch1 = ch1; comp->steps[comp->nbStep].ch2 = ch2; comp->steps[comp->nbStep].op = op; comp->steps[comp->nbStep].value = value; comp->steps[comp->nbStep].value2 = value2; comp->steps[comp->nbStep].value3 = value3; if ((comp->dict != NULL) && ((op == XPATH_OP_FUNCTION) || (op == XPATH_OP_VARIABLE) || (op == XPATH_OP_COLLECT))) { if (value4 != NULL) { comp->steps[comp->nbStep].value4 = (xmlChar *) (void *)xmlDictLookup(comp->dict, value4, -1); xmlFree(value4); } else comp->steps[comp->nbStep].value4 = NULL; if (value5 != NULL) { comp->steps[comp->nbStep].value5 = (xmlChar *) (void *)xmlDictLookup(comp->dict, value5, -1); xmlFree(value5); } else comp->steps[comp->nbStep].value5 = NULL; } else { comp->steps[comp->nbStep].value4 = value4; comp->steps[comp->nbStep].value5 = value5; } comp->steps[comp->nbStep].cache = NULL; return(comp->nbStep++);}/** * xmlXPathCompSwap: * @comp: the compiled expression * @op: operation index * * Swaps 2 operations in the compiled expression */static voidxmlXPathCompSwap(xmlXPathStepOpPtr op) { int tmp;#ifndef LIBXML_THREAD_ENABLED /* * Since this manipulates possibly shared variables, this is * disabled if one detects that the library is used in a multithreaded * application */ if (xmlXPathDisableOptimizer) return;#endif tmp = op->ch1; op->ch1 = op->ch2; op->ch2 = tmp;}#define PUSH_FULL_EXPR(op, op1, op2, val, val2, val3, val4, val5) \ xmlXPathCompExprAdd(ctxt->comp, (op1), (op2), \ (op), (val), (val2), (val3), (val4), (val5))#define PUSH_LONG_EXPR(op, val, val2, val3, val4, val5) \ xmlXPathCompExprAdd(ctxt->comp, ctxt->comp->last, -1, \ (op), (val), (val2), (val3), (val4), (val5))#define PUSH_LEAVE_EXPR(op, val, val2) \xmlXPathCompExprAdd(ctxt->comp, -1, -1, (op), (val), (val2), 0 ,NULL ,NULL)#define PUSH_UNARY_EXPR(op, ch, val, val2) \xmlXPathCompExprAdd(ctxt->comp, (ch), -1, (op), (val), (val2), 0 ,NULL ,NULL)#define PUSH_BINARY_EXPR(op, ch1, ch2, val, val2) \xmlXPathCompExprAdd(ctxt->comp, (ch1), (ch2), (op), \ (val), (val2), 0 ,NULL ,NULL)/************************************************************************ * * * Debugging related functions * * * ************************************************************************/#define STRANGE \ xmlGenericError(xmlGenericErrorContext, \ "Internal error at %s:%d\n", \ __FILE__, __LINE__);#ifdef LIBXML_DEBUG_ENABLEDstatic voidxmlXPathDebugDumpNode(FILE *output, xmlNodePtr cur, int depth) { int i; char shift[100]; for (i = 0;((i < depth) && (i < 25));i++) shift[2 * i] = shift[2 * i + 1] = ' '; shift[2 * i] = shift[2 * i + 1] = 0; if (cur == NULL) { fprintf(output, shift); fprintf(output, "Node is NULL !\n"); return; } if ((cur->type == XML_DOCUMENT_NODE) || (cur->type == XML_HTML_DOCUMENT_NODE)) { fprintf(output, shift); fprintf(output, " /\n"); } else if (cur->type == XML_ATTRIBUTE_NODE) xmlDebugDumpAttr(output, (xmlAttrPtr)cur, depth); else xmlDebugDumpOneNode(output, cur, depth);}static voidxmlXPathDebugDumpNodeList(FILE *output, xmlNodePtr cur, int depth) { xmlNodePtr tmp; int i; char shift[100]; for (i = 0;((i < depth) && (i < 25));i++) shift[2 * i] = shift[2 * i + 1] = ' '; shift[2 * i] = shift[2 * i + 1] = 0; if (cur == NULL) { fprintf(output, shift); fprintf(output, "Node is NULL !\n"); return; } while (cur != NULL) { tmp = cur; cur = cur->next; xmlDebugDumpOneNode(output, tmp, depth); }}static voidxmlXPathDebugDumpNodeSet(FILE *output, xmlNodeSetPtr cur, int depth) { int i; char shift[100]; for (i = 0;((i < depth) && (i < 25));i++) shift[2 * i] = shift[2 * i + 1] = ' '; shift[2 * i] = shift[2 * i + 1] = 0; if (cur == NULL) { fprintf(output, shift); fprintf(output, "NodeSet is NULL !\n"); return; } if (cur != NULL) { fprintf(output, "Set contains %d nodes:\n", cur->nodeNr); for (i = 0;i < cur->nodeNr;i++) { fprintf(output, shift); fprintf(output, "%d", i + 1); xmlXPathDebugDumpNode(output, cur->nodeTab[i], depth + 1); } }}static voidxmlXPathDebugDumpValueTree(FILE *output, xmlNodeSetPtr cur, int depth) { int i; char shift[100]; for (i = 0;((i < depth) && (i < 25));i++) shift[2 * i] = shift[2 * i + 1] = ' '; shift[2 * i] = shift[2 * i + 1] = 0; if ((cur == NULL) || (cur->nodeNr == 0) || (cur->nodeTab[0] == NULL)) { fprintf(output, shift); fprintf(output, "Value Tree is NULL !\n"); return; } fprintf(output, shift); fprintf(output, "%d", i + 1); xmlXPathDebugDumpNodeList(output, cur->nodeTab[0]->children, depth + 1);}#if defined(LIBXML_XPTR_ENABLED)static voidxmlXPathDebugDumpLocationSet(FILE *output, xmlLocationSetPtr cur, int depth) { int i; char shift[100]; for (i = 0;((i < depth) && (i < 25));i++) shift[2 * i] = shift[2 * i + 1] = ' '; shift[2 * i] = shift[2 * i + 1] = 0; if (cur == NULL) { fprintf(output, shift); fprintf(output, "LocationSet is NULL !\n"); return; } for (i = 0;i < cur->locNr;i++) { fprintf(output, shift); fprintf(output, "%d : ", i + 1); xmlXPathDebugDumpObject(output, cur->locTab[i], depth + 1); }}#endif /* LIBXML_XPTR_ENABLED *//** * xmlXPathDebugDumpObject: * @output: the FILE * to dump the output * @cur: the object to inspect * @depth: indentation level * * Dump the content of the object for debugging purposes */voidxmlXPathDebugDumpObject(FILE *output, xmlXPathObjectPtr cur, int depth) { int i; char shift[100]; for (i = 0;((i < depth) && (i < 25));i++) shift[2 * i] = shift[2 * i + 1] = ' '; shift[2 * i] = shift[2 * i + 1] = 0; fprintf(output, shift); if (cur == NULL) { fprintf(output, "Object is empty (NULL)\n"); return; } switch(cur->type) { case XPATH_UNDEFINED: fprintf(output, "Object is uninitialized\n"); break; case XPATH_NODESET: fprintf(output, "Object is a Node Set :\n"); xmlXPathDebugDumpNodeSet(output, cur->nodesetval, depth); break; case XPATH_XSLT_TREE: fprintf(output, "Object is an XSLT value tree :\n"); xmlXPathDebugDumpValueTree(output, cur->nodesetval, depth); break; case XPATH_BOOLEAN: fprintf(output, "Object is a Boolean : "); if (cur->boolval) fprintf(output, "true\n"); else fprintf(output, "false\n"); break; case XPATH_NUMBER: switch (xmlXPathIsInf(cur->floatval)) { case 1: fprintf(output, "Object is a number : Infinity\n"); break; case -1: fprintf(output, "Object is a number : -Infinity\n"); break; default: if (xmlXPathIsNaN(cur->floatval)) { fprintf(output, "Object is a number : NaN\n"); } else if (cur->floatval == 0 && xmlXPathGetSign(cur->floatval) != 0) { fprintf(output, "Object is a number : 0\n"); } else { fprintf(output, "Object is a number : %0g\n", cur->floatval); } } break; case XPATH_STRING: fprintf(output, "Object is a string : "); xmlDebugDumpString(output, cur->stringval); fprintf(output, "\n"); break; case XPATH_POINT: fprintf(output, "Object is a point : index %d in node", cur->index); xmlXPathDebugDumpNode(output, (xmlNodePtr) cur->user, depth + 1); fprintf(output, "\n"); break; case XPATH_RANGE: if ((cur->user2 == NULL) || ((cur->user2 == cur->user) && (cur->index == cur->index2))) { fprintf(output, "Object is a collapsed range :\n"); fprintf(output, shift); if (cur->index >= 0) fprintf(output, "index %d in ", cur->index); fprintf(output, "node\n"); xmlXPathDebugDumpNode(output, (xmlNodePtr) cur->user, depth + 1); } else { fprintf(output, "Object is a range :\n"); fprintf(output, shift); fprintf(output, "From "); if (cur->index >= 0) fprintf(output, "index %d in ", cur->index); fprintf(output, "node\n"); xmlXPathDebugDumpNode(output, (xmlNodePtr) cur->user, depth + 1); fprintf(output, shift); fprintf(output, "To "); if (cur->index2 >= 0) fprintf(output, "index %d in ", cur->index2); fprintf(output, "node\n"); xmlXPathDebugDumpNode(output, (xmlNodePtr) cur->user2, depth + 1); fprintf(output, "\n"); } break; case XPATH_LOCATIONSET:#if defined(LIBXML_XPTR_ENABLED) fprintf(output, "Object is a Location Set:\n"); xmlXPathDebugDumpLocationSet(output, (xmlLocationSetPtr) cur->user, depth);#endif break; case XPATH_USERS: fprintf(output, "Object is user defined\n"); break; }}static voidxmlXPathDebugDumpStepOp(FILE *output, xmlXPathCompExprPtr comp, xmlXPathStepOpPtr op, int depth) { int i; char shift[100]; for (i = 0;((i < depth) && (i < 25));i++) shift[2 * i] = shift[2 * i + 1] = ' '; shift[2 * i] = shift[2 * i + 1] = 0; fprintf(output, shift); if (op == NULL) { fprintf(output, "Step is NULL\n"); return; } switch (op->op) { case XPATH_OP_END: fprintf(output, "END"); break; case XPATH_OP_AND: fprintf(output, "AND"); break; case XPATH_OP_OR: fprintf(output, "OR"); break; case XPATH_OP_EQUAL: if (op->value) fprintf(output, "EQUAL ="); else fprintf(output, "EQUAL !="); break; case XPATH_OP_CMP: if (op->value) fprintf(output, "CMP <"); else fprintf(output, "CMP >"); if (!op->value2) fprintf(output, "="); break; case XPATH_OP_PLUS: if (op->value == 0) fprintf(output, "PLUS -"); else if (op->value == 1) fprintf(output, "PLUS +"); else if (op->value == 2) fprintf(output, "PLUS unary -"); else if (op->value == 3) fprintf(output, "PLUS unary - -"); break; case XPATH_OP_MULT: if (op->value == 0) fprintf(output, "MULT *"); else if (op->value == 1) fprintf(output, "MULT div"); else fprintf(output, "MULT mod"); break; case XPATH_OP_UNION: fprintf(output, "UNION"); break; case XPATH_OP_ROOT: fprintf(output, "ROOT"); break; case XPATH_OP_NODE: fprintf(output, "NODE"); break; case XPATH_OP_RESET: fprintf(output, "RESET"); break; case XPATH_OP_SORT: fprintf(output, "SORT"); break; case XPATH_OP_COLLECT: { xmlXPathAxisVal axis = (xmlXPathAxisVal)op->value; xmlXPathTestVal test = (xmlXPathTestVal)op->value2; xmlXPathTypeVal type = (xmlXPathTypeVal)op->value3; const xmlChar *prefix = op->value4; const xmlChar *name = op->value5; fprintf(output, "COLLECT "); switch (axis) { case AXIS_ANCESTOR: fprintf(output, " 'ancestors' "); break; case AXIS_ANCESTOR_OR_SELF: fprintf(output, " 'ancestors-or-self' "); break; case AXIS_ATTRIBUTE: fprintf(output, " 'attributes' "); break; case AXIS_CHILD: fprintf(output, " 'child' "); break; case AXIS_DESCENDANT: fprintf(output, " 'descendant' "); break; case AXIS_DESCENDANT_OR_SELF: fprintf(output, " 'descendant-or-self' "); break; case AXIS_FOLLOWING: fprintf(output, " 'following' "); break; case AXIS_FOLLOWING_SIBLING: fprintf(output, " 'following-siblings' "); break; case AXIS_NAMESPACE: fprintf(output, " 'namespace' "); break; case AXIS_PARENT: fprintf(output, " 'parent' "); break; case AXIS_PRECEDING: fprintf(output, " 'preceding' "); break; case AXIS_PRECEDING_SIBLING: fprintf(output, " 'preceding-sibling' "); break; case AXIS_SELF: fprintf(output, " 'self' "); break; } switch (test) { case NODE_TEST_NONE: fprintf(output, "'none' "); break; case NODE_TEST_TYPE: fprintf(output, "'type' "); break; case NODE_TEST_PI: fprintf(output, "'PI' "); break; case NODE_TEST_ALL: fprintf(output, "'all' "); break; case NODE_TEST_NS: fprintf(output, "'namespace' "); break; case NODE_TEST_NAME: fprintf(output, "'name' "); break; } switch (type) { case NODE_TYPE_NODE: fprintf(output, "'node' "); break; case NODE_TYPE_COMMENT: fprintf(output, "'comment' "); break; case NODE_TYPE_TEXT: fprintf(output, "'text' "); break; case NODE_TYPE_PI: fprintf(output, "'PI' "); break; } if (prefix != NULL) fprintf(output, "%s:", prefix); if (name != NULL) fprintf(output, "%s", (const char *) name); break; } case XPATH_OP_VALUE: { xmlXPathObjectPtr object = (xmlXPathObjectPtr) op->value4; fprintf(output, "ELEM "); xmlXPathDebugDumpObject(output, object, 0); goto finish; } case XPATH_OP_VARIABLE: { const xmlChar *prefix = op->value5; const xmlChar *name = op->value4;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -