📄 xpointer.c.svn-base
字号:
xmlXPtrNewCollapsedRange(xmlNodePtr start) { xmlXPathObjectPtr ret; if (start == NULL) return(NULL); ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); if (ret == NULL) { xmlXPtrErrMemory("allocating range"); return(NULL); } memset(ret, 0 , (size_t) sizeof(xmlXPathObject)); ret->type = XPATH_RANGE; ret->user = start; ret->index = -1; ret->user2 = NULL; ret->index2 = -1; return(ret);}/** * xmlXPtrNewRangeNodeObject: * @start: the starting node * @end: the ending object * * Create a new xmlXPathObjectPtr of type range from a not to an object * * Returns the newly created object. */xmlXPathObjectPtrxmlXPtrNewRangeNodeObject(xmlNodePtr start, xmlXPathObjectPtr end) { xmlXPathObjectPtr ret; if (start == NULL) return(NULL); if (end == NULL) return(NULL); switch (end->type) { case XPATH_POINT: case XPATH_RANGE: break; case XPATH_NODESET: /* * Empty set ... */ if (end->nodesetval->nodeNr <= 0) return(NULL); break; default: TODO return(NULL); } ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); if (ret == NULL) { xmlXPtrErrMemory("allocating range"); return(NULL); } memset(ret, 0 , (size_t) sizeof(xmlXPathObject)); ret->type = XPATH_RANGE; ret->user = start; ret->index = -1; switch (end->type) { case XPATH_POINT: ret->user2 = end->user; ret->index2 = end->index; break; case XPATH_RANGE: ret->user2 = end->user2; ret->index2 = end->index2; break; case XPATH_NODESET: { ret->user2 = end->nodesetval->nodeTab[end->nodesetval->nodeNr - 1]; ret->index2 = -1; break; } default: STRANGE return(NULL); } xmlXPtrRangeCheckOrder(ret); return(ret);}#define XML_RANGESET_DEFAULT 10/** * xmlXPtrLocationSetCreate: * @val: an initial xmlXPathObjectPtr, or NULL * * Create a new xmlLocationSetPtr of type double and of value @val * * Returns the newly created object. */xmlLocationSetPtrxmlXPtrLocationSetCreate(xmlXPathObjectPtr val) { xmlLocationSetPtr ret; ret = (xmlLocationSetPtr) xmlMalloc(sizeof(xmlLocationSet)); if (ret == NULL) { xmlXPtrErrMemory("allocating locationset"); return(NULL); } memset(ret, 0 , (size_t) sizeof(xmlLocationSet)); if (val != NULL) { ret->locTab = (xmlXPathObjectPtr *) xmlMalloc(XML_RANGESET_DEFAULT * sizeof(xmlXPathObjectPtr)); if (ret->locTab == NULL) { xmlXPtrErrMemory("allocating locationset"); xmlFree(ret); return(NULL); } memset(ret->locTab, 0 , XML_RANGESET_DEFAULT * (size_t) sizeof(xmlXPathObjectPtr)); ret->locMax = XML_RANGESET_DEFAULT; ret->locTab[ret->locNr++] = val; } return(ret);}/** * xmlXPtrLocationSetAdd: * @cur: the initial range set * @val: a new xmlXPathObjectPtr * * add a new xmlXPathObjectPtr to an existing LocationSet * If the location already exist in the set @val is freed. */voidxmlXPtrLocationSetAdd(xmlLocationSetPtr cur, xmlXPathObjectPtr val) { int i; if (val == NULL) return; /* * check against doublons */ for (i = 0;i < cur->locNr;i++) { if (xmlXPtrRangesEqual(cur->locTab[i], val)) { xmlXPathFreeObject(val); return; } } /* * grow the locTab if needed */ if (cur->locMax == 0) { cur->locTab = (xmlXPathObjectPtr *) xmlMalloc(XML_RANGESET_DEFAULT * sizeof(xmlXPathObjectPtr)); if (cur->locTab == NULL) { xmlXPtrErrMemory("adding location to set"); return; } memset(cur->locTab, 0 , XML_RANGESET_DEFAULT * (size_t) sizeof(xmlXPathObjectPtr)); cur->locMax = XML_RANGESET_DEFAULT; } else if (cur->locNr == cur->locMax) { xmlXPathObjectPtr *temp; cur->locMax *= 2; temp = (xmlXPathObjectPtr *) xmlRealloc(cur->locTab, cur->locMax * sizeof(xmlXPathObjectPtr)); if (temp == NULL) { xmlXPtrErrMemory("adding location to set"); return; } cur->locTab = temp; } cur->locTab[cur->locNr++] = val;}/** * xmlXPtrLocationSetMerge: * @val1: the first LocationSet * @val2: the second LocationSet * * Merges two rangesets, all ranges from @val2 are added to @val1 * * Returns val1 once extended or NULL in case of error. */xmlLocationSetPtrxmlXPtrLocationSetMerge(xmlLocationSetPtr val1, xmlLocationSetPtr val2) { int i; if (val1 == NULL) return(NULL); if (val2 == NULL) return(val1); /* * !!!!! this can be optimized a lot, knowing that both * val1 and val2 already have unicity of their values. */ for (i = 0;i < val2->locNr;i++) xmlXPtrLocationSetAdd(val1, val2->locTab[i]); return(val1);}/** * xmlXPtrLocationSetDel: * @cur: the initial range set * @val: an xmlXPathObjectPtr * * Removes an xmlXPathObjectPtr from an existing LocationSet */voidxmlXPtrLocationSetDel(xmlLocationSetPtr cur, xmlXPathObjectPtr val) { int i; if (cur == NULL) return; if (val == NULL) return; /* * check against doublons */ for (i = 0;i < cur->locNr;i++) if (cur->locTab[i] == val) break; if (i >= cur->locNr) {#ifdef DEBUG xmlGenericError(xmlGenericErrorContext, "xmlXPtrLocationSetDel: Range wasn't found in RangeList\n");#endif return; } cur->locNr--; for (;i < cur->locNr;i++) cur->locTab[i] = cur->locTab[i + 1]; cur->locTab[cur->locNr] = NULL;}/** * xmlXPtrLocationSetRemove: * @cur: the initial range set * @val: the index to remove * * Removes an entry from an existing LocationSet list. */voidxmlXPtrLocationSetRemove(xmlLocationSetPtr cur, int val) { if (cur == NULL) return; if (val >= cur->locNr) return; cur->locNr--; for (;val < cur->locNr;val++) cur->locTab[val] = cur->locTab[val + 1]; cur->locTab[cur->locNr] = NULL;}/** * xmlXPtrFreeLocationSet: * @obj: the xmlLocationSetPtr to free * * Free the LocationSet compound (not the actual ranges !). */voidxmlXPtrFreeLocationSet(xmlLocationSetPtr obj) { int i; if (obj == NULL) return; if (obj->locTab != NULL) { for (i = 0;i < obj->locNr; i++) { xmlXPathFreeObject(obj->locTab[i]); } xmlFree(obj->locTab); } xmlFree(obj);}/** * xmlXPtrNewLocationSetNodes: * @start: the start NodePtr value * @end: the end NodePtr value or NULL * * Create a new xmlXPathObjectPtr of type LocationSet and initialize * it with the single range made of the two nodes @start and @end * * Returns the newly created object. */xmlXPathObjectPtrxmlXPtrNewLocationSetNodes(xmlNodePtr start, xmlNodePtr end) { xmlXPathObjectPtr ret; ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); if (ret == NULL) { xmlXPtrErrMemory("allocating locationset"); return(NULL); } memset(ret, 0 , (size_t) sizeof(xmlXPathObject)); ret->type = XPATH_LOCATIONSET; if (end == NULL) ret->user = xmlXPtrLocationSetCreate(xmlXPtrNewCollapsedRange(start)); else ret->user = xmlXPtrLocationSetCreate(xmlXPtrNewRangeNodes(start,end)); return(ret);}/** * xmlXPtrNewLocationSetNodeSet: * @set: a node set * * Create a new xmlXPathObjectPtr of type LocationSet and initialize * it with all the nodes from @set * * Returns the newly created object. */xmlXPathObjectPtrxmlXPtrNewLocationSetNodeSet(xmlNodeSetPtr set) { xmlXPathObjectPtr ret; ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); if (ret == NULL) { xmlXPtrErrMemory("allocating locationset"); return(NULL); } memset(ret, 0 , (size_t) sizeof(xmlXPathObject)); ret->type = XPATH_LOCATIONSET; if (set != NULL) { int i; xmlLocationSetPtr newset; newset = xmlXPtrLocationSetCreate(NULL); if (newset == NULL) return(ret); for (i = 0;i < set->nodeNr;i++) xmlXPtrLocationSetAdd(newset, xmlXPtrNewCollapsedRange(set->nodeTab[i])); ret->user = (void *) newset; } return(ret);}/** * xmlXPtrWrapLocationSet: * @val: the LocationSet value * * Wrap the LocationSet @val in a new xmlXPathObjectPtr * * Returns the newly created object. */xmlXPathObjectPtrxmlXPtrWrapLocationSet(xmlLocationSetPtr val) { xmlXPathObjectPtr ret; ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); if (ret == NULL) { xmlXPtrErrMemory("allocating locationset"); return(NULL); } memset(ret, 0 , (size_t) sizeof(xmlXPathObject)); ret->type = XPATH_LOCATIONSET; ret->user = (void *) val; return(ret);}/************************************************************************ * * * The parser * * * ************************************************************************/static void xmlXPtrEvalChildSeq(xmlXPathParserContextPtr ctxt, xmlChar *name);/* * Macros for accessing the content. Those should be used only by the parser, * and not exported. * * Dirty macros, i.e. one need to make assumption on the context to use them * * CUR_PTR return the current pointer to the xmlChar to be parsed. * CUR returns the current xmlChar value, i.e. a 8 bit value * in ISO-Latin or UTF-8. * This should be used internally by the parser * only to compare to ASCII values otherwise it would break when * running with UTF-8 encoding. * NXT(n) returns the n'th next xmlChar. Same as CUR is should be used only * to compare on ASCII based substring. * SKIP(n) Skip n xmlChar, and must also be used only to skip ASCII defined * strings within the parser. * CURRENT Returns the current char value, with the full decoding of * UTF-8 if we are using this mode. It returns an int. * NEXT Skip to the next character, this does the proper decoding * in UTF-8 mode. It also pop-up unfinished entities on the fly. * It returns the pointer to the current xmlChar. */#define CUR (*ctxt->cur)#define SKIP(val) ctxt->cur += (val)#define NXT(val) ctxt->cur[(val)]#define CUR_PTR ctxt->cur#define SKIP_BLANKS \ while (IS_BLANK_CH(*(ctxt->cur))) NEXT#define CURRENT (*ctxt->cur)#define NEXT ((*ctxt->cur) ? ctxt->cur++: ctxt->cur)/* * xmlXPtrGetChildNo: * @ctxt: the XPointer Parser context * @index: the child number * * Move the current node of the nodeset on the stack to the * given child if found */static voidxmlXPtrGetChildNo(xmlXPathParserContextPtr ctxt, int indx) { xmlNodePtr cur = NULL; xmlXPathObjectPtr obj; xmlNodeSetPtr oldset; CHECK_TYPE(XPATH_NODESET); obj = valuePop(ctxt); oldset = obj->nodesetval; if ((indx <= 0) || (oldset == NULL) || (oldset->nodeNr != 1)) { xmlXPathFreeObject(obj); valuePush(ctxt, xmlXPathNewNodeSet(NULL)); return; } cur = xmlXPtrGetNthChild(oldset->nodeTab[0], indx); if (cur == NULL) { xmlXPathFreeObject(obj); valuePush(ctxt, xmlXPathNewNodeSet(NULL)); return; } oldset->nodeTab[0] = cur; valuePush(ctxt, obj);}/** * xmlXPtrEvalXPtrPart: * @ctxt: the XPointer Parser context * @name: the preparsed Scheme for the XPtrPart * * XPtrPart ::= 'xpointer' '(' XPtrExpr ')' * | Scheme '(' SchemeSpecificExpr ')' * * Scheme ::= NCName - 'xpointer' [VC: Non-XPointer schemes] * * SchemeSpecificExpr ::= StringWithBalancedParens * * StringWithBalancedParens ::= * [^()]* ('(' StringWithBalancedParens ')' [^()]*)* * [VC: Parenthesis escaping] * * XPtrExpr ::= Expr [VC: Parenthesis escaping] * * VC: Parenthesis escaping: * The end of an XPointer part is signaled by the right parenthesis ")" * character that is balanced with the left parenthesis "(" character * that began the part. Any unbalanced parenthesis character inside the * expression, even within literals, must be escaped with a circumflex (^) * character preceding it. If the expression contains any literal * occurrences of the circumflex, each must be escaped with an additional * circumflex (that is, ^^). If the unescaped parentheses in the expression * are not balanced, a syntax error results. * * Parse and evaluate an XPtrPart. Basically it generates the unescaped * string and if the scheme is 'xpointer' it will call the XPath interpreter. * * TODO: there is no new scheme registration mechanism */static voidxmlXPtrEvalXPtrPart(xmlXPathParserContextPtr ctxt, xmlChar *name) { xmlChar *buffer, *cur; int len; int level; if (name == NULL) name = xmlXPathParseName(ctxt); if (name == NULL) XP_ERROR(XPATH_EXPR_ERROR); if (CUR != '(') XP_ERROR(XPATH_EXPR_ERROR); NEXT; level = 1; len = xmlStrlen(ctxt->cur); len++; buffer = (xmlChar *) xmlMallocAtomic(len * sizeof (xmlChar)); if (buffer == NULL) { xmlXPtrErrMemory("allocating buffer"); return; } cur = buffer; while (CUR != 0) { if (CUR == ')') { level--; if (level == 0) { NEXT; break; } *cur++ = CUR; } else if (CUR == '(') { level++; *cur++ = CUR; } else if (CUR == '^') { NEXT; if ((CUR == ')') || (CUR == '(') || (CUR == '^')) { *cur++ = CUR; } else { *cur++ = '^'; *cur++ = CUR; } } else { *cur++ = CUR; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -