Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(263)

Side by Side Diff: third_party/libxml/xpath.c

Issue 2951008: Update libxml to 2.7.7. (Closed) Base URL: http://src.chromium.org/git/chromium.git
Patch Set: Created 10 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * xpath.c: XML Path Language implementation 2 * xpath.c: XML Path Language implementation
3 * XPath is a language for addressing parts of an XML document, 3 * XPath is a language for addressing parts of an XML document,
4 * designed to be used by both XSLT and XPointer 4 * designed to be used by both XSLT and XPointer
5 *f 5 *f
6 * Reference: W3C Recommendation 16 November 1999 6 * Reference: W3C Recommendation 16 November 1999
7 * http://www.w3.org/TR/1999/REC-xpath-19991116 7 * http://www.w3.org/TR/1999/REC-xpath-19991116
8 * Public reference: 8 * Public reference:
9 * http://www.w3.org/TR/xpath 9 * http://www.w3.org/TR/xpath
10 * 10 *
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 #include <libxml/threads.h> 52 #include <libxml/threads.h>
53 #include <libxml/globals.h> 53 #include <libxml/globals.h>
54 #ifdef LIBXML_PATTERN_ENABLED 54 #ifdef LIBXML_PATTERN_ENABLED
55 #include <libxml/pattern.h> 55 #include <libxml/pattern.h>
56 #endif 56 #endif
57 57
58 #ifdef LIBXML_PATTERN_ENABLED 58 #ifdef LIBXML_PATTERN_ENABLED
59 #define XPATH_STREAMING 59 #define XPATH_STREAMING
60 #endif 60 #endif
61 61
62 #define TODO » » » » » » » » \ 62 #define TODO» » » » » » » » \
63 xmlGenericError(xmlGenericErrorContext, \ 63 xmlGenericError(xmlGenericErrorContext, \
64 "Unimplemented block at %s:%d\n", \ 64 "Unimplemented block at %s:%d\n", \
65 __FILE__, __LINE__); 65 __FILE__, __LINE__);
66 66
67 /* 67 /*
68 * XP_OPTIMIZED_NON_ELEM_COMPARISON: 68 * XP_OPTIMIZED_NON_ELEM_COMPARISON:
69 * If defined, this will use xmlXPathCmpNodesExt() instead of 69 * If defined, this will use xmlXPathCmpNodesExt() instead of
70 * xmlXPathCmpNodes(). The new function is optimized comparison of 70 * xmlXPathCmpNodes(). The new function is optimized comparison of
71 * non-element nodes; actually it will speed up comparison only if 71 * non-element nodes; actually it will speed up comparison only if
72 * xmlXPathOrderDocElems() was called in order to index the elements of 72 * xmlXPathOrderDocElems() was called in order to index the elements of
73 * a tree in document order; Libxslt does such an indexing, thus it will 73 * a tree in document order; Libxslt does such an indexing, thus it will
74 * benefit from this optimization. 74 * benefit from this optimization.
75 */ 75 */
76 #define XP_OPTIMIZED_NON_ELEM_COMPARISON 76 #define XP_OPTIMIZED_NON_ELEM_COMPARISON
77 77
78 /* 78 /*
79 * XP_OPTIMIZED_FILTER_FIRST: 79 * XP_OPTIMIZED_FILTER_FIRST:
80 * If defined, this will optimize expressions like "key('foo', 'val')[b][1]" 80 * If defined, this will optimize expressions like "key('foo', 'val')[b][1]"
81 * in a way, that it stop evaluation at the first node. 81 * in a way, that it stop evaluation at the first node.
82 */ 82 */
83 #define XP_OPTIMIZED_FILTER_FIRST 83 #define XP_OPTIMIZED_FILTER_FIRST
84 84
85 /* 85 /*
86 * XP_DEBUG_OBJ_USAGE: 86 * XP_DEBUG_OBJ_USAGE:
87 * Internal flag to enable tracking of how much XPath objects have been 87 * Internal flag to enable tracking of how much XPath objects have been
88 * created. 88 * created.
89 */ 89 */
90 /* #define XP_DEBUG_OBJ_USAGE */ 90 /* #define XP_DEBUG_OBJ_USAGE */
91 91
92 /* 92 /*
93 * TODO: 93 * TODO:
94 * There are a few spots where some tests are done which depend upon ascii 94 * There are a few spots where some tests are done which depend upon ascii
95 * data. These should be enhanced for full UTF8 support (see particularly 95 * data. These should be enhanced for full UTF8 support (see particularly
96 * any use of the macros IS_ASCII_CHARACTER and IS_ASCII_DIGIT) 96 * any use of the macros IS_ASCII_CHARACTER and IS_ASCII_DIGIT)
97 */ 97 */
98 98
99 #if defined(LIBXML_XPATH_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED) 99 #if defined(LIBXML_XPATH_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
100 100
101 /************************************************************************ 101 /************************************************************************
102 * » » » » » » » » » * 102 *» » » » » » » » » *
103 * » » » Floating point stuff» » » » * 103 *» » » Floating point stuff» » » » *
104 * » » » » » » » » » * 104 *» » » » » » » » » *
105 ************************************************************************/ 105 ************************************************************************/
106 106
107 #ifndef TRIO_REPLACE_STDIO 107 #ifndef TRIO_REPLACE_STDIO
108 #define TRIO_PUBLIC static 108 #define TRIO_PUBLIC static
109 #endif 109 #endif
110 #include "trionan.c" 110 #include "trionan.c"
111 111
112 /* 112 /*
113 * The lack of portability of this section of the libc is annoying ! 113 * The lack of portability of this section of the libc is annoying !
114 */ 114 */
(...skipping 20 matching lines...) Expand all
135 xmlXPathInitialized = 1; 135 xmlXPathInitialized = 1;
136 } 136 }
137 137
138 /** 138 /**
139 * xmlXPathIsNaN: 139 * xmlXPathIsNaN:
140 * @val: a double value 140 * @val: a double value
141 * 141 *
142 * Provides a portable isnan() function to detect whether a double 142 * Provides a portable isnan() function to detect whether a double
143 * is a NotaNumber. Based on trio code 143 * is a NotaNumber. Based on trio code
144 * http://sourceforge.net/projects/ctrio/ 144 * http://sourceforge.net/projects/ctrio/
145 * 145 *
146 * Returns 1 if the value is a NaN, 0 otherwise 146 * Returns 1 if the value is a NaN, 0 otherwise
147 */ 147 */
148 int 148 int
149 xmlXPathIsNaN(double val) { 149 xmlXPathIsNaN(double val) {
150 return(trio_isnan(val)); 150 return(trio_isnan(val));
151 } 151 }
152 152
153 /** 153 /**
154 * xmlXPathIsInf: 154 * xmlXPathIsInf:
155 * @val: a double value 155 * @val: a double value
156 * 156 *
157 * Provides a portable isinf() function to detect whether a double 157 * Provides a portable isinf() function to detect whether a double
158 * is a +Infinite or -Infinite. Based on trio code 158 * is a +Infinite or -Infinite. Based on trio code
159 * http://sourceforge.net/projects/ctrio/ 159 * http://sourceforge.net/projects/ctrio/
160 * 160 *
161 * Returns 1 vi the value is +Infinite, -1 if -Infinite, 0 otherwise 161 * Returns 1 vi the value is +Infinite, -1 if -Infinite, 0 otherwise
162 */ 162 */
163 int 163 int
164 xmlXPathIsInf(double val) { 164 xmlXPathIsInf(double val) {
165 return(trio_isinf(val)); 165 return(trio_isinf(val));
166 } 166 }
167 167
168 #endif /* SCHEMAS or XPATH */ 168 #endif /* SCHEMAS or XPATH */
169 #ifdef LIBXML_XPATH_ENABLED 169 #ifdef LIBXML_XPATH_ENABLED
170 /** 170 /**
171 * xmlXPathGetSign: 171 * xmlXPathGetSign:
172 * @val: a double value 172 * @val: a double value
173 * 173 *
174 * Provides a portable function to detect the sign of a double 174 * Provides a portable function to detect the sign of a double
175 * Modified from trio code 175 * Modified from trio code
176 * http://sourceforge.net/projects/ctrio/ 176 * http://sourceforge.net/projects/ctrio/
177 * 177 *
178 * Returns 1 if the value is Negative, 0 if positive 178 * Returns 1 if the value is Negative, 0 if positive
179 */ 179 */
180 static int 180 static int
181 xmlXPathGetSign(double val) { 181 xmlXPathGetSign(double val) {
182 return(trio_signbit(val)); 182 return(trio_signbit(val));
183 } 183 }
184 184
185 185
186 /* 186 /*
187 * TODO: when compatibility allows remove all "fake node libxslt" strings 187 * TODO: when compatibility allows remove all "fake node libxslt" strings
188 * the test should just be name[0] = ' ' 188 * the test should just be name[0] = ' '
189 */ 189 */
190 /* #define DEBUG */ 190 #ifdef DEBUG_XPATH_EXPRESSION
191 /* #define DEBUG_STEP */ 191 #define DEBUG_STEP
192 /* #define DEBUG_STEP_NTH */ 192 #define DEBUG_EXPR
193 /* #define DEBUG_EXPR */ 193 #define DEBUG_EVAL_COUNTS
194 /* #define DEBUG_EVAL_COUNTS */ 194 #endif
195 195
196 static xmlNs xmlXPathXMLNamespaceStruct = { 196 static xmlNs xmlXPathXMLNamespaceStruct = {
197 NULL, 197 NULL,
198 XML_NAMESPACE_DECL, 198 XML_NAMESPACE_DECL,
199 XML_XML_NAMESPACE, 199 XML_XML_NAMESPACE,
200 BAD_CAST "xml", 200 BAD_CAST "xml",
201 NULL, 201 NULL,
202 NULL 202 NULL
203 }; 203 };
204 static xmlNsPtr xmlXPathXMLNamespace = &xmlXPathXMLNamespaceStruct; 204 static xmlNsPtr xmlXPathXMLNamespace = &xmlXPathXMLNamespaceStruct;
205 #ifndef LIBXML_THREAD_ENABLED 205 #ifndef LIBXML_THREAD_ENABLED
206 /* 206 /*
207 * Optimizer is disabled only when threaded apps are detected while 207 * Optimizer is disabled only when threaded apps are detected while
208 * the library ain't compiled for thread safety. 208 * the library ain't compiled for thread safety.
209 */ 209 */
210 static int xmlXPathDisableOptimizer = 0; 210 static int xmlXPathDisableOptimizer = 0;
211 #endif 211 #endif
212 212
213 /************************************************************************ 213 /************************************************************************
214 * * 214 * *
215 * Error handling routines * 215 * Error handling routines *
216 * * 216 * *
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
327 xmlXPathErr(xmlXPathParserContextPtr ctxt, int error) 327 xmlXPathErr(xmlXPathParserContextPtr ctxt, int error)
328 { 328 {
329 if ((error < 0) || (error > MAXERRNO)) 329 if ((error < 0) || (error > MAXERRNO))
330 error = MAXERRNO; 330 error = MAXERRNO;
331 if (ctxt == NULL) { 331 if (ctxt == NULL) {
332 __xmlRaiseError(NULL, NULL, NULL, 332 __xmlRaiseError(NULL, NULL, NULL,
333 NULL, NULL, XML_FROM_XPATH, 333 NULL, NULL, XML_FROM_XPATH,
334 error + XML_XPATH_EXPRESSION_OK - XPATH_EXPRESSION_OK, 334 error + XML_XPATH_EXPRESSION_OK - XPATH_EXPRESSION_OK,
335 XML_ERR_ERROR, NULL, 0, 335 XML_ERR_ERROR, NULL, 0,
336 NULL, NULL, NULL, 0, 0, 336 NULL, NULL, NULL, 0, 0,
337 » » » xmlXPathErrorMessages[error]); 337 » » » "%s", xmlXPathErrorMessages[error]);
338 return; 338 return;
339 } 339 }
340 ctxt->error = error; 340 ctxt->error = error;
341 if (ctxt->context == NULL) { 341 if (ctxt->context == NULL) {
342 __xmlRaiseError(NULL, NULL, NULL, 342 __xmlRaiseError(NULL, NULL, NULL,
343 NULL, NULL, XML_FROM_XPATH, 343 NULL, NULL, XML_FROM_XPATH,
344 error + XML_XPATH_EXPRESSION_OK - XPATH_EXPRESSION_OK, 344 error + XML_XPATH_EXPRESSION_OK - XPATH_EXPRESSION_OK,
345 XML_ERR_ERROR, NULL, 0, 345 XML_ERR_ERROR, NULL, 0,
346 (const char *) ctxt->base, NULL, NULL, 346 (const char *) ctxt->base, NULL, NULL,
347 ctxt->cur - ctxt->base, 0, 347 ctxt->cur - ctxt->base, 0,
348 » » » xmlXPathErrorMessages[error]); 348 » » » "%s", xmlXPathErrorMessages[error]);
349 return; 349 return;
350 } 350 }
351 351
352 /* cleanup current last error */ 352 /* cleanup current last error */
353 xmlResetError(&ctxt->context->lastError); 353 xmlResetError(&ctxt->context->lastError);
354 354
355 ctxt->context->lastError.domain = XML_FROM_XPATH; 355 ctxt->context->lastError.domain = XML_FROM_XPATH;
356 ctxt->context->lastError.code = error + XML_XPATH_EXPRESSION_OK - 356 ctxt->context->lastError.code = error + XML_XPATH_EXPRESSION_OK -
357 XPATH_EXPRESSION_OK; 357 XPATH_EXPRESSION_OK;
358 ctxt->context->lastError.level = XML_ERR_ERROR; 358 ctxt->context->lastError.level = XML_ERR_ERROR;
359 ctxt->context->lastError.str1 = (char *) xmlStrdup(ctxt->base); 359 ctxt->context->lastError.str1 = (char *) xmlStrdup(ctxt->base);
360 ctxt->context->lastError.int1 = ctxt->cur - ctxt->base; 360 ctxt->context->lastError.int1 = ctxt->cur - ctxt->base;
361 ctxt->context->lastError.node = ctxt->context->debugNode; 361 ctxt->context->lastError.node = ctxt->context->debugNode;
362 if (ctxt->context->error != NULL) { 362 if (ctxt->context->error != NULL) {
363 ctxt->context->error(ctxt->context->userData, 363 ctxt->context->error(ctxt->context->userData,
364 &ctxt->context->lastError); 364 &ctxt->context->lastError);
365 } else { 365 } else {
366 __xmlRaiseError(NULL, NULL, NULL, 366 __xmlRaiseError(NULL, NULL, NULL,
367 NULL, ctxt->context->debugNode, XML_FROM_XPATH, 367 NULL, ctxt->context->debugNode, XML_FROM_XPATH,
368 error + XML_XPATH_EXPRESSION_OK - XPATH_EXPRESSION_OK, 368 error + XML_XPATH_EXPRESSION_OK - XPATH_EXPRESSION_OK,
369 XML_ERR_ERROR, NULL, 0, 369 XML_ERR_ERROR, NULL, 0,
370 (const char *) ctxt->base, NULL, NULL, 370 (const char *) ctxt->base, NULL, NULL,
371 ctxt->cur - ctxt->base, 0, 371 ctxt->cur - ctxt->base, 0,
372 » » » xmlXPathErrorMessages[error]); 372 » » » "%s", xmlXPathErrorMessages[error]);
373 } 373 }
374 374
375 } 375 }
376 376
377 /** 377 /**
378 * xmlXPatherror: 378 * xmlXPatherror:
379 * @ctxt: the XPath Parser context 379 * @ctxt: the XPath Parser context
380 * @file: the file name 380 * @file: the file name
381 * @line: the line number 381 * @line: the line number
382 * @no: the error number 382 * @no: the error number
383 * 383 *
384 * Formats an error message. 384 * Formats an error message.
385 */ 385 */
386 void 386 void
387 xmlXPatherror(xmlXPathParserContextPtr ctxt, const char *file ATTRIBUTE_UNUSED, 387 xmlXPatherror(xmlXPathParserContextPtr ctxt, const char *file ATTRIBUTE_UNUSED,
388 int line ATTRIBUTE_UNUSED, int no) { 388 int line ATTRIBUTE_UNUSED, int no) {
389 xmlXPathErr(ctxt, no); 389 xmlXPathErr(ctxt, no);
390 } 390 }
391 391
392 /************************************************************************ 392 /************************************************************************
393 * » » » » » » » » » * 393 *» » » » » » » » » *
394 * » » » Utilities» » » » » * 394 *» » » Utilities» » » » » *
395 * » » » » » » » » » * 395 *» » » » » » » » » *
396 ************************************************************************/ 396 ************************************************************************/
397 397
398 /** 398 /**
399 * xsltPointerList: 399 * xsltPointerList:
400 * 400 *
401 * Pointer-list for various purposes. 401 * Pointer-list for various purposes.
402 */ 402 */
403 typedef struct _xmlPointerList xmlPointerList; 403 typedef struct _xmlPointerList xmlPointerList;
404 typedef xmlPointerList *xmlPointerListPtr; 404 typedef xmlPointerList *xmlPointerListPtr;
405 struct _xmlPointerList { 405 struct _xmlPointerList {
406 void **items; 406 void **items;
407 int number; 407 int number;
408 int size; 408 int size;
409 }; 409 };
410 /* 410 /*
411 * TODO: Since such a list-handling is used in xmlschemas.c and libxslt 411 * TODO: Since such a list-handling is used in xmlschemas.c and libxslt
412 * and here, we should make the functions public. 412 * and here, we should make the functions public.
413 */ 413 */
414 static int 414 static int
415 xmlPointerListAddSize(xmlPointerListPtr list,» » 415 xmlPointerListAddSize(xmlPointerListPtr list,
416 void *item, 416 void *item,
417 int initialSize) 417 int initialSize)
418 { 418 {
419 if (list->items == NULL) { 419 if (list->items == NULL) {
420 if (initialSize <= 0) 420 if (initialSize <= 0)
421 initialSize = 1; 421 initialSize = 1;
422 list->items = (void **) xmlMalloc( 422 list->items = (void **) xmlMalloc(
423 initialSize * sizeof(void *)); 423 initialSize * sizeof(void *));
424 if (list->items == NULL) { 424 if (list->items == NULL) {
425 xmlXPathErrMemory(NULL, 425 xmlXPathErrMemory(NULL,
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
479 xmlPointerListFree(xmlPointerListPtr list) 479 xmlPointerListFree(xmlPointerListPtr list)
480 { 480 {
481 if (list == NULL) 481 if (list == NULL)
482 return; 482 return;
483 if (list->items != NULL) 483 if (list->items != NULL)
484 xmlFree(list->items); 484 xmlFree(list->items);
485 xmlFree(list); 485 xmlFree(list);
486 } 486 }
487 487
488 /************************************************************************ 488 /************************************************************************
489 * » » » » » » » » » * 489 *» » » » » » » » » *
490 * » » » Parser Types» » » » » * 490 *» » » Parser Types» » » » » *
491 * » » » » » » » » » * 491 *» » » » » » » » » *
492 ************************************************************************/ 492 ************************************************************************/
493 493
494 /* 494 /*
495 * Types are private: 495 * Types are private:
496 */ 496 */
497 497
498 typedef enum { 498 typedef enum {
499 XPATH_OP_END=0, 499 XPATH_OP_END=0,
500 XPATH_OP_AND, 500 XPATH_OP_AND,
501 XPATH_OP_OR, 501 XPATH_OP_OR,
(...skipping 24 matching lines...) Expand all
526 AXIS_ATTRIBUTE, 526 AXIS_ATTRIBUTE,
527 AXIS_CHILD, 527 AXIS_CHILD,
528 AXIS_DESCENDANT, 528 AXIS_DESCENDANT,
529 AXIS_DESCENDANT_OR_SELF, 529 AXIS_DESCENDANT_OR_SELF,
530 AXIS_FOLLOWING, 530 AXIS_FOLLOWING,
531 AXIS_FOLLOWING_SIBLING, 531 AXIS_FOLLOWING_SIBLING,
532 AXIS_NAMESPACE, 532 AXIS_NAMESPACE,
533 AXIS_PARENT, 533 AXIS_PARENT,
534 AXIS_PRECEDING, 534 AXIS_PRECEDING,
535 AXIS_PRECEDING_SIBLING, 535 AXIS_PRECEDING_SIBLING,
536 AXIS_SELF 536 AXIS_SELF
537 } xmlXPathAxisVal; 537 } xmlXPathAxisVal;
538 538
539 typedef enum { 539 typedef enum {
540 NODE_TEST_NONE = 0, 540 NODE_TEST_NONE = 0,
541 NODE_TEST_TYPE = 1, 541 NODE_TEST_TYPE = 1,
542 NODE_TEST_PI = 2, 542 NODE_TEST_PI = 2,
543 NODE_TEST_ALL = 3, 543 NODE_TEST_ALL = 3,
544 NODE_TEST_NS = 4, 544 NODE_TEST_NS = 4,
545 NODE_TEST_NAME = 5 545 NODE_TEST_NAME = 5
546 } xmlXPathTestVal; 546 } xmlXPathTestVal;
547 547
548 typedef enum { 548 typedef enum {
549 NODE_TYPE_NODE = 0, 549 NODE_TYPE_NODE = 0,
550 NODE_TYPE_COMMENT = XML_COMMENT_NODE, 550 NODE_TYPE_COMMENT = XML_COMMENT_NODE,
551 NODE_TYPE_TEXT = XML_TEXT_NODE, 551 NODE_TYPE_TEXT = XML_TEXT_NODE,
552 NODE_TYPE_PI = XML_PI_NODE 552 NODE_TYPE_PI = XML_PI_NODE
553 } xmlXPathTypeVal; 553 } xmlXPathTypeVal;
554 554
555 #define XP_REWRITE_DOS_CHILD_ELEM 1 555 #define XP_REWRITE_DOS_CHILD_ELEM 1
556 556
557 typedef struct _xmlXPathStepOp xmlXPathStepOp; 557 typedef struct _xmlXPathStepOp xmlXPathStepOp;
558 typedef xmlXPathStepOp *xmlXPathStepOpPtr; 558 typedef xmlXPathStepOp *xmlXPathStepOpPtr;
559 struct _xmlXPathStepOp { 559 struct _xmlXPathStepOp {
560 xmlXPathOp op; /* The identifier of the operation */ 560 xmlXPathOp op; /* The identifier of the operation */
561 int ch1; /* First child */ 561 int ch1; /* First child */
562 int ch2; /* Second child */ 562 int ch2; /* Second child */
(...skipping 17 matching lines...) Expand all
580 #ifdef DEBUG_EVAL_COUNTS 580 #ifdef DEBUG_EVAL_COUNTS
581 int nb; 581 int nb;
582 xmlChar *string; 582 xmlChar *string;
583 #endif 583 #endif
584 #ifdef XPATH_STREAMING 584 #ifdef XPATH_STREAMING
585 xmlPatternPtr stream; 585 xmlPatternPtr stream;
586 #endif 586 #endif
587 }; 587 };
588 588
589 /************************************************************************ 589 /************************************************************************
590 * » » » » » » » » » * 590 *» » » » » » » » » *
591 * » » » Forward declarations» » » » * 591 *» » » Forward declarations» » » » *
592 * » » » » » » » » » * 592 *» » » » » » » » » *
593 ************************************************************************/ 593 ************************************************************************/
594 static void 594 static void
595 xmlXPathFreeValueTree(xmlNodeSetPtr obj); 595 xmlXPathFreeValueTree(xmlNodeSetPtr obj);
596 static void 596 static void
597 xmlXPathReleaseObject(xmlXPathContextPtr ctxt, xmlXPathObjectPtr obj); 597 xmlXPathReleaseObject(xmlXPathContextPtr ctxt, xmlXPathObjectPtr obj);
598 static int 598 static int
599 xmlXPathCompOpEvalFirst(xmlXPathParserContextPtr ctxt, 599 xmlXPathCompOpEvalFirst(xmlXPathParserContextPtr ctxt,
600 xmlXPathStepOpPtr op, xmlNodePtr *first); 600 xmlXPathStepOpPtr op, xmlNodePtr *first);
601 static int 601 static int
602 xmlXPathCompOpEvalToBoolean(xmlXPathParserContextPtr ctxt, 602 xmlXPathCompOpEvalToBoolean(xmlXPathParserContextPtr ctxt,
603 xmlXPathStepOpPtr op, 603 xmlXPathStepOpPtr op,
604 int isPredicate); 604 int isPredicate);
605 605
606 /************************************************************************ 606 /************************************************************************
607 * » » » » » » » » » * 607 *» » » » » » » » » *
608 * » » » Parser Type functions » » » » * 608 *» » » Parser Type functions» » » » *
609 * » » » » » » » » » * 609 *» » » » » » » » » *
610 ************************************************************************/ 610 ************************************************************************/
611 611
612 /** 612 /**
613 * xmlXPathNewCompExpr: 613 * xmlXPathNewCompExpr:
614 * 614 *
615 * Create a new Xpath component 615 * Create a new Xpath component
616 * 616 *
617 * Returns the newly allocated xmlXPathCompExprPtr or NULL in case of error 617 * Returns the newly allocated xmlXPathCompExprPtr or NULL in case of error
618 */ 618 */
619 static xmlXPathCompExprPtr 619 static xmlXPathCompExprPtr
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
789 op->ch2 = tmp; 789 op->ch2 = tmp;
790 } 790 }
791 791
792 #define PUSH_FULL_EXPR(op, op1, op2, val, val2, val3, val4, val5) \ 792 #define PUSH_FULL_EXPR(op, op1, op2, val, val2, val3, val4, val5) \
793 xmlXPathCompExprAdd(ctxt->comp, (op1), (op2), \ 793 xmlXPathCompExprAdd(ctxt->comp, (op1), (op2), \
794 (op), (val), (val2), (val3), (val4), (val5)) 794 (op), (val), (val2), (val3), (val4), (val5))
795 #define PUSH_LONG_EXPR(op, val, val2, val3, val4, val5) \ 795 #define PUSH_LONG_EXPR(op, val, val2, val3, val4, val5) \
796 xmlXPathCompExprAdd(ctxt->comp, ctxt->comp->last, -1, \ 796 xmlXPathCompExprAdd(ctxt->comp, ctxt->comp->last, -1, \
797 (op), (val), (val2), (val3), (val4), (val5)) 797 (op), (val), (val2), (val3), (val4), (val5))
798 798
799 #define PUSH_LEAVE_EXPR(op, val, val2) »» » » » \ 799 #define PUSH_LEAVE_EXPR(op, val, val2)» » » » » \
800 xmlXPathCompExprAdd(ctxt->comp, -1, -1, (op), (val), (val2), 0 ,NULL ,NULL) 800 xmlXPathCompExprAdd(ctxt->comp, -1, -1, (op), (val), (val2), 0 ,NULL ,NULL)
801 801
802 #define PUSH_UNARY_EXPR(op, ch, val, val2) » » » » \ 802 #define PUSH_UNARY_EXPR(op, ch, val, val2)» » » » \
803 xmlXPathCompExprAdd(ctxt->comp, (ch), -1, (op), (val), (val2), 0 ,NULL ,NULL) 803 xmlXPathCompExprAdd(ctxt->comp, (ch), -1, (op), (val), (val2), 0 ,NULL ,NULL)
804 804
805 #define PUSH_BINARY_EXPR(op, ch1, ch2, val, val2) » » » \ 805 #define PUSH_BINARY_EXPR(op, ch1, ch2, val, val2)» » » \
806 xmlXPathCompExprAdd(ctxt->comp, (ch1), (ch2), (op), \ 806 xmlXPathCompExprAdd(ctxt->comp, (ch1), (ch2), (op), \
807 (val), (val2), 0 ,NULL ,NULL) 807 (val), (val2), 0 ,NULL ,NULL)
808 808
809 /************************************************************************ 809 /************************************************************************
810 * * 810 * *
811 * » » XPath object cache structures» » » » * 811 *» » XPath object cache structures» » » » *
812 * * 812 * *
813 ************************************************************************/ 813 ************************************************************************/
814 814
815 /* #define XP_DEFAULT_CACHE_ON */ 815 /* #define XP_DEFAULT_CACHE_ON */
816 816
817 #define XP_HAS_CACHE(c) ((c != NULL) && ((c)->cache != NULL)) 817 #define XP_HAS_CACHE(c) ((c != NULL) && ((c)->cache != NULL))
818 818
819 typedef struct _xmlXPathContextCache xmlXPathContextCache; 819 typedef struct _xmlXPathContextCache xmlXPathContextCache;
820 typedef xmlXPathContextCache *xmlXPathContextCachePtr; 820 typedef xmlXPathContextCache *xmlXPathContextCachePtr;
821 struct _xmlXPathContextCache { 821 struct _xmlXPathContextCache {
(...skipping 11 matching lines...) Expand all
833 int dbgCachedAll; 833 int dbgCachedAll;
834 int dbgCachedNodeset; 834 int dbgCachedNodeset;
835 int dbgCachedString; 835 int dbgCachedString;
836 int dbgCachedBool; 836 int dbgCachedBool;
837 int dbgCachedNumber; 837 int dbgCachedNumber;
838 int dbgCachedPoint; 838 int dbgCachedPoint;
839 int dbgCachedRange; 839 int dbgCachedRange;
840 int dbgCachedLocset; 840 int dbgCachedLocset;
841 int dbgCachedUsers; 841 int dbgCachedUsers;
842 int dbgCachedXSLTTree; 842 int dbgCachedXSLTTree;
843 int dbgCachedUndefined; 843 int dbgCachedUndefined;
844 844
845 845
846 int dbgReusedAll; 846 int dbgReusedAll;
847 int dbgReusedNodeset; 847 int dbgReusedNodeset;
848 int dbgReusedString; 848 int dbgReusedString;
849 int dbgReusedBool; 849 int dbgReusedBool;
850 int dbgReusedNumber; 850 int dbgReusedNumber;
851 int dbgReusedPoint; 851 int dbgReusedPoint;
852 int dbgReusedRange; 852 int dbgReusedRange;
853 int dbgReusedLocset; 853 int dbgReusedLocset;
854 int dbgReusedUsers; 854 int dbgReusedUsers;
855 int dbgReusedXSLTTree; 855 int dbgReusedXSLTTree;
856 int dbgReusedUndefined; 856 int dbgReusedUndefined;
857 857
858 #endif 858 #endif
859 }; 859 };
860 860
861 /************************************************************************ 861 /************************************************************************
862 * * 862 * *
863 * » » Debugging related functions» » » » * 863 *» » Debugging related functions» » » » *
864 * * 864 * *
865 ************************************************************************/ 865 ************************************************************************/
866 866
867 #define STRANGE » » » » » » » \ 867 #define STRANGE»» » » » » » \
868 xmlGenericError(xmlGenericErrorContext, \ 868 xmlGenericError(xmlGenericErrorContext, \
869 "Internal error at %s:%d\n", \ 869 "Internal error at %s:%d\n", \
870 __FILE__, __LINE__); 870 __FILE__, __LINE__);
871 871
872 #ifdef LIBXML_DEBUG_ENABLED 872 #ifdef LIBXML_DEBUG_ENABLED
873 static void 873 static void
874 xmlXPathDebugDumpNode(FILE *output, xmlNodePtr cur, int depth) { 874 xmlXPathDebugDumpNode(FILE *output, xmlNodePtr cur, int depth) {
875 int i; 875 int i;
876 char shift[100]; 876 char shift[100];
877 877
878 for (i = 0;((i < depth) && (i < 25));i++) 878 for (i = 0;((i < depth) && (i < 25));i++)
879 shift[2 * i] = shift[2 * i + 1] = ' '; 879 shift[2 * i] = shift[2 * i + 1] = ' ';
880 shift[2 * i] = shift[2 * i + 1] = 0; 880 shift[2 * i] = shift[2 * i + 1] = 0;
881 if (cur == NULL) { 881 if (cur == NULL) {
882 » fprintf(output, shift); 882 » fprintf(output, "%s", shift);
883 fprintf(output, "Node is NULL !\n"); 883 fprintf(output, "Node is NULL !\n");
884 return; 884 return;
885 885
886 } 886 }
887 887
888 if ((cur->type == XML_DOCUMENT_NODE) || 888 if ((cur->type == XML_DOCUMENT_NODE) ||
889 (cur->type == XML_HTML_DOCUMENT_NODE)) { 889 (cur->type == XML_HTML_DOCUMENT_NODE)) {
890 » fprintf(output, shift); 890 » fprintf(output, "%s", shift);
891 fprintf(output, " /\n"); 891 fprintf(output, " /\n");
892 } else if (cur->type == XML_ATTRIBUTE_NODE) 892 } else if (cur->type == XML_ATTRIBUTE_NODE)
893 xmlDebugDumpAttr(output, (xmlAttrPtr)cur, depth); 893 xmlDebugDumpAttr(output, (xmlAttrPtr)cur, depth);
894 else 894 else
895 xmlDebugDumpOneNode(output, cur, depth); 895 xmlDebugDumpOneNode(output, cur, depth);
896 } 896 }
897 static void 897 static void
898 xmlXPathDebugDumpNodeList(FILE *output, xmlNodePtr cur, int depth) { 898 xmlXPathDebugDumpNodeList(FILE *output, xmlNodePtr cur, int depth) {
899 xmlNodePtr tmp; 899 xmlNodePtr tmp;
900 int i; 900 int i;
901 char shift[100]; 901 char shift[100];
902 902
903 for (i = 0;((i < depth) && (i < 25));i++) 903 for (i = 0;((i < depth) && (i < 25));i++)
904 shift[2 * i] = shift[2 * i + 1] = ' '; 904 shift[2 * i] = shift[2 * i + 1] = ' ';
905 shift[2 * i] = shift[2 * i + 1] = 0; 905 shift[2 * i] = shift[2 * i + 1] = 0;
906 if (cur == NULL) { 906 if (cur == NULL) {
907 » fprintf(output, shift); 907 » fprintf(output, "%s", shift);
908 fprintf(output, "Node is NULL !\n"); 908 fprintf(output, "Node is NULL !\n");
909 return; 909 return;
910 910
911 } 911 }
912 912
913 while (cur != NULL) { 913 while (cur != NULL) {
914 tmp = cur; 914 tmp = cur;
915 cur = cur->next; 915 cur = cur->next;
916 xmlDebugDumpOneNode(output, tmp, depth); 916 xmlDebugDumpOneNode(output, tmp, depth);
917 } 917 }
918 } 918 }
919 919
920 static void 920 static void
921 xmlXPathDebugDumpNodeSet(FILE *output, xmlNodeSetPtr cur, int depth) { 921 xmlXPathDebugDumpNodeSet(FILE *output, xmlNodeSetPtr cur, int depth) {
922 int i; 922 int i;
923 char shift[100]; 923 char shift[100];
924 924
925 for (i = 0;((i < depth) && (i < 25));i++) 925 for (i = 0;((i < depth) && (i < 25));i++)
926 shift[2 * i] = shift[2 * i + 1] = ' '; 926 shift[2 * i] = shift[2 * i + 1] = ' ';
927 shift[2 * i] = shift[2 * i + 1] = 0; 927 shift[2 * i] = shift[2 * i + 1] = 0;
928 928
929 if (cur == NULL) { 929 if (cur == NULL) {
930 » fprintf(output, shift); 930 » fprintf(output, "%s", shift);
931 fprintf(output, "NodeSet is NULL !\n"); 931 fprintf(output, "NodeSet is NULL !\n");
932 return; 932 return;
933 933
934 } 934 }
935 935
936 if (cur != NULL) { 936 if (cur != NULL) {
937 fprintf(output, "Set contains %d nodes:\n", cur->nodeNr); 937 fprintf(output, "Set contains %d nodes:\n", cur->nodeNr);
938 for (i = 0;i < cur->nodeNr;i++) { 938 for (i = 0;i < cur->nodeNr;i++) {
939 » fprintf(output, shift); 939 » fprintf(output, "%s", shift);
940 fprintf(output, "%d", i + 1); 940 fprintf(output, "%d", i + 1);
941 xmlXPathDebugDumpNode(output, cur->nodeTab[i], depth + 1); 941 xmlXPathDebugDumpNode(output, cur->nodeTab[i], depth + 1);
942 } 942 }
943 } 943 }
944 } 944 }
945 945
946 static void 946 static void
947 xmlXPathDebugDumpValueTree(FILE *output, xmlNodeSetPtr cur, int depth) { 947 xmlXPathDebugDumpValueTree(FILE *output, xmlNodeSetPtr cur, int depth) {
948 int i; 948 int i;
949 char shift[100]; 949 char shift[100];
950 950
951 for (i = 0;((i < depth) && (i < 25));i++) 951 for (i = 0;((i < depth) && (i < 25));i++)
952 shift[2 * i] = shift[2 * i + 1] = ' '; 952 shift[2 * i] = shift[2 * i + 1] = ' ';
953 shift[2 * i] = shift[2 * i + 1] = 0; 953 shift[2 * i] = shift[2 * i + 1] = 0;
954 954
955 if ((cur == NULL) || (cur->nodeNr == 0) || (cur->nodeTab[0] == NULL)) { 955 if ((cur == NULL) || (cur->nodeNr == 0) || (cur->nodeTab[0] == NULL)) {
956 » fprintf(output, shift); 956 » fprintf(output, "%s", shift);
957 fprintf(output, "Value Tree is NULL !\n"); 957 fprintf(output, "Value Tree is NULL !\n");
958 return; 958 return;
959 959
960 } 960 }
961 961
962 fprintf(output, shift); 962 fprintf(output, "%s", shift);
963 fprintf(output, "%d", i + 1); 963 fprintf(output, "%d", i + 1);
964 xmlXPathDebugDumpNodeList(output, cur->nodeTab[0]->children, depth + 1); 964 xmlXPathDebugDumpNodeList(output, cur->nodeTab[0]->children, depth + 1);
965 } 965 }
966 #if defined(LIBXML_XPTR_ENABLED) 966 #if defined(LIBXML_XPTR_ENABLED)
967 static void 967 static void
968 xmlXPathDebugDumpLocationSet(FILE *output, xmlLocationSetPtr cur, int depth) { 968 xmlXPathDebugDumpLocationSet(FILE *output, xmlLocationSetPtr cur, int depth) {
969 int i; 969 int i;
970 char shift[100]; 970 char shift[100];
971 971
972 for (i = 0;((i < depth) && (i < 25));i++) 972 for (i = 0;((i < depth) && (i < 25));i++)
973 shift[2 * i] = shift[2 * i + 1] = ' '; 973 shift[2 * i] = shift[2 * i + 1] = ' ';
974 shift[2 * i] = shift[2 * i + 1] = 0; 974 shift[2 * i] = shift[2 * i + 1] = 0;
975 975
976 if (cur == NULL) { 976 if (cur == NULL) {
977 » fprintf(output, shift); 977 » fprintf(output, "%s", shift);
978 fprintf(output, "LocationSet is NULL !\n"); 978 fprintf(output, "LocationSet is NULL !\n");
979 return; 979 return;
980 980
981 } 981 }
982 982
983 for (i = 0;i < cur->locNr;i++) { 983 for (i = 0;i < cur->locNr;i++) {
984 » fprintf(output, shift); 984 » fprintf(output, "%s", shift);
985 fprintf(output, "%d : ", i + 1); 985 fprintf(output, "%d : ", i + 1);
986 xmlXPathDebugDumpObject(output, cur->locTab[i], depth + 1); 986 xmlXPathDebugDumpObject(output, cur->locTab[i], depth + 1);
987 } 987 }
988 } 988 }
989 #endif /* LIBXML_XPTR_ENABLED */ 989 #endif /* LIBXML_XPTR_ENABLED */
990 990
991 /** 991 /**
992 * xmlXPathDebugDumpObject: 992 * xmlXPathDebugDumpObject:
993 * @output: the FILE * to dump the output 993 * @output: the FILE * to dump the output
994 * @cur: the object to inspect 994 * @cur: the object to inspect
995 * @depth: indentation level 995 * @depth: indentation level
996 * 996 *
997 * Dump the content of the object for debugging purposes 997 * Dump the content of the object for debugging purposes
998 */ 998 */
999 void 999 void
1000 xmlXPathDebugDumpObject(FILE *output, xmlXPathObjectPtr cur, int depth) { 1000 xmlXPathDebugDumpObject(FILE *output, xmlXPathObjectPtr cur, int depth) {
1001 int i; 1001 int i;
1002 char shift[100]; 1002 char shift[100];
1003 1003
1004 if (output == NULL) return; 1004 if (output == NULL) return;
1005 1005
1006 for (i = 0;((i < depth) && (i < 25));i++) 1006 for (i = 0;((i < depth) && (i < 25));i++)
1007 shift[2 * i] = shift[2 * i + 1] = ' '; 1007 shift[2 * i] = shift[2 * i + 1] = ' ';
1008 shift[2 * i] = shift[2 * i + 1] = 0; 1008 shift[2 * i] = shift[2 * i + 1] = 0;
1009 1009
1010 1010
1011 fprintf(output, shift); 1011 fprintf(output, "%s", shift);
1012 1012
1013 if (cur == NULL) { 1013 if (cur == NULL) {
1014 fprintf(output, "Object is empty (NULL)\n"); 1014 fprintf(output, "Object is empty (NULL)\n");
1015 return; 1015 return;
1016 } 1016 }
1017 switch(cur->type) { 1017 switch(cur->type) {
1018 case XPATH_UNDEFINED: 1018 case XPATH_UNDEFINED:
1019 fprintf(output, "Object is uninitialized\n"); 1019 fprintf(output, "Object is uninitialized\n");
1020 break; 1020 break;
1021 case XPATH_NODESET: 1021 case XPATH_NODESET:
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1056 break; 1056 break;
1057 case XPATH_POINT: 1057 case XPATH_POINT:
1058 fprintf(output, "Object is a point : index %d in node", cur->index); 1058 fprintf(output, "Object is a point : index %d in node", cur->index);
1059 xmlXPathDebugDumpNode(output, (xmlNodePtr) cur->user, depth + 1); 1059 xmlXPathDebugDumpNode(output, (xmlNodePtr) cur->user, depth + 1);
1060 fprintf(output, "\n"); 1060 fprintf(output, "\n");
1061 break; 1061 break;
1062 case XPATH_RANGE: 1062 case XPATH_RANGE:
1063 if ((cur->user2 == NULL) || 1063 if ((cur->user2 == NULL) ||
1064 ((cur->user2 == cur->user) && (cur->index == cur->index2))) { 1064 ((cur->user2 == cur->user) && (cur->index == cur->index2))) {
1065 fprintf(output, "Object is a collapsed range :\n"); 1065 fprintf(output, "Object is a collapsed range :\n");
1066 » » fprintf(output, shift); 1066 » » fprintf(output, "%s", shift);
1067 if (cur->index >= 0) 1067 if (cur->index >= 0)
1068 fprintf(output, "index %d in ", cur->index); 1068 fprintf(output, "index %d in ", cur->index);
1069 fprintf(output, "node\n"); 1069 fprintf(output, "node\n");
1070 xmlXPathDebugDumpNode(output, (xmlNodePtr) cur->user, 1070 xmlXPathDebugDumpNode(output, (xmlNodePtr) cur->user,
1071 depth + 1); 1071 depth + 1);
1072 } else { 1072 } else {
1073 fprintf(output, "Object is a range :\n"); 1073 fprintf(output, "Object is a range :\n");
1074 » » fprintf(output, shift); 1074 » » fprintf(output, "%s", shift);
1075 fprintf(output, "From "); 1075 fprintf(output, "From ");
1076 if (cur->index >= 0) 1076 if (cur->index >= 0)
1077 fprintf(output, "index %d in ", cur->index); 1077 fprintf(output, "index %d in ", cur->index);
1078 fprintf(output, "node\n"); 1078 fprintf(output, "node\n");
1079 xmlXPathDebugDumpNode(output, (xmlNodePtr) cur->user, 1079 xmlXPathDebugDumpNode(output, (xmlNodePtr) cur->user,
1080 depth + 1); 1080 depth + 1);
1081 » » fprintf(output, shift); 1081 » » fprintf(output, "%s", shift);
1082 fprintf(output, "To "); 1082 fprintf(output, "To ");
1083 if (cur->index2 >= 0) 1083 if (cur->index2 >= 0)
1084 fprintf(output, "index %d in ", cur->index2); 1084 fprintf(output, "index %d in ", cur->index2);
1085 fprintf(output, "node\n"); 1085 fprintf(output, "node\n");
1086 xmlXPathDebugDumpNode(output, (xmlNodePtr) cur->user2, 1086 xmlXPathDebugDumpNode(output, (xmlNodePtr) cur->user2,
1087 depth + 1); 1087 depth + 1);
1088 fprintf(output, "\n"); 1088 fprintf(output, "\n");
1089 } 1089 }
1090 break; 1090 break;
1091 case XPATH_LOCATIONSET: 1091 case XPATH_LOCATIONSET:
(...skipping 12 matching lines...) Expand all
1104 static void 1104 static void
1105 xmlXPathDebugDumpStepOp(FILE *output, xmlXPathCompExprPtr comp, 1105 xmlXPathDebugDumpStepOp(FILE *output, xmlXPathCompExprPtr comp,
1106 xmlXPathStepOpPtr op, int depth) { 1106 xmlXPathStepOpPtr op, int depth) {
1107 int i; 1107 int i;
1108 char shift[100]; 1108 char shift[100];
1109 1109
1110 for (i = 0;((i < depth) && (i < 25));i++) 1110 for (i = 0;((i < depth) && (i < 25));i++)
1111 shift[2 * i] = shift[2 * i + 1] = ' '; 1111 shift[2 * i] = shift[2 * i + 1] = ' ';
1112 shift[2 * i] = shift[2 * i + 1] = 0; 1112 shift[2 * i] = shift[2 * i + 1] = 0;
1113 1113
1114 fprintf(output, shift); 1114 fprintf(output, "%s", shift);
1115 if (op == NULL) { 1115 if (op == NULL) {
1116 fprintf(output, "Step is NULL\n"); 1116 fprintf(output, "Step is NULL\n");
1117 return; 1117 return;
1118 } 1118 }
1119 switch (op->op) { 1119 switch (op->op) {
1120 case XPATH_OP_END: 1120 case XPATH_OP_END:
1121 fprintf(output, "END"); break; 1121 fprintf(output, "END"); break;
1122 case XPATH_OP_AND: 1122 case XPATH_OP_AND:
1123 fprintf(output, "AND"); break; 1123 fprintf(output, "AND"); break;
1124 case XPATH_OP_OR: 1124 case XPATH_OP_OR:
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
1291 int depth) { 1291 int depth) {
1292 int i; 1292 int i;
1293 char shift[100]; 1293 char shift[100];
1294 1294
1295 if ((output == NULL) || (comp == NULL)) return; 1295 if ((output == NULL) || (comp == NULL)) return;
1296 1296
1297 for (i = 0;((i < depth) && (i < 25));i++) 1297 for (i = 0;((i < depth) && (i < 25));i++)
1298 shift[2 * i] = shift[2 * i + 1] = ' '; 1298 shift[2 * i] = shift[2 * i + 1] = ' ';
1299 shift[2 * i] = shift[2 * i + 1] = 0; 1299 shift[2 * i] = shift[2 * i + 1] = 0;
1300 1300
1301 fprintf(output, shift); 1301 fprintf(output, "%s", shift);
1302 1302
1303 fprintf(output, "Compiled Expression : %d elements\n", 1303 fprintf(output, "Compiled Expression : %d elements\n",
1304 comp->nbStep); 1304 comp->nbStep);
1305 i = comp->last; 1305 i = comp->last;
1306 xmlXPathDebugDumpStepOp(output, comp, &comp->steps[i], depth + 1); 1306 xmlXPathDebugDumpStepOp(output, comp, &comp->steps[i], depth + 1);
1307 } 1307 }
1308 1308
1309 #ifdef XP_DEBUG_OBJ_USAGE 1309 #ifdef XP_DEBUG_OBJ_USAGE
1310 1310
1311 /* 1311 /*
(...skipping 14 matching lines...) Expand all
1326 static int xmlXPathDebugObjTotalUndefined = 0; 1326 static int xmlXPathDebugObjTotalUndefined = 0;
1327 static int xmlXPathDebugObjTotalNodeset = 0; 1327 static int xmlXPathDebugObjTotalNodeset = 0;
1328 static int xmlXPathDebugObjTotalBool = 0; 1328 static int xmlXPathDebugObjTotalBool = 0;
1329 static int xmlXPathDebugObjTotalNumber = 0; 1329 static int xmlXPathDebugObjTotalNumber = 0;
1330 static int xmlXPathDebugObjTotalString = 0; 1330 static int xmlXPathDebugObjTotalString = 0;
1331 static int xmlXPathDebugObjTotalPoint = 0; 1331 static int xmlXPathDebugObjTotalPoint = 0;
1332 static int xmlXPathDebugObjTotalRange = 0; 1332 static int xmlXPathDebugObjTotalRange = 0;
1333 static int xmlXPathDebugObjTotalLocset = 0; 1333 static int xmlXPathDebugObjTotalLocset = 0;
1334 static int xmlXPathDebugObjTotalUsers = 0; 1334 static int xmlXPathDebugObjTotalUsers = 0;
1335 static int xmlXPathDebugObjTotalXSLTTree = 0; 1335 static int xmlXPathDebugObjTotalXSLTTree = 0;
1336 static int xmlXPathDebugObjTotalAll = 0; 1336 static int xmlXPathDebugObjTotalAll = 0;
1337 1337
1338 static int xmlXPathDebugObjMaxUndefined = 0; 1338 static int xmlXPathDebugObjMaxUndefined = 0;
1339 static int xmlXPathDebugObjMaxNodeset = 0; 1339 static int xmlXPathDebugObjMaxNodeset = 0;
1340 static int xmlXPathDebugObjMaxBool = 0; 1340 static int xmlXPathDebugObjMaxBool = 0;
1341 static int xmlXPathDebugObjMaxNumber = 0; 1341 static int xmlXPathDebugObjMaxNumber = 0;
1342 static int xmlXPathDebugObjMaxString = 0; 1342 static int xmlXPathDebugObjMaxString = 0;
1343 static int xmlXPathDebugObjMaxPoint = 0; 1343 static int xmlXPathDebugObjMaxPoint = 0;
1344 static int xmlXPathDebugObjMaxRange = 0; 1344 static int xmlXPathDebugObjMaxRange = 0;
1345 static int xmlXPathDebugObjMaxLocset = 0; 1345 static int xmlXPathDebugObjMaxLocset = 0;
1346 static int xmlXPathDebugObjMaxUsers = 0; 1346 static int xmlXPathDebugObjMaxUsers = 0;
(...skipping 12 matching lines...) Expand all
1359 cache->dbgCachedAll = 0; 1359 cache->dbgCachedAll = 0;
1360 cache->dbgCachedNodeset = 0; 1360 cache->dbgCachedNodeset = 0;
1361 cache->dbgCachedString = 0; 1361 cache->dbgCachedString = 0;
1362 cache->dbgCachedBool = 0; 1362 cache->dbgCachedBool = 0;
1363 cache->dbgCachedNumber = 0; 1363 cache->dbgCachedNumber = 0;
1364 cache->dbgCachedPoint = 0; 1364 cache->dbgCachedPoint = 0;
1365 cache->dbgCachedRange = 0; 1365 cache->dbgCachedRange = 0;
1366 cache->dbgCachedLocset = 0; 1366 cache->dbgCachedLocset = 0;
1367 cache->dbgCachedUsers = 0; 1367 cache->dbgCachedUsers = 0;
1368 cache->dbgCachedXSLTTree = 0; 1368 cache->dbgCachedXSLTTree = 0;
1369 » cache->dbgCachedUndefined = 0; 1369 » cache->dbgCachedUndefined = 0;
1370 1370
1371 cache->dbgReusedAll = 0; 1371 cache->dbgReusedAll = 0;
1372 cache->dbgReusedNodeset = 0; 1372 cache->dbgReusedNodeset = 0;
1373 cache->dbgReusedString = 0; 1373 cache->dbgReusedString = 0;
1374 cache->dbgReusedBool = 0; 1374 cache->dbgReusedBool = 0;
1375 cache->dbgReusedNumber = 0; 1375 cache->dbgReusedNumber = 0;
1376 cache->dbgReusedPoint = 0; 1376 cache->dbgReusedPoint = 0;
1377 cache->dbgReusedRange = 0; 1377 cache->dbgReusedRange = 0;
1378 cache->dbgReusedLocset = 0; 1378 cache->dbgReusedLocset = 0;
1379 cache->dbgReusedUsers = 0; 1379 cache->dbgReusedUsers = 0;
1380 cache->dbgReusedXSLTTree = 0; 1380 cache->dbgReusedXSLTTree = 0;
1381 cache->dbgReusedUndefined = 0; 1381 cache->dbgReusedUndefined = 0;
1382 } 1382 }
1383 } 1383 }
1384 1384
1385 xmlXPathDebugObjCounterUndefined = 0; 1385 xmlXPathDebugObjCounterUndefined = 0;
1386 xmlXPathDebugObjCounterNodeset = 0; 1386 xmlXPathDebugObjCounterNodeset = 0;
1387 xmlXPathDebugObjCounterBool = 0; 1387 xmlXPathDebugObjCounterBool = 0;
1388 xmlXPathDebugObjCounterNumber = 0; 1388 xmlXPathDebugObjCounterNumber = 0;
1389 xmlXPathDebugObjCounterString = 0; 1389 xmlXPathDebugObjCounterString = 0;
1390 xmlXPathDebugObjCounterPoint = 0; 1390 xmlXPathDebugObjCounterPoint = 0;
1391 xmlXPathDebugObjCounterRange = 0; 1391 xmlXPathDebugObjCounterRange = 0;
1392 xmlXPathDebugObjCounterLocset = 0; 1392 xmlXPathDebugObjCounterLocset = 0;
1393 xmlXPathDebugObjCounterUsers = 0; 1393 xmlXPathDebugObjCounterUsers = 0;
1394 xmlXPathDebugObjCounterXSLTTree = 0; 1394 xmlXPathDebugObjCounterXSLTTree = 0;
1395 xmlXPathDebugObjCounterAll = 0; 1395 xmlXPathDebugObjCounterAll = 0;
1396 1396
1397 xmlXPathDebugObjTotalUndefined = 0; 1397 xmlXPathDebugObjTotalUndefined = 0;
1398 xmlXPathDebugObjTotalNodeset = 0; 1398 xmlXPathDebugObjTotalNodeset = 0;
1399 xmlXPathDebugObjTotalBool = 0; 1399 xmlXPathDebugObjTotalBool = 0;
1400 xmlXPathDebugObjTotalNumber = 0; 1400 xmlXPathDebugObjTotalNumber = 0;
1401 xmlXPathDebugObjTotalString = 0; 1401 xmlXPathDebugObjTotalString = 0;
1402 xmlXPathDebugObjTotalPoint = 0; 1402 xmlXPathDebugObjTotalPoint = 0;
1403 xmlXPathDebugObjTotalRange = 0; 1403 xmlXPathDebugObjTotalRange = 0;
1404 xmlXPathDebugObjTotalLocset = 0; 1404 xmlXPathDebugObjTotalLocset = 0;
1405 xmlXPathDebugObjTotalUsers = 0; 1405 xmlXPathDebugObjTotalUsers = 0;
1406 xmlXPathDebugObjTotalXSLTTree = 0; 1406 xmlXPathDebugObjTotalXSLTTree = 0;
1407 xmlXPathDebugObjTotalAll = 0; 1407 xmlXPathDebugObjTotalAll = 0;
1408 1408
1409 xmlXPathDebugObjMaxUndefined = 0; 1409 xmlXPathDebugObjMaxUndefined = 0;
1410 xmlXPathDebugObjMaxNodeset = 0; 1410 xmlXPathDebugObjMaxNodeset = 0;
1411 xmlXPathDebugObjMaxBool = 0; 1411 xmlXPathDebugObjMaxBool = 0;
1412 xmlXPathDebugObjMaxNumber = 0; 1412 xmlXPathDebugObjMaxNumber = 0;
1413 xmlXPathDebugObjMaxString = 0; 1413 xmlXPathDebugObjMaxString = 0;
1414 xmlXPathDebugObjMaxPoint = 0; 1414 xmlXPathDebugObjMaxPoint = 0;
1415 xmlXPathDebugObjMaxRange = 0; 1415 xmlXPathDebugObjMaxRange = 0;
1416 xmlXPathDebugObjMaxLocset = 0; 1416 xmlXPathDebugObjMaxLocset = 0;
1417 xmlXPathDebugObjMaxUsers = 0; 1417 xmlXPathDebugObjMaxUsers = 0;
1418 xmlXPathDebugObjMaxXSLTTree = 0; 1418 xmlXPathDebugObjMaxXSLTTree = 0;
1419 xmlXPathDebugObjMaxAll = 0; 1419 xmlXPathDebugObjMaxAll = 0;
1420 1420
1421 } 1421 }
1422 1422
1423 static void 1423 static void
1424 xmlXPathDebugObjUsageRequested(xmlXPathContextPtr ctxt, 1424 xmlXPathDebugObjUsageRequested(xmlXPathContextPtr ctxt,
1425 xmlXPathObjectType objType) 1425 xmlXPathObjectType objType)
1426 { 1426 {
1427 int isCached = 0; 1427 int isCached = 0;
1428 1428
1429 if (ctxt != NULL) { 1429 if (ctxt != NULL) {
1430 if (ctxt->cache != NULL) { 1430 if (ctxt->cache != NULL) {
1431 xmlXPathContextCachePtr cache = 1431 xmlXPathContextCachePtr cache =
1432 (xmlXPathContextCachePtr) ctxt->cache; 1432 (xmlXPathContextCachePtr) ctxt->cache;
1433 » 1433
1434 isCached = 1; 1434 isCached = 1;
1435 » 1435
1436 » cache->dbgReusedAll++;» 1436 » cache->dbgReusedAll++;
1437 switch (objType) { 1437 switch (objType) {
1438 case XPATH_UNDEFINED: 1438 case XPATH_UNDEFINED:
1439 cache->dbgReusedUndefined++; 1439 cache->dbgReusedUndefined++;
1440 break; 1440 break;
1441 case XPATH_NODESET: 1441 case XPATH_NODESET:
1442 cache->dbgReusedNodeset++; 1442 cache->dbgReusedNodeset++;
1443 break; 1443 break;
1444 case XPATH_BOOLEAN: 1444 case XPATH_BOOLEAN:
1445 cache->dbgReusedBool++; 1445 cache->dbgReusedBool++;
1446 break; 1446 break;
(...skipping 13 matching lines...) Expand all
1460 cache->dbgReusedLocset++; 1460 cache->dbgReusedLocset++;
1461 break; 1461 break;
1462 case XPATH_USERS: 1462 case XPATH_USERS:
1463 cache->dbgReusedUsers++; 1463 cache->dbgReusedUsers++;
1464 break; 1464 break;
1465 case XPATH_XSLT_TREE: 1465 case XPATH_XSLT_TREE:
1466 cache->dbgReusedXSLTTree++; 1466 cache->dbgReusedXSLTTree++;
1467 break; 1467 break;
1468 default: 1468 default:
1469 break; 1469 break;
1470 » }» 1470 » }
1471 } 1471 }
1472 } 1472 }
1473 1473
1474 switch (objType) { 1474 switch (objType) {
1475 case XPATH_UNDEFINED: 1475 case XPATH_UNDEFINED:
1476 if (! isCached) 1476 if (! isCached)
1477 xmlXPathDebugObjTotalUndefined++; 1477 xmlXPathDebugObjTotalUndefined++;
1478 » xmlXPathDebugObjCounterUndefined++;» 1478 » xmlXPathDebugObjCounterUndefined++;
1479 if (xmlXPathDebugObjCounterUndefined > 1479 if (xmlXPathDebugObjCounterUndefined >
1480 xmlXPathDebugObjMaxUndefined) 1480 xmlXPathDebugObjMaxUndefined)
1481 xmlXPathDebugObjMaxUndefined = 1481 xmlXPathDebugObjMaxUndefined =
1482 xmlXPathDebugObjCounterUndefined; 1482 xmlXPathDebugObjCounterUndefined;
1483 break; 1483 break;
1484 case XPATH_NODESET: 1484 case XPATH_NODESET:
1485 if (! isCached) 1485 if (! isCached)
1486 xmlXPathDebugObjTotalNodeset++; 1486 xmlXPathDebugObjTotalNodeset++;
1487 » xmlXPathDebugObjCounterNodeset++;» 1487 » xmlXPathDebugObjCounterNodeset++;
1488 if (xmlXPathDebugObjCounterNodeset > 1488 if (xmlXPathDebugObjCounterNodeset >
1489 xmlXPathDebugObjMaxNodeset) 1489 xmlXPathDebugObjMaxNodeset)
1490 xmlXPathDebugObjMaxNodeset = 1490 xmlXPathDebugObjMaxNodeset =
1491 xmlXPathDebugObjCounterNodeset; 1491 xmlXPathDebugObjCounterNodeset;
1492 break; 1492 break;
1493 case XPATH_BOOLEAN: 1493 case XPATH_BOOLEAN:
1494 if (! isCached) 1494 if (! isCached)
1495 xmlXPathDebugObjTotalBool++; 1495 xmlXPathDebugObjTotalBool++;
1496 » xmlXPathDebugObjCounterBool++;» 1496 » xmlXPathDebugObjCounterBool++;
1497 if (xmlXPathDebugObjCounterBool > 1497 if (xmlXPathDebugObjCounterBool >
1498 xmlXPathDebugObjMaxBool) 1498 xmlXPathDebugObjMaxBool)
1499 xmlXPathDebugObjMaxBool = 1499 xmlXPathDebugObjMaxBool =
1500 xmlXPathDebugObjCounterBool; 1500 xmlXPathDebugObjCounterBool;
1501 break; 1501 break;
1502 case XPATH_NUMBER: 1502 case XPATH_NUMBER:
1503 if (! isCached) 1503 if (! isCached)
1504 xmlXPathDebugObjTotalNumber++; 1504 xmlXPathDebugObjTotalNumber++;
1505 » xmlXPathDebugObjCounterNumber++;» 1505 » xmlXPathDebugObjCounterNumber++;
1506 if (xmlXPathDebugObjCounterNumber > 1506 if (xmlXPathDebugObjCounterNumber >
1507 xmlXPathDebugObjMaxNumber) 1507 xmlXPathDebugObjMaxNumber)
1508 xmlXPathDebugObjMaxNumber = 1508 xmlXPathDebugObjMaxNumber =
1509 xmlXPathDebugObjCounterNumber; 1509 xmlXPathDebugObjCounterNumber;
1510 break; 1510 break;
1511 case XPATH_STRING: 1511 case XPATH_STRING:
1512 if (! isCached) 1512 if (! isCached)
1513 xmlXPathDebugObjTotalString++; 1513 xmlXPathDebugObjTotalString++;
1514 » xmlXPathDebugObjCounterString++;» 1514 » xmlXPathDebugObjCounterString++;
1515 if (xmlXPathDebugObjCounterString > 1515 if (xmlXPathDebugObjCounterString >
1516 xmlXPathDebugObjMaxString) 1516 xmlXPathDebugObjMaxString)
1517 xmlXPathDebugObjMaxString = 1517 xmlXPathDebugObjMaxString =
1518 xmlXPathDebugObjCounterString; 1518 xmlXPathDebugObjCounterString;
1519 break; 1519 break;
1520 case XPATH_POINT: 1520 case XPATH_POINT:
1521 if (! isCached) 1521 if (! isCached)
1522 xmlXPathDebugObjTotalPoint++; 1522 xmlXPathDebugObjTotalPoint++;
1523 » xmlXPathDebugObjCounterPoint++;» 1523 » xmlXPathDebugObjCounterPoint++;
1524 if (xmlXPathDebugObjCounterPoint > 1524 if (xmlXPathDebugObjCounterPoint >
1525 xmlXPathDebugObjMaxPoint) 1525 xmlXPathDebugObjMaxPoint)
1526 xmlXPathDebugObjMaxPoint = 1526 xmlXPathDebugObjMaxPoint =
1527 xmlXPathDebugObjCounterPoint; 1527 xmlXPathDebugObjCounterPoint;
1528 break; 1528 break;
1529 case XPATH_RANGE: 1529 case XPATH_RANGE:
1530 if (! isCached) 1530 if (! isCached)
1531 xmlXPathDebugObjTotalRange++; 1531 xmlXPathDebugObjTotalRange++;
1532 xmlXPathDebugObjCounterRange++; 1532 xmlXPathDebugObjCounterRange++;
1533 if (xmlXPathDebugObjCounterRange > 1533 if (xmlXPathDebugObjCounterRange >
1534 xmlXPathDebugObjMaxRange) 1534 xmlXPathDebugObjMaxRange)
1535 xmlXPathDebugObjMaxRange = 1535 xmlXPathDebugObjMaxRange =
1536 xmlXPathDebugObjCounterRange; 1536 xmlXPathDebugObjCounterRange;
1537 break; 1537 break;
1538 case XPATH_LOCATIONSET: 1538 case XPATH_LOCATIONSET:
1539 if (! isCached) 1539 if (! isCached)
1540 xmlXPathDebugObjTotalLocset++; 1540 xmlXPathDebugObjTotalLocset++;
1541 xmlXPathDebugObjCounterLocset++; 1541 xmlXPathDebugObjCounterLocset++;
1542 if (xmlXPathDebugObjCounterLocset > 1542 if (xmlXPathDebugObjCounterLocset >
1543 xmlXPathDebugObjMaxLocset) 1543 xmlXPathDebugObjMaxLocset)
1544 xmlXPathDebugObjMaxLocset = 1544 xmlXPathDebugObjMaxLocset =
1545 xmlXPathDebugObjCounterLocset; 1545 xmlXPathDebugObjCounterLocset;
1546 break; 1546 break;
1547 case XPATH_USERS: 1547 case XPATH_USERS:
1548 if (! isCached) 1548 if (! isCached)
1549 xmlXPathDebugObjTotalUsers++; 1549 xmlXPathDebugObjTotalUsers++;
1550 » xmlXPathDebugObjCounterUsers++;» 1550 » xmlXPathDebugObjCounterUsers++;
1551 if (xmlXPathDebugObjCounterUsers > 1551 if (xmlXPathDebugObjCounterUsers >
1552 xmlXPathDebugObjMaxUsers) 1552 xmlXPathDebugObjMaxUsers)
1553 xmlXPathDebugObjMaxUsers = 1553 xmlXPathDebugObjMaxUsers =
1554 xmlXPathDebugObjCounterUsers; 1554 xmlXPathDebugObjCounterUsers;
1555 break; 1555 break;
1556 case XPATH_XSLT_TREE: 1556 case XPATH_XSLT_TREE:
1557 if (! isCached) 1557 if (! isCached)
1558 xmlXPathDebugObjTotalXSLTTree++; 1558 xmlXPathDebugObjTotalXSLTTree++;
1559 » xmlXPathDebugObjCounterXSLTTree++;» 1559 » xmlXPathDebugObjCounterXSLTTree++;
1560 if (xmlXPathDebugObjCounterXSLTTree > 1560 if (xmlXPathDebugObjCounterXSLTTree >
1561 xmlXPathDebugObjMaxXSLTTree) 1561 xmlXPathDebugObjMaxXSLTTree)
1562 xmlXPathDebugObjMaxXSLTTree = 1562 xmlXPathDebugObjMaxXSLTTree =
1563 xmlXPathDebugObjCounterXSLTTree; 1563 xmlXPathDebugObjCounterXSLTTree;
1564 break; 1564 break;
1565 default: 1565 default:
1566 break; 1566 break;
1567 } 1567 }
1568 if (! isCached) 1568 if (! isCached)
1569 xmlXPathDebugObjTotalAll++; 1569 xmlXPathDebugObjTotalAll++;
1570 xmlXPathDebugObjCounterAll++; 1570 xmlXPathDebugObjCounterAll++;
1571 if (xmlXPathDebugObjCounterAll > 1571 if (xmlXPathDebugObjCounterAll >
1572 xmlXPathDebugObjMaxAll) 1572 xmlXPathDebugObjMaxAll)
1573 xmlXPathDebugObjMaxAll = 1573 xmlXPathDebugObjMaxAll =
1574 xmlXPathDebugObjCounterAll; 1574 xmlXPathDebugObjCounterAll;
1575 } 1575 }
1576 1576
1577 static void 1577 static void
1578 xmlXPathDebugObjUsageReleased(xmlXPathContextPtr ctxt, 1578 xmlXPathDebugObjUsageReleased(xmlXPathContextPtr ctxt,
1579 xmlXPathObjectType objType) 1579 xmlXPathObjectType objType)
1580 { 1580 {
1581 int isCached = 0; 1581 int isCached = 0;
1582 1582
1583 if (ctxt != NULL) { 1583 if (ctxt != NULL) {
1584 if (ctxt->cache != NULL) { 1584 if (ctxt->cache != NULL) {
1585 xmlXPathContextCachePtr cache = 1585 xmlXPathContextCachePtr cache =
1586 (xmlXPathContextCachePtr) ctxt->cache; 1586 (xmlXPathContextCachePtr) ctxt->cache;
1587 1587
1588 » isCached = 1;» 1588 » isCached = 1;
1589 » 1589
1590 cache->dbgCachedAll++; 1590 cache->dbgCachedAll++;
1591 switch (objType) { 1591 switch (objType) {
1592 case XPATH_UNDEFINED: 1592 case XPATH_UNDEFINED:
1593 cache->dbgCachedUndefined++; 1593 cache->dbgCachedUndefined++;
1594 break; 1594 break;
1595 case XPATH_NODESET: 1595 case XPATH_NODESET:
1596 cache->dbgCachedNodeset++; 1596 cache->dbgCachedNodeset++;
1597 break; 1597 break;
1598 case XPATH_BOOLEAN: 1598 case XPATH_BOOLEAN:
1599 cache->dbgCachedBool++; 1599 cache->dbgCachedBool++;
(...skipping 15 matching lines...) Expand all
1615 break; 1615 break;
1616 case XPATH_USERS: 1616 case XPATH_USERS:
1617 cache->dbgCachedUsers++; 1617 cache->dbgCachedUsers++;
1618 break; 1618 break;
1619 case XPATH_XSLT_TREE: 1619 case XPATH_XSLT_TREE:
1620 cache->dbgCachedXSLTTree++; 1620 cache->dbgCachedXSLTTree++;
1621 break; 1621 break;
1622 default: 1622 default:
1623 break; 1623 break;
1624 } 1624 }
1625 » 1625
1626 } 1626 }
1627 } 1627 }
1628 switch (objType) { 1628 switch (objType) {
1629 case XPATH_UNDEFINED: 1629 case XPATH_UNDEFINED:
1630 xmlXPathDebugObjCounterUndefined--; 1630 xmlXPathDebugObjCounterUndefined--;
1631 break; 1631 break;
1632 case XPATH_NODESET: 1632 case XPATH_NODESET:
1633 xmlXPathDebugObjCounterNodeset--; 1633 xmlXPathDebugObjCounterNodeset--;
1634 break; 1634 break;
1635 case XPATH_BOOLEAN: 1635 case XPATH_BOOLEAN:
(...skipping 15 matching lines...) Expand all
1651 xmlXPathDebugObjCounterLocset--; 1651 xmlXPathDebugObjCounterLocset--;
1652 break; 1652 break;
1653 case XPATH_USERS: 1653 case XPATH_USERS:
1654 xmlXPathDebugObjCounterUsers--; 1654 xmlXPathDebugObjCounterUsers--;
1655 break; 1655 break;
1656 case XPATH_XSLT_TREE: 1656 case XPATH_XSLT_TREE:
1657 xmlXPathDebugObjCounterXSLTTree--; 1657 xmlXPathDebugObjCounterXSLTTree--;
1658 break; 1658 break;
1659 default: 1659 default:
1660 break; 1660 break;
1661 } 1661 }
1662 xmlXPathDebugObjCounterAll--; 1662 xmlXPathDebugObjCounterAll--;
1663 } 1663 }
1664 1664
1665 /* REVISIT TODO: Make this static when committing */ 1665 /* REVISIT TODO: Make this static when committing */
1666 static void 1666 static void
1667 xmlXPathDebugObjUsageDisplay(xmlXPathContextPtr ctxt) 1667 xmlXPathDebugObjUsageDisplay(xmlXPathContextPtr ctxt)
1668 { 1668 {
1669 int reqAll, reqNodeset, reqString, reqBool, reqNumber, 1669 int reqAll, reqNodeset, reqString, reqBool, reqNumber,
1670 reqXSLTTree, reqUndefined; 1670 reqXSLTTree, reqUndefined;
1671 int caAll = 0, caNodeset = 0, caString = 0, caBool = 0, 1671 int caAll = 0, caNodeset = 0, caString = 0, caBool = 0,
1672 caNumber = 0, caXSLTTree = 0, caUndefined = 0; 1672 caNumber = 0, caXSLTTree = 0, caUndefined = 0;
1673 int reAll = 0, reNodeset = 0, reString = 0, reBool = 0, 1673 int reAll = 0, reNodeset = 0, reString = 0, reBool = 0,
1674 reNumber = 0, reXSLTTree = 0, reUndefined = 0; 1674 reNumber = 0, reXSLTTree = 0, reUndefined = 0;
1675 int leftObjs = xmlXPathDebugObjCounterAll; 1675 int leftObjs = xmlXPathDebugObjCounterAll;
1676 1676
1677 reqAll = xmlXPathDebugObjTotalAll; 1677 reqAll = xmlXPathDebugObjTotalAll;
1678 reqNodeset = xmlXPathDebugObjTotalNodeset; 1678 reqNodeset = xmlXPathDebugObjTotalNodeset;
1679 reqString = xmlXPathDebugObjTotalString; 1679 reqString = xmlXPathDebugObjTotalString;
1680 reqBool = xmlXPathDebugObjTotalBool; 1680 reqBool = xmlXPathDebugObjTotalBool;
1681 reqNumber = xmlXPathDebugObjTotalNumber; 1681 reqNumber = xmlXPathDebugObjTotalNumber;
1682 reqXSLTTree = xmlXPathDebugObjTotalXSLTTree; 1682 reqXSLTTree = xmlXPathDebugObjTotalXSLTTree;
1683 reqUndefined = xmlXPathDebugObjTotalUndefined; 1683 reqUndefined = xmlXPathDebugObjTotalUndefined;
1684 1684
1685 printf("# XPath object usage:\n"); 1685 printf("# XPath object usage:\n");
1686 1686
1687 if (ctxt != NULL) { 1687 if (ctxt != NULL) {
1688 if (ctxt->cache != NULL) { 1688 if (ctxt->cache != NULL) {
1689 xmlXPathContextCachePtr cache = 1689 xmlXPathContextCachePtr cache =
1690 (xmlXPathContextCachePtr) ctxt->cache; 1690 (xmlXPathContextCachePtr) ctxt->cache;
1691 1691
1692 reAll = cache->dbgReusedAll; 1692 reAll = cache->dbgReusedAll;
1693 reqAll += reAll; 1693 reqAll += reAll;
1694 reNodeset = cache->dbgReusedNodeset; 1694 reNodeset = cache->dbgReusedNodeset;
1695 reqNodeset += reNodeset; 1695 reqNodeset += reNodeset;
1696 reString = cache->dbgReusedString; 1696 reString = cache->dbgReusedString;
1697 reqString += reString; 1697 reqString += reString;
1698 reBool = cache->dbgReusedBool; 1698 reBool = cache->dbgReusedBool;
1699 reqBool += reBool; 1699 reqBool += reBool;
1700 reNumber = cache->dbgReusedNumber; 1700 reNumber = cache->dbgReusedNumber;
1701 reqNumber += reNumber; 1701 reqNumber += reNumber;
1702 reXSLTTree = cache->dbgReusedXSLTTree; 1702 reXSLTTree = cache->dbgReusedXSLTTree;
1703 reqXSLTTree += reXSLTTree; 1703 reqXSLTTree += reXSLTTree;
1704 reUndefined = cache->dbgReusedUndefined; 1704 reUndefined = cache->dbgReusedUndefined;
1705 reqUndefined += reUndefined; 1705 reqUndefined += reUndefined;
1706 » 1706
1707 caAll = cache->dbgCachedAll; 1707 caAll = cache->dbgCachedAll;
1708 caBool = cache->dbgCachedBool; 1708 caBool = cache->dbgCachedBool;
1709 caNodeset = cache->dbgCachedNodeset; 1709 caNodeset = cache->dbgCachedNodeset;
1710 caString = cache->dbgCachedString; 1710 caString = cache->dbgCachedString;
1711 caNumber = cache->dbgCachedNumber; 1711 caNumber = cache->dbgCachedNumber;
1712 caXSLTTree = cache->dbgCachedXSLTTree; 1712 caXSLTTree = cache->dbgCachedXSLTTree;
1713 caUndefined = cache->dbgCachedUndefined; 1713 caUndefined = cache->dbgCachedUndefined;
1714 » 1714
1715 if (cache->nodesetObjs) 1715 if (cache->nodesetObjs)
1716 leftObjs -= cache->nodesetObjs->number; 1716 leftObjs -= cache->nodesetObjs->number;
1717 if (cache->stringObjs) 1717 if (cache->stringObjs)
1718 leftObjs -= cache->stringObjs->number; 1718 leftObjs -= cache->stringObjs->number;
1719 if (cache->booleanObjs) 1719 if (cache->booleanObjs)
1720 leftObjs -= cache->booleanObjs->number; 1720 leftObjs -= cache->booleanObjs->number;
1721 if (cache->numberObjs) 1721 if (cache->numberObjs)
1722 leftObjs -= cache->numberObjs->number; 1722 leftObjs -= cache->numberObjs->number;
1723 if (cache->miscObjs) 1723 if (cache->miscObjs)
1724 leftObjs -= cache->miscObjs->number; 1724 leftObjs -= cache->miscObjs->number;
1725 } 1725 }
1726 } 1726 }
1727 1727
1728 printf("# all\n"); 1728 printf("# all\n");
1729 printf("# total : %d\n", reqAll); 1729 printf("# total : %d\n", reqAll);
1730 printf("# left : %d\n", leftObjs); 1730 printf("# left : %d\n", leftObjs);
1731 printf("# created: %d\n", xmlXPathDebugObjTotalAll); 1731 printf("# created: %d\n", xmlXPathDebugObjTotalAll);
1732 printf("# reused : %d\n", reAll); 1732 printf("# reused : %d\n", reAll);
1733 printf("# max : %d\n", xmlXPathDebugObjMaxAll); 1733 printf("# max : %d\n", xmlXPathDebugObjMaxAll);
1734 1734
1735 printf("# node-sets\n"); 1735 printf("# node-sets\n");
1736 printf("# total : %d\n", reqNodeset); 1736 printf("# total : %d\n", reqNodeset);
1737 printf("# created: %d\n", xmlXPathDebugObjTotalNodeset); 1737 printf("# created: %d\n", xmlXPathDebugObjTotalNodeset);
1738 printf("# reused : %d\n", reNodeset); 1738 printf("# reused : %d\n", reNodeset);
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
1841 return; 1841 return;
1842 if (cache->nodesetObjs) 1842 if (cache->nodesetObjs)
1843 xmlXPathCacheFreeObjectList(cache->nodesetObjs); 1843 xmlXPathCacheFreeObjectList(cache->nodesetObjs);
1844 if (cache->stringObjs) 1844 if (cache->stringObjs)
1845 xmlXPathCacheFreeObjectList(cache->stringObjs); 1845 xmlXPathCacheFreeObjectList(cache->stringObjs);
1846 if (cache->booleanObjs) 1846 if (cache->booleanObjs)
1847 xmlXPathCacheFreeObjectList(cache->booleanObjs); 1847 xmlXPathCacheFreeObjectList(cache->booleanObjs);
1848 if (cache->numberObjs) 1848 if (cache->numberObjs)
1849 xmlXPathCacheFreeObjectList(cache->numberObjs); 1849 xmlXPathCacheFreeObjectList(cache->numberObjs);
1850 if (cache->miscObjs) 1850 if (cache->miscObjs)
1851 » xmlXPathCacheFreeObjectList(cache->miscObjs); 1851 » xmlXPathCacheFreeObjectList(cache->miscObjs);
1852 xmlFree(cache); 1852 xmlFree(cache);
1853 } 1853 }
1854 1854
1855 /** 1855 /**
1856 * xmlXPathContextSetCache: 1856 * xmlXPathContextSetCache:
1857 * 1857 *
1858 * @ctxt: the XPath context 1858 * @ctxt: the XPath context
1859 * @active: enables/disables (creates/frees) the cache 1859 * @active: enables/disables (creates/frees) the cache
1860 * @value: a value with semantics dependant on @options 1860 * @value: a value with semantics dependant on @options
1861 * @options: options (currently only the value 0 is used) 1861 * @options: options (currently only the value 0 is used)
1862 * 1862 *
1863 * Creates/frees an object cache on the XPath context. 1863 * Creates/frees an object cache on the XPath context.
1864 * If activates XPath objects (xmlXPathObject) will be cached internally 1864 * If activates XPath objects (xmlXPathObject) will be cached internally
1865 * to be reused. 1865 * to be reused.
1866 * @options: 1866 * @options:
1867 * 0: This will set the XPath object caching: 1867 * 0: This will set the XPath object caching:
1868 * @value: 1868 * @value:
1869 * This will set the maximum number of XPath objects 1869 * This will set the maximum number of XPath objects
1870 * to be cached per slot 1870 * to be cached per slot
1871 * There are 5 slots for: node-set, string, number, boolean, and 1871 * There are 5 slots for: node-set, string, number, boolean, and
1872 * misc objects. Use <0 for the default number (100). 1872 * misc objects. Use <0 for the default number (100).
1873 * Other values for @options have currently no effect. 1873 * Other values for @options have currently no effect.
1874 * 1874 *
1875 * Returns 0 if the setting succeeded, and -1 on API or internal errors. 1875 * Returns 0 if the setting succeeded, and -1 on API or internal errors.
1876 */ 1876 */
1877 int 1877 int
1878 xmlXPathContextSetCache(xmlXPathContextPtr ctxt, 1878 xmlXPathContextSetCache(xmlXPathContextPtr ctxt,
1879 int active, 1879 int active,
1880 int value, 1880 int value,
1881 int options) 1881 int options)
1882 { 1882 {
1883 if (ctxt == NULL) 1883 if (ctxt == NULL)
1884 return(-1); 1884 return(-1);
1885 if (active) { 1885 if (active) {
1886 xmlXPathContextCachePtr cache; 1886 xmlXPathContextCachePtr cache;
1887 » 1887
1888 if (ctxt->cache == NULL) { 1888 if (ctxt->cache == NULL) {
1889 ctxt->cache = xmlXPathNewCache(); 1889 ctxt->cache = xmlXPathNewCache();
1890 if (ctxt->cache == NULL) 1890 if (ctxt->cache == NULL)
1891 return(-1); 1891 return(-1);
1892 } 1892 }
1893 cache = (xmlXPathContextCachePtr) ctxt->cache; 1893 cache = (xmlXPathContextCachePtr) ctxt->cache;
1894 if (options == 0) { 1894 if (options == 0) {
1895 if (value < 0) 1895 if (value < 0)
1896 value = 100; 1896 value = 100;
1897 cache->maxNodeset = value; 1897 cache->maxNodeset = value;
(...skipping 14 matching lines...) Expand all
1912 * @ctxt: the XPath context 1912 * @ctxt: the XPath context
1913 * @val: the NodePtr value 1913 * @val: the NodePtr value
1914 * 1914 *
1915 * This is the cached version of xmlXPathWrapNodeSet(). 1915 * This is the cached version of xmlXPathWrapNodeSet().
1916 * Wrap the Nodeset @val in a new xmlXPathObjectPtr 1916 * Wrap the Nodeset @val in a new xmlXPathObjectPtr
1917 * 1917 *
1918 * Returns the created or reused object. 1918 * Returns the created or reused object.
1919 */ 1919 */
1920 static xmlXPathObjectPtr 1920 static xmlXPathObjectPtr
1921 xmlXPathCacheWrapNodeSet(xmlXPathContextPtr ctxt, xmlNodeSetPtr val) 1921 xmlXPathCacheWrapNodeSet(xmlXPathContextPtr ctxt, xmlNodeSetPtr val)
1922 { 1922 {
1923 if ((ctxt != NULL) && (ctxt->cache != NULL)) { 1923 if ((ctxt != NULL) && (ctxt->cache != NULL)) {
1924 xmlXPathContextCachePtr cache = 1924 xmlXPathContextCachePtr cache =
1925 (xmlXPathContextCachePtr) ctxt->cache; 1925 (xmlXPathContextCachePtr) ctxt->cache;
1926 1926
1927 if ((cache->miscObjs != NULL) && 1927 if ((cache->miscObjs != NULL) &&
1928 (cache->miscObjs->number != 0)) 1928 (cache->miscObjs->number != 0))
1929 { 1929 {
1930 xmlXPathObjectPtr ret; 1930 xmlXPathObjectPtr ret;
1931 » 1931
1932 ret = (xmlXPathObjectPtr) 1932 ret = (xmlXPathObjectPtr)
1933 cache->miscObjs->items[--cache->miscObjs->number]; 1933 cache->miscObjs->items[--cache->miscObjs->number];
1934 ret->type = XPATH_NODESET; 1934 ret->type = XPATH_NODESET;
1935 ret->nodesetval = val; 1935 ret->nodesetval = val;
1936 #ifdef XP_DEBUG_OBJ_USAGE 1936 #ifdef XP_DEBUG_OBJ_USAGE
1937 xmlXPathDebugObjUsageRequested(ctxt, XPATH_NODESET); 1937 xmlXPathDebugObjUsageRequested(ctxt, XPATH_NODESET);
1938 #endif 1938 #endif
1939 » return(ret);» 1939 » return(ret);
1940 } 1940 }
1941 } 1941 }
1942 » 1942
1943 return(xmlXPathWrapNodeSet(val)); 1943 return(xmlXPathWrapNodeSet(val));
1944 1944
1945 } 1945 }
1946 1946
1947 /** 1947 /**
1948 * xmlXPathCacheWrapString: 1948 * xmlXPathCacheWrapString:
1949 * @ctxt: the XPath context 1949 * @ctxt: the XPath context
1950 * @val: the xmlChar * value 1950 * @val: the xmlChar * value
1951 * 1951 *
1952 * This is the cached version of xmlXPathWrapString(). 1952 * This is the cached version of xmlXPathWrapString().
1953 * Wraps the @val string into an XPath object. 1953 * Wraps the @val string into an XPath object.
1954 * 1954 *
1955 * Returns the created or reused object. 1955 * Returns the created or reused object.
1956 */ 1956 */
1957 static xmlXPathObjectPtr 1957 static xmlXPathObjectPtr
1958 xmlXPathCacheWrapString(xmlXPathContextPtr ctxt, xmlChar *val) 1958 xmlXPathCacheWrapString(xmlXPathContextPtr ctxt, xmlChar *val)
1959 { 1959 {
1960 if ((ctxt != NULL) && (ctxt->cache != NULL)) { 1960 if ((ctxt != NULL) && (ctxt->cache != NULL)) {
1961 xmlXPathContextCachePtr cache = (xmlXPathContextCachePtr) ctxt->cache; 1961 xmlXPathContextCachePtr cache = (xmlXPathContextCachePtr) ctxt->cache;
1962 1962
1963 if ((cache->stringObjs != NULL) && 1963 if ((cache->stringObjs != NULL) &&
1964 (cache->stringObjs->number != 0)) 1964 (cache->stringObjs->number != 0))
1965 { 1965 {
1966 » 1966
1967 xmlXPathObjectPtr ret; 1967 xmlXPathObjectPtr ret;
1968 » 1968
1969 ret = (xmlXPathObjectPtr) 1969 ret = (xmlXPathObjectPtr)
1970 cache->stringObjs->items[--cache->stringObjs->number]; 1970 cache->stringObjs->items[--cache->stringObjs->number];
1971 ret->type = XPATH_STRING; 1971 ret->type = XPATH_STRING;
1972 ret->stringval = val; 1972 ret->stringval = val;
1973 #ifdef XP_DEBUG_OBJ_USAGE 1973 #ifdef XP_DEBUG_OBJ_USAGE
1974 xmlXPathDebugObjUsageRequested(ctxt, XPATH_STRING); 1974 xmlXPathDebugObjUsageRequested(ctxt, XPATH_STRING);
1975 #endif 1975 #endif
1976 return(ret); 1976 return(ret);
1977 } else if ((cache->miscObjs != NULL) && 1977 } else if ((cache->miscObjs != NULL) &&
1978 (cache->miscObjs->number != 0)) 1978 (cache->miscObjs->number != 0))
(...skipping 28 matching lines...) Expand all
2007 * Returns the created or reused object. 2007 * Returns the created or reused object.
2008 */ 2008 */
2009 static xmlXPathObjectPtr 2009 static xmlXPathObjectPtr
2010 xmlXPathCacheNewNodeSet(xmlXPathContextPtr ctxt, xmlNodePtr val) 2010 xmlXPathCacheNewNodeSet(xmlXPathContextPtr ctxt, xmlNodePtr val)
2011 { 2011 {
2012 if ((ctxt != NULL) && (ctxt->cache)) { 2012 if ((ctxt != NULL) && (ctxt->cache)) {
2013 xmlXPathContextCachePtr cache = (xmlXPathContextCachePtr) ctxt->cache; 2013 xmlXPathContextCachePtr cache = (xmlXPathContextCachePtr) ctxt->cache;
2014 2014
2015 if ((cache->nodesetObjs != NULL) && 2015 if ((cache->nodesetObjs != NULL) &&
2016 (cache->nodesetObjs->number != 0)) 2016 (cache->nodesetObjs->number != 0))
2017 » {» 2017 » {
2018 xmlXPathObjectPtr ret; 2018 xmlXPathObjectPtr ret;
2019 /* 2019 /*
2020 * Use the nodset-cache. 2020 * Use the nodset-cache.
2021 » */» 2021 » */
2022 ret = (xmlXPathObjectPtr) 2022 ret = (xmlXPathObjectPtr)
2023 cache->nodesetObjs->items[--cache->nodesetObjs->number]; 2023 cache->nodesetObjs->items[--cache->nodesetObjs->number];
2024 ret->type = XPATH_NODESET; 2024 ret->type = XPATH_NODESET;
2025 ret->boolval = 0; 2025 ret->boolval = 0;
2026 » if (val) {» » 2026 » if (val) {
2027 if ((ret->nodesetval->nodeMax == 0) || 2027 if ((ret->nodesetval->nodeMax == 0) ||
2028 (val->type == XML_NAMESPACE_DECL)) 2028 (val->type == XML_NAMESPACE_DECL))
2029 { 2029 {
2030 » » xmlXPathNodeSetAddUnique(ret->nodesetval, val);» » 2030 » » xmlXPathNodeSetAddUnique(ret->nodesetval, val);
2031 } else { 2031 } else {
2032 ret->nodesetval->nodeTab[0] = val; 2032 ret->nodesetval->nodeTab[0] = val;
2033 ret->nodesetval->nodeNr = 1; 2033 ret->nodesetval->nodeNr = 1;
2034 } 2034 }
2035 } 2035 }
2036 #ifdef XP_DEBUG_OBJ_USAGE 2036 #ifdef XP_DEBUG_OBJ_USAGE
2037 xmlXPathDebugObjUsageRequested(ctxt, XPATH_NODESET); 2037 xmlXPathDebugObjUsageRequested(ctxt, XPATH_NODESET);
2038 #endif 2038 #endif
2039 return(ret); 2039 return(ret);
2040 } else if ((cache->miscObjs != NULL) && 2040 } else if ((cache->miscObjs != NULL) &&
(...skipping 24 matching lines...) Expand all
2065 * @ctxt: the XPath context 2065 * @ctxt: the XPath context
2066 * @val: the char * value 2066 * @val: the char * value
2067 * 2067 *
2068 * This is the cached version of xmlXPathNewCString(). 2068 * This is the cached version of xmlXPathNewCString().
2069 * Acquire an xmlXPathObjectPtr of type string and of value @val 2069 * Acquire an xmlXPathObjectPtr of type string and of value @val
2070 * 2070 *
2071 * Returns the created or reused object. 2071 * Returns the created or reused object.
2072 */ 2072 */
2073 static xmlXPathObjectPtr 2073 static xmlXPathObjectPtr
2074 xmlXPathCacheNewCString(xmlXPathContextPtr ctxt, const char *val) 2074 xmlXPathCacheNewCString(xmlXPathContextPtr ctxt, const char *val)
2075 { 2075 {
2076 if ((ctxt != NULL) && (ctxt->cache)) { 2076 if ((ctxt != NULL) && (ctxt->cache)) {
2077 xmlXPathContextCachePtr cache = (xmlXPathContextCachePtr) ctxt->cache; 2077 xmlXPathContextCachePtr cache = (xmlXPathContextCachePtr) ctxt->cache;
2078 2078
2079 if ((cache->stringObjs != NULL) && 2079 if ((cache->stringObjs != NULL) &&
2080 (cache->stringObjs->number != 0)) 2080 (cache->stringObjs->number != 0))
2081 » {» 2081 » {
2082 xmlXPathObjectPtr ret; 2082 xmlXPathObjectPtr ret;
2083 » 2083
2084 ret = (xmlXPathObjectPtr) 2084 ret = (xmlXPathObjectPtr)
2085 cache->stringObjs->items[--cache->stringObjs->number]; 2085 cache->stringObjs->items[--cache->stringObjs->number];
2086 2086
2087 ret->type = XPATH_STRING; 2087 ret->type = XPATH_STRING;
2088 ret->stringval = xmlStrdup(BAD_CAST val); 2088 ret->stringval = xmlStrdup(BAD_CAST val);
2089 #ifdef XP_DEBUG_OBJ_USAGE 2089 #ifdef XP_DEBUG_OBJ_USAGE
2090 xmlXPathDebugObjUsageRequested(ctxt, XPATH_STRING); 2090 xmlXPathDebugObjUsageRequested(ctxt, XPATH_STRING);
2091 #endif 2091 #endif
2092 return(ret); 2092 return(ret);
2093 } else if ((cache->miscObjs != NULL) && 2093 } else if ((cache->miscObjs != NULL) &&
(...skipping 20 matching lines...) Expand all
2114 * @ctxt: the XPath context 2114 * @ctxt: the XPath context
2115 * @val: the xmlChar * value 2115 * @val: the xmlChar * value
2116 * 2116 *
2117 * This is the cached version of xmlXPathNewString(). 2117 * This is the cached version of xmlXPathNewString().
2118 * Acquire an xmlXPathObjectPtr of type string and of value @val 2118 * Acquire an xmlXPathObjectPtr of type string and of value @val
2119 * 2119 *
2120 * Returns the created or reused object. 2120 * Returns the created or reused object.
2121 */ 2121 */
2122 static xmlXPathObjectPtr 2122 static xmlXPathObjectPtr
2123 xmlXPathCacheNewString(xmlXPathContextPtr ctxt, const xmlChar *val) 2123 xmlXPathCacheNewString(xmlXPathContextPtr ctxt, const xmlChar *val)
2124 { 2124 {
2125 if ((ctxt != NULL) && (ctxt->cache)) { 2125 if ((ctxt != NULL) && (ctxt->cache)) {
2126 xmlXPathContextCachePtr cache = (xmlXPathContextCachePtr) ctxt->cache; 2126 xmlXPathContextCachePtr cache = (xmlXPathContextCachePtr) ctxt->cache;
2127 2127
2128 if ((cache->stringObjs != NULL) && 2128 if ((cache->stringObjs != NULL) &&
2129 (cache->stringObjs->number != 0)) 2129 (cache->stringObjs->number != 0))
2130 » {» 2130 » {
2131 xmlXPathObjectPtr ret; 2131 xmlXPathObjectPtr ret;
2132 » 2132
2133 ret = (xmlXPathObjectPtr) 2133 ret = (xmlXPathObjectPtr)
2134 cache->stringObjs->items[--cache->stringObjs->number]; 2134 cache->stringObjs->items[--cache->stringObjs->number];
2135 ret->type = XPATH_STRING; 2135 ret->type = XPATH_STRING;
2136 if (val != NULL) 2136 if (val != NULL)
2137 ret->stringval = xmlStrdup(val); 2137 ret->stringval = xmlStrdup(val);
2138 else 2138 else
2139 ret->stringval = xmlStrdup((const xmlChar *)""); 2139 ret->stringval = xmlStrdup((const xmlChar *)"");
2140 #ifdef XP_DEBUG_OBJ_USAGE 2140 #ifdef XP_DEBUG_OBJ_USAGE
2141 xmlXPathDebugObjUsageRequested(ctxt, XPATH_STRING); 2141 xmlXPathDebugObjUsageRequested(ctxt, XPATH_STRING);
2142 #endif 2142 #endif
(...skipping 25 matching lines...) Expand all
2168 * @ctxt: the XPath context 2168 * @ctxt: the XPath context
2169 * @val: the boolean value 2169 * @val: the boolean value
2170 * 2170 *
2171 * This is the cached version of xmlXPathNewBoolean(). 2171 * This is the cached version of xmlXPathNewBoolean().
2172 * Acquires an xmlXPathObjectPtr of type boolean and of value @val 2172 * Acquires an xmlXPathObjectPtr of type boolean and of value @val
2173 * 2173 *
2174 * Returns the created or reused object. 2174 * Returns the created or reused object.
2175 */ 2175 */
2176 static xmlXPathObjectPtr 2176 static xmlXPathObjectPtr
2177 xmlXPathCacheNewBoolean(xmlXPathContextPtr ctxt, int val) 2177 xmlXPathCacheNewBoolean(xmlXPathContextPtr ctxt, int val)
2178 { 2178 {
2179 if ((ctxt != NULL) && (ctxt->cache)) { 2179 if ((ctxt != NULL) && (ctxt->cache)) {
2180 xmlXPathContextCachePtr cache = (xmlXPathContextCachePtr) ctxt->cache; 2180 xmlXPathContextCachePtr cache = (xmlXPathContextCachePtr) ctxt->cache;
2181 2181
2182 if ((cache->booleanObjs != NULL) && 2182 if ((cache->booleanObjs != NULL) &&
2183 (cache->booleanObjs->number != 0)) 2183 (cache->booleanObjs->number != 0))
2184 » {» 2184 » {
2185 xmlXPathObjectPtr ret; 2185 xmlXPathObjectPtr ret;
2186 » 2186
2187 ret = (xmlXPathObjectPtr) 2187 ret = (xmlXPathObjectPtr)
2188 cache->booleanObjs->items[--cache->booleanObjs->number]; 2188 cache->booleanObjs->items[--cache->booleanObjs->number];
2189 ret->type = XPATH_BOOLEAN; 2189 ret->type = XPATH_BOOLEAN;
2190 ret->boolval = (val != 0); 2190 ret->boolval = (val != 0);
2191 #ifdef XP_DEBUG_OBJ_USAGE 2191 #ifdef XP_DEBUG_OBJ_USAGE
2192 xmlXPathDebugObjUsageRequested(ctxt, XPATH_BOOLEAN); 2192 xmlXPathDebugObjUsageRequested(ctxt, XPATH_BOOLEAN);
2193 #endif 2193 #endif
2194 return(ret); 2194 return(ret);
2195 } else if ((cache->miscObjs != NULL) && 2195 } else if ((cache->miscObjs != NULL) &&
2196 (cache->miscObjs->number != 0)) 2196 (cache->miscObjs->number != 0))
(...skipping 25 matching lines...) Expand all
2222 * Returns the created or reused object. 2222 * Returns the created or reused object.
2223 */ 2223 */
2224 static xmlXPathObjectPtr 2224 static xmlXPathObjectPtr
2225 xmlXPathCacheNewFloat(xmlXPathContextPtr ctxt, double val) 2225 xmlXPathCacheNewFloat(xmlXPathContextPtr ctxt, double val)
2226 { 2226 {
2227 if ((ctxt != NULL) && (ctxt->cache)) { 2227 if ((ctxt != NULL) && (ctxt->cache)) {
2228 xmlXPathContextCachePtr cache = (xmlXPathContextCachePtr) ctxt->cache; 2228 xmlXPathContextCachePtr cache = (xmlXPathContextCachePtr) ctxt->cache;
2229 2229
2230 if ((cache->numberObjs != NULL) && 2230 if ((cache->numberObjs != NULL) &&
2231 (cache->numberObjs->number != 0)) 2231 (cache->numberObjs->number != 0))
2232 » {» 2232 » {
2233 xmlXPathObjectPtr ret; 2233 xmlXPathObjectPtr ret;
2234 » 2234
2235 ret = (xmlXPathObjectPtr) 2235 ret = (xmlXPathObjectPtr)
2236 cache->numberObjs->items[--cache->numberObjs->number]; 2236 cache->numberObjs->items[--cache->numberObjs->number];
2237 ret->type = XPATH_NUMBER; 2237 ret->type = XPATH_NUMBER;
2238 ret->floatval = val; 2238 ret->floatval = val;
2239 #ifdef XP_DEBUG_OBJ_USAGE 2239 #ifdef XP_DEBUG_OBJ_USAGE
2240 xmlXPathDebugObjUsageRequested(ctxt, XPATH_NUMBER); 2240 xmlXPathDebugObjUsageRequested(ctxt, XPATH_NUMBER);
2241 #endif 2241 #endif
2242 return(ret); 2242 return(ret);
2243 } else if ((cache->miscObjs != NULL) && 2243 } else if ((cache->miscObjs != NULL) &&
2244 (cache->miscObjs->number != 0)) 2244 (cache->miscObjs->number != 0))
(...skipping 21 matching lines...) Expand all
2266 * 2266 *
2267 * This is the cached version of xmlXPathConvertString(). 2267 * This is the cached version of xmlXPathConvertString().
2268 * Converts an existing object to its string() equivalent 2268 * Converts an existing object to its string() equivalent
2269 * 2269 *
2270 * Returns a created or reused object, the old one is freed (cached) 2270 * Returns a created or reused object, the old one is freed (cached)
2271 * (or the operation is done directly on @val) 2271 * (or the operation is done directly on @val)
2272 */ 2272 */
2273 2273
2274 static xmlXPathObjectPtr 2274 static xmlXPathObjectPtr
2275 xmlXPathCacheConvertString(xmlXPathContextPtr ctxt, xmlXPathObjectPtr val) { 2275 xmlXPathCacheConvertString(xmlXPathContextPtr ctxt, xmlXPathObjectPtr val) {
2276 xmlChar *res = NULL; 2276 xmlChar *res = NULL;
2277 2277
2278 if (val == NULL) 2278 if (val == NULL)
2279 return(xmlXPathCacheNewCString(ctxt, "")); 2279 return(xmlXPathCacheNewCString(ctxt, ""));
2280 2280
2281 switch (val->type) { 2281 switch (val->type) {
2282 case XPATH_UNDEFINED: 2282 case XPATH_UNDEFINED:
2283 #ifdef DEBUG_EXPR 2283 #ifdef DEBUG_EXPR
2284 xmlGenericError(xmlGenericErrorContext, "STRING: undefined\n"); 2284 xmlGenericError(xmlGenericErrorContext, "STRING: undefined\n");
2285 #endif 2285 #endif
2286 break; 2286 break;
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
2350 * 2350 *
2351 * This is the cached version of xmlXPathConvertBoolean(). 2351 * This is the cached version of xmlXPathConvertBoolean().
2352 * Converts an existing object to its boolean() equivalent 2352 * Converts an existing object to its boolean() equivalent
2353 * 2353 *
2354 * Returns a created or reused object, the old one is freed (or the operation 2354 * Returns a created or reused object, the old one is freed (or the operation
2355 * is done directly on @val) 2355 * is done directly on @val)
2356 */ 2356 */
2357 static xmlXPathObjectPtr 2357 static xmlXPathObjectPtr
2358 xmlXPathCacheConvertBoolean(xmlXPathContextPtr ctxt, xmlXPathObjectPtr val) { 2358 xmlXPathCacheConvertBoolean(xmlXPathContextPtr ctxt, xmlXPathObjectPtr val) {
2359 xmlXPathObjectPtr ret; 2359 xmlXPathObjectPtr ret;
2360 2360
2361 if (val == NULL) 2361 if (val == NULL)
2362 return(xmlXPathCacheNewBoolean(ctxt, 0)); 2362 return(xmlXPathCacheNewBoolean(ctxt, 0));
2363 if (val->type == XPATH_BOOLEAN) 2363 if (val->type == XPATH_BOOLEAN)
2364 return(val); 2364 return(val);
2365 ret = xmlXPathCacheNewBoolean(ctxt, xmlXPathCastToBoolean(val)); 2365 ret = xmlXPathCacheNewBoolean(ctxt, xmlXPathCastToBoolean(val));
2366 xmlXPathReleaseObject(ctxt, val); 2366 xmlXPathReleaseObject(ctxt, val);
2367 return(ret); 2367 return(ret);
2368 } 2368 }
2369 2369
2370 /** 2370 /**
2371 * xmlXPathCacheConvertNumber: 2371 * xmlXPathCacheConvertNumber:
2372 * @ctxt: the XPath context 2372 * @ctxt: the XPath context
2373 * @val: an XPath object 2373 * @val: an XPath object
2374 * 2374 *
2375 * This is the cached version of xmlXPathConvertNumber(). 2375 * This is the cached version of xmlXPathConvertNumber().
2376 * Converts an existing object to its number() equivalent 2376 * Converts an existing object to its number() equivalent
2377 * 2377 *
2378 * Returns a created or reused object, the old one is freed (or the operation 2378 * Returns a created or reused object, the old one is freed (or the operation
2379 * is done directly on @val) 2379 * is done directly on @val)
2380 */ 2380 */
2381 static xmlXPathObjectPtr 2381 static xmlXPathObjectPtr
2382 xmlXPathCacheConvertNumber(xmlXPathContextPtr ctxt, xmlXPathObjectPtr val) { 2382 xmlXPathCacheConvertNumber(xmlXPathContextPtr ctxt, xmlXPathObjectPtr val) {
2383 xmlXPathObjectPtr ret; 2383 xmlXPathObjectPtr ret;
2384 2384
2385 if (val == NULL) 2385 if (val == NULL)
2386 return(xmlXPathCacheNewFloat(ctxt, 0.0)); 2386 return(xmlXPathCacheNewFloat(ctxt, 0.0));
2387 if (val->type == XPATH_NUMBER) 2387 if (val->type == XPATH_NUMBER)
2388 return(val); 2388 return(val);
2389 ret = xmlXPathCacheNewFloat(ctxt, xmlXPathCastToNumber(val)); 2389 ret = xmlXPathCacheNewFloat(ctxt, xmlXPathCastToNumber(val));
2390 xmlXPathReleaseObject(ctxt, val); 2390 xmlXPathReleaseObject(ctxt, val);
2391 return(ret); 2391 return(ret);
2392 } 2392 }
2393 2393
2394 /************************************************************************ 2394 /************************************************************************
2395 * * 2395 * *
2396 * » » Parser stacks related functions and macros» » * 2396 *» » Parser stacks related functions and macros» » *
2397 * * 2397 * *
2398 ************************************************************************/ 2398 ************************************************************************/
2399 2399
2400 /** 2400 /**
2401 * valuePop: 2401 * valuePop:
2402 * @ctxt: an XPath evaluation context 2402 * @ctxt: an XPath evaluation context
2403 * 2403 *
2404 * Pops the top XPath object from the value stack 2404 * Pops the top XPath object from the value stack
2405 * 2405 *
2406 * Returns the XPath object just removed 2406 * Returns the XPath object just removed
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
2625 #define NXT(val) ctxt->cur[(val)] 2625 #define NXT(val) ctxt->cur[(val)]
2626 #define CUR_PTR ctxt->cur 2626 #define CUR_PTR ctxt->cur
2627 #define CUR_CHAR(l) xmlXPathCurrentChar(ctxt, &l) 2627 #define CUR_CHAR(l) xmlXPathCurrentChar(ctxt, &l)
2628 2628
2629 #define COPY_BUF(l,b,i,v) \ 2629 #define COPY_BUF(l,b,i,v) \
2630 if (l == 1) b[i++] = (xmlChar) v; \ 2630 if (l == 1) b[i++] = (xmlChar) v; \
2631 else i += xmlCopyChar(l,&b[i],v) 2631 else i += xmlCopyChar(l,&b[i],v)
2632 2632
2633 #define NEXTL(l) ctxt->cur += l 2633 #define NEXTL(l) ctxt->cur += l
2634 2634
2635 #define SKIP_BLANKS » » » » » » » \ 2635 #define SKIP_BLANKS» » » » » » » \
2636 while (IS_BLANK_CH(*(ctxt->cur))) NEXT 2636 while (IS_BLANK_CH(*(ctxt->cur))) NEXT
2637 2637
2638 #define CURRENT (*ctxt->cur) 2638 #define CURRENT (*ctxt->cur)
2639 #define NEXT ((*ctxt->cur) ? ctxt->cur++: ctxt->cur) 2639 #define NEXT ((*ctxt->cur) ? ctxt->cur++: ctxt->cur)
2640 2640
2641 2641
2642 #ifndef DBL_DIG 2642 #ifndef DBL_DIG
2643 #define DBL_DIG 16 2643 #define DBL_DIG 16
2644 #endif 2644 #endif
2645 #ifndef DBL_EPSILON 2645 #ifndef DBL_EPSILON
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after
2994 int misc = 0, precedence1 = 0, precedence2 = 0; 2994 int misc = 0, precedence1 = 0, precedence2 = 0;
2995 xmlNodePtr miscNode1 = NULL, miscNode2 = NULL; 2995 xmlNodePtr miscNode1 = NULL, miscNode2 = NULL;
2996 xmlNodePtr cur, root; 2996 xmlNodePtr cur, root;
2997 long l1, l2; 2997 long l1, l2;
2998 2998
2999 if ((node1 == NULL) || (node2 == NULL)) 2999 if ((node1 == NULL) || (node2 == NULL))
3000 return(-2); 3000 return(-2);
3001 3001
3002 if (node1 == node2) 3002 if (node1 == node2)
3003 return(0); 3003 return(0);
3004 3004
3005 /* 3005 /*
3006 * a couple of optimizations which will avoid computations in most cases 3006 * a couple of optimizations which will avoid computations in most cases
3007 */ 3007 */
3008 switch (node1->type) { 3008 switch (node1->type) {
3009 case XML_ELEMENT_NODE: 3009 case XML_ELEMENT_NODE:
3010 if (node2->type == XML_ELEMENT_NODE) { 3010 if (node2->type == XML_ELEMENT_NODE) {
3011 if ((0 > (long) node1->content) && /* TODO: Would a != 0 suffice here? */ 3011 if ((0 > (long) node1->content) && /* TODO: Would a != 0 suffice here? */
3012 (0 > (long) node2->content) && 3012 (0 > (long) node2->content) &&
3013 (node1->doc == node2->doc)) 3013 (node1->doc == node2->doc))
3014 » » {» » 3014 » » {
3015 l1 = -((long) node1->content); 3015 l1 = -((long) node1->content);
3016 l2 = -((long) node2->content); 3016 l2 = -((long) node2->content);
3017 if (l1 < l2) 3017 if (l1 < l2)
3018 return(1); 3018 return(1);
3019 if (l1 > l2) 3019 if (l1 > l2)
3020 return(-1); 3020 return(-1);
3021 } else 3021 } else
3022 » » goto turtle_comparison;» » 3022 » » goto turtle_comparison;
3023 } 3023 }
3024 break; 3024 break;
3025 case XML_ATTRIBUTE_NODE: 3025 case XML_ATTRIBUTE_NODE:
3026 precedence1 = 1; /* element is owner */ 3026 precedence1 = 1; /* element is owner */
3027 miscNode1 = node1; 3027 miscNode1 = node1;
3028 node1 = node1->parent; 3028 node1 = node1->parent;
3029 misc = 1; 3029 misc = 1;
3030 break; 3030 break;
3031 case XML_TEXT_NODE: 3031 case XML_TEXT_NODE:
3032 case XML_CDATA_SECTION_NODE: 3032 case XML_CDATA_SECTION_NODE:
3033 case XML_COMMENT_NODE: 3033 case XML_COMMENT_NODE:
3034 case XML_PI_NODE: { 3034 case XML_PI_NODE: {
3035 miscNode1 = node1; 3035 miscNode1 = node1;
3036 /* 3036 /*
3037 * Find nearest element node. 3037 * Find nearest element node.
3038 » */» 3038 » */
3039 if (node1->prev != NULL) { 3039 if (node1->prev != NULL) {
3040 do { 3040 do {
3041 node1 = node1->prev; 3041 node1 = node1->prev;
3042 if (node1->type == XML_ELEMENT_NODE) { 3042 if (node1->type == XML_ELEMENT_NODE) {
3043 precedence1 = 3; /* element in prev-sibl axis */ 3043 precedence1 = 3; /* element in prev-sibl axis */
3044 break; 3044 break;
3045 } 3045 }
3046 if (node1->prev == NULL) { 3046 if (node1->prev == NULL) {
3047 precedence1 = 2; /* element is parent */ 3047 precedence1 = 2; /* element is parent */
3048 /* 3048 /*
(...skipping 19 matching lines...) Expand all
3068 misc = 1; 3068 misc = 1;
3069 } 3069 }
3070 break; 3070 break;
3071 case XML_NAMESPACE_DECL: 3071 case XML_NAMESPACE_DECL:
3072 /* 3072 /*
3073 * TODO: why do we return 1 for namespace nodes? 3073 * TODO: why do we return 1 for namespace nodes?
3074 */ 3074 */
3075 return(1); 3075 return(1);
3076 default: 3076 default:
3077 break; 3077 break;
3078 } 3078 }
3079 switch (node2->type) { 3079 switch (node2->type) {
3080 » case XML_ELEMENT_NODE:» 3080 » case XML_ELEMENT_NODE:
3081 break; 3081 break;
3082 case XML_ATTRIBUTE_NODE: 3082 case XML_ATTRIBUTE_NODE:
3083 precedence2 = 1; /* element is owner */ 3083 precedence2 = 1; /* element is owner */
3084 miscNode2 = node2; 3084 miscNode2 = node2;
3085 node2 = node2->parent; 3085 node2 = node2->parent;
3086 misc = 1; 3086 misc = 1;
3087 break; 3087 break;
3088 case XML_TEXT_NODE: 3088 case XML_TEXT_NODE:
3089 case XML_CDATA_SECTION_NODE: 3089 case XML_CDATA_SECTION_NODE:
3090 case XML_COMMENT_NODE: 3090 case XML_COMMENT_NODE:
3091 case XML_PI_NODE: { 3091 case XML_PI_NODE: {
3092 miscNode2 = node2; 3092 miscNode2 = node2;
3093 if (node2->prev != NULL) { 3093 if (node2->prev != NULL) {
3094 do { 3094 do {
3095 node2 = node2->prev; 3095 node2 = node2->prev;
3096 if (node2->type == XML_ELEMENT_NODE) { 3096 if (node2->type == XML_ELEMENT_NODE) {
3097 precedence2 = 3; /* element in prev-sibl axis */ 3097 precedence2 = 3; /* element in prev-sibl axis */
3098 break; 3098 break;
3099 } 3099 }
3100 if (node2->prev == NULL) { 3100 if (node2->prev == NULL) {
3101 precedence2 = 2; /* element is parent */ 3101 precedence2 = 2; /* element is parent */
3102 node2 = node2->parent; 3102 node2 = node2->parent;
3103 break; 3103 break;
3104 } 3104 }
3105 } while (1); 3105 } while (1);
3106 } else { 3106 } else {
3107 precedence2 = 2; /* element is parent */ 3107 precedence2 = 2; /* element is parent */
3108 node2 = node2->parent; 3108 node2 = node2->parent;
3109 » }» 3109 » }
3110 if ((node2 == NULL) || (node2->type != XML_ELEMENT_NODE) || 3110 if ((node2 == NULL) || (node2->type != XML_ELEMENT_NODE) ||
3111 (0 <= (long) node1->content)) 3111 (0 <= (long) node1->content))
3112 { 3112 {
3113 node2 = miscNode2; 3113 node2 = miscNode2;
3114 precedence2 = 0; 3114 precedence2 = 0;
3115 } else 3115 } else
3116 misc = 1; 3116 misc = 1;
3117 } 3117 }
3118 break; 3118 break;
3119 case XML_NAMESPACE_DECL: 3119 case XML_NAMESPACE_DECL:
(...skipping 17 matching lines...) Expand all
3137 cur = cur->prev; 3137 cur = cur->prev;
3138 } 3138 }
3139 return (-1); 3139 return (-1);
3140 } else { 3140 } else {
3141 /* 3141 /*
3142 * Evaluate based on higher precedence wrt to the element. 3142 * Evaluate based on higher precedence wrt to the element.
3143 * TODO: This assumes attributes are sorted before content. 3143 * TODO: This assumes attributes are sorted before content.
3144 * Is this 100% correct? 3144 * Is this 100% correct?
3145 */ 3145 */
3146 if (precedence1 < precedence2) 3146 if (precedence1 < precedence2)
3147 » » return(1); 3147 » » return(1);
3148 else 3148 else
3149 » » return(-1);» 3149 » » return(-1);
3150 } 3150 }
3151 » } 3151 » }
3152 /* 3152 /*
3153 * Special case: One of the helper-elements is contained by the other. 3153 * Special case: One of the helper-elements is contained by the other.
3154 * <foo> 3154 * <foo>
3155 * <node2> 3155 * <node2>
3156 * <node1>Text-1(precedence1 == 2)</node1> 3156 * <node1>Text-1(precedence1 == 2)</node1>
3157 * </node2> 3157 * </node2>
3158 * Text-6(precedence2 == 3) 3158 * Text-6(precedence2 == 3)
3159 * </foo> 3159 * </foo>
3160 » */» 3160 » */
3161 if ((precedence2 == 3) && (precedence1 > 1)) { 3161 if ((precedence2 == 3) && (precedence1 > 1)) {
3162 cur = node1->parent; 3162 cur = node1->parent;
3163 while (cur) { 3163 while (cur) {
3164 if (cur == node2) 3164 if (cur == node2)
3165 return(1); 3165 return(1);
3166 cur = cur->parent; 3166 cur = cur->parent;
3167 } 3167 }
3168 } 3168 }
3169 » if ((precedence1 == 3) && (precedence2 > 1)) {» 3169 » if ((precedence1 == 3) && (precedence2 > 1)) {
3170 cur = node2->parent; 3170 cur = node2->parent;
3171 while (cur) { 3171 while (cur) {
3172 if (cur == node1) 3172 if (cur == node1)
3173 return(-1); 3173 return(-1);
3174 cur = cur->parent; 3174 cur = cur->parent;
3175 } 3175 }
3176 } 3176 }
3177 } 3177 }
3178 3178
3179 /* 3179 /*
3180 * Speedup using document order if availble. 3180 * Speedup using document order if availble.
3181 */ 3181 */
3182 if ((node1->type == XML_ELEMENT_NODE) &&» 3182 if ((node1->type == XML_ELEMENT_NODE) &&
3183 (node2->type == XML_ELEMENT_NODE) && 3183 (node2->type == XML_ELEMENT_NODE) &&
3184 (0 > (long) node1->content) && 3184 (0 > (long) node1->content) &&
3185 (0 > (long) node2->content) && 3185 (0 > (long) node2->content) &&
3186 » (node1->doc == node2->doc)) {» 3186 » (node1->doc == node2->doc)) {
3187 3187
3188 l1 = -((long) node1->content); 3188 l1 = -((long) node1->content);
3189 l2 = -((long) node2->content); 3189 l2 = -((long) node2->content);
3190 if (l1 < l2) 3190 if (l1 < l2)
3191 return(1); 3191 return(1);
3192 if (l1 > l2) 3192 if (l1 > l2)
3193 return(-1); 3193 return(-1);
3194 } 3194 }
3195 3195
3196 turtle_comparison: 3196 turtle_comparison:
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
3244 return(1); 3244 return(1);
3245 if (node1 == node2->next) 3245 if (node1 == node2->next)
3246 return(-1); 3246 return(-1);
3247 /* 3247 /*
3248 * Speedup using document order if availble. 3248 * Speedup using document order if availble.
3249 */ 3249 */
3250 if ((node1->type == XML_ELEMENT_NODE) && 3250 if ((node1->type == XML_ELEMENT_NODE) &&
3251 (node2->type == XML_ELEMENT_NODE) && 3251 (node2->type == XML_ELEMENT_NODE) &&
3252 (0 > (long) node1->content) && 3252 (0 > (long) node1->content) &&
3253 (0 > (long) node2->content) && 3253 (0 > (long) node2->content) &&
3254 » (node1->doc == node2->doc)) {» 3254 » (node1->doc == node2->doc)) {
3255 3255
3256 l1 = -((long) node1->content); 3256 l1 = -((long) node1->content);
3257 l2 = -((long) node2->content); 3257 l2 = -((long) node2->content);
3258 if (l1 < l2) 3258 if (l1 < l2)
3259 return(1); 3259 return(1);
3260 if (l1 > l2) 3260 if (l1 > l2)
3261 return(-1); 3261 return(-1);
3262 } 3262 }
3263 3263
3264 for (cur = node1->next;cur != NULL;cur = cur->next) 3264 for (cur = node1->next;cur != NULL;cur = cur->next)
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
3332 * Allocate a new Namespace and fill the fields. 3332 * Allocate a new Namespace and fill the fields.
3333 */ 3333 */
3334 cur = (xmlNsPtr) xmlMalloc(sizeof(xmlNs)); 3334 cur = (xmlNsPtr) xmlMalloc(sizeof(xmlNs));
3335 if (cur == NULL) { 3335 if (cur == NULL) {
3336 xmlXPathErrMemory(NULL, "duplicating namespace\n"); 3336 xmlXPathErrMemory(NULL, "duplicating namespace\n");
3337 return(NULL); 3337 return(NULL);
3338 } 3338 }
3339 memset(cur, 0, sizeof(xmlNs)); 3339 memset(cur, 0, sizeof(xmlNs));
3340 cur->type = XML_NAMESPACE_DECL; 3340 cur->type = XML_NAMESPACE_DECL;
3341 if (ns->href != NULL) 3341 if (ns->href != NULL)
3342 » cur->href = xmlStrdup(ns->href); 3342 » cur->href = xmlStrdup(ns->href);
3343 if (ns->prefix != NULL) 3343 if (ns->prefix != NULL)
3344 » cur->prefix = xmlStrdup(ns->prefix); 3344 » cur->prefix = xmlStrdup(ns->prefix);
3345 cur->next = (xmlNsPtr) node; 3345 cur->next = (xmlNsPtr) node;
3346 return((xmlNodePtr) cur); 3346 return((xmlNodePtr) cur);
3347 } 3347 }
3348 3348
3349 /** 3349 /**
3350 * xmlXPathNodeSetFreeNs: 3350 * xmlXPathNodeSetFreeNs:
3351 * @ns: the XPath namespace node found in a nodeset. 3351 * @ns: the XPath namespace node found in a nodeset.
3352 * 3352 *
3353 * Namespace nodes in libxml don't match the XPath semantic. In a node set 3353 * Namespace nodes in libxml don't match the XPath semantic. In a node set
3354 * the namespace nodes are duplicated and the next pointer is set to the 3354 * the namespace nodes are duplicated and the next pointer is set to the
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
3428 memset(ret, 0 , (size_t) sizeof(xmlNodeSet)); 3428 memset(ret, 0 , (size_t) sizeof(xmlNodeSet));
3429 if (size < XML_NODESET_DEFAULT) 3429 if (size < XML_NODESET_DEFAULT)
3430 size = XML_NODESET_DEFAULT; 3430 size = XML_NODESET_DEFAULT;
3431 ret->nodeTab = (xmlNodePtr *) xmlMalloc(size * sizeof(xmlNodePtr)); 3431 ret->nodeTab = (xmlNodePtr *) xmlMalloc(size * sizeof(xmlNodePtr));
3432 if (ret->nodeTab == NULL) { 3432 if (ret->nodeTab == NULL) {
3433 xmlXPathErrMemory(NULL, "creating nodeset\n"); 3433 xmlXPathErrMemory(NULL, "creating nodeset\n");
3434 xmlFree(ret); 3434 xmlFree(ret);
3435 return(NULL); 3435 return(NULL);
3436 } 3436 }
3437 memset(ret->nodeTab, 0 , size * (size_t) sizeof(xmlNodePtr)); 3437 memset(ret->nodeTab, 0 , size * (size_t) sizeof(xmlNodePtr));
3438 ret->nodeMax = size; 3438 ret->nodeMax = size;
3439 return(ret); 3439 return(ret);
3440 } 3440 }
3441 3441
3442 /** 3442 /**
3443 * xmlXPathNodeSetContains: 3443 * xmlXPathNodeSetContains:
3444 * @cur: the node-set 3444 * @cur: the node-set
3445 * @val: the node 3445 * @val: the node
3446 * 3446 *
3447 * checks whether @cur contains @val 3447 * checks whether @cur contains @val
3448 * 3448 *
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
3481 * @cur: the initial node set 3481 * @cur: the initial node set
3482 * @node: the hosting node 3482 * @node: the hosting node
3483 * @ns: a the namespace node 3483 * @ns: a the namespace node
3484 * 3484 *
3485 * add a new namespace node to an existing NodeSet 3485 * add a new namespace node to an existing NodeSet
3486 */ 3486 */
3487 void 3487 void
3488 xmlXPathNodeSetAddNs(xmlNodeSetPtr cur, xmlNodePtr node, xmlNsPtr ns) { 3488 xmlXPathNodeSetAddNs(xmlNodeSetPtr cur, xmlNodePtr node, xmlNsPtr ns) {
3489 int i; 3489 int i;
3490 3490
3491 3491
3492 if ((cur == NULL) || (ns == NULL) || (node == NULL) || 3492 if ((cur == NULL) || (ns == NULL) || (node == NULL) ||
3493 (ns->type != XML_NAMESPACE_DECL) || 3493 (ns->type != XML_NAMESPACE_DECL) ||
3494 (node->type != XML_ELEMENT_NODE)) 3494 (node->type != XML_ELEMENT_NODE))
3495 return; 3495 return;
3496 3496
3497 /* @@ with_ns to check whether namespace nodes should be looked at @@ */ 3497 /* @@ with_ns to check whether namespace nodes should be looked at @@ */
3498 /* 3498 /*
3499 * prevent duplicates 3499 * prevent duplicates
3500 */ 3500 */
3501 for (i = 0;i < cur->nodeNr;i++) { 3501 for (i = 0;i < cur->nodeNr;i++) {
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
3580 sizeof(xmlNodePtr)); 3580 sizeof(xmlNodePtr));
3581 if (temp == NULL) { 3581 if (temp == NULL) {
3582 xmlXPathErrMemory(NULL, "growing nodeset\n"); 3582 xmlXPathErrMemory(NULL, "growing nodeset\n");
3583 return; 3583 return;
3584 } 3584 }
3585 cur->nodeTab = temp; 3585 cur->nodeTab = temp;
3586 } 3586 }
3587 if (val->type == XML_NAMESPACE_DECL) { 3587 if (val->type == XML_NAMESPACE_DECL) {
3588 xmlNsPtr ns = (xmlNsPtr) val; 3588 xmlNsPtr ns = (xmlNsPtr) val;
3589 3589
3590 » cur->nodeTab[cur->nodeNr++] = 3590 » cur->nodeTab[cur->nodeNr++] =
3591 xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns); 3591 xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns);
3592 } else 3592 } else
3593 cur->nodeTab[cur->nodeNr++] = val; 3593 cur->nodeTab[cur->nodeNr++] = val;
3594 } 3594 }
3595 3595
3596 /** 3596 /**
3597 * xmlXPathNodeSetAddUnique: 3597 * xmlXPathNodeSetAddUnique:
3598 * @cur: the initial node set 3598 * @cur: the initial node set
3599 * @val: a new xmlNodePtr 3599 * @val: a new xmlNodePtr
3600 * 3600 *
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
3632 sizeof(xmlNodePtr)); 3632 sizeof(xmlNodePtr));
3633 if (temp == NULL) { 3633 if (temp == NULL) {
3634 xmlXPathErrMemory(NULL, "growing nodeset\n"); 3634 xmlXPathErrMemory(NULL, "growing nodeset\n");
3635 return; 3635 return;
3636 } 3636 }
3637 cur->nodeTab = temp; 3637 cur->nodeTab = temp;
3638 } 3638 }
3639 if (val->type == XML_NAMESPACE_DECL) { 3639 if (val->type == XML_NAMESPACE_DECL) {
3640 xmlNsPtr ns = (xmlNsPtr) val; 3640 xmlNsPtr ns = (xmlNsPtr) val;
3641 3641
3642 » cur->nodeTab[cur->nodeNr++] = 3642 » cur->nodeTab[cur->nodeNr++] =
3643 xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns); 3643 xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns);
3644 } else 3644 } else
3645 cur->nodeTab[cur->nodeNr++] = val; 3645 cur->nodeTab[cur->nodeNr++] = val;
3646 } 3646 }
3647 3647
3648 /** 3648 /**
3649 * xmlXPathNodeSetMerge: 3649 * xmlXPathNodeSetMerge:
3650 * @val1: the first NodeSet or NULL 3650 * @val1: the first NodeSet or NULL
3651 * @val2: the second NodeSet 3651 * @val2: the second NodeSet
3652 * 3652 *
(...skipping 14 matching lines...) Expand all
3667 return (NULL); 3667 return (NULL);
3668 #if 0 3668 #if 0
3669 /* 3669 /*
3670 * TODO: The optimization won't work in every case, since 3670 * TODO: The optimization won't work in every case, since
3671 * those nasty namespace nodes need to be added with 3671 * those nasty namespace nodes need to be added with
3672 * xmlXPathNodeSetDupNs() to the set; thus a pure 3672 * xmlXPathNodeSetDupNs() to the set; thus a pure
3673 * memcpy is not possible. 3673 * memcpy is not possible.
3674 * If there was a flag on the nodesetval, indicating that 3674 * If there was a flag on the nodesetval, indicating that
3675 * some temporary nodes are in, that would be helpfull. 3675 * some temporary nodes are in, that would be helpfull.
3676 */ 3676 */
3677 » /*» 3677 » /*
3678 * Optimization: Create an equally sized node-set 3678 * Optimization: Create an equally sized node-set
3679 * and memcpy the content. 3679 * and memcpy the content.
3680 */ 3680 */
3681 val1 = xmlXPathNodeSetCreateSize(val2->nodeNr); 3681 val1 = xmlXPathNodeSetCreateSize(val2->nodeNr);
3682 if (val1 == NULL) 3682 if (val1 == NULL)
3683 return(NULL); 3683 return(NULL);
3684 if (val2->nodeNr != 0) { 3684 if (val2->nodeNr != 0) {
3685 if (val2->nodeNr == 1) 3685 if (val2->nodeNr == 1)
3686 *(val1->nodeTab) = *(val2->nodeTab); 3686 *(val1->nodeTab) = *(val2->nodeTab);
3687 else { 3687 else {
3688 memcpy(val1->nodeTab, val2->nodeTab, 3688 memcpy(val1->nodeTab, val2->nodeTab,
3689 val2->nodeNr * sizeof(xmlNodePtr)); 3689 val2->nodeNr * sizeof(xmlNodePtr));
3690 } 3690 }
3691 val1->nodeNr = val2->nodeNr; 3691 val1->nodeNr = val2->nodeNr;
3692 } 3692 }
3693 return(val1); 3693 return(val1);
3694 #endif 3694 #endif
3695 } 3695 }
3696 3696
3697 /* @@ with_ns to check whether namespace nodes should be looked at @@ */ 3697 /* @@ with_ns to check whether namespace nodes should be looked at @@ */
3698 initNr = val1->nodeNr; 3698 initNr = val1->nodeNr;
3699 3699
3700 for (i = 0;i < val2->nodeNr;i++) { 3700 for (i = 0;i < val2->nodeNr;i++) {
3701 » n2 = val2->nodeTab[i]; 3701 » n2 = val2->nodeTab[i];
3702 /* 3702 /*
3703 * check against duplicates 3703 * check against duplicates
3704 */ 3704 */
3705 skip = 0; 3705 skip = 0;
3706 for (j = 0; j < initNr; j++) { 3706 for (j = 0; j < initNr; j++) {
3707 n1 = val1->nodeTab[j]; 3707 n1 = val1->nodeTab[j];
3708 if (n1 == n2) { 3708 if (n1 == n2) {
3709 skip = 1; 3709 skip = 1;
3710 break; 3710 break;
3711 } else if ((n1->type == XML_NAMESPACE_DECL) && 3711 } else if ((n1->type == XML_NAMESPACE_DECL) &&
3712 » » (n2->type == XML_NAMESPACE_DECL)) {» » 3712 » » (n2->type == XML_NAMESPACE_DECL)) {
3713 if ((((xmlNsPtr) n1)->next == ((xmlNsPtr) n2)->next) && 3713 if ((((xmlNsPtr) n1)->next == ((xmlNsPtr) n2)->next) &&
3714 (xmlStrEqual(((xmlNsPtr) n1)->prefix, 3714 (xmlStrEqual(((xmlNsPtr) n1)->prefix,
3715 ((xmlNsPtr) n2)->prefix))) 3715 ((xmlNsPtr) n2)->prefix)))
3716 { 3716 {
3717 skip = 1; 3717 skip = 1;
3718 break; 3718 break;
3719 } 3719 }
3720 } 3720 }
3721 } 3721 }
3722 if (skip) 3722 if (skip)
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
3853 } 3853 }
3854 } else { 3854 } else {
3855 int i, j, initNbSet1; 3855 int i, j, initNbSet1;
3856 xmlNodePtr n1, n2; 3856 xmlNodePtr n1, n2;
3857 3857
3858 if (set1 == NULL) 3858 if (set1 == NULL)
3859 set1 = xmlXPathNodeSetCreate(NULL); 3859 set1 = xmlXPathNodeSetCreate(NULL);
3860 if (set1 == NULL) 3860 if (set1 == NULL)
3861 return (NULL); 3861 return (NULL);
3862 3862
3863 » initNbSet1 = set1->nodeNr; 3863 » initNbSet1 = set1->nodeNr;
3864 for (i = 0;i < set2->nodeNr;i++) { 3864 for (i = 0;i < set2->nodeNr;i++) {
3865 n2 = set2->nodeTab[i]; 3865 n2 = set2->nodeTab[i];
3866 /* 3866 /*
3867 * Skip NULLed entries. 3867 * Skip NULLed entries.
3868 */ 3868 */
3869 if (n2 == NULL) 3869 if (n2 == NULL)
3870 continue; 3870 continue;
3871 /* 3871 /*
3872 * Skip duplicates. 3872 * Skip duplicates.
3873 */ 3873 */
3874 for (j = 0; j < initNbSet1; j++) { 3874 for (j = 0; j < initNbSet1; j++) {
3875 n1 = set1->nodeTab[j]; 3875 n1 = set1->nodeTab[j];
3876 » » if (n1 == n2) {»» 3876 » » if (n1 == n2) {
3877 goto skip_node; 3877 goto skip_node;
3878 } else if ((n1->type == XML_NAMESPACE_DECL) && 3878 } else if ((n1->type == XML_NAMESPACE_DECL) &&
3879 (n2->type == XML_NAMESPACE_DECL)) 3879 (n2->type == XML_NAMESPACE_DECL))
3880 » » {» » 3880 » » {
3881 if ((((xmlNsPtr) n1)->next == ((xmlNsPtr) n2)->next) && 3881 if ((((xmlNsPtr) n1)->next == ((xmlNsPtr) n2)->next) &&
3882 (xmlStrEqual(((xmlNsPtr) n1)->prefix, 3882 (xmlStrEqual(((xmlNsPtr) n1)->prefix,
3883 ((xmlNsPtr) n2)->prefix))) 3883 ((xmlNsPtr) n2)->prefix)))
3884 { 3884 {
3885 /* 3885 /*
3886 * Free the namespace node. 3886 * Free the namespace node.
3887 */ 3887 */
3888 set2->nodeTab[i] = NULL; 3888 set2->nodeTab[i] = NULL;
3889 xmlXPathNodeSetFreeNs((xmlNsPtr) n2); 3889 xmlXPathNodeSetFreeNs((xmlNsPtr) n2);
3890 goto skip_node; 3890 goto skip_node;
3891 } 3891 }
3892 } 3892 }
3893 } 3893 }
3894 /* 3894 /*
3895 * grow the nodeTab if needed 3895 * grow the nodeTab if needed
3896 */ 3896 */
3897 if (set1->nodeMax == 0) { 3897 if (set1->nodeMax == 0) {
3898 set1->nodeTab = (xmlNodePtr *) xmlMalloc( 3898 set1->nodeTab = (xmlNodePtr *) xmlMalloc(
3899 XML_NODESET_DEFAULT * sizeof(xmlNodePtr)); 3899 XML_NODESET_DEFAULT * sizeof(xmlNodePtr));
3900 if (set1->nodeTab == NULL) { 3900 if (set1->nodeTab == NULL) {
3901 xmlXPathErrMemory(NULL, "merging nodeset\n"); 3901 xmlXPathErrMemory(NULL, "merging nodeset\n");
3902 return(NULL); 3902 return(NULL);
3903 } 3903 }
3904 memset(set1->nodeTab, 0, 3904 memset(set1->nodeTab, 0,
3905 XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr)); 3905 XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));
3906 set1->nodeMax = XML_NODESET_DEFAULT; 3906 set1->nodeMax = XML_NODESET_DEFAULT;
3907 } else if (set1->nodeNr >= set1->nodeMax) { 3907 } else if (set1->nodeNr >= set1->nodeMax) {
3908 xmlNodePtr *temp; 3908 xmlNodePtr *temp;
3909 » » 3909
3910 set1->nodeMax *= 2; 3910 set1->nodeMax *= 2;
3911 temp = (xmlNodePtr *) xmlRealloc( 3911 temp = (xmlNodePtr *) xmlRealloc(
3912 set1->nodeTab, set1->nodeMax * sizeof(xmlNodePtr)); 3912 set1->nodeTab, set1->nodeMax * sizeof(xmlNodePtr));
3913 if (temp == NULL) { 3913 if (temp == NULL) {
3914 xmlXPathErrMemory(NULL, "merging nodeset\n"); 3914 xmlXPathErrMemory(NULL, "merging nodeset\n");
3915 return(NULL); 3915 return(NULL);
3916 } 3916 }
3917 set1->nodeTab = temp; 3917 set1->nodeTab = temp;
3918 } 3918 }
3919 if (n2->type == XML_NAMESPACE_DECL) { 3919 if (n2->type == XML_NAMESPACE_DECL) {
3920 xmlNsPtr ns = (xmlNsPtr) n2; 3920 xmlNsPtr ns = (xmlNsPtr) n2;
3921 » » 3921
3922 set1->nodeTab[set1->nodeNr++] = 3922 set1->nodeTab[set1->nodeNr++] =
3923 xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns); 3923 xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns);
3924 } else 3924 } else
3925 set1->nodeTab[set1->nodeNr++] = n2; 3925 set1->nodeTab[set1->nodeNr++] = n2;
3926 skip_node: 3926 skip_node:
3927 {} 3927 {}
3928 } 3928 }
3929 } 3929 }
3930 set2->nodeNr = 0; 3930 set2->nodeNr = 0;
3931 return(set1); 3931 return(set1);
3932 } 3932 }
3933 3933
3934 /** 3934 /**
3935 * xmlXPathNodeSetMergeAndClearNoDupls: 3935 * xmlXPathNodeSetMergeAndClearNoDupls:
3936 * @set1: the first NodeSet or NULL 3936 * @set1: the first NodeSet or NULL
3937 * @set2: the second NodeSet 3937 * @set2: the second NodeSet
3938 * @hasSet2NsNodes: 1 if set2 contains namespaces nodes 3938 * @hasSet2NsNodes: 1 if set2 contains namespaces nodes
3939 * 3939 *
3940 * Merges two nodesets, all nodes from @set2 are added to @set1 3940 * Merges two nodesets, all nodes from @set2 are added to @set1
3941 * if @set1 is NULL, a new set is created and copied from @set2. 3941 * if @set1 is NULL, a new set is created and copied from @set2.
3942 * Doesn't chack for duplicate nodes. Clears set2. 3942 * Doesn't chack for duplicate nodes. Clears set2.
3943 * 3943 *
3944 * Returns @set1 once extended or NULL in case of error. 3944 * Returns @set1 once extended or NULL in case of error.
3945 */ 3945 */
3946 static xmlNodeSetPtr 3946 static xmlNodeSetPtr
3947 xmlXPathNodeSetMergeAndClearNoDupls(xmlNodeSetPtr set1, xmlNodeSetPtr set2, 3947 xmlXPathNodeSetMergeAndClearNoDupls(xmlNodeSetPtr set1, xmlNodeSetPtr set2,
3948 int hasNullEntries) 3948 int hasNullEntries)
3949 { 3949 {
3950 if (set2 == NULL) 3950 if (set2 == NULL)
3951 return(set1); 3951 return(set1);
3952 if ((set1 == NULL) && (hasNullEntries == 0)) { 3952 if ((set1 == NULL) && (hasNullEntries == 0)) {
3953 /* 3953 /*
3954 * Note that doing a memcpy of the list, namespace nodes are 3954 * Note that doing a memcpy of the list, namespace nodes are
3955 * just assigned to set1, since set2 is cleared anyway. 3955 * just assigned to set1, since set2 is cleared anyway.
3956 */ 3956 */
3957 set1 = xmlXPathNodeSetCreateSize(set2->nodeNr); 3957 set1 = xmlXPathNodeSetCreateSize(set2->nodeNr);
3958 if (set1 == NULL) 3958 if (set1 == NULL)
3959 return(NULL); 3959 return(NULL);
3960 if (set2->nodeNr != 0) { 3960 if (set2->nodeNr != 0) {
3961 memcpy(set1->nodeTab, set2->nodeTab, 3961 memcpy(set1->nodeTab, set2->nodeTab,
3962 set2->nodeNr * sizeof(xmlNodePtr)); 3962 set2->nodeNr * sizeof(xmlNodePtr));
3963 set1->nodeNr = set2->nodeNr; 3963 set1->nodeNr = set2->nodeNr;
3964 } 3964 }
3965 } else { 3965 } else {
3966 int i; 3966 int i;
3967 xmlNodePtr n2; 3967 xmlNodePtr n2;
3968 3968
3969 if (set1 == NULL) 3969 if (set1 == NULL)
3970 set1 = xmlXPathNodeSetCreate(NULL); 3970 set1 = xmlXPathNodeSetCreate(NULL);
3971 if (set1 == NULL) 3971 if (set1 == NULL)
3972 return (NULL); 3972 return (NULL);
3973 3973
3974 for (i = 0;i < set2->nodeNr;i++) { 3974 for (i = 0;i < set2->nodeNr;i++) {
3975 n2 = set2->nodeTab[i]; 3975 n2 = set2->nodeTab[i];
3976 /* 3976 /*
3977 * Skip NULLed entries. 3977 * Skip NULLed entries.
3978 */ 3978 */
3979 if (n2 == NULL) 3979 if (n2 == NULL)
3980 » » continue;» 3980 » » continue;
3981 if (set1->nodeMax == 0) { 3981 if (set1->nodeMax == 0) {
3982 set1->nodeTab = (xmlNodePtr *) xmlMalloc( 3982 set1->nodeTab = (xmlNodePtr *) xmlMalloc(
3983 XML_NODESET_DEFAULT * sizeof(xmlNodePtr)); 3983 XML_NODESET_DEFAULT * sizeof(xmlNodePtr));
3984 if (set1->nodeTab == NULL) { 3984 if (set1->nodeTab == NULL) {
3985 xmlXPathErrMemory(NULL, "merging nodeset\n"); 3985 xmlXPathErrMemory(NULL, "merging nodeset\n");
3986 return(NULL); 3986 return(NULL);
3987 } 3987 }
3988 memset(set1->nodeTab, 0, 3988 memset(set1->nodeTab, 0,
3989 XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr)); 3989 XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));
3990 set1->nodeMax = XML_NODESET_DEFAULT; 3990 set1->nodeMax = XML_NODESET_DEFAULT;
3991 } else if (set1->nodeNr >= set1->nodeMax) { 3991 } else if (set1->nodeNr >= set1->nodeMax) {
3992 xmlNodePtr *temp; 3992 xmlNodePtr *temp;
3993 » » 3993
3994 set1->nodeMax *= 2; 3994 set1->nodeMax *= 2;
3995 temp = (xmlNodePtr *) xmlRealloc( 3995 temp = (xmlNodePtr *) xmlRealloc(
3996 set1->nodeTab, set1->nodeMax * sizeof(xmlNodePtr)); 3996 set1->nodeTab, set1->nodeMax * sizeof(xmlNodePtr));
3997 if (temp == NULL) { 3997 if (temp == NULL) {
3998 xmlXPathErrMemory(NULL, "merging nodeset\n"); 3998 xmlXPathErrMemory(NULL, "merging nodeset\n");
3999 return(NULL); 3999 return(NULL);
4000 } 4000 }
4001 set1->nodeTab = temp; 4001 set1->nodeTab = temp;
4002 } 4002 }
4003 set1->nodeTab[set1->nodeNr++] = n2; 4003 set1->nodeTab[set1->nodeNr++] = n2;
(...skipping 18 matching lines...) Expand all
4022 if (val == NULL) return; 4022 if (val == NULL) return;
4023 4023
4024 /* 4024 /*
4025 * find node in nodeTab 4025 * find node in nodeTab
4026 */ 4026 */
4027 for (i = 0;i < cur->nodeNr;i++) 4027 for (i = 0;i < cur->nodeNr;i++)
4028 if (cur->nodeTab[i] == val) break; 4028 if (cur->nodeTab[i] == val) break;
4029 4029
4030 if (i >= cur->nodeNr) { /* not found */ 4030 if (i >= cur->nodeNr) { /* not found */
4031 #ifdef DEBUG 4031 #ifdef DEBUG
4032 xmlGenericError(xmlGenericErrorContext, 4032 xmlGenericError(xmlGenericErrorContext,
4033 "xmlXPathNodeSetDel: Node %s wasn't found in NodeList\n", 4033 "xmlXPathNodeSetDel: Node %s wasn't found in NodeList\n",
4034 val->name); 4034 val->name);
4035 #endif 4035 #endif
4036 return; 4036 return;
4037 } 4037 }
4038 if ((cur->nodeTab[i] != NULL) && 4038 if ((cur->nodeTab[i] != NULL) &&
4039 (cur->nodeTab[i]->type == XML_NAMESPACE_DECL)) 4039 (cur->nodeTab[i]->type == XML_NAMESPACE_DECL))
4040 xmlXPathNodeSetFreeNs((xmlNsPtr) cur->nodeTab[i]); 4040 xmlXPathNodeSetFreeNs((xmlNsPtr) cur->nodeTab[i]);
4041 cur->nodeNr--; 4041 cur->nodeNr--;
4042 for (;i < cur->nodeNr;i++) 4042 for (;i < cur->nodeNr;i++)
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
4082 (obj->nodeTab[i]->type == XML_NAMESPACE_DECL)) 4082 (obj->nodeTab[i]->type == XML_NAMESPACE_DECL))
4083 xmlXPathNodeSetFreeNs((xmlNsPtr) obj->nodeTab[i]); 4083 xmlXPathNodeSetFreeNs((xmlNsPtr) obj->nodeTab[i]);
4084 xmlFree(obj->nodeTab); 4084 xmlFree(obj->nodeTab);
4085 } 4085 }
4086 xmlFree(obj); 4086 xmlFree(obj);
4087 } 4087 }
4088 4088
4089 /** 4089 /**
4090 * xmlXPathNodeSetClear: 4090 * xmlXPathNodeSetClear:
4091 * @set: the node set to clear 4091 * @set: the node set to clear
4092 * 4092 *
4093 * Clears the list from all temporary XPath objects (e.g. namespace nodes 4093 * Clears the list from all temporary XPath objects (e.g. namespace nodes
4094 * are feed), but does *not* free the list itself. Sets the length of the 4094 * are feed), but does *not* free the list itself. Sets the length of the
4095 * list to 0. 4095 * list to 0.
4096 */ 4096 */
4097 static void 4097 static void
4098 xmlXPathNodeSetClear(xmlNodeSetPtr set, int hasNsNodes) 4098 xmlXPathNodeSetClear(xmlNodeSetPtr set, int hasNsNodes)
4099 { 4099 {
4100 if ((set == NULL) || (set->nodeNr <= 0)) 4100 if ((set == NULL) || (set->nodeNr <= 0))
4101 return; 4101 return;
4102 else if (hasNsNodes) { 4102 else if (hasNsNodes) {
4103 int i; 4103 int i;
4104 xmlNodePtr node; 4104 xmlNodePtr node;
4105 » 4105
4106 for (i = 0; i < set->nodeNr; i++) { 4106 for (i = 0; i < set->nodeNr; i++) {
4107 node = set->nodeTab[i]; 4107 node = set->nodeTab[i];
4108 if ((node != NULL) && 4108 if ((node != NULL) &&
4109 (node->type == XML_NAMESPACE_DECL)) 4109 (node->type == XML_NAMESPACE_DECL))
4110 xmlXPathNodeSetFreeNs((xmlNsPtr) node); 4110 xmlXPathNodeSetFreeNs((xmlNsPtr) node);
4111 » }» 4111 » }
4112 } 4112 }
4113 set->nodeNr = 0; 4113 set->nodeNr = 0;
4114 } 4114 }
4115 4115
4116 /** 4116 /**
4117 * xmlXPathNodeSetClearFromPos: 4117 * xmlXPathNodeSetClearFromPos:
4118 * @set: the node set to be cleared 4118 * @set: the node set to be cleared
4119 * @pos: the start position to clear from 4119 * @pos: the start position to clear from
4120 * 4120 *
4121 * Clears the list from temporary XPath objects (e.g. namespace nodes 4121 * Clears the list from temporary XPath objects (e.g. namespace nodes
4122 * are feed) starting with the entry at @pos, but does *not* free the list 4122 * are feed) starting with the entry at @pos, but does *not* free the list
4123 * itself. Sets the length of the list to @pos. 4123 * itself. Sets the length of the list to @pos.
4124 */ 4124 */
4125 static void 4125 static void
4126 xmlXPathNodeSetClearFromPos(xmlNodeSetPtr set, int pos, int hasNsNodes) 4126 xmlXPathNodeSetClearFromPos(xmlNodeSetPtr set, int pos, int hasNsNodes)
4127 { 4127 {
4128 if ((set == NULL) || (set->nodeNr <= 0) || (pos >= set->nodeNr)) 4128 if ((set == NULL) || (set->nodeNr <= 0) || (pos >= set->nodeNr))
4129 return; 4129 return;
4130 else if ((hasNsNodes)) { 4130 else if ((hasNsNodes)) {
4131 int i; 4131 int i;
4132 xmlNodePtr node; 4132 xmlNodePtr node;
4133 » 4133
4134 for (i = pos; i < set->nodeNr; i++) { 4134 for (i = pos; i < set->nodeNr; i++) {
4135 node = set->nodeTab[i]; 4135 node = set->nodeTab[i];
4136 if ((node != NULL) && 4136 if ((node != NULL) &&
4137 (node->type == XML_NAMESPACE_DECL)) 4137 (node->type == XML_NAMESPACE_DECL))
4138 xmlXPathNodeSetFreeNs((xmlNsPtr) node); 4138 xmlXPathNodeSetFreeNs((xmlNsPtr) node);
4139 » }» 4139 » }
4140 } 4140 }
4141 set->nodeNr = pos; 4141 set->nodeNr = pos;
4142 } 4142 }
4143 4143
4144 /** 4144 /**
4145 * xmlXPathFreeValueTree: 4145 * xmlXPathFreeValueTree:
4146 * @obj: the xmlNodeSetPtr to free 4146 * @obj: the xmlNodeSetPtr to free
4147 * 4147 *
4148 * Free the NodeSet compound and the actual tree, this is different 4148 * Free the NodeSet compound and the actual tree, this is different
4149 * from xmlXPathFreeNodeSet() 4149 * from xmlXPathFreeNodeSet()
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
4406 } 4406 }
4407 return(ret); 4407 return(ret);
4408 } 4408 }
4409 4409
4410 /** 4410 /**
4411 * xmlXPathDistinctSorted: 4411 * xmlXPathDistinctSorted:
4412 * @nodes: a node-set, sorted by document order 4412 * @nodes: a node-set, sorted by document order
4413 * 4413 *
4414 * Implements the EXSLT - Sets distinct() function: 4414 * Implements the EXSLT - Sets distinct() function:
4415 * node-set set:distinct (node-set) 4415 * node-set set:distinct (node-set)
4416 * 4416 *
4417 * Returns a subset of the nodes contained in @nodes, or @nodes if 4417 * Returns a subset of the nodes contained in @nodes, or @nodes if
4418 * it is empty 4418 * it is empty
4419 */ 4419 */
4420 xmlNodeSetPtr 4420 xmlNodeSetPtr
4421 xmlXPathDistinctSorted (xmlNodeSetPtr nodes) { 4421 xmlXPathDistinctSorted (xmlNodeSetPtr nodes) {
4422 xmlNodeSetPtr ret; 4422 xmlNodeSetPtr ret;
4423 xmlHashTablePtr hash; 4423 xmlHashTablePtr hash;
4424 int i, l; 4424 int i, l;
4425 xmlChar * strval; 4425 xmlChar * strval;
4426 xmlNodePtr cur; 4426 xmlNodePtr cur;
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
4715 /** 4715 /**
4716 * xmlXPathRegisterFunc: 4716 * xmlXPathRegisterFunc:
4717 * @ctxt: the XPath context 4717 * @ctxt: the XPath context
4718 * @name: the function name 4718 * @name: the function name
4719 * @f: the function implementation or NULL 4719 * @f: the function implementation or NULL
4720 * 4720 *
4721 * Register a new function. If @f is NULL it unregisters the function 4721 * Register a new function. If @f is NULL it unregisters the function
4722 * 4722 *
4723 * Returns 0 in case of success, -1 in case of error 4723 * Returns 0 in case of success, -1 in case of error
4724 */ 4724 */
4725 int» » 4725 int
4726 xmlXPathRegisterFunc(xmlXPathContextPtr ctxt, const xmlChar *name, 4726 xmlXPathRegisterFunc(xmlXPathContextPtr ctxt, const xmlChar *name,
4727 xmlXPathFunction f) { 4727 xmlXPathFunction f) {
4728 return(xmlXPathRegisterFuncNS(ctxt, name, NULL, f)); 4728 return(xmlXPathRegisterFuncNS(ctxt, name, NULL, f));
4729 } 4729 }
4730 4730
4731 /** 4731 /**
4732 * xmlXPathRegisterFuncNS: 4732 * xmlXPathRegisterFuncNS:
4733 * @ctxt: the XPath context 4733 * @ctxt: the XPath context
4734 * @name: the function name 4734 * @name: the function name
4735 * @ns_uri: the function namespace URI 4735 * @ns_uri: the function namespace URI
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
4809 * 4809 *
4810 * Search in the Function array of the context for the given 4810 * Search in the Function array of the context for the given
4811 * function. 4811 * function.
4812 * 4812 *
4813 * Returns the xmlXPathFunction or NULL if not found 4813 * Returns the xmlXPathFunction or NULL if not found
4814 */ 4814 */
4815 xmlXPathFunction 4815 xmlXPathFunction
4816 xmlXPathFunctionLookupNS(xmlXPathContextPtr ctxt, const xmlChar *name, 4816 xmlXPathFunctionLookupNS(xmlXPathContextPtr ctxt, const xmlChar *name,
4817 const xmlChar *ns_uri) { 4817 const xmlChar *ns_uri) {
4818 xmlXPathFunction ret; 4818 xmlXPathFunction ret;
4819 4819
4820 if (ctxt == NULL) 4820 if (ctxt == NULL)
4821 return(NULL); 4821 return(NULL);
4822 if (name == NULL) 4822 if (name == NULL)
4823 return(NULL); 4823 return(NULL);
4824 4824
4825 if (ctxt->funcLookupFunc != NULL) { 4825 if (ctxt->funcLookupFunc != NULL) {
4826 xmlXPathFuncLookupFunc f; 4826 xmlXPathFuncLookupFunc f;
4827 4827
4828 f = ctxt->funcLookupFunc; 4828 f = ctxt->funcLookupFunc;
4829 ret = f(ctxt->funcLookupData, name, ns_uri); 4829 ret = f(ctxt->funcLookupData, name, ns_uri);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
4863 * xmlXPathRegisterVariable: 4863 * xmlXPathRegisterVariable:
4864 * @ctxt: the XPath context 4864 * @ctxt: the XPath context
4865 * @name: the variable name 4865 * @name: the variable name
4866 * @value: the variable value or NULL 4866 * @value: the variable value or NULL
4867 * 4867 *
4868 * Register a new variable value. If @value is NULL it unregisters 4868 * Register a new variable value. If @value is NULL it unregisters
4869 * the variable 4869 * the variable
4870 * 4870 *
4871 * Returns 0 in case of success, -1 in case of error 4871 * Returns 0 in case of success, -1 in case of error
4872 */ 4872 */
4873 int» » 4873 int
4874 xmlXPathRegisterVariable(xmlXPathContextPtr ctxt, const xmlChar *name, 4874 xmlXPathRegisterVariable(xmlXPathContextPtr ctxt, const xmlChar *name,
4875 xmlXPathObjectPtr value) { 4875 xmlXPathObjectPtr value) {
4876 return(xmlXPathRegisterVariableNS(ctxt, name, NULL, value)); 4876 return(xmlXPathRegisterVariableNS(ctxt, name, NULL, value));
4877 } 4877 }
4878 4878
4879 /** 4879 /**
4880 * xmlXPathRegisterVariableNS: 4880 * xmlXPathRegisterVariableNS:
4881 * @ctxt: the XPath context 4881 * @ctxt: the XPath context
4882 * @name: the variable name 4882 * @name: the variable name
4883 * @ns_uri: the variable namespace URI 4883 * @ns_uri: the variable namespace URI
(...skipping 11 matching lines...) Expand all
4895 if (ctxt == NULL) 4895 if (ctxt == NULL)
4896 return(-1); 4896 return(-1);
4897 if (name == NULL) 4897 if (name == NULL)
4898 return(-1); 4898 return(-1);
4899 4899
4900 if (ctxt->varHash == NULL) 4900 if (ctxt->varHash == NULL)
4901 ctxt->varHash = xmlHashCreate(0); 4901 ctxt->varHash = xmlHashCreate(0);
4902 if (ctxt->varHash == NULL) 4902 if (ctxt->varHash == NULL)
4903 return(-1); 4903 return(-1);
4904 if (value == NULL) 4904 if (value == NULL)
4905 return(xmlHashRemoveEntry2(ctxt->varHash, name, ns_uri, 4905 return(xmlHashRemoveEntry2(ctxt->varHash, name, ns_uri,
4906 (xmlHashDeallocator)xmlXPathFreeObject)); 4906 (xmlHashDeallocator)xmlXPathFreeObject));
4907 return(xmlHashUpdateEntry2(ctxt->varHash, name, ns_uri, 4907 return(xmlHashUpdateEntry2(ctxt->varHash, name, ns_uri,
4908 (void *) value, 4908 (void *) value,
4909 (xmlHashDeallocator)xmlXPathFreeObject)); 4909 (xmlHashDeallocator)xmlXPathFreeObject));
4910 } 4910 }
4911 4911
4912 /** 4912 /**
4913 * xmlXPathRegisterVariableLookup: 4913 * xmlXPathRegisterVariableLookup:
4914 * @ctxt: the XPath context 4914 * @ctxt: the XPath context
4915 * @f: the lookup function 4915 * @f: the lookup function
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
4951 return(xmlXPathVariableLookupNS(ctxt, name, NULL)); 4951 return(xmlXPathVariableLookupNS(ctxt, name, NULL));
4952 } 4952 }
4953 4953
4954 /** 4954 /**
4955 * xmlXPathVariableLookupNS: 4955 * xmlXPathVariableLookupNS:
4956 * @ctxt: the XPath context 4956 * @ctxt: the XPath context
4957 * @name: the variable name 4957 * @name: the variable name
4958 * @ns_uri: the variable namespace URI 4958 * @ns_uri: the variable namespace URI
4959 * 4959 *
4960 * Search in the Variable array of the context for the given 4960 * Search in the Variable array of the context for the given
4961 * variable value. 4961 * variable value.
4962 * 4962 *
4963 * Returns the a copy of the value or NULL if not found 4963 * Returns the a copy of the value or NULL if not found
4964 */ 4964 */
4965 xmlXPathObjectPtr 4965 xmlXPathObjectPtr
4966 xmlXPathVariableLookupNS(xmlXPathContextPtr ctxt, const xmlChar *name, 4966 xmlXPathVariableLookupNS(xmlXPathContextPtr ctxt, const xmlChar *name,
4967 const xmlChar *ns_uri) { 4967 const xmlChar *ns_uri) {
4968 if (ctxt == NULL) 4968 if (ctxt == NULL)
4969 return(NULL); 4969 return(NULL);
4970 4970
4971 if (ctxt->varLookupFunc != NULL) { 4971 if (ctxt->varLookupFunc != NULL) {
(...skipping 24 matching lines...) Expand all
4996 if (ctxt == NULL) 4996 if (ctxt == NULL)
4997 return; 4997 return;
4998 4998
4999 xmlHashFree(ctxt->varHash, (xmlHashDeallocator)xmlXPathFreeObject); 4999 xmlHashFree(ctxt->varHash, (xmlHashDeallocator)xmlXPathFreeObject);
5000 ctxt->varHash = NULL; 5000 ctxt->varHash = NULL;
5001 } 5001 }
5002 5002
5003 /** 5003 /**
5004 * xmlXPathRegisterNs: 5004 * xmlXPathRegisterNs:
5005 * @ctxt: the XPath context 5005 * @ctxt: the XPath context
5006 * @prefix: the namespace prefix 5006 * @prefix: the namespace prefix cannot be NULL or empty string
5007 * @ns_uri: the namespace name 5007 * @ns_uri: the namespace name
5008 * 5008 *
5009 * Register a new namespace. If @ns_uri is NULL it unregisters 5009 * Register a new namespace. If @ns_uri is NULL it unregisters
5010 * the namespace 5010 * the namespace
5011 * 5011 *
5012 * Returns 0 in case of success, -1 in case of error 5012 * Returns 0 in case of success, -1 in case of error
5013 */ 5013 */
5014 int 5014 int
5015 xmlXPathRegisterNs(xmlXPathContextPtr ctxt, const xmlChar *prefix, 5015 xmlXPathRegisterNs(xmlXPathContextPtr ctxt, const xmlChar *prefix,
5016 const xmlChar *ns_uri) { 5016 const xmlChar *ns_uri) {
5017 if (ctxt == NULL) 5017 if (ctxt == NULL)
5018 return(-1); 5018 return(-1);
5019 if (prefix == NULL) 5019 if (prefix == NULL)
5020 return(-1); 5020 return(-1);
5021 if (prefix[0] == 0)
5022 return(-1);
5021 5023
5022 if (ctxt->nsHash == NULL) 5024 if (ctxt->nsHash == NULL)
5023 ctxt->nsHash = xmlHashCreate(10); 5025 ctxt->nsHash = xmlHashCreate(10);
5024 if (ctxt->nsHash == NULL) 5026 if (ctxt->nsHash == NULL)
5025 return(-1); 5027 return(-1);
5026 if (ns_uri == NULL) 5028 if (ns_uri == NULL)
5027 return(xmlHashRemoveEntry(ctxt->nsHash, prefix, 5029 return(xmlHashRemoveEntry(ctxt->nsHash, prefix,
5028 (xmlHashDeallocator)xmlFree)); 5030 (xmlHashDeallocator)xmlFree));
5029 return(xmlHashUpdateEntry(ctxt->nsHash, prefix, (void *) xmlStrdup(ns_uri), 5031 return(xmlHashUpdateEntry(ctxt->nsHash, prefix, (void *) xmlStrdup(ns_uri),
5030 (xmlHashDeallocator)xmlFree)); 5032 (xmlHashDeallocator)xmlFree));
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after
5334 case XPATH_LOCATIONSET: 5336 case XPATH_LOCATIONSET:
5335 #ifdef LIBXML_XPTR_ENABLED 5337 #ifdef LIBXML_XPTR_ENABLED
5336 { 5338 {
5337 xmlLocationSetPtr loc = val->user; 5339 xmlLocationSetPtr loc = val->user;
5338 ret->user = (void *) xmlXPtrLocationSetMerge(NULL, loc); 5340 ret->user = (void *) xmlXPtrLocationSetMerge(NULL, loc);
5339 break; 5341 break;
5340 } 5342 }
5341 #endif 5343 #endif
5342 case XPATH_USERS: 5344 case XPATH_USERS:
5343 ret->user = val->user; 5345 ret->user = val->user;
5344 » break; 5346 » break;
5345 case XPATH_UNDEFINED: 5347 case XPATH_UNDEFINED:
5346 xmlGenericError(xmlGenericErrorContext, 5348 xmlGenericError(xmlGenericErrorContext,
5347 "xmlXPathObjectCopy: unsupported type %d\n", 5349 "xmlXPathObjectCopy: unsupported type %d\n",
5348 val->type); 5350 val->type);
5349 break; 5351 break;
5350 } 5352 }
5351 return(ret); 5353 return(ret);
5352 } 5354 }
5353 5355
5354 /** 5356 /**
5355 * xmlXPathFreeObject: 5357 * xmlXPathFreeObject:
5356 * @obj: the object to free 5358 * @obj: the object to free
5357 * 5359 *
5358 * Free up an xmlXPathObjectPtr object. 5360 * Free up an xmlXPathObjectPtr object.
5359 */ 5361 */
5360 void 5362 void
5361 xmlXPathFreeObject(xmlXPathObjectPtr obj) { 5363 xmlXPathFreeObject(xmlXPathObjectPtr obj) {
5362 if (obj == NULL) return; 5364 if (obj == NULL) return;
5363 if ((obj->type == XPATH_NODESET) || (obj->type == XPATH_XSLT_TREE)) { 5365 if ((obj->type == XPATH_NODESET) || (obj->type == XPATH_XSLT_TREE)) {
5364 if (obj->boolval) { 5366 if (obj->boolval) {
5365 #if 0 5367 #if 0
5366 if (obj->user != NULL) { 5368 if (obj->user != NULL) {
5367 xmlXPathFreeNodeSet(obj->nodesetval); 5369 xmlXPathFreeNodeSet(obj->nodesetval);
5368 xmlFreeNodeList((xmlNodePtr) obj->user); 5370 xmlFreeNodeList((xmlNodePtr) obj->user);
5369 } else 5371 } else
5370 #endif 5372 #endif
5371 obj->type = XPATH_XSLT_TREE; /* TODO: Just for debugging. */ 5373 obj->type = XPATH_XSLT_TREE; /* TODO: Just for debugging. */
5372 if (obj->nodesetval != NULL) 5374 if (obj->nodesetval != NULL)
5373 » » xmlXPathFreeValueTree(obj->nodesetval);» 5375 » » xmlXPathFreeValueTree(obj->nodesetval);
5374 } else { 5376 } else {
5375 if (obj->nodesetval != NULL) 5377 if (obj->nodesetval != NULL)
5376 xmlXPathFreeNodeSet(obj->nodesetval); 5378 xmlXPathFreeNodeSet(obj->nodesetval);
5377 } 5379 }
5378 #ifdef LIBXML_XPTR_ENABLED 5380 #ifdef LIBXML_XPTR_ENABLED
5379 } else if (obj->type == XPATH_LOCATIONSET) { 5381 } else if (obj->type == XPATH_LOCATIONSET) {
5380 if (obj->user != NULL) 5382 if (obj->user != NULL)
5381 xmlXPtrFreeLocationSet(obj->user); 5383 xmlXPtrFreeLocationSet(obj->user);
5382 #endif 5384 #endif
5383 } else if (obj->type == XPATH_STRING) { 5385 } else if (obj->type == XPATH_STRING) {
5384 if (obj->stringval != NULL) 5386 if (obj->stringval != NULL)
5385 xmlFree(obj->stringval); 5387 xmlFree(obj->stringval);
5386 } 5388 }
5387 #ifdef XP_DEBUG_OBJ_USAGE 5389 #ifdef XP_DEBUG_OBJ_USAGE
5388 xmlXPathDebugObjUsageReleased(NULL, obj->type); 5390 xmlXPathDebugObjUsageReleased(NULL, obj->type);
5389 #endif 5391 #endif
5390 xmlFree(obj); 5392 xmlFree(obj);
5391 } 5393 }
5392 5394
5393 /** 5395 /**
5394 * xmlXPathReleaseObject: 5396 * xmlXPathReleaseObject:
5395 * @obj: the xmlXPathObjectPtr to free or to cache 5397 * @obj: the xmlXPathObjectPtr to free or to cache
5396 * 5398 *
5397 * Depending on the state of the cache this frees the given 5399 * Depending on the state of the cache this frees the given
5398 * XPath object or stores it in the cache. 5400 * XPath object or stores it in the cache.
5399 */ 5401 */
5400 static void 5402 static void
5401 xmlXPathReleaseObject(xmlXPathContextPtr ctxt, xmlXPathObjectPtr obj) 5403 xmlXPathReleaseObject(xmlXPathContextPtr ctxt, xmlXPathObjectPtr obj)
5402 { 5404 {
5403 #define XP_CACHE_ADD(sl, o) if (sl == NULL) { \ 5405 #define XP_CACHE_ADD(sl, o) if (sl == NULL) { \
5404 sl = xmlPointerListCreate(10); if (sl == NULL) goto free_obj; } \ 5406 sl = xmlPointerListCreate(10); if (sl == NULL) goto free_obj; } \
5405 if (xmlPointerListAddSize(sl, obj, 0) == -1) goto free_obj; 5407 if (xmlPointerListAddSize(sl, obj, 0) == -1) goto free_obj;
5406 5408
5407 #define XP_CACHE_WANTS(sl, n) ((sl == NULL) || ((sl)->number < n)) 5409 #define XP_CACHE_WANTS(sl, n) ((sl == NULL) || ((sl)->number < n))
5408 5410
5409 if (obj == NULL) 5411 if (obj == NULL)
5410 return; 5412 return;
5411 if ((ctxt == NULL) || (ctxt->cache == NULL)) { 5413 if ((ctxt == NULL) || (ctxt->cache == NULL)) {
5412 xmlXPathFreeObject(obj); 5414 xmlXPathFreeObject(obj);
5413 } else { 5415 } else {
5414 xmlXPathContextCachePtr cache = 5416 xmlXPathContextCachePtr cache =
5415 (xmlXPathContextCachePtr) ctxt->cache; 5417 (xmlXPathContextCachePtr) ctxt->cache;
5416 5418
5417 switch (obj->type) { 5419 switch (obj->type) {
5418 case XPATH_NODESET: 5420 case XPATH_NODESET:
5419 case XPATH_XSLT_TREE: 5421 case XPATH_XSLT_TREE:
5420 if (obj->nodesetval != NULL) { 5422 if (obj->nodesetval != NULL) {
5421 if (obj->boolval) { 5423 if (obj->boolval) {
5422 » » » /* 5424 » » » /*
5423 * It looks like the @boolval is used for 5425 * It looks like the @boolval is used for
5424 * evaluation if this an XSLT Result Tree Fragment. 5426 * evaluation if this an XSLT Result Tree Fragment.
5425 * TODO: Check if this assumption is correct. 5427 * TODO: Check if this assumption is correct.
5426 */ 5428 */
5427 obj->type = XPATH_XSLT_TREE; /* just for debugging */ 5429 obj->type = XPATH_XSLT_TREE; /* just for debugging */
5428 xmlXPathFreeValueTree(obj->nodesetval); 5430 xmlXPathFreeValueTree(obj->nodesetval);
5429 obj->nodesetval = NULL; 5431 obj->nodesetval = NULL;
5430 } else if ((obj->nodesetval->nodeMax <= 40) && 5432 } else if ((obj->nodesetval->nodeMax <= 40) &&
5431 (XP_CACHE_WANTS(cache->nodesetObjs, 5433 (XP_CACHE_WANTS(cache->nodesetObjs,
5432 cache->maxNodeset))) 5434 cache->maxNodeset)))
(...skipping 26 matching lines...) Expand all
5459 XP_CACHE_ADD(cache->numberObjs, obj); 5461 XP_CACHE_ADD(cache->numberObjs, obj);
5460 goto obj_cached; 5462 goto obj_cached;
5461 } 5463 }
5462 break; 5464 break;
5463 #ifdef LIBXML_XPTR_ENABLED 5465 #ifdef LIBXML_XPTR_ENABLED
5464 case XPATH_LOCATIONSET: 5466 case XPATH_LOCATIONSET:
5465 if (obj->user != NULL) { 5467 if (obj->user != NULL) {
5466 xmlXPtrFreeLocationSet(obj->user); 5468 xmlXPtrFreeLocationSet(obj->user);
5467 } 5469 }
5468 goto free_obj; 5470 goto free_obj;
5469 #endif» 5471 #endif
5470 default: 5472 default:
5471 goto free_obj; 5473 goto free_obj;
5472 } 5474 }
5473 5475
5474 /* 5476 /*
5475 * Fallback to adding to the misc-objects slot. 5477 * Fallback to adding to the misc-objects slot.
5476 */ 5478 */
5477 if (XP_CACHE_WANTS(cache->miscObjs, cache->maxMisc)) { 5479 if (XP_CACHE_WANTS(cache->miscObjs, cache->maxMisc)) {
5478 XP_CACHE_ADD(cache->miscObjs, obj); 5480 XP_CACHE_ADD(cache->miscObjs, obj);
5479 } else 5481 } else
5480 goto free_obj; 5482 goto free_obj;
5481 5483
5482 obj_cached: 5484 obj_cached:
5483 5485
5484 #ifdef XP_DEBUG_OBJ_USAGE 5486 #ifdef XP_DEBUG_OBJ_USAGE
5485 xmlXPathDebugObjUsageReleased(ctxt, obj->type); 5487 xmlXPathDebugObjUsageReleased(ctxt, obj->type);
5486 #endif 5488 #endif
5487 5489
5488 if (obj->nodesetval != NULL) { 5490 if (obj->nodesetval != NULL) {
5489 xmlNodeSetPtr tmpset = obj->nodesetval; 5491 xmlNodeSetPtr tmpset = obj->nodesetval;
5490 » 5492
5491 /* 5493 /*
5492 * TODO: Due to those nasty ns-nodes, we need to traverse 5494 * TODO: Due to those nasty ns-nodes, we need to traverse
5493 * the list and free the ns-nodes. 5495 * the list and free the ns-nodes.
5494 * URGENT TODO: Check if it's actually slowing things down. 5496 * URGENT TODO: Check if it's actually slowing things down.
5495 * Maybe we shouldn't try to preserve the list. 5497 * Maybe we shouldn't try to preserve the list.
5496 */ 5498 */
5497 if (tmpset->nodeNr > 1) { 5499 if (tmpset->nodeNr > 1) {
5498 int i; 5500 int i;
5499 xmlNodePtr node; 5501 xmlNodePtr node;
5500 5502
5501 for (i = 0; i < tmpset->nodeNr; i++) { 5503 for (i = 0; i < tmpset->nodeNr; i++) {
5502 node = tmpset->nodeTab[i]; 5504 node = tmpset->nodeTab[i];
5503 if ((node != NULL) && 5505 if ((node != NULL) &&
5504 (node->type == XML_NAMESPACE_DECL)) 5506 (node->type == XML_NAMESPACE_DECL))
5505 { 5507 {
5506 xmlXPathNodeSetFreeNs((xmlNsPtr) node); 5508 xmlXPathNodeSetFreeNs((xmlNsPtr) node);
5507 } 5509 }
5508 } 5510 }
5509 } else if (tmpset->nodeNr == 1) { 5511 } else if (tmpset->nodeNr == 1) {
5510 if ((tmpset->nodeTab[0] != NULL) && 5512 if ((tmpset->nodeTab[0] != NULL) &&
5511 (tmpset->nodeTab[0]->type == XML_NAMESPACE_DECL)) 5513 (tmpset->nodeTab[0]->type == XML_NAMESPACE_DECL))
5512 xmlXPathNodeSetFreeNs((xmlNsPtr) tmpset->nodeTab[0]); 5514 xmlXPathNodeSetFreeNs((xmlNsPtr) tmpset->nodeTab[0]);
5513 » }» » 5515 » }
5514 tmpset->nodeNr = 0; 5516 tmpset->nodeNr = 0;
5515 memset(obj, 0, sizeof(xmlXPathObject)); 5517 memset(obj, 0, sizeof(xmlXPathObject));
5516 obj->nodesetval = tmpset; 5518 obj->nodesetval = tmpset;
5517 } else 5519 } else
5518 memset(obj, 0, sizeof(xmlXPathObject)); 5520 memset(obj, 0, sizeof(xmlXPathObject));
5519 5521
5520 return; 5522 return;
5521 5523
5522 free_obj: 5524 free_obj:
5523 /* 5525 /*
5524 * Cache is full; free the object. 5526 * Cache is full; free the object.
5525 » */ 5527 » */
5526 if (obj->nodesetval != NULL) 5528 if (obj->nodesetval != NULL)
5527 xmlXPathFreeNodeSet(obj->nodesetval); 5529 xmlXPathFreeNodeSet(obj->nodesetval);
5528 #ifdef XP_DEBUG_OBJ_USAGE 5530 #ifdef XP_DEBUG_OBJ_USAGE
5529 xmlXPathDebugObjUsageReleased(NULL, obj->type); 5531 xmlXPathDebugObjUsageReleased(NULL, obj->type);
5530 #endif 5532 #endif
5531 xmlFree(obj); 5533 xmlFree(obj);
5532 } 5534 }
5533 return; 5535 return;
5534 } 5536 }
5535 5537
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
5626 return(xmlXPathCastNodeToString(ns->nodeTab[0])); 5628 return(xmlXPathCastNodeToString(ns->nodeTab[0]));
5627 } 5629 }
5628 5630
5629 /** 5631 /**
5630 * xmlXPathCastToString: 5632 * xmlXPathCastToString:
5631 * @val: an XPath object 5633 * @val: an XPath object
5632 * 5634 *
5633 * Converts an existing object to its string() equivalent 5635 * Converts an existing object to its string() equivalent
5634 * 5636 *
5635 * Returns the allocated string value of the object, NULL in case of error. 5637 * Returns the allocated string value of the object, NULL in case of error.
5636 * It's up to the caller to free the string memory with xmlFree(). 5638 * It's up to the caller to free the string memory with xmlFree().
5637 */ 5639 */
5638 xmlChar * 5640 xmlChar *
5639 xmlXPathCastToString(xmlXPathObjectPtr val) { 5641 xmlXPathCastToString(xmlXPathObjectPtr val) {
5640 xmlChar *ret = NULL; 5642 xmlChar *ret = NULL;
5641 5643
5642 if (val == NULL) 5644 if (val == NULL)
5643 return(xmlStrdup((const xmlChar *) "")); 5645 return(xmlStrdup((const xmlChar *) ""));
5644 switch (val->type) { 5646 switch (val->type) {
5645 case XPATH_UNDEFINED: 5647 case XPATH_UNDEFINED:
5646 #ifdef DEBUG_EXPR 5648 #ifdef DEBUG_EXPR
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after
6017 ret->contextSize = -1; 6019 ret->contextSize = -1;
6018 ret->proximityPosition = -1; 6020 ret->proximityPosition = -1;
6019 6021
6020 #ifdef XP_DEFAULT_CACHE_ON 6022 #ifdef XP_DEFAULT_CACHE_ON
6021 if (xmlXPathContextSetCache(ret, 1, -1, 0) == -1) { 6023 if (xmlXPathContextSetCache(ret, 1, -1, 0) == -1) {
6022 xmlXPathFreeContext(ret); 6024 xmlXPathFreeContext(ret);
6023 return(NULL); 6025 return(NULL);
6024 } 6026 }
6025 #endif 6027 #endif
6026 6028
6027 xmlXPathRegisterAllFunctions(ret); 6029 xmlXPathRegisterAllFunctions(ret);
6028 6030
6029 return(ret); 6031 return(ret);
6030 } 6032 }
6031 6033
6032 /** 6034 /**
6033 * xmlXPathFreeContext: 6035 * xmlXPathFreeContext:
6034 * @ctxt: the context to free 6036 * @ctxt: the context to free
6035 * 6037 *
6036 * Free up an xmlXPathContext 6038 * Free up an xmlXPathContext
6037 */ 6039 */
(...skipping 10 matching lines...) Expand all
6048 xmlFree(ctxt); 6050 xmlFree(ctxt);
6049 } 6051 }
6050 6052
6051 /************************************************************************ 6053 /************************************************************************
6052 * * 6054 * *
6053 * Routines to handle XPath parser contexts * 6055 * Routines to handle XPath parser contexts *
6054 * * 6056 * *
6055 ************************************************************************/ 6057 ************************************************************************/
6056 6058
6057 #define CHECK_CTXT(ctxt) \ 6059 #define CHECK_CTXT(ctxt) \
6058 if (ctxt == NULL) { » » » » » » \ 6060 if (ctxt == NULL) {»» » » » » \
6059 __xmlRaiseError(NULL, NULL, NULL, \ 6061 __xmlRaiseError(NULL, NULL, NULL, \
6060 NULL, NULL, XML_FROM_XPATH, \ 6062 NULL, NULL, XML_FROM_XPATH, \
6061 XML_ERR_INTERNAL_ERROR, XML_ERR_FATAL, \ 6063 XML_ERR_INTERNAL_ERROR, XML_ERR_FATAL, \
6062 __FILE__, __LINE__, \ 6064 __FILE__, __LINE__, \
6063 NULL, NULL, NULL, 0, 0, \ 6065 NULL, NULL, NULL, 0, 0, \
6064 "NULL context pointer\n"); \ 6066 "NULL context pointer\n"); \
6065 return(NULL); \ 6067 return(NULL); \
6066 } \ 6068 } \
6067 6069
6068 #define CHECK_CTXT_NEG(ctxt) \ 6070 #define CHECK_CTXT_NEG(ctxt) \
6069 if (ctxt == NULL) { » » » » » » \ 6071 if (ctxt == NULL) {»» » » » » \
6070 __xmlRaiseError(NULL, NULL, NULL, \ 6072 __xmlRaiseError(NULL, NULL, NULL, \
6071 NULL, NULL, XML_FROM_XPATH, \ 6073 NULL, NULL, XML_FROM_XPATH, \
6072 XML_ERR_INTERNAL_ERROR, XML_ERR_FATAL, \ 6074 XML_ERR_INTERNAL_ERROR, XML_ERR_FATAL, \
6073 __FILE__, __LINE__, \ 6075 __FILE__, __LINE__, \
6074 NULL, NULL, NULL, 0, 0, \ 6076 NULL, NULL, NULL, 0, 0, \
6075 "NULL context pointer\n"); \ 6077 "NULL context pointer\n"); \
6076 return(-1); \ 6078 return(-1); \
6077 } \ 6079 } \
6078 6080
6079 6081
6080 #define CHECK_CONTEXT(ctxt) \ 6082 #define CHECK_CONTEXT(ctxt) \
6081 if ((ctxt == NULL) || (ctxt->doc == NULL) || \ 6083 if ((ctxt == NULL) || (ctxt->doc == NULL) || \
6082 (ctxt->doc->children == NULL)) { » » » » \ 6084 (ctxt->doc->children == NULL)) {» » » » \
6083 xmlXPatherror(ctxt, __FILE__, __LINE__, XPATH_INVALID_CTXT); \ 6085 xmlXPatherror(ctxt, __FILE__, __LINE__, XPATH_INVALID_CTXT); \
6084 return(NULL); \ 6086 return(NULL); \
6085 } 6087 }
6086 6088
6087 6089
6088 /** 6090 /**
6089 * xmlXPathNewParserContext: 6091 * xmlXPathNewParserContext:
6090 * @str: the XPath expression 6092 * @str: the XPath expression
6091 * @ctxt: the XPath context 6093 * @ctxt: the XPath context
6092 * 6094 *
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
6135 xmlXPathParserContextPtr ret; 6137 xmlXPathParserContextPtr ret;
6136 6138
6137 ret = (xmlXPathParserContextPtr) xmlMalloc(sizeof(xmlXPathParserContext)); 6139 ret = (xmlXPathParserContextPtr) xmlMalloc(sizeof(xmlXPathParserContext));
6138 if (ret == NULL) { 6140 if (ret == NULL) {
6139 xmlXPathErrMemory(ctxt, "creating evaluation context\n"); 6141 xmlXPathErrMemory(ctxt, "creating evaluation context\n");
6140 return(NULL); 6142 return(NULL);
6141 } 6143 }
6142 memset(ret, 0 , (size_t) sizeof(xmlXPathParserContext)); 6144 memset(ret, 0 , (size_t) sizeof(xmlXPathParserContext));
6143 6145
6144 /* Allocate the value stack */ 6146 /* Allocate the value stack */
6145 ret->valueTab = (xmlXPathObjectPtr *) 6147 ret->valueTab = (xmlXPathObjectPtr *)
6146 xmlMalloc(10 * sizeof(xmlXPathObjectPtr)); 6148 xmlMalloc(10 * sizeof(xmlXPathObjectPtr));
6147 if (ret->valueTab == NULL) { 6149 if (ret->valueTab == NULL) {
6148 xmlFree(ret); 6150 xmlFree(ret);
6149 xmlXPathErrMemory(ctxt, "creating evaluation context\n"); 6151 xmlXPathErrMemory(ctxt, "creating evaluation context\n");
6150 return(NULL); 6152 return(NULL);
6151 } 6153 }
6152 ret->valueNr = 0; 6154 ret->valueNr = 0;
6153 ret->valueMax = 10; 6155 ret->valueMax = 10;
6154 ret->value = NULL; 6156 ret->value = NULL;
6155 6157
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
6282 continue; 6284 continue;
6283 } 6285 }
6284 } 6286 }
6285 if (tmp == node) 6287 if (tmp == node)
6286 break; 6288 break;
6287 6289
6288 if (tmp->next != NULL) { 6290 if (tmp->next != NULL) {
6289 tmp = tmp->next; 6291 tmp = tmp->next;
6290 continue; 6292 continue;
6291 } 6293 }
6292 » 6294
6293 do { 6295 do {
6294 tmp = tmp->parent; 6296 tmp = tmp->parent;
6295 if (tmp == NULL) 6297 if (tmp == NULL)
6296 break; 6298 break;
6297 if (tmp == node) { 6299 if (tmp == node) {
6298 tmp = NULL; 6300 tmp = NULL;
6299 break; 6301 break;
6300 } 6302 }
6301 if (tmp->next != NULL) { 6303 if (tmp->next != NULL) {
6302 tmp = tmp->next; 6304 tmp = tmp->next;
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
6441 * @inf: less than (1) or greater than (0) 6443 * @inf: less than (1) or greater than (0)
6442 * @strict: is the comparison strict 6444 * @strict: is the comparison strict
6443 * @arg1: the first node set object 6445 * @arg1: the first node set object
6444 * @arg2: the second node set object 6446 * @arg2: the second node set object
6445 * 6447 *
6446 * Implement the compare operation on nodesets: 6448 * Implement the compare operation on nodesets:
6447 * 6449 *
6448 * If both objects to be compared are node-sets, then the comparison 6450 * If both objects to be compared are node-sets, then the comparison
6449 * will be true if and only if there is a node in the first node-set 6451 * will be true if and only if there is a node in the first node-set
6450 * and a node in the second node-set such that the result of performing 6452 * and a node in the second node-set such that the result of performing
6451 * the comparison on the string-values of the two nodes is true. 6453 * the comparison on the string-values of the two nodes is true.
6452 * .... 6454 * ....
6453 * When neither object to be compared is a node-set and the operator 6455 * When neither object to be compared is a node-set and the operator
6454 * is <=, <, >= or >, then the objects are compared by converting both 6456 * is <=, <, >= or >, then the objects are compared by converting both
6455 * objects to numbers and comparing the numbers according to IEEE 754. 6457 * objects to numbers and comparing the numbers according to IEEE 754.
6456 * .... 6458 * ....
6457 * The number function converts its argument to a number as follows: 6459 * The number function converts its argument to a number as follows:
6458 * - a string that consists of optional whitespace followed by an 6460 * - a string that consists of optional whitespace followed by an
6459 * optional minus sign followed by a Number followed by whitespace 6461 * optional minus sign followed by a Number followed by whitespace
6460 * is converted to the IEEE 754 number that is nearest (according 6462 * is converted to the IEEE 754 number that is nearest (according
6461 * to the IEEE 754 round-to-nearest rule) to the mathematical value 6463 * to the IEEE 754 round-to-nearest rule) to the mathematical value
6462 * represented by the string; any other string is converted to NaN 6464 * represented by the string; any other string is converted to NaN
6463 * 6465 *
6464 * Conclusion all nodes need to be converted first to their string value 6466 * Conclusion all nodes need to be converted first to their string value
6465 * and then the comparison must be done when possible 6467 * and then the comparison must be done when possible
6466 */ 6468 */
6467 static int 6469 static int
6468 xmlXPathCompareNodeSets(int inf, int strict, 6470 xmlXPathCompareNodeSets(int inf, int strict,
6469 xmlXPathObjectPtr arg1, xmlXPathObjectPtr arg2) { 6471 xmlXPathObjectPtr arg1, xmlXPathObjectPtr arg2) {
6470 int i, j, init = 0; 6472 int i, j, init = 0;
6471 double val1; 6473 double val1;
6472 double *values2; 6474 double *values2;
6473 int ret = 0; 6475 int ret = 0;
6474 xmlNodeSetPtr ns1; 6476 xmlNodeSetPtr ns1;
6475 xmlNodeSetPtr ns2; 6477 xmlNodeSetPtr ns2;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
6510 for (i = 0;i < ns1->nodeNr;i++) { 6512 for (i = 0;i < ns1->nodeNr;i++) {
6511 val1 = xmlXPathCastNodeToNumber(ns1->nodeTab[i]); 6513 val1 = xmlXPathCastNodeToNumber(ns1->nodeTab[i]);
6512 if (xmlXPathIsNaN(val1)) 6514 if (xmlXPathIsNaN(val1))
6513 continue; 6515 continue;
6514 for (j = 0;j < ns2->nodeNr;j++) { 6516 for (j = 0;j < ns2->nodeNr;j++) {
6515 if (init == 0) { 6517 if (init == 0) {
6516 values2[j] = xmlXPathCastNodeToNumber(ns2->nodeTab[j]); 6518 values2[j] = xmlXPathCastNodeToNumber(ns2->nodeTab[j]);
6517 } 6519 }
6518 if (xmlXPathIsNaN(values2[j])) 6520 if (xmlXPathIsNaN(values2[j]))
6519 continue; 6521 continue;
6520 » if (inf && strict) 6522 » if (inf && strict)
6521 ret = (val1 < values2[j]); 6523 ret = (val1 < values2[j]);
6522 else if (inf && !strict) 6524 else if (inf && !strict)
6523 ret = (val1 <= values2[j]); 6525 ret = (val1 <= values2[j]);
6524 else if (!inf && strict) 6526 else if (!inf && strict)
6525 ret = (val1 > values2[j]); 6527 ret = (val1 > values2[j]);
6526 else if (!inf && !strict) 6528 else if (!inf && !strict)
6527 ret = (val1 >= values2[j]); 6529 ret = (val1 >= values2[j]);
6528 if (ret) 6530 if (ret)
6529 break; 6531 break;
6530 } 6532 }
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after
6850 #endif 6852 #endif
6851 ret = (arg1->boolval == arg2->boolval); 6853 ret = (arg1->boolval == arg2->boolval);
6852 break; 6854 break;
6853 case XPATH_NUMBER: 6855 case XPATH_NUMBER:
6854 ret = (arg1->boolval == 6856 ret = (arg1->boolval ==
6855 xmlXPathCastNumberToBoolean(arg2->floatval)); 6857 xmlXPathCastNumberToBoolean(arg2->floatval));
6856 break; 6858 break;
6857 case XPATH_STRING: 6859 case XPATH_STRING:
6858 if ((arg2->stringval == NULL) || 6860 if ((arg2->stringval == NULL) ||
6859 (arg2->stringval[0] == 0)) ret = 0; 6861 (arg2->stringval[0] == 0)) ret = 0;
6860 » » else 6862 » » else
6861 ret = 1; 6863 ret = 1;
6862 ret = (arg1->boolval == ret); 6864 ret = (arg1->boolval == ret);
6863 break; 6865 break;
6864 case XPATH_USERS: 6866 case XPATH_USERS:
6865 case XPATH_POINT: 6867 case XPATH_POINT:
6866 case XPATH_RANGE: 6868 case XPATH_RANGE:
6867 case XPATH_LOCATIONSET: 6869 case XPATH_LOCATIONSET:
6868 TODO 6870 TODO
6869 break; 6871 break;
6870 case XPATH_NODESET: 6872 case XPATH_NODESET:
(...skipping 14 matching lines...) Expand all
6885 xmlXPathCastNumberToBoolean(arg1->floatval)); 6887 xmlXPathCastNumberToBoolean(arg1->floatval));
6886 break; 6888 break;
6887 case XPATH_STRING: 6889 case XPATH_STRING:
6888 valuePush(ctxt, arg2); 6890 valuePush(ctxt, arg2);
6889 xmlXPathNumberFunction(ctxt, 1); 6891 xmlXPathNumberFunction(ctxt, 1);
6890 arg2 = valuePop(ctxt); 6892 arg2 = valuePop(ctxt);
6891 /* no break on purpose */ 6893 /* no break on purpose */
6892 case XPATH_NUMBER: 6894 case XPATH_NUMBER:
6893 /* Hand check NaN and Infinity equalities */ 6895 /* Hand check NaN and Infinity equalities */
6894 if (xmlXPathIsNaN(arg1->floatval) || 6896 if (xmlXPathIsNaN(arg1->floatval) ||
6895 » » » xmlXPathIsNaN(arg2->floatval)) { 6897 » » » xmlXPathIsNaN(arg2->floatval)) {
6896 ret = 0; 6898 ret = 0;
6897 } else if (xmlXPathIsInf(arg1->floatval) == 1) { 6899 } else if (xmlXPathIsInf(arg1->floatval) == 1) {
6898 if (xmlXPathIsInf(arg2->floatval) == 1) 6900 if (xmlXPathIsInf(arg2->floatval) == 1)
6899 ret = 1; 6901 ret = 1;
6900 else 6902 else
6901 ret = 0; 6903 ret = 0;
6902 } else if (xmlXPathIsInf(arg1->floatval) == -1) { 6904 } else if (xmlXPathIsInf(arg1->floatval) == -1) {
6903 if (xmlXPathIsInf(arg2->floatval) == -1) 6905 if (xmlXPathIsInf(arg2->floatval) == -1)
6904 ret = 1; 6906 ret = 1;
6905 else 6907 else
(...skipping 27 matching lines...) Expand all
6933 switch (arg2->type) { 6935 switch (arg2->type) {
6934 case XPATH_UNDEFINED: 6936 case XPATH_UNDEFINED:
6935 #ifdef DEBUG_EXPR 6937 #ifdef DEBUG_EXPR
6936 xmlGenericError(xmlGenericErrorContext, 6938 xmlGenericError(xmlGenericErrorContext,
6937 "Equal: undefined\n"); 6939 "Equal: undefined\n");
6938 #endif 6940 #endif
6939 break; 6941 break;
6940 case XPATH_BOOLEAN: 6942 case XPATH_BOOLEAN:
6941 if ((arg1->stringval == NULL) || 6943 if ((arg1->stringval == NULL) ||
6942 (arg1->stringval[0] == 0)) ret = 0; 6944 (arg1->stringval[0] == 0)) ret = 0;
6943 » » else 6945 » » else
6944 ret = 1; 6946 ret = 1;
6945 ret = (arg2->boolval == ret); 6947 ret = (arg2->boolval == ret);
6946 break; 6948 break;
6947 case XPATH_STRING: 6949 case XPATH_STRING:
6948 ret = xmlStrEqual(arg1->stringval, arg2->stringval); 6950 ret = xmlStrEqual(arg1->stringval, arg2->stringval);
6949 break; 6951 break;
6950 case XPATH_NUMBER: 6952 case XPATH_NUMBER:
6951 valuePush(ctxt, arg1); 6953 valuePush(ctxt, arg1);
6952 xmlXPathNumberFunction(ctxt, 1); 6954 xmlXPathNumberFunction(ctxt, 1);
6953 arg1 = valuePop(ctxt); 6955 arg1 = valuePop(ctxt);
6954 /* Hand check NaN and Infinity equalities */ 6956 /* Hand check NaN and Infinity equalities */
6955 if (xmlXPathIsNaN(arg1->floatval) || 6957 if (xmlXPathIsNaN(arg1->floatval) ||
6956 » » » xmlXPathIsNaN(arg2->floatval)) { 6958 » » » xmlXPathIsNaN(arg2->floatval)) {
6957 ret = 0; 6959 ret = 0;
6958 } else if (xmlXPathIsInf(arg1->floatval) == 1) { 6960 } else if (xmlXPathIsInf(arg1->floatval) == 1) {
6959 if (xmlXPathIsInf(arg2->floatval) == 1) 6961 if (xmlXPathIsInf(arg2->floatval) == 1)
6960 ret = 1; 6962 ret = 1;
6961 else 6963 else
6962 ret = 0; 6964 ret = 0;
6963 } else if (xmlXPathIsInf(arg1->floatval) == -1) { 6965 } else if (xmlXPathIsInf(arg1->floatval) == -1) {
6964 if (xmlXPathIsInf(arg2->floatval) == -1) 6966 if (xmlXPathIsInf(arg2->floatval) == -1)
6965 ret = 1; 6967 ret = 1;
6966 else 6968 else
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
7012 * Implement the equal operation on XPath objects content: @arg1 == @arg2 7014 * Implement the equal operation on XPath objects content: @arg1 == @arg2
7013 * 7015 *
7014 * Returns 0 or 1 depending on the results of the test. 7016 * Returns 0 or 1 depending on the results of the test.
7015 */ 7017 */
7016 int 7018 int
7017 xmlXPathEqualValues(xmlXPathParserContextPtr ctxt) { 7019 xmlXPathEqualValues(xmlXPathParserContextPtr ctxt) {
7018 xmlXPathObjectPtr arg1, arg2, argtmp; 7020 xmlXPathObjectPtr arg1, arg2, argtmp;
7019 int ret = 0; 7021 int ret = 0;
7020 7022
7021 if ((ctxt == NULL) || (ctxt->context == NULL)) return(0); 7023 if ((ctxt == NULL) || (ctxt->context == NULL)) return(0);
7022 arg2 = valuePop(ctxt); 7024 arg2 = valuePop(ctxt);
7023 arg1 = valuePop(ctxt); 7025 arg1 = valuePop(ctxt);
7024 if ((arg1 == NULL) || (arg2 == NULL)) { 7026 if ((arg1 == NULL) || (arg2 == NULL)) {
7025 if (arg1 != NULL) 7027 if (arg1 != NULL)
7026 xmlXPathReleaseObject(ctxt->context, arg1); 7028 xmlXPathReleaseObject(ctxt->context, arg1);
7027 else 7029 else
7028 xmlXPathReleaseObject(ctxt->context, arg2); 7030 xmlXPathReleaseObject(ctxt->context, arg2);
7029 XP_ERROR0(XPATH_INVALID_OPERAND); 7031 XP_ERROR0(XPATH_INVALID_OPERAND);
7030 } 7032 }
7031 7033
7032 if (arg1 == arg2) { 7034 if (arg1 == arg2) {
(...skipping 25 matching lines...) Expand all
7058 "Equal: undefined\n"); 7060 "Equal: undefined\n");
7059 #endif 7061 #endif
7060 break; 7062 break;
7061 case XPATH_NODESET: 7063 case XPATH_NODESET:
7062 case XPATH_XSLT_TREE: 7064 case XPATH_XSLT_TREE:
7063 ret = xmlXPathEqualNodeSets(arg1, arg2, 0); 7065 ret = xmlXPathEqualNodeSets(arg1, arg2, 0);
7064 break; 7066 break;
7065 case XPATH_BOOLEAN: 7067 case XPATH_BOOLEAN:
7066 if ((arg1->nodesetval == NULL) || 7068 if ((arg1->nodesetval == NULL) ||
7067 (arg1->nodesetval->nodeNr == 0)) ret = 0; 7069 (arg1->nodesetval->nodeNr == 0)) ret = 0;
7068 » » else 7070 » » else
7069 ret = 1; 7071 ret = 1;
7070 ret = (ret == arg2->boolval); 7072 ret = (ret == arg2->boolval);
7071 break; 7073 break;
7072 case XPATH_NUMBER: 7074 case XPATH_NUMBER:
7073 ret = xmlXPathEqualNodeSetFloat(ctxt, arg1, arg2->floatval, 0); 7075 ret = xmlXPathEqualNodeSetFloat(ctxt, arg1, arg2->floatval, 0);
7074 break; 7076 break;
7075 case XPATH_STRING: 7077 case XPATH_STRING:
7076 ret = xmlXPathEqualNodeSetString(arg1, arg2->stringval, 0); 7078 ret = xmlXPathEqualNodeSetString(arg1, arg2->stringval, 0);
7077 break; 7079 break;
7078 case XPATH_USERS: 7080 case XPATH_USERS:
(...skipping 18 matching lines...) Expand all
7097 * Implement the equal operation on XPath objects content: @arg1 == @arg2 7099 * Implement the equal operation on XPath objects content: @arg1 == @arg2
7098 * 7100 *
7099 * Returns 0 or 1 depending on the results of the test. 7101 * Returns 0 or 1 depending on the results of the test.
7100 */ 7102 */
7101 int 7103 int
7102 xmlXPathNotEqualValues(xmlXPathParserContextPtr ctxt) { 7104 xmlXPathNotEqualValues(xmlXPathParserContextPtr ctxt) {
7103 xmlXPathObjectPtr arg1, arg2, argtmp; 7105 xmlXPathObjectPtr arg1, arg2, argtmp;
7104 int ret = 0; 7106 int ret = 0;
7105 7107
7106 if ((ctxt == NULL) || (ctxt->context == NULL)) return(0); 7108 if ((ctxt == NULL) || (ctxt->context == NULL)) return(0);
7107 arg2 = valuePop(ctxt); 7109 arg2 = valuePop(ctxt);
7108 arg1 = valuePop(ctxt); 7110 arg1 = valuePop(ctxt);
7109 if ((arg1 == NULL) || (arg2 == NULL)) { 7111 if ((arg1 == NULL) || (arg2 == NULL)) {
7110 if (arg1 != NULL) 7112 if (arg1 != NULL)
7111 xmlXPathReleaseObject(ctxt->context, arg1); 7113 xmlXPathReleaseObject(ctxt->context, arg1);
7112 else 7114 else
7113 xmlXPathReleaseObject(ctxt->context, arg2); 7115 xmlXPathReleaseObject(ctxt->context, arg2);
7114 XP_ERROR0(XPATH_INVALID_OPERAND); 7116 XP_ERROR0(XPATH_INVALID_OPERAND);
7115 } 7117 }
7116 7118
7117 if (arg1 == arg2) { 7119 if (arg1 == arg2) {
(...skipping 25 matching lines...) Expand all
7143 "NotEqual: undefined\n"); 7145 "NotEqual: undefined\n");
7144 #endif 7146 #endif
7145 break; 7147 break;
7146 case XPATH_NODESET: 7148 case XPATH_NODESET:
7147 case XPATH_XSLT_TREE: 7149 case XPATH_XSLT_TREE:
7148 ret = xmlXPathEqualNodeSets(arg1, arg2, 1); 7150 ret = xmlXPathEqualNodeSets(arg1, arg2, 1);
7149 break; 7151 break;
7150 case XPATH_BOOLEAN: 7152 case XPATH_BOOLEAN:
7151 if ((arg1->nodesetval == NULL) || 7153 if ((arg1->nodesetval == NULL) ||
7152 (arg1->nodesetval->nodeNr == 0)) ret = 0; 7154 (arg1->nodesetval->nodeNr == 0)) ret = 0;
7153 » » else 7155 » » else
7154 ret = 1; 7156 ret = 1;
7155 ret = (ret != arg2->boolval); 7157 ret = (ret != arg2->boolval);
7156 break; 7158 break;
7157 case XPATH_NUMBER: 7159 case XPATH_NUMBER:
7158 ret = xmlXPathEqualNodeSetFloat(ctxt, arg1, arg2->floatval, 1); 7160 ret = xmlXPathEqualNodeSetFloat(ctxt, arg1, arg2->floatval, 1);
7159 break; 7161 break;
7160 case XPATH_STRING: 7162 case XPATH_STRING:
7161 ret = xmlXPathEqualNodeSetString(arg1, arg2->stringval,1); 7163 ret = xmlXPathEqualNodeSetString(arg1, arg2->stringval,1);
7162 break; 7164 break;
7163 case XPATH_USERS: 7165 case XPATH_USERS:
(...skipping 10 matching lines...) Expand all
7174 7176
7175 return (!xmlXPathEqualValuesCommon(ctxt, arg1, arg2)); 7177 return (!xmlXPathEqualValuesCommon(ctxt, arg1, arg2));
7176 } 7178 }
7177 7179
7178 /** 7180 /**
7179 * xmlXPathCompareValues: 7181 * xmlXPathCompareValues:
7180 * @ctxt: the XPath Parser context 7182 * @ctxt: the XPath Parser context
7181 * @inf: less than (1) or greater than (0) 7183 * @inf: less than (1) or greater than (0)
7182 * @strict: is the comparison strict 7184 * @strict: is the comparison strict
7183 * 7185 *
7184 * Implement the compare operation on XPath objects: 7186 * Implement the compare operation on XPath objects:
7185 * @arg1 < @arg2 (1, 1, ... 7187 * @arg1 < @arg2 (1, 1, ...
7186 * @arg1 <= @arg2 (1, 0, ... 7188 * @arg1 <= @arg2 (1, 0, ...
7187 * @arg1 > @arg2 (0, 1, ... 7189 * @arg1 > @arg2 (0, 1, ...
7188 * @arg1 >= @arg2 (0, 0, ... 7190 * @arg1 >= @arg2 (0, 0, ...
7189 * 7191 *
7190 * When neither object to be compared is a node-set and the operator is 7192 * When neither object to be compared is a node-set and the operator is
7191 * <=, <, >=, >, then the objects are compared by converted both objects 7193 * <=, <, >=, >, then the objects are compared by converted both objects
7192 * to numbers and comparing the numbers according to IEEE 754. The < 7194 * to numbers and comparing the numbers according to IEEE 754. The <
7193 * comparison will be true if and only if the first number is less than the 7195 * comparison will be true if and only if the first number is less than the
7194 * second number. The <= comparison will be true if and only if the first 7196 * second number. The <= comparison will be true if and only if the first
7195 * number is less than or equal to the second number. The > comparison 7197 * number is less than or equal to the second number. The > comparison
7196 * will be true if and only if the first number is greater than the second 7198 * will be true if and only if the first number is greater than the second
7197 * number. The >= comparison will be true if and only if the first number 7199 * number. The >= comparison will be true if and only if the first number
7198 * is greater than or equal to the second number. 7200 * is greater than or equal to the second number.
7199 * 7201 *
7200 * Returns 1 if the comparison succeeded, 0 if it failed 7202 * Returns 1 if the comparison succeeded, 0 if it failed
7201 */ 7203 */
7202 int 7204 int
7203 xmlXPathCompareValues(xmlXPathParserContextPtr ctxt, int inf, int strict) { 7205 xmlXPathCompareValues(xmlXPathParserContextPtr ctxt, int inf, int strict) {
7204 int ret = 0, arg1i = 0, arg2i = 0; 7206 int ret = 0, arg1i = 0, arg2i = 0;
7205 xmlXPathObjectPtr arg1, arg2; 7207 xmlXPathObjectPtr arg1, arg2;
7206 7208
7207 if ((ctxt == NULL) || (ctxt->context == NULL)) return(0); 7209 if ((ctxt == NULL) || (ctxt->context == NULL)) return(0);
7208 arg2 = valuePop(ctxt); 7210 arg2 = valuePop(ctxt);
7209 arg1 = valuePop(ctxt); 7211 arg1 = valuePop(ctxt);
7210 if ((arg1 == NULL) || (arg2 == NULL)) { 7212 if ((arg1 == NULL) || (arg2 == NULL)) {
7211 if (arg1 != NULL) 7213 if (arg1 != NULL)
7212 xmlXPathReleaseObject(ctxt->context, arg1); 7214 xmlXPathReleaseObject(ctxt->context, arg1);
7213 else 7215 else
7214 xmlXPathReleaseObject(ctxt->context, arg2); 7216 xmlXPathReleaseObject(ctxt->context, arg2);
7215 XP_ERROR0(XPATH_INVALID_OPERAND); 7217 XP_ERROR0(XPATH_INVALID_OPERAND);
7216 } 7218 }
7217 7219
7218 if ((arg2->type == XPATH_NODESET) || (arg2->type == XPATH_XSLT_TREE) || 7220 if ((arg2->type == XPATH_NODESET) || (arg2->type == XPATH_XSLT_TREE) ||
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
7439 else if (ctxt->value->floatval < 0) 7441 else if (ctxt->value->floatval < 0)
7440 ctxt->value->floatval = xmlXPathPINF; 7442 ctxt->value->floatval = xmlXPathPINF;
7441 } 7443 }
7442 else if (val == 0) { 7444 else if (val == 0) {
7443 if (ctxt->value->floatval == 0) 7445 if (ctxt->value->floatval == 0)
7444 ctxt->value->floatval = xmlXPathNAN; 7446 ctxt->value->floatval = xmlXPathNAN;
7445 else if (ctxt->value->floatval > 0) 7447 else if (ctxt->value->floatval > 0)
7446 ctxt->value->floatval = xmlXPathPINF; 7448 ctxt->value->floatval = xmlXPathPINF;
7447 else if (ctxt->value->floatval < 0) 7449 else if (ctxt->value->floatval < 0)
7448 ctxt->value->floatval = xmlXPathNINF; 7450 ctxt->value->floatval = xmlXPathNINF;
7449 } else 7451 } else
7450 ctxt->value->floatval /= val; 7452 ctxt->value->floatval /= val;
7451 } 7453 }
7452 7454
7453 /** 7455 /**
7454 * xmlXPathModValues: 7456 * xmlXPathModValues:
7455 * @ctxt: the XPath Parser context 7457 * @ctxt: the XPath Parser context
7456 * 7458 *
7457 * Implement the mod operation on XPath objects: @arg1 / @arg2 7459 * Implement the mod operation on XPath objects: @arg1 / @arg2
7458 * The numeric operators convert their operands to numbers as if 7460 * The numeric operators convert their operands to numbers as if
7459 * by calling the number function. 7461 * by calling the number function.
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
7674 if (contextNode == NULL) 7676 if (contextNode == NULL)
7675 return(NULL); 7677 return(NULL);
7676 switch (contextNode->type) { 7678 switch (contextNode->type) {
7677 case XML_ELEMENT_NODE: 7679 case XML_ELEMENT_NODE:
7678 case XML_XINCLUDE_START: 7680 case XML_XINCLUDE_START:
7679 case XML_DOCUMENT_FRAG_NODE: 7681 case XML_DOCUMENT_FRAG_NODE:
7680 case XML_DOCUMENT_NODE: 7682 case XML_DOCUMENT_NODE:
7681 #ifdef LIBXML_DOCB_ENABLED 7683 #ifdef LIBXML_DOCB_ENABLED
7682 case XML_DOCB_DOCUMENT_NODE: 7684 case XML_DOCB_DOCUMENT_NODE:
7683 #endif 7685 #endif
7684 » case XML_HTML_DOCUMENT_NODE:» » 7686 » case XML_HTML_DOCUMENT_NODE:»
7685 return(contextNode); 7687 return(contextNode);
7686 default: 7688 default:
7687 » » return(NULL);» 7689 » » return(NULL);
7688 } 7690 }
7689 return(NULL); 7691 return(NULL);
7690 } else { 7692 } else {
7691 xmlNodePtr start = cur; 7693 xmlNodePtr start = cur;
7692 7694
7693 while (cur != NULL) { 7695 while (cur != NULL) {
7694 switch (cur->type) { 7696 switch (cur->type) {
7695 case XML_ELEMENT_NODE: 7697 case XML_ELEMENT_NODE:
7696 /* TODO: OK to have XInclude here? */ 7698 /* TODO: OK to have XInclude here? */
7697 case XML_XINCLUDE_START: 7699 case XML_XINCLUDE_START:
7698 » » case XML_DOCUMENT_FRAG_NODE:» » 7700 » » case XML_DOCUMENT_FRAG_NODE:
7699 if (cur != start) 7701 if (cur != start)
7700 return(cur); 7702 return(cur);
7701 if (cur->children != NULL) { 7703 if (cur->children != NULL) {
7702 cur = cur->children; 7704 cur = cur->children;
7703 continue; 7705 continue;
7704 } 7706 }
7705 break; 7707 break;
7706 /* Not sure if we need those here. */ 7708 /* Not sure if we need those here. */
7707 case XML_DOCUMENT_NODE: 7709 case XML_DOCUMENT_NODE:
7708 #ifdef LIBXML_DOCB_ENABLED 7710 #ifdef LIBXML_DOCB_ENABLED
7709 case XML_DOCB_DOCUMENT_NODE: 7711 case XML_DOCB_DOCUMENT_NODE:
7710 #endif 7712 #endif
7711 case XML_HTML_DOCUMENT_NODE: 7713 case XML_HTML_DOCUMENT_NODE:
7712 if (cur != start) 7714 if (cur != start)
7713 return(cur); 7715 return(cur);
7714 return(xmlDocGetRootElement((xmlDocPtr) cur)); 7716 return(xmlDocGetRootElement((xmlDocPtr) cur));
7715 default: 7717 default:
7716 break; 7718 break;
7717 » }» 7719 » }
7718 » 7720
7719 next_sibling: 7721 next_sibling:
7720 if ((cur == NULL) || (cur == contextNode)) 7722 if ((cur == NULL) || (cur == contextNode))
7721 » » return(NULL);» 7723 » » return(NULL);
7722 if (cur->next != NULL) { 7724 if (cur->next != NULL) {
7723 » » cur = cur->next;» » 7725 » » cur = cur->next;
7724 } else { 7726 } else {
7725 cur = cur->parent; 7727 cur = cur->parent;
7726 goto next_sibling; 7728 goto next_sibling;
7727 } 7729 }
7728 } 7730 }
7729 } 7731 }
7730 return(NULL); 7732 return(NULL);
7731 } 7733 }
7732 7734
7733 /** 7735 /**
7734 * xmlXPathNextDescendant: 7736 * xmlXPathNextDescendant:
7735 * @ctxt: the XPath Parser context 7737 * @ctxt: the XPath Parser context
7736 * @cur: the current node in the traversal 7738 * @cur: the current node in the traversal
7737 * 7739 *
7738 * Traversal function for the "descendant" direction 7740 * Traversal function for the "descendant" direction
7739 * the descendant axis contains the descendants of the context node in document 7741 * the descendant axis contains the descendants of the context node in document
7740 * order; a descendant is a child or a child of a child and so on. 7742 * order; a descendant is a child or a child of a child and so on.
7741 * 7743 *
(...skipping 11 matching lines...) Expand all
7753 7755
7754 if (ctxt->context->node == (xmlNodePtr) ctxt->context->doc) 7756 if (ctxt->context->node == (xmlNodePtr) ctxt->context->doc)
7755 return(ctxt->context->doc->children); 7757 return(ctxt->context->doc->children);
7756 return(ctxt->context->node->children); 7758 return(ctxt->context->node->children);
7757 } 7759 }
7758 7760
7759 if (cur->children != NULL) { 7761 if (cur->children != NULL) {
7760 /* 7762 /*
7761 * Do not descend on entities declarations 7763 * Do not descend on entities declarations
7762 */ 7764 */
7763 » if (cur->children->type != XML_ENTITY_DECL) { 7765 » if (cur->children->type != XML_ENTITY_DECL) {
7764 cur = cur->children; 7766 cur = cur->children;
7765 /* 7767 /*
7766 * Skip DTDs 7768 * Skip DTDs
7767 */ 7769 */
7768 if (cur->type != XML_DTD_NODE) 7770 if (cur->type != XML_DTD_NODE)
7769 return(cur); 7771 return(cur);
7770 } 7772 }
7771 } 7773 }
7772 7774
7773 if (cur == ctxt->context->node) return(NULL); 7775 if (cur == ctxt->context->node) return(NULL);
7774 7776
7775 while (cur->next != NULL) { 7777 while (cur->next != NULL) {
7776 cur = cur->next; 7778 cur = cur->next;
7777 if ((cur->type != XML_ENTITY_DECL) && 7779 if ((cur->type != XML_ENTITY_DECL) &&
7778 (cur->type != XML_DTD_NODE)) 7780 (cur->type != XML_DTD_NODE))
7779 return(cur); 7781 return(cur);
7780 } 7782 }
7781 7783
7782 do { 7784 do {
7783 cur = cur->parent; 7785 cur = cur->parent;
7784 if (cur == NULL) break; 7786 if (cur == NULL) break;
7785 if (cur == ctxt->context->node) return(NULL); 7787 if (cur == ctxt->context->node) return(NULL);
7786 if (cur->next != NULL) { 7788 if (cur->next != NULL) {
7787 cur = cur->next; 7789 cur = cur->next;
7788 return(cur); 7790 return(cur);
7789 } 7791 }
7790 } while (cur != NULL); 7792 } while (cur != NULL);
7791 return(cur); 7793 return(cur);
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
7870 case XML_DOCUMENT_NODE: 7872 case XML_DOCUMENT_NODE:
7871 case XML_DOCUMENT_TYPE_NODE: 7873 case XML_DOCUMENT_TYPE_NODE:
7872 case XML_DOCUMENT_FRAG_NODE: 7874 case XML_DOCUMENT_FRAG_NODE:
7873 case XML_HTML_DOCUMENT_NODE: 7875 case XML_HTML_DOCUMENT_NODE:
7874 #ifdef LIBXML_DOCB_ENABLED 7876 #ifdef LIBXML_DOCB_ENABLED
7875 case XML_DOCB_DOCUMENT_NODE: 7877 case XML_DOCB_DOCUMENT_NODE:
7876 #endif 7878 #endif
7877 return(NULL); 7879 return(NULL);
7878 case XML_NAMESPACE_DECL: { 7880 case XML_NAMESPACE_DECL: {
7879 xmlNsPtr ns = (xmlNsPtr) ctxt->context->node; 7881 xmlNsPtr ns = (xmlNsPtr) ctxt->context->node;
7880 » » 7882
7881 if ((ns->next != NULL) && 7883 if ((ns->next != NULL) &&
7882 (ns->next->type != XML_NAMESPACE_DECL)) 7884 (ns->next->type != XML_NAMESPACE_DECL))
7883 return((xmlNodePtr) ns->next); 7885 return((xmlNodePtr) ns->next);
7884 return(NULL); 7886 return(NULL);
7885 } 7887 }
7886 } 7888 }
7887 } 7889 }
7888 return(NULL); 7890 return(NULL);
7889 } 7891 }
7890 7892
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
7943 case XML_DOCUMENT_NODE: 7945 case XML_DOCUMENT_NODE:
7944 case XML_DOCUMENT_TYPE_NODE: 7946 case XML_DOCUMENT_TYPE_NODE:
7945 case XML_DOCUMENT_FRAG_NODE: 7947 case XML_DOCUMENT_FRAG_NODE:
7946 case XML_HTML_DOCUMENT_NODE: 7948 case XML_HTML_DOCUMENT_NODE:
7947 #ifdef LIBXML_DOCB_ENABLED 7949 #ifdef LIBXML_DOCB_ENABLED
7948 case XML_DOCB_DOCUMENT_NODE: 7950 case XML_DOCB_DOCUMENT_NODE:
7949 #endif 7951 #endif
7950 return(NULL); 7952 return(NULL);
7951 case XML_NAMESPACE_DECL: { 7953 case XML_NAMESPACE_DECL: {
7952 xmlNsPtr ns = (xmlNsPtr) ctxt->context->node; 7954 xmlNsPtr ns = (xmlNsPtr) ctxt->context->node;
7953 » » 7955
7954 if ((ns->next != NULL) && 7956 if ((ns->next != NULL) &&
7955 (ns->next->type != XML_NAMESPACE_DECL)) 7957 (ns->next->type != XML_NAMESPACE_DECL))
7956 return((xmlNodePtr) ns->next); 7958 return((xmlNodePtr) ns->next);
7957 /* Bad, how did that namespace end up here ? */ 7959 /* Bad, how did that namespace end up here ? */
7958 return(NULL); 7960 return(NULL);
7959 } 7961 }
7960 } 7962 }
7961 return(NULL); 7963 return(NULL);
7962 } 7964 }
7963 if (cur == ctxt->context->doc->children) 7965 if (cur == ctxt->context->doc->children)
(...skipping 23 matching lines...) Expand all
7987 BAD_CAST "fake node libxslt")))) 7989 BAD_CAST "fake node libxslt"))))
7988 return(NULL); 7990 return(NULL);
7989 return(cur->parent); 7991 return(cur->parent);
7990 case XML_ATTRIBUTE_NODE: { 7992 case XML_ATTRIBUTE_NODE: {
7991 xmlAttrPtr att = (xmlAttrPtr) ctxt->context->node; 7993 xmlAttrPtr att = (xmlAttrPtr) ctxt->context->node;
7992 7994
7993 return(att->parent); 7995 return(att->parent);
7994 } 7996 }
7995 case XML_NAMESPACE_DECL: { 7997 case XML_NAMESPACE_DECL: {
7996 xmlNsPtr ns = (xmlNsPtr) ctxt->context->node; 7998 xmlNsPtr ns = (xmlNsPtr) ctxt->context->node;
7997 » » 7999
7998 if ((ns->next != NULL) && 8000 if ((ns->next != NULL) &&
7999 (ns->next->type != XML_NAMESPACE_DECL)) 8001 (ns->next->type != XML_NAMESPACE_DECL))
8000 return((xmlNodePtr) ns->next); 8002 return((xmlNodePtr) ns->next);
8001 /* Bad, how did that namespace end up here ? */ 8003 /* Bad, how did that namespace end up here ? */
8002 return(NULL); 8004 return(NULL);
8003 } 8005 }
8004 case XML_DOCUMENT_NODE: 8006 case XML_DOCUMENT_NODE:
8005 case XML_DOCUMENT_TYPE_NODE: 8007 case XML_DOCUMENT_TYPE_NODE:
8006 case XML_DOCUMENT_FRAG_NODE: 8008 case XML_DOCUMENT_FRAG_NODE:
8007 case XML_HTML_DOCUMENT_NODE: 8009 case XML_HTML_DOCUMENT_NODE:
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
8184 /** 8186 /**
8185 * xmlXPathNextPrecedingInternal: 8187 * xmlXPathNextPrecedingInternal:
8186 * @ctxt: the XPath Parser context 8188 * @ctxt: the XPath Parser context
8187 * @cur: the current node in the traversal 8189 * @cur: the current node in the traversal
8188 * 8190 *
8189 * Traversal function for the "preceding" direction 8191 * Traversal function for the "preceding" direction
8190 * the preceding axis contains all nodes in the same document as the context 8192 * the preceding axis contains all nodes in the same document as the context
8191 * node that are before the context node in document order, excluding any 8193 * node that are before the context node in document order, excluding any
8192 * ancestors and excluding attribute nodes and namespace nodes; the nodes are 8194 * ancestors and excluding attribute nodes and namespace nodes; the nodes are
8193 * ordered in reverse document order 8195 * ordered in reverse document order
8194 * This is a faster implementation but internal only since it requires a 8196 * This is a faster implementation but internal only since it requires a
8195 * state kept in the parser context: ctxt->ancestor. 8197 * state kept in the parser context: ctxt->ancestor.
8196 * 8198 *
8197 * Returns the next element following that axis 8199 * Returns the next element following that axis
8198 */ 8200 */
8199 static xmlNodePtr 8201 static xmlNodePtr
8200 xmlXPathNextPrecedingInternal(xmlXPathParserContextPtr ctxt, 8202 xmlXPathNextPrecedingInternal(xmlXPathParserContextPtr ctxt,
8201 xmlNodePtr cur) 8203 xmlNodePtr cur)
8202 { 8204 {
8203 if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL); 8205 if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL);
8204 if (cur == NULL) { 8206 if (cur == NULL) {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
8241 * 8243 *
8242 * Returns the next element following that axis 8244 * Returns the next element following that axis
8243 */ 8245 */
8244 xmlNodePtr 8246 xmlNodePtr
8245 xmlXPathNextNamespace(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { 8247 xmlXPathNextNamespace(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
8246 if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL); 8248 if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL);
8247 if (ctxt->context->node->type != XML_ELEMENT_NODE) return(NULL); 8249 if (ctxt->context->node->type != XML_ELEMENT_NODE) return(NULL);
8248 if (ctxt->context->tmpNsList == NULL && cur != (xmlNodePtr) xmlXPathXMLNames pace) { 8250 if (ctxt->context->tmpNsList == NULL && cur != (xmlNodePtr) xmlXPathXMLNames pace) {
8249 if (ctxt->context->tmpNsList != NULL) 8251 if (ctxt->context->tmpNsList != NULL)
8250 xmlFree(ctxt->context->tmpNsList); 8252 xmlFree(ctxt->context->tmpNsList);
8251 » ctxt->context->tmpNsList = 8253 » ctxt->context->tmpNsList =
8252 xmlGetNsList(ctxt->context->doc, ctxt->context->node); 8254 xmlGetNsList(ctxt->context->doc, ctxt->context->node);
8253 ctxt->context->tmpNsNr = 0; 8255 ctxt->context->tmpNsNr = 0;
8254 if (ctxt->context->tmpNsList != NULL) { 8256 if (ctxt->context->tmpNsList != NULL) {
8255 while (ctxt->context->tmpNsList[ctxt->context->tmpNsNr] != NULL) { 8257 while (ctxt->context->tmpNsList[ctxt->context->tmpNsNr] != NULL) {
8256 ctxt->context->tmpNsNr++; 8258 ctxt->context->tmpNsNr++;
8257 } 8259 }
8258 } 8260 }
8259 return((xmlNodePtr) xmlXPathXMLNamespace); 8261 return((xmlNodePtr) xmlXPathXMLNamespace);
8260 } 8262 }
8261 if (ctxt->context->tmpNsNr > 0) { 8263 if (ctxt->context->tmpNsNr > 0) {
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
8389 * @nargs: the number of arguments 8391 * @nargs: the number of arguments
8390 * 8392 *
8391 * Implement the count() XPath function 8393 * Implement the count() XPath function
8392 * number count(node-set) 8394 * number count(node-set)
8393 */ 8395 */
8394 void 8396 void
8395 xmlXPathCountFunction(xmlXPathParserContextPtr ctxt, int nargs) { 8397 xmlXPathCountFunction(xmlXPathParserContextPtr ctxt, int nargs) {
8396 xmlXPathObjectPtr cur; 8398 xmlXPathObjectPtr cur;
8397 8399
8398 CHECK_ARITY(1); 8400 CHECK_ARITY(1);
8399 if ((ctxt->value == NULL) || 8401 if ((ctxt->value == NULL) ||
8400 ((ctxt->value->type != XPATH_NODESET) && 8402 ((ctxt->value->type != XPATH_NODESET) &&
8401 (ctxt->value->type != XPATH_XSLT_TREE))) 8403 (ctxt->value->type != XPATH_XSLT_TREE)))
8402 XP_ERROR(XPATH_INVALID_TYPE); 8404 XP_ERROR(XPATH_INVALID_TYPE);
8403 cur = valuePop(ctxt); 8405 cur = valuePop(ctxt);
8404 8406
8405 if ((cur == NULL) || (cur->nodesetval == NULL)) 8407 if ((cur == NULL) || (cur->nodesetval == NULL))
8406 valuePush(ctxt, xmlXPathCacheNewFloat(ctxt->context, (double) 0)); 8408 valuePush(ctxt, xmlXPathCacheNewFloat(ctxt->context, (double) 0));
8407 else if ((cur->type == XPATH_NODESET) || (cur->type == XPATH_XSLT_TREE)) { 8409 else if ((cur->type == XPATH_NODESET) || (cur->type == XPATH_XSLT_TREE)) {
8408 valuePush(ctxt, xmlXPathCacheNewFloat(ctxt->context, 8410 valuePush(ctxt, xmlXPathCacheNewFloat(ctxt->context,
8409 (double) cur->nodesetval->nodeNr)); 8411 (double) cur->nodesetval->nodeNr));
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
8534 if (tokens != NULL) 8536 if (tokens != NULL)
8535 xmlFree(tokens); 8537 xmlFree(tokens);
8536 } 8538 }
8537 } 8539 }
8538 xmlXPathReleaseObject(ctxt->context, obj); 8540 xmlXPathReleaseObject(ctxt->context, obj);
8539 valuePush(ctxt, xmlXPathCacheWrapNodeSet(ctxt->context, ret)); 8541 valuePush(ctxt, xmlXPathCacheWrapNodeSet(ctxt->context, ret));
8540 return; 8542 return;
8541 } 8543 }
8542 obj = xmlXPathCacheConvertString(ctxt->context, obj); 8544 obj = xmlXPathCacheConvertString(ctxt->context, obj);
8543 ret = xmlXPathGetElementsByIds(ctxt->context->doc, obj->stringval); 8545 ret = xmlXPathGetElementsByIds(ctxt->context->doc, obj->stringval);
8544 valuePush(ctxt, xmlXPathCacheWrapNodeSet(ctxt->context, ret)); 8546 valuePush(ctxt, xmlXPathCacheWrapNodeSet(ctxt->context, ret));
8545 xmlXPathReleaseObject(ctxt->context, obj); 8547 xmlXPathReleaseObject(ctxt->context, obj);
8546 return; 8548 return;
8547 } 8549 }
8548 8550
8549 /** 8551 /**
8550 * xmlXPathLocalNameFunction: 8552 * xmlXPathLocalNameFunction:
8551 * @ctxt: the XPath Parser context 8553 * @ctxt: the XPath Parser context
8552 * @nargs: the number of arguments 8554 * @nargs: the number of arguments
8553 * 8555 *
8554 * Implement the local-name() XPath function 8556 * Implement the local-name() XPath function
(...skipping 10 matching lines...) Expand all
8565 8567
8566 if (ctxt == NULL) return; 8568 if (ctxt == NULL) return;
8567 8569
8568 if (nargs == 0) { 8570 if (nargs == 0) {
8569 valuePush(ctxt, xmlXPathCacheNewNodeSet(ctxt->context, 8571 valuePush(ctxt, xmlXPathCacheNewNodeSet(ctxt->context,
8570 ctxt->context->node)); 8572 ctxt->context->node));
8571 nargs = 1; 8573 nargs = 1;
8572 } 8574 }
8573 8575
8574 CHECK_ARITY(1); 8576 CHECK_ARITY(1);
8575 if ((ctxt->value == NULL) || 8577 if ((ctxt->value == NULL) ||
8576 ((ctxt->value->type != XPATH_NODESET) && 8578 ((ctxt->value->type != XPATH_NODESET) &&
8577 (ctxt->value->type != XPATH_XSLT_TREE))) 8579 (ctxt->value->type != XPATH_XSLT_TREE)))
8578 XP_ERROR(XPATH_INVALID_TYPE); 8580 XP_ERROR(XPATH_INVALID_TYPE);
8579 cur = valuePop(ctxt); 8581 cur = valuePop(ctxt);
8580 8582
8581 if ((cur->nodesetval == NULL) || (cur->nodesetval->nodeNr == 0)) { 8583 if ((cur->nodesetval == NULL) || (cur->nodesetval->nodeNr == 0)) {
8582 valuePush(ctxt, xmlXPathCacheNewCString(ctxt->context, "")); 8584 valuePush(ctxt, xmlXPathCacheNewCString(ctxt->context, ""));
8583 } else { 8585 } else {
8584 int i = 0; /* Should be first in document order !!!!! */ 8586 int i = 0; /* Should be first in document order !!!!! */
8585 switch (cur->nodesetval->nodeTab[i]->type) { 8587 switch (cur->nodesetval->nodeTab[i]->type) {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
8623 xmlXPathObjectPtr cur; 8625 xmlXPathObjectPtr cur;
8624 8626
8625 if (ctxt == NULL) return; 8627 if (ctxt == NULL) return;
8626 8628
8627 if (nargs == 0) { 8629 if (nargs == 0) {
8628 valuePush(ctxt, xmlXPathCacheNewNodeSet(ctxt->context, 8630 valuePush(ctxt, xmlXPathCacheNewNodeSet(ctxt->context,
8629 ctxt->context->node)); 8631 ctxt->context->node));
8630 nargs = 1; 8632 nargs = 1;
8631 } 8633 }
8632 CHECK_ARITY(1); 8634 CHECK_ARITY(1);
8633 if ((ctxt->value == NULL) || 8635 if ((ctxt->value == NULL) ||
8634 ((ctxt->value->type != XPATH_NODESET) && 8636 ((ctxt->value->type != XPATH_NODESET) &&
8635 (ctxt->value->type != XPATH_XSLT_TREE))) 8637 (ctxt->value->type != XPATH_XSLT_TREE)))
8636 XP_ERROR(XPATH_INVALID_TYPE); 8638 XP_ERROR(XPATH_INVALID_TYPE);
8637 cur = valuePop(ctxt); 8639 cur = valuePop(ctxt);
8638 8640
8639 if ((cur->nodesetval == NULL) || (cur->nodesetval->nodeNr == 0)) { 8641 if ((cur->nodesetval == NULL) || (cur->nodesetval->nodeNr == 0)) {
8640 valuePush(ctxt, xmlXPathCacheNewCString(ctxt->context, "")); 8642 valuePush(ctxt, xmlXPathCacheNewCString(ctxt->context, ""));
8641 } else { 8643 } else {
8642 int i = 0; /* Should be first in document order !!!!! */ 8644 int i = 0; /* Should be first in document order !!!!! */
8643 switch (cur->nodesetval->nodeTab[i]->type) { 8645 switch (cur->nodesetval->nodeTab[i]->type) {
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
8707 if (cur->nodesetval->nodeTab[i]->name[0] == ' ') 8709 if (cur->nodesetval->nodeTab[i]->name[0] == ' ')
8708 valuePush(ctxt, 8710 valuePush(ctxt,
8709 xmlXPathCacheNewCString(ctxt->context, "")); 8711 xmlXPathCacheNewCString(ctxt->context, ""));
8710 else if ((cur->nodesetval->nodeTab[i]->ns == NULL) || 8712 else if ((cur->nodesetval->nodeTab[i]->ns == NULL) ||
8711 (cur->nodesetval->nodeTab[i]->ns->prefix == NULL)) { 8713 (cur->nodesetval->nodeTab[i]->ns->prefix == NULL)) {
8712 valuePush(ctxt, 8714 valuePush(ctxt,
8713 xmlXPathCacheNewString(ctxt->context, 8715 xmlXPathCacheNewString(ctxt->context,
8714 cur->nodesetval->nodeTab[i]->name)); 8716 cur->nodesetval->nodeTab[i]->name));
8715 } else { 8717 } else {
8716 xmlChar *fullname; 8718 xmlChar *fullname;
8717 » » 8719
8718 fullname = xmlBuildQName(cur->nodesetval->nodeTab[i]->name, 8720 fullname = xmlBuildQName(cur->nodesetval->nodeTab[i]->name,
8719 cur->nodesetval->nodeTab[i]->ns->prefix, 8721 cur->nodesetval->nodeTab[i]->ns->prefix,
8720 NULL, 0); 8722 NULL, 0);
8721 if (fullname == cur->nodesetval->nodeTab[i]->name) 8723 if (fullname == cur->nodesetval->nodeTab[i]->name)
8722 fullname = xmlStrdup(cur->nodesetval->nodeTab[i]->name); 8724 fullname = xmlStrdup(cur->nodesetval->nodeTab[i]->name);
8723 if (fullname == NULL) { 8725 if (fullname == NULL) {
8724 XP_ERROR(XPATH_MEMORY_ERROR); 8726 XP_ERROR(XPATH_MEMORY_ERROR);
8725 } 8727 }
8726 valuePush(ctxt, xmlXPathCacheWrapString( 8728 valuePush(ctxt, xmlXPathCacheWrapString(
8727 ctxt->context, fullname)); 8729 ctxt->context, fullname));
(...skipping 14 matching lines...) Expand all
8742 * @ctxt: the XPath Parser context 8744 * @ctxt: the XPath Parser context
8743 * @nargs: the number of arguments 8745 * @nargs: the number of arguments
8744 * 8746 *
8745 * Implement the string() XPath function 8747 * Implement the string() XPath function
8746 * string string(object?) 8748 * string string(object?)
8747 * The string function converts an object to a string as follows: 8749 * The string function converts an object to a string as follows:
8748 * - A node-set is converted to a string by returning the value of 8750 * - A node-set is converted to a string by returning the value of
8749 * the node in the node-set that is first in document order. 8751 * the node in the node-set that is first in document order.
8750 * If the node-set is empty, an empty string is returned. 8752 * If the node-set is empty, an empty string is returned.
8751 * - A number is converted to a string as follows 8753 * - A number is converted to a string as follows
8752 * + NaN is converted to the string NaN 8754 * + NaN is converted to the string NaN
8753 * + positive zero is converted to the string 0 8755 * + positive zero is converted to the string 0
8754 * + negative zero is converted to the string 0 8756 * + negative zero is converted to the string 0
8755 * + positive infinity is converted to the string Infinity 8757 * + positive infinity is converted to the string Infinity
8756 * + negative infinity is converted to the string -Infinity 8758 * + negative infinity is converted to the string -Infinity
8757 * + if the number is an integer, the number is represented in 8759 * + if the number is an integer, the number is represented in
8758 * decimal form as a Number with no decimal point and no leading 8760 * decimal form as a Number with no decimal point and no leading
8759 * zeros, preceded by a minus sign (-) if the number is negative 8761 * zeros, preceded by a minus sign (-) if the number is negative
8760 * + otherwise, the number is represented in decimal form as a 8762 * + otherwise, the number is represented in decimal form as a
8761 * Number including a decimal point with at least one digit 8763 * Number including a decimal point with at least one digit
8762 * before the decimal point and at least one digit after the 8764 * before the decimal point and at least one digit after the
8763 * decimal point, preceded by a minus sign (-) if the number 8765 * decimal point, preceded by a minus sign (-) if the number
8764 * is negative; there must be no leading zeros before the decimal 8766 * is negative; there must be no leading zeros before the decimal
8765 * point apart possibly from the one required digit immediately 8767 * point apart possibly from the one required digit immediately
8766 * before the decimal point; beyond the one required digit 8768 * before the decimal point; beyond the one required digit
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
8820 xmlUTF8Strlen(content))); 8822 xmlUTF8Strlen(content)));
8821 xmlFree(content); 8823 xmlFree(content);
8822 } 8824 }
8823 return; 8825 return;
8824 } 8826 }
8825 CHECK_ARITY(1); 8827 CHECK_ARITY(1);
8826 CAST_TO_STRING; 8828 CAST_TO_STRING;
8827 CHECK_TYPE(XPATH_STRING); 8829 CHECK_TYPE(XPATH_STRING);
8828 cur = valuePop(ctxt); 8830 cur = valuePop(ctxt);
8829 valuePush(ctxt, xmlXPathCacheNewFloat(ctxt->context, 8831 valuePush(ctxt, xmlXPathCacheNewFloat(ctxt->context,
8830 » xmlUTF8Strlen(cur->stringval))); 8832 » xmlUTF8Strlen(cur->stringval)));
8831 xmlXPathReleaseObject(ctxt->context, cur); 8833 xmlXPathReleaseObject(ctxt->context, cur);
8832 } 8834 }
8833 8835
8834 /** 8836 /**
8835 * xmlXPathConcatFunction: 8837 * xmlXPathConcatFunction:
8836 * @ctxt: the XPath Parser context 8838 * @ctxt: the XPath Parser context
8837 * @nargs: the number of arguments 8839 * @nargs: the number of arguments
8838 * 8840 *
8839 * Implement the concat() XPath function 8841 * Implement the concat() XPath function
8840 * string concat(string, string, string*) 8842 * string concat(string, string, string*)
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
8959 * specified, it returns the substring starting at the position specified 8961 * specified, it returns the substring starting at the position specified
8960 * in the second argument and continuing to the end of the string. For 8962 * in the second argument and continuing to the end of the string. For
8961 * example, substring("12345",2) returns "2345". More precisely, each 8963 * example, substring("12345",2) returns "2345". More precisely, each
8962 * character in the string (see [3.6 Strings]) is considered to have a 8964 * character in the string (see [3.6 Strings]) is considered to have a
8963 * numeric position: the position of the first character is 1, the position 8965 * numeric position: the position of the first character is 1, the position
8964 * of the second character is 2 and so on. The returned substring contains 8966 * of the second character is 2 and so on. The returned substring contains
8965 * those characters for which the position of the character is greater than 8967 * those characters for which the position of the character is greater than
8966 * or equal to the second argument and, if the third argument is specified, 8968 * or equal to the second argument and, if the third argument is specified,
8967 * less than the sum of the second and third arguments; the comparisons 8969 * less than the sum of the second and third arguments; the comparisons
8968 * and addition used for the above follow the standard IEEE 754 rules. Thus: 8970 * and addition used for the above follow the standard IEEE 754 rules. Thus:
8969 * - substring("12345", 1.5, 2.6) returns "234" 8971 * - substring("12345", 1.5, 2.6) returns "234"
8970 * - substring("12345", 0, 3) returns "12" 8972 * - substring("12345", 0, 3) returns "12"
8971 * - substring("12345", 0 div 0, 3) returns "" 8973 * - substring("12345", 0 div 0, 3) returns ""
8972 * - substring("12345", 1, 0 div 0) returns "" 8974 * - substring("12345", 1, 0 div 0) returns ""
8973 * - substring("12345", -42, 1 div 0) returns "12345" 8975 * - substring("12345", -42, 1 div 0) returns "12345"
8974 * - substring("12345", -1 div 0, 1 div 0) returns "" 8976 * - substring("12345", -1 div 0, 1 div 0) returns ""
8975 */ 8977 */
8976 void 8978 void
8977 xmlXPathSubstringFunction(xmlXPathParserContextPtr ctxt, int nargs) { 8979 xmlXPathSubstringFunction(xmlXPathParserContextPtr ctxt, int nargs) {
8978 xmlXPathObjectPtr str, start, len; 8980 xmlXPathObjectPtr str, start, len;
8979 double le=0, in; 8981 double le=0, in;
8980 int i, l, m; 8982 int i, l, m;
8981 xmlChar *ret; 8983 xmlChar *ret;
8982 8984
8983 if (nargs < 2) { 8985 if (nargs < 2) {
8984 CHECK_ARITY(2); 8986 CHECK_ARITY(2);
(...skipping 20 matching lines...) Expand all
9005 CAST_TO_STRING; 9007 CAST_TO_STRING;
9006 CHECK_TYPE(XPATH_STRING); 9008 CHECK_TYPE(XPATH_STRING);
9007 str = valuePop(ctxt); 9009 str = valuePop(ctxt);
9008 m = xmlUTF8Strlen((const unsigned char *)str->stringval); 9010 m = xmlUTF8Strlen((const unsigned char *)str->stringval);
9009 9011
9010 /* 9012 /*
9011 * If last pos not present, calculate last position 9013 * If last pos not present, calculate last position
9012 */ 9014 */
9013 if (nargs != 3) { 9015 if (nargs != 3) {
9014 le = (double)m; 9016 le = (double)m;
9015 » if (in < 1.0) 9017 » if (in < 1.0)
9016 in = 1.0; 9018 in = 1.0;
9017 } 9019 }
9018 9020
9019 /* Need to check for the special cases where either 9021 /* Need to check for the special cases where either
9020 * the index is NaN, the length is NaN, or both 9022 * the index is NaN, the length is NaN, or both
9021 * arguments are infinity (relying on Inf + -Inf = NaN) 9023 * arguments are infinity (relying on Inf + -Inf = NaN)
9022 */ 9024 */
9023 if (!xmlXPathIsNaN(in + le) && !xmlXPathIsInf(in)) { 9025 if (!xmlXPathIsInf(in) && !xmlXPathIsNaN(in + le)) {
9024 /* 9026 /*
9025 * To meet the requirements of the spec, the arguments 9027 * To meet the requirements of the spec, the arguments
9026 » * must be converted to integer format before 9028 » * must be converted to integer format before
9027 * initial index calculations are done 9029 * initial index calculations are done
9028 * 9030 *
9029 * First we go to integer form, rounding up 9031 * First we go to integer form, rounding up
9030 * and checking for special cases 9032 * and checking for special cases
9031 */ 9033 */
9032 i = (int) in; 9034 i = (int) in;
9033 if (((double)i)+0.5 <= in) i++; 9035 if (((double)i)+0.5 <= in) i++;
9034 9036
9035 if (xmlXPathIsInf(le) == 1) { 9037 if (xmlXPathIsInf(le) == 1) {
9036 l = m; 9038 l = m;
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
9082 * if the first argument string does not contain the second argument 9084 * if the first argument string does not contain the second argument
9083 * string. For example, substring-before("1999/04/01","/") returns 1999. 9085 * string. For example, substring-before("1999/04/01","/") returns 1999.
9084 */ 9086 */
9085 void 9087 void
9086 xmlXPathSubstringBeforeFunction(xmlXPathParserContextPtr ctxt, int nargs) { 9088 xmlXPathSubstringBeforeFunction(xmlXPathParserContextPtr ctxt, int nargs) {
9087 xmlXPathObjectPtr str; 9089 xmlXPathObjectPtr str;
9088 xmlXPathObjectPtr find; 9090 xmlXPathObjectPtr find;
9089 xmlBufferPtr target; 9091 xmlBufferPtr target;
9090 const xmlChar *point; 9092 const xmlChar *point;
9091 int offset; 9093 int offset;
9092 9094
9093 CHECK_ARITY(2); 9095 CHECK_ARITY(2);
9094 CAST_TO_STRING; 9096 CAST_TO_STRING;
9095 find = valuePop(ctxt); 9097 find = valuePop(ctxt);
9096 CAST_TO_STRING; 9098 CAST_TO_STRING;
9097 str = valuePop(ctxt); 9099 str = valuePop(ctxt);
9098 9100
9099 target = xmlBufferCreate(); 9101 target = xmlBufferCreate();
9100 if (target) { 9102 if (target) {
9101 point = xmlStrstr(str->stringval, find->stringval); 9103 point = xmlStrstr(str->stringval, find->stringval);
9102 if (point) { 9104 if (point) {
9103 offset = (int)(point - str->stringval); 9105 offset = (int)(point - str->stringval);
9104 xmlBufferAdd(target, str->stringval, offset); 9106 xmlBufferAdd(target, str->stringval, offset);
9105 } 9107 }
9106 valuePush(ctxt, xmlXPathCacheNewString(ctxt->context, 9108 valuePush(ctxt, xmlXPathCacheNewString(ctxt->context,
9107 xmlBufferContent(target))); 9109 xmlBufferContent(target)));
9108 xmlBufferFree(target); 9110 xmlBufferFree(target);
(...skipping 16 matching lines...) Expand all
9125 * string. For example, substring-after("1999/04/01","/") returns 04/01, 9127 * string. For example, substring-after("1999/04/01","/") returns 04/01,
9126 * and substring-after("1999/04/01","19") returns 99/04/01. 9128 * and substring-after("1999/04/01","19") returns 99/04/01.
9127 */ 9129 */
9128 void 9130 void
9129 xmlXPathSubstringAfterFunction(xmlXPathParserContextPtr ctxt, int nargs) { 9131 xmlXPathSubstringAfterFunction(xmlXPathParserContextPtr ctxt, int nargs) {
9130 xmlXPathObjectPtr str; 9132 xmlXPathObjectPtr str;
9131 xmlXPathObjectPtr find; 9133 xmlXPathObjectPtr find;
9132 xmlBufferPtr target; 9134 xmlBufferPtr target;
9133 const xmlChar *point; 9135 const xmlChar *point;
9134 int offset; 9136 int offset;
9135 9137
9136 CHECK_ARITY(2); 9138 CHECK_ARITY(2);
9137 CAST_TO_STRING; 9139 CAST_TO_STRING;
9138 find = valuePop(ctxt); 9140 find = valuePop(ctxt);
9139 CAST_TO_STRING; 9141 CAST_TO_STRING;
9140 str = valuePop(ctxt); 9142 str = valuePop(ctxt);
9141 9143
9142 target = xmlBufferCreate(); 9144 target = xmlBufferCreate();
9143 if (target) { 9145 if (target) {
9144 point = xmlStrstr(str->stringval, find->stringval); 9146 point = xmlStrstr(str->stringval, find->stringval);
9145 if (point) { 9147 if (point) {
9146 offset = (int)(point - str->stringval) + xmlStrlen(find->stringval); 9148 offset = (int)(point - str->stringval) + xmlStrlen(find->stringval);
9147 xmlBufferAdd(target, &str->stringval[offset], 9149 xmlBufferAdd(target, &str->stringval[offset],
9148 xmlStrlen(str->stringval) - offset); 9150 xmlStrlen(str->stringval) - offset);
9149 } 9151 }
9150 valuePush(ctxt, xmlXPathCacheNewString(ctxt->context, 9152 valuePush(ctxt, xmlXPathCacheNewString(ctxt->context,
9151 » xmlBufferContent(target))); 9153 » xmlBufferContent(target)));
9152 xmlBufferFree(target); 9154 xmlBufferFree(target);
9153 } 9155 }
9154 xmlXPathReleaseObject(ctxt->context, str); 9156 xmlXPathReleaseObject(ctxt->context, str);
9155 xmlXPathReleaseObject(ctxt->context, find); 9157 xmlXPathReleaseObject(ctxt->context, find);
9156 } 9158 }
9157 9159
9158 /** 9160 /**
9159 * xmlXPathNormalizeFunction: 9161 * xmlXPathNormalizeFunction:
9160 * @ctxt: the XPath Parser context 9162 * @ctxt: the XPath Parser context
9161 * @nargs: the number of arguments 9163 * @nargs: the number of arguments
9162 * 9164 *
9163 * Implement the normalize-space() XPath function 9165 * Implement the normalize-space() XPath function
9164 * string normalize-space(string?) 9166 * string normalize-space(string?)
9165 * The normalize-space function returns the argument string with white 9167 * The normalize-space function returns the argument string with white
9166 * space normalized by stripping leading and trailing whitespace 9168 * space normalized by stripping leading and trailing whitespace
9167 * and replacing sequences of whitespace characters by a single 9169 * and replacing sequences of whitespace characters by a single
9168 * space. Whitespace characters are the same allowed by the S production 9170 * space. Whitespace characters are the same allowed by the S production
9169 * in XML. If the argument is omitted, it defaults to the context 9171 * in XML. If the argument is omitted, it defaults to the context
9170 * node converted to a string, in other words the value of the context node. 9172 * node converted to a string, in other words the value of the context node.
9171 */ 9173 */
9172 void 9174 void
9173 xmlXPathNormalizeFunction(xmlXPathParserContextPtr ctxt, int nargs) { 9175 xmlXPathNormalizeFunction(xmlXPathParserContextPtr ctxt, int nargs) {
9174 xmlXPathObjectPtr obj = NULL; 9176 xmlXPathObjectPtr obj = NULL;
9175 xmlChar *source = NULL; 9177 xmlChar *source = NULL;
9176 xmlBufferPtr target; 9178 xmlBufferPtr target;
9177 xmlChar blank; 9179 xmlChar blank;
9178 9180
9179 if (ctxt == NULL) return; 9181 if (ctxt == NULL) return;
9180 if (nargs == 0) { 9182 if (nargs == 0) {
9181 /* Use current context node */ 9183 /* Use current context node */
9182 valuePush(ctxt, 9184 valuePush(ctxt,
9183 xmlXPathCacheWrapString(ctxt->context, 9185 xmlXPathCacheWrapString(ctxt->context,
9184 xmlXPathCastNodeToString(ctxt->context->node))); 9186 xmlXPathCastNodeToString(ctxt->context->node)));
9185 nargs = 1; 9187 nargs = 1;
9186 } 9188 }
9187 9189
9188 CHECK_ARITY(1); 9190 CHECK_ARITY(1);
9189 CAST_TO_STRING; 9191 CAST_TO_STRING;
9190 CHECK_TYPE(XPATH_STRING); 9192 CHECK_TYPE(XPATH_STRING);
9191 obj = valuePop(ctxt); 9193 obj = valuePop(ctxt);
9192 source = obj->stringval; 9194 source = obj->stringval;
9193 9195
9194 target = xmlBufferCreate(); 9196 target = xmlBufferCreate();
9195 if (target && source) { 9197 if (target && source) {
9196 9198
9197 /* Skip leading whitespaces */ 9199 /* Skip leading whitespaces */
9198 while (IS_BLANK_CH(*source)) 9200 while (IS_BLANK_CH(*source))
9199 source++; 9201 source++;
9200 9202
9201 /* Collapse intermediate whitespaces, and skip trailing whitespaces */ 9203 /* Collapse intermediate whitespaces, and skip trailing whitespaces */
9202 blank = 0; 9204 blank = 0;
9203 while (*source) { 9205 while (*source) {
9204 if (IS_BLANK_CH(*source)) { 9206 if (IS_BLANK_CH(*source)) {
9205 blank = 0x20; 9207 blank = 0x20;
9206 } else { 9208 } else {
9207 if (blank) { 9209 if (blank) {
9208 xmlBufferAdd(target, &blank, 1); 9210 xmlBufferAdd(target, &blank, 1);
9209 blank = 0; 9211 blank = 0;
9210 } 9212 }
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
9465 * The sum function returns the sum of the values of the nodes in 9467 * The sum function returns the sum of the values of the nodes in
9466 * the argument node-set. 9468 * the argument node-set.
9467 */ 9469 */
9468 void 9470 void
9469 xmlXPathSumFunction(xmlXPathParserContextPtr ctxt, int nargs) { 9471 xmlXPathSumFunction(xmlXPathParserContextPtr ctxt, int nargs) {
9470 xmlXPathObjectPtr cur; 9472 xmlXPathObjectPtr cur;
9471 int i; 9473 int i;
9472 double res = 0.0; 9474 double res = 0.0;
9473 9475
9474 CHECK_ARITY(1); 9476 CHECK_ARITY(1);
9475 if ((ctxt->value == NULL) || 9477 if ((ctxt->value == NULL) ||
9476 ((ctxt->value->type != XPATH_NODESET) && 9478 ((ctxt->value->type != XPATH_NODESET) &&
9477 (ctxt->value->type != XPATH_XSLT_TREE))) 9479 (ctxt->value->type != XPATH_XSLT_TREE)))
9478 XP_ERROR(XPATH_INVALID_TYPE); 9480 XP_ERROR(XPATH_INVALID_TYPE);
9479 cur = valuePop(ctxt); 9481 cur = valuePop(ctxt);
9480 9482
9481 if ((cur->nodesetval != NULL) && (cur->nodesetval->nodeNr != 0)) { 9483 if ((cur->nodesetval != NULL) && (cur->nodesetval->nodeNr != 0)) {
9482 for (i = 0; i < cur->nodesetval->nodeNr; i++) { 9484 for (i = 0; i < cur->nodesetval->nodeNr; i++) {
9483 res += xmlXPathCastNodeToNumber(cur->nodesetval->nodeTab[i]); 9485 res += xmlXPathCastNodeToNumber(cur->nodesetval->nodeTab[i]);
9484 } 9486 }
9485 } 9487 }
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
9584 if ((xmlXPathIsNaN(ctxt->value->floatval)) || 9586 if ((xmlXPathIsNaN(ctxt->value->floatval)) ||
9585 (xmlXPathIsInf(ctxt->value->floatval) == 1) || 9587 (xmlXPathIsInf(ctxt->value->floatval) == 1) ||
9586 (xmlXPathIsInf(ctxt->value->floatval) == -1) || 9588 (xmlXPathIsInf(ctxt->value->floatval) == -1) ||
9587 (ctxt->value->floatval == 0.0)) 9589 (ctxt->value->floatval == 0.0))
9588 return; 9590 return;
9589 9591
9590 XTRUNC(f, ctxt->value->floatval); 9592 XTRUNC(f, ctxt->value->floatval);
9591 if (ctxt->value->floatval < 0) { 9593 if (ctxt->value->floatval < 0) {
9592 if (ctxt->value->floatval < f - 0.5) 9594 if (ctxt->value->floatval < f - 0.5)
9593 ctxt->value->floatval = f - 1; 9595 ctxt->value->floatval = f - 1;
9594 » else 9596 » else
9595 ctxt->value->floatval = f; 9597 ctxt->value->floatval = f;
9596 if (ctxt->value->floatval == 0) 9598 if (ctxt->value->floatval == 0)
9597 ctxt->value->floatval = xmlXPathNZERO; 9599 ctxt->value->floatval = xmlXPathNZERO;
9598 } else { 9600 } else {
9599 if (ctxt->value->floatval < f + 0.5) 9601 if (ctxt->value->floatval < f + 0.5)
9600 ctxt->value->floatval = f; 9602 ctxt->value->floatval = f;
9601 » else 9603 » else
9602 ctxt->value->floatval = f + 1; 9604 ctxt->value->floatval = f + 1;
9603 } 9605 }
9604 } 9606 }
9605 9607
9606 /************************************************************************ 9608 /************************************************************************
9607 * * 9609 * *
9608 * The Parser * 9610 * The Parser *
9609 * * 9611 * *
9610 ************************************************************************/ 9612 ************************************************************************/
9611 9613
(...skipping 30 matching lines...) Expand all
9642 return(0); 9644 return(0);
9643 cur = ctxt->cur; 9645 cur = ctxt->cur;
9644 9646
9645 /* 9647 /*
9646 * We are supposed to handle UTF8, check it's valid 9648 * We are supposed to handle UTF8, check it's valid
9647 * From rfc2044: encoding of the Unicode values on UTF-8: 9649 * From rfc2044: encoding of the Unicode values on UTF-8:
9648 * 9650 *
9649 * UCS-4 range (hex.) UTF-8 octet sequence (binary) 9651 * UCS-4 range (hex.) UTF-8 octet sequence (binary)
9650 * 0000 0000-0000 007F 0xxxxxxx 9652 * 0000 0000-0000 007F 0xxxxxxx
9651 * 0000 0080-0000 07FF 110xxxxx 10xxxxxx 9653 * 0000 0080-0000 07FF 110xxxxx 10xxxxxx
9652 * 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx 9654 * 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
9653 * 9655 *
9654 * Check for the 0x110000 limit too 9656 * Check for the 0x110000 limit too
9655 */ 9657 */
9656 c = *cur; 9658 c = *cur;
9657 if (c & 0x80) { 9659 if (c & 0x80) {
9658 if ((cur[1] & 0xc0) != 0x80) 9660 if ((cur[1] & 0xc0) != 0x80)
9659 goto encoding_error; 9661 goto encoding_error;
9660 if ((c & 0xe0) == 0xe0) { 9662 if ((c & 0xe0) == 0xe0) {
9661 9663
9662 if ((cur[2] & 0xc0) != 0x80) 9664 if ((cur[2] & 0xc0) != 0x80)
(...skipping 16 matching lines...) Expand all
9679 val |= cur[2] & 0x3f; 9681 val |= cur[2] & 0x3f;
9680 } 9682 }
9681 } else { 9683 } else {
9682 /* 2-byte code */ 9684 /* 2-byte code */
9683 *len = 2; 9685 *len = 2;
9684 val = (cur[0] & 0x1f) << 6; 9686 val = (cur[0] & 0x1f) << 6;
9685 val |= cur[1] & 0x3f; 9687 val |= cur[1] & 0x3f;
9686 } 9688 }
9687 if (!IS_CHAR(val)) { 9689 if (!IS_CHAR(val)) {
9688 XP_ERROR0(XPATH_INVALID_CHAR_ERROR); 9690 XP_ERROR0(XPATH_INVALID_CHAR_ERROR);
9689 » } 9691 » }
9690 return(val); 9692 return(val);
9691 } else { 9693 } else {
9692 /* 1-byte code */ 9694 /* 1-byte code */
9693 *len = 1; 9695 *len = 1;
9694 return((int) *cur); 9696 return((int) *cur);
9695 } 9697 }
9696 encoding_error: 9698 encoding_error:
9697 /* 9699 /*
9698 * If we detect an UTF8 error that probably means that the 9700 * If we detect an UTF8 error that probably means that the
9699 * input encoding didn't get properly advertised in the 9701 * input encoding didn't get properly advertised in the
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
9751 return(ret); 9753 return(ret);
9752 } 9754 }
9753 } 9755 }
9754 return(xmlXPathParseNameComplex(ctxt, 0)); 9756 return(xmlXPathParseNameComplex(ctxt, 0));
9755 } 9757 }
9756 9758
9757 9759
9758 /** 9760 /**
9759 * xmlXPathParseQName: 9761 * xmlXPathParseQName:
9760 * @ctxt: the XPath Parser context 9762 * @ctxt: the XPath Parser context
9761 * @prefix: a xmlChar ** 9763 * @prefix: a xmlChar **
9762 * 9764 *
9763 * parse an XML qualified name 9765 * parse an XML qualified name
9764 * 9766 *
9765 * [NS 5] QName ::= (Prefix ':')? LocalPart 9767 * [NS 5] QName ::= (Prefix ':')? LocalPart
9766 * 9768 *
9767 * [NS 6] Prefix ::= NCName 9769 * [NS 6] Prefix ::= NCName
9768 * 9770 *
9769 * [NS 7] LocalPart ::= NCName 9771 * [NS 7] LocalPart ::= NCName
9770 * 9772 *
9771 * Returns the function returns the local part, and prefix is updated 9773 * Returns the function returns the local part, and prefix is updated
9772 * to get the Prefix if any. 9774 * to get the Prefix if any.
9773 */ 9775 */
9774 9776
9775 static xmlChar * 9777 static xmlChar *
9776 xmlXPathParseQName(xmlXPathParserContextPtr ctxt, xmlChar **prefix) { 9778 xmlXPathParseQName(xmlXPathParserContextPtr ctxt, xmlChar **prefix) {
9777 xmlChar *ret = NULL; 9779 xmlChar *ret = NULL;
9778 9780
9779 *prefix = NULL; 9781 *prefix = NULL;
9780 ret = xmlXPathParseNCName(ctxt); 9782 ret = xmlXPathParseNCName(ctxt);
9781 if (CUR == ':') { 9783 if (ret && CUR == ':') {
9782 *prefix = ret; 9784 *prefix = ret;
9783 NEXT; 9785 NEXT;
9784 ret = xmlXPathParseNCName(ctxt); 9786 ret = xmlXPathParseNCName(ctxt);
9785 } 9787 }
9786 return(ret); 9788 return(ret);
9787 } 9789 }
9788 9790
9789 /** 9791 /**
9790 * xmlXPathParseName: 9792 * xmlXPathParseName:
9791 * @ctxt: the XPath Parser context 9793 * @ctxt: the XPath Parser context
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
9845 (c == '[') || (c == ']') || (c == '@') || /* accelerators */ 9847 (c == '[') || (c == ']') || (c == '@') || /* accelerators */
9846 (c == '*') || /* accelerators */ 9848 (c == '*') || /* accelerators */
9847 (!IS_LETTER(c) && (c != '_') && 9849 (!IS_LETTER(c) && (c != '_') &&
9848 ((qualified) && (c != ':')))) { 9850 ((qualified) && (c != ':')))) {
9849 return(NULL); 9851 return(NULL);
9850 } 9852 }
9851 9853
9852 while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */ 9854 while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */
9853 ((IS_LETTER(c)) || (IS_DIGIT(c)) || 9855 ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
9854 (c == '.') || (c == '-') || 9856 (c == '.') || (c == '-') ||
9855 » (c == '_') || ((qualified) && (c == ':')) || 9857 » (c == '_') || ((qualified) && (c == ':')) ||
9856 (IS_COMBINING(c)) || 9858 (IS_COMBINING(c)) ||
9857 (IS_EXTENDER(c)))) { 9859 (IS_EXTENDER(c)))) {
9858 COPY_BUF(l,buf,len,c); 9860 COPY_BUF(l,buf,len,c);
9859 NEXTL(l); 9861 NEXTL(l);
9860 c = CUR_CHAR(l); 9862 c = CUR_CHAR(l);
9861 if (len >= XML_MAX_NAMELEN) { 9863 if (len >= XML_MAX_NAMELEN) {
9862 /* 9864 /*
9863 * Okay someone managed to make a huge name, so he's ready to pay 9865 * Okay someone managed to make a huge name, so he's ready to pay
9864 * for the processing speed. 9866 * for the processing speed.
9865 */ 9867 */
9866 xmlChar *buffer; 9868 xmlChar *buffer;
9867 int max = len * 2; 9869 int max = len * 2;
9868 » 9870
9869 buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar)); 9871 buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
9870 if (buffer == NULL) { 9872 if (buffer == NULL) {
9871 XP_ERRORNULL(XPATH_MEMORY_ERROR); 9873 XP_ERRORNULL(XPATH_MEMORY_ERROR);
9872 } 9874 }
9873 memcpy(buffer, buf, len); 9875 memcpy(buffer, buf, len);
9874 while ((IS_LETTER(c)) || (IS_DIGIT(c)) || /* test bigname.xml */ 9876 while ((IS_LETTER(c)) || (IS_DIGIT(c)) || /* test bigname.xml */
9875 (c == '.') || (c == '-') || 9877 (c == '.') || (c == '-') ||
9876 » » (c == '_') || ((qualified) && (c == ':')) || 9878 » » (c == '_') || ((qualified) && (c == ':')) ||
9877 (IS_COMBINING(c)) || 9879 (IS_COMBINING(c)) ||
9878 (IS_EXTENDER(c))) { 9880 (IS_EXTENDER(c))) {
9879 if (len + 10 > max) { 9881 if (len + 10 > max) {
9880 max *= 2; 9882 max *= 2;
9881 buffer = (xmlChar *) xmlRealloc(buffer, 9883 buffer = (xmlChar *) xmlRealloc(buffer,
9882 max * sizeof(xmlChar)); 9884 max * sizeof(xmlChar));
9883 if (buffer == NULL) { 9885 if (buffer == NULL) {
9884 XP_ERRORNULL(XPATH_MEMORY_ERROR); 9886 XP_ERRORNULL(XPATH_MEMORY_ERROR);
9885 } 9887 }
9886 } 9888 }
(...skipping 26 matching lines...) Expand all
9913 1000000000000000000.0, 10000000000000000000.0, 100000000000000000000.0 9915 1000000000000000000.0, 10000000000000000000.0, 100000000000000000000.0
9914 }; 9916 };
9915 9917
9916 /** 9918 /**
9917 * xmlXPathStringEvalNumber: 9919 * xmlXPathStringEvalNumber:
9918 * @str: A string to scan 9920 * @str: A string to scan
9919 * 9921 *
9920 * [30a] Float ::= Number ('e' Digits?)? 9922 * [30a] Float ::= Number ('e' Digits?)?
9921 * 9923 *
9922 * [30] Number ::= Digits ('.' Digits?)? 9924 * [30] Number ::= Digits ('.' Digits?)?
9923 * | '.' Digits 9925 * | '.' Digits
9924 * [31] Digits ::= [0-9]+ 9926 * [31] Digits ::= [0-9]+
9925 * 9927 *
9926 * Compile a Number in the string 9928 * Compile a Number in the string
9927 * In complement of the Number expression, this function also handles 9929 * In complement of the Number expression, this function also handles
9928 * negative values : '-' Number. 9930 * negative values : '-' Number.
9929 * 9931 *
9930 * Returns the double value. 9932 * Returns the double value.
9931 */ 9933 */
9932 double 9934 double
9933 xmlXPathStringEvalNumber(const xmlChar *str) { 9935 xmlXPathStringEvalNumber(const xmlChar *str) {
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
10012 if (is_exponent_negative) exponent = -exponent; 10014 if (is_exponent_negative) exponent = -exponent;
10013 ret *= pow(10.0, (double)exponent); 10015 ret *= pow(10.0, (double)exponent);
10014 return(ret); 10016 return(ret);
10015 } 10017 }
10016 10018
10017 /** 10019 /**
10018 * xmlXPathCompNumber: 10020 * xmlXPathCompNumber:
10019 * @ctxt: the XPath Parser context 10021 * @ctxt: the XPath Parser context
10020 * 10022 *
10021 * [30] Number ::= Digits ('.' Digits?)? 10023 * [30] Number ::= Digits ('.' Digits?)?
10022 * | '.' Digits 10024 * | '.' Digits
10023 * [31] Digits ::= [0-9]+ 10025 * [31] Digits ::= [0-9]+
10024 * 10026 *
10025 * Compile a Number, then push it on the stack 10027 * Compile a Number, then push it on the stack
10026 * 10028 *
10027 */ 10029 */
10028 static void 10030 static void
10029 xmlXPathCompNumber(xmlXPathParserContextPtr ctxt) 10031 xmlXPathCompNumber(xmlXPathParserContextPtr ctxt)
10030 { 10032 {
10031 double ret = 0.0; 10033 double ret = 0.0;
10032 double mult = 1; 10034 double mult = 1;
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
10192 * 10194 *
10193 * Parse a VariableReference, evaluate it and push it on the stack. 10195 * Parse a VariableReference, evaluate it and push it on the stack.
10194 * 10196 *
10195 * The variable bindings consist of a mapping from variable names 10197 * The variable bindings consist of a mapping from variable names
10196 * to variable values. The value of a variable is an object, which can be 10198 * to variable values. The value of a variable is an object, which can be
10197 * of any of the types that are possible for the value of an expression, 10199 * of any of the types that are possible for the value of an expression,
10198 * and may also be of additional types not specified here. 10200 * and may also be of additional types not specified here.
10199 * 10201 *
10200 * Early evaluation is possible since: 10202 * Early evaluation is possible since:
10201 * The variable bindings [...] used to evaluate a subexpression are 10203 * The variable bindings [...] used to evaluate a subexpression are
10202 * always the same as those used to evaluate the containing expression. 10204 * always the same as those used to evaluate the containing expression.
10203 * 10205 *
10204 * [36] VariableReference ::= '$' QName 10206 * [36] VariableReference ::= '$' QName
10205 */ 10207 */
10206 static void 10208 static void
10207 xmlXPathCompVariableReference(xmlXPathParserContextPtr ctxt) { 10209 xmlXPathCompVariableReference(xmlXPathParserContextPtr ctxt) {
10208 xmlChar *name; 10210 xmlChar *name;
10209 xmlChar *prefix; 10211 xmlChar *prefix;
10210 10212
10211 SKIP_BLANKS; 10213 SKIP_BLANKS;
10212 if (CUR != '$') { 10214 if (CUR != '$') {
10213 XP_ERROR(XPATH_VARIABLE_REF_ERROR); 10215 XP_ERROR(XPATH_VARIABLE_REF_ERROR);
10214 } 10216 }
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
10253 if (xmlStrEqual(name, BAD_CAST "processing-instruction")) 10255 if (xmlStrEqual(name, BAD_CAST "processing-instruction"))
10254 return(1); 10256 return(1);
10255 return(0); 10257 return(0);
10256 } 10258 }
10257 10259
10258 /** 10260 /**
10259 * xmlXPathCompFunctionCall: 10261 * xmlXPathCompFunctionCall:
10260 * @ctxt: the XPath Parser context 10262 * @ctxt: the XPath Parser context
10261 * 10263 *
10262 * [16] FunctionCall ::= FunctionName '(' ( Argument ( ',' Argument)*)? ')' 10264 * [16] FunctionCall ::= FunctionName '(' ( Argument ( ',' Argument)*)? ')'
10263 * [17] Argument ::= Expr 10265 * [17] Argument ::= Expr
10264 * 10266 *
10265 * Compile a function call, the evaluation of all arguments are 10267 * Compile a function call, the evaluation of all arguments are
10266 * pushed on the stack 10268 * pushed on the stack
10267 */ 10269 */
10268 static void 10270 static void
10269 xmlXPathCompFunctionCall(xmlXPathParserContextPtr ctxt) { 10271 xmlXPathCompFunctionCall(xmlXPathParserContextPtr ctxt) {
10270 xmlChar *name; 10272 xmlChar *name;
10271 xmlChar *prefix; 10273 xmlChar *prefix;
10272 int nbargs = 0; 10274 int nbargs = 0;
10273 int sort = 1; 10275 int sort = 1;
10274 10276
10275 name = xmlXPathParseQName(ctxt, &prefix); 10277 name = xmlXPathParseQName(ctxt, &prefix);
10276 if (name == NULL) { 10278 if (name == NULL) {
10279 xmlFree(prefix);
10277 XP_ERROR(XPATH_EXPR_ERROR); 10280 XP_ERROR(XPATH_EXPR_ERROR);
10278 } 10281 }
10279 SKIP_BLANKS; 10282 SKIP_BLANKS;
10280 #ifdef DEBUG_EXPR 10283 #ifdef DEBUG_EXPR
10281 if (prefix == NULL) 10284 if (prefix == NULL)
10282 xmlGenericError(xmlGenericErrorContext, "Calling function %s\n", 10285 xmlGenericError(xmlGenericErrorContext, "Calling function %s\n",
10283 name); 10286 name);
10284 else 10287 else
10285 xmlGenericError(xmlGenericErrorContext, "Calling function %s:%s\n", 10288 xmlGenericError(xmlGenericErrorContext, "Calling function %s:%s\n",
10286 prefix, name); 10289 prefix, name);
(...skipping 12 matching lines...) Expand all
10299 xmlStrEqual(name, BAD_CAST "count")) 10302 xmlStrEqual(name, BAD_CAST "count"))
10300 { 10303 {
10301 sort = 0; 10304 sort = 0;
10302 } 10305 }
10303 ctxt->comp->last = -1; 10306 ctxt->comp->last = -1;
10304 if (CUR != ')') { 10307 if (CUR != ')') {
10305 while (CUR != 0) { 10308 while (CUR != 0) {
10306 int op1 = ctxt->comp->last; 10309 int op1 = ctxt->comp->last;
10307 ctxt->comp->last = -1; 10310 ctxt->comp->last = -1;
10308 xmlXPathCompileExpr(ctxt, sort); 10311 xmlXPathCompileExpr(ctxt, sort);
10309 » CHECK_ERROR; 10312 » if (ctxt->error != XPATH_EXPRESSION_OK) {
10313 » » xmlFree(name);
10314 » » xmlFree(prefix);
10315 » » return;
10316 » }
10310 PUSH_BINARY_EXPR(XPATH_OP_ARG, op1, ctxt->comp->last, 0, 0); 10317 PUSH_BINARY_EXPR(XPATH_OP_ARG, op1, ctxt->comp->last, 0, 0);
10311 nbargs++; 10318 nbargs++;
10312 if (CUR == ')') break; 10319 if (CUR == ')') break;
10313 if (CUR != ',') { 10320 if (CUR != ',') {
10314 XP_ERROR(XPATH_EXPR_ERROR); 10321 XP_ERROR(XPATH_EXPR_ERROR);
10315 } 10322 }
10316 NEXT; 10323 NEXT;
10317 SKIP_BLANKS; 10324 SKIP_BLANKS;
10318 } 10325 }
10319 } 10326 }
10320 PUSH_LONG_EXPR(XPATH_OP_FUNCTION, nbargs, 0, 0, 10327 PUSH_LONG_EXPR(XPATH_OP_FUNCTION, nbargs, 0, 0,
10321 name, prefix); 10328 name, prefix);
10322 NEXT; 10329 NEXT;
10323 SKIP_BLANKS; 10330 SKIP_BLANKS;
10324 } 10331 }
10325 10332
10326 /** 10333 /**
10327 * xmlXPathCompPrimaryExpr: 10334 * xmlXPathCompPrimaryExpr:
10328 * @ctxt: the XPath Parser context 10335 * @ctxt: the XPath Parser context
10329 * 10336 *
10330 * [15] PrimaryExpr ::= VariableReference 10337 * [15] PrimaryExpr ::= VariableReference
10331 * | '(' Expr ')' 10338 * | '(' Expr ')'
10332 * | Literal 10339 * | Literal
10333 * | Number 10340 * | Number
10334 * | FunctionCall 10341 * | FunctionCall
10335 * 10342 *
10336 * Compile a primary expression. 10343 * Compile a primary expression.
10337 */ 10344 */
10338 static void 10345 static void
10339 xmlXPathCompPrimaryExpr(xmlXPathParserContextPtr ctxt) { 10346 xmlXPathCompPrimaryExpr(xmlXPathParserContextPtr ctxt) {
10340 SKIP_BLANKS; 10347 SKIP_BLANKS;
10341 if (CUR == '$') xmlXPathCompVariableReference(ctxt); 10348 if (CUR == '$') xmlXPathCompVariableReference(ctxt);
10342 else if (CUR == '(') { 10349 else if (CUR == '(') {
10343 NEXT; 10350 NEXT;
10344 SKIP_BLANKS; 10351 SKIP_BLANKS;
(...skipping 11 matching lines...) Expand all
10356 } else { 10363 } else {
10357 xmlXPathCompFunctionCall(ctxt); 10364 xmlXPathCompFunctionCall(ctxt);
10358 } 10365 }
10359 SKIP_BLANKS; 10366 SKIP_BLANKS;
10360 } 10367 }
10361 10368
10362 /** 10369 /**
10363 * xmlXPathCompFilterExpr: 10370 * xmlXPathCompFilterExpr:
10364 * @ctxt: the XPath Parser context 10371 * @ctxt: the XPath Parser context
10365 * 10372 *
10366 * [20] FilterExpr ::= PrimaryExpr 10373 * [20] FilterExpr ::= PrimaryExpr
10367 * | FilterExpr Predicate 10374 * | FilterExpr Predicate
10368 * 10375 *
10369 * Compile a filter expression. 10376 * Compile a filter expression.
10370 * Square brackets are used to filter expressions in the same way that 10377 * Square brackets are used to filter expressions in the same way that
10371 * they are used in location paths. It is an error if the expression to 10378 * they are used in location paths. It is an error if the expression to
10372 * be filtered does not evaluate to a node-set. The context node list 10379 * be filtered does not evaluate to a node-set. The context node list
10373 * used for evaluating the expression in square brackets is the node-set 10380 * used for evaluating the expression in square brackets is the node-set
10374 * to be filtered listed in document order. 10381 * to be filtered listed in document order.
10375 */ 10382 */
10376 10383
10377 static void 10384 static void
10378 xmlXPathCompFilterExpr(xmlXPathParserContextPtr ctxt) { 10385 xmlXPathCompFilterExpr(xmlXPathParserContextPtr ctxt) {
10379 xmlXPathCompPrimaryExpr(ctxt); 10386 xmlXPathCompPrimaryExpr(ctxt);
10380 CHECK_ERROR; 10387 CHECK_ERROR;
10381 SKIP_BLANKS; 10388 SKIP_BLANKS;
10382 10389
10383 while (CUR == '[') { 10390 while (CUR == '[') {
10384 xmlXPathCompPredicate(ctxt, 1); 10391 xmlXPathCompPredicate(ctxt, 1);
10385 SKIP_BLANKS; 10392 SKIP_BLANKS;
10386 } 10393 }
10387 10394
10388 10395
10389 } 10396 }
10390 10397
10391 /** 10398 /**
10392 * xmlXPathScanName: 10399 * xmlXPathScanName:
10393 * @ctxt: the XPath Parser context 10400 * @ctxt: the XPath Parser context
10394 * 10401 *
10395 * Trickery: parse an XML name but without consuming the input flow 10402 * Trickery: parse an XML name but without consuming the input flow
10396 * Needed to avoid insanity in the parser state. 10403 * Needed to avoid insanity in the parser state.
10397 * 10404 *
10398 * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' | 10405 * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
(...skipping 18 matching lines...) Expand all
10417 c = CUR_CHAR(l); 10424 c = CUR_CHAR(l);
10418 if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */ 10425 if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
10419 (!IS_LETTER(c) && (c != '_') && 10426 (!IS_LETTER(c) && (c != '_') &&
10420 (c != ':'))) { 10427 (c != ':'))) {
10421 return(NULL); 10428 return(NULL);
10422 } 10429 }
10423 10430
10424 while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */ 10431 while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */
10425 ((IS_LETTER(c)) || (IS_DIGIT(c)) || 10432 ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
10426 (c == '.') || (c == '-') || 10433 (c == '.') || (c == '-') ||
10427 » (c == '_') || (c == ':') || 10434 » (c == '_') || (c == ':') ||
10428 (IS_COMBINING(c)) || 10435 (IS_COMBINING(c)) ||
10429 (IS_EXTENDER(c)))) { 10436 (IS_EXTENDER(c)))) {
10430 len += l; 10437 len += l;
10431 NEXTL(l); 10438 NEXTL(l);
10432 c = CUR_CHAR(l); 10439 c = CUR_CHAR(l);
10433 } 10440 }
10434 ret = xmlStrndup(cur, ctxt->cur - cur); 10441 ret = xmlStrndup(cur, ctxt->cur - cur);
10435 ctxt->cur = cur; 10442 ctxt->cur = cur;
10436 return(ret); 10443 return(ret);
10437 } 10444 }
10438 10445
10439 /** 10446 /**
10440 * xmlXPathCompPathExpr: 10447 * xmlXPathCompPathExpr:
10441 * @ctxt: the XPath Parser context 10448 * @ctxt: the XPath Parser context
10442 * 10449 *
10443 * [19] PathExpr ::= LocationPath 10450 * [19] PathExpr ::= LocationPath
10444 * | FilterExpr 10451 * | FilterExpr
10445 * | FilterExpr '/' RelativeLocationPath 10452 * | FilterExpr '/' RelativeLocationPath
10446 * | FilterExpr '//' RelativeLocationPath 10453 * | FilterExpr '//' RelativeLocationPath
10447 * 10454 *
10448 * Compile a path expression. 10455 * Compile a path expression.
10449 * The / operator and // operators combine an arbitrary expression 10456 * The / operator and // operators combine an arbitrary expression
10450 * and a relative location path. It is an error if the expression 10457 * and a relative location path. It is an error if the expression
10451 * does not evaluate to a node-set. 10458 * does not evaluate to a node-set.
10452 * The / operator does composition in the same way as when / is 10459 * The / operator does composition in the same way as when / is
10453 * used in a location path. As in location paths, // is short for 10460 * used in a location path. As in location paths, // is short for
10454 * /descendant-or-self::node()/. 10461 * /descendant-or-self::node()/.
10455 */ 10462 */
10456 10463
10457 static void 10464 static void
10458 xmlXPathCompPathExpr(xmlXPathParserContextPtr ctxt) { 10465 xmlXPathCompPathExpr(xmlXPathParserContextPtr ctxt) {
10459 int lc = 1; /* Should we branch to LocationPath ? */ 10466 int lc = 1; /* Should we branch to LocationPath ? */
10460 xmlChar *name = NULL; /* we may have to preparse a name to find out */ 10467 xmlChar *name = NULL; /* we may have to preparse a name to find out */
10461 10468
10462 SKIP_BLANKS; 10469 SKIP_BLANKS;
10463 if ((CUR == '$') || (CUR == '(') || 10470 if ((CUR == '$') || (CUR == '(') ||
10464 » (IS_ASCII_DIGIT(CUR)) || 10471 » (IS_ASCII_DIGIT(CUR)) ||
10465 (CUR == '\'') || (CUR == '"') || 10472 (CUR == '\'') || (CUR == '"') ||
10466 (CUR == '.' && IS_ASCII_DIGIT(NXT(1)))) { 10473 (CUR == '.' && IS_ASCII_DIGIT(NXT(1)))) {
10467 lc = 0; 10474 lc = 0;
10468 } else if (CUR == '*') { 10475 } else if (CUR == '*') {
10469 /* relative or absolute location path */ 10476 /* relative or absolute location path */
10470 lc = 1; 10477 lc = 1;
10471 } else if (CUR == '/') { 10478 } else if (CUR == '/') {
10472 /* relative or absolute location path */ 10479 /* relative or absolute location path */
10473 lc = 1; 10480 lc = 1;
10474 } else if (CUR == '@') { 10481 } else if (CUR == '@') {
(...skipping 19 matching lines...) Expand all
10494 if ((name != NULL) && (xmlStrstr(name, (xmlChar *) "::") != NULL)) { 10501 if ((name != NULL) && (xmlStrstr(name, (xmlChar *) "::") != NULL)) {
10495 #ifdef DEBUG_STEP 10502 #ifdef DEBUG_STEP
10496 xmlGenericError(xmlGenericErrorContext, 10503 xmlGenericError(xmlGenericErrorContext,
10497 "PathExpr: Axis\n"); 10504 "PathExpr: Axis\n");
10498 #endif 10505 #endif
10499 lc = 1; 10506 lc = 1;
10500 xmlFree(name); 10507 xmlFree(name);
10501 } else if (name != NULL) { 10508 } else if (name != NULL) {
10502 int len =xmlStrlen(name); 10509 int len =xmlStrlen(name);
10503 10510
10504 » 10511
10505 while (NXT(len) != 0) { 10512 while (NXT(len) != 0) {
10506 if (NXT(len) == '/') { 10513 if (NXT(len) == '/') {
10507 /* element name */ 10514 /* element name */
10508 #ifdef DEBUG_STEP 10515 #ifdef DEBUG_STEP
10509 xmlGenericError(xmlGenericErrorContext, 10516 xmlGenericError(xmlGenericErrorContext,
10510 "PathExpr: AbbrRelLocation\n"); 10517 "PathExpr: AbbrRelLocation\n");
10511 #endif 10518 #endif
10512 lc = 1; 10519 lc = 1;
10513 break; 10520 break;
10514 } else if (IS_BLANK_CH(NXT(len))) { 10521 } else if (IS_BLANK_CH(NXT(len))) {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
10561 "PathExpr: AbbrRelLocation\n"); 10568 "PathExpr: AbbrRelLocation\n");
10562 #endif 10569 #endif
10563 /* element name */ 10570 /* element name */
10564 lc = 1; 10571 lc = 1;
10565 } 10572 }
10566 xmlFree(name); 10573 xmlFree(name);
10567 } else { 10574 } else {
10568 /* make sure all cases are covered explicitly */ 10575 /* make sure all cases are covered explicitly */
10569 XP_ERROR(XPATH_EXPR_ERROR); 10576 XP_ERROR(XPATH_EXPR_ERROR);
10570 } 10577 }
10571 } 10578 }
10572 10579
10573 if (lc) { 10580 if (lc) {
10574 if (CUR == '/') { 10581 if (CUR == '/') {
10575 PUSH_LEAVE_EXPR(XPATH_OP_ROOT, 0, 0); 10582 PUSH_LEAVE_EXPR(XPATH_OP_ROOT, 0, 0);
10576 } else { 10583 } else {
10577 PUSH_LEAVE_EXPR(XPATH_OP_NODE, 0, 0); 10584 PUSH_LEAVE_EXPR(XPATH_OP_NODE, 0, 0);
10578 } 10585 }
10579 xmlXPathCompLocationPath(ctxt); 10586 xmlXPathCompLocationPath(ctxt);
10580 } else { 10587 } else {
10581 xmlXPathCompFilterExpr(ctxt); 10588 xmlXPathCompFilterExpr(ctxt);
(...skipping 11 matching lines...) Expand all
10593 xmlXPathCompRelativeLocationPath(ctxt); 10600 xmlXPathCompRelativeLocationPath(ctxt);
10594 } 10601 }
10595 } 10602 }
10596 SKIP_BLANKS; 10603 SKIP_BLANKS;
10597 } 10604 }
10598 10605
10599 /** 10606 /**
10600 * xmlXPathCompUnionExpr: 10607 * xmlXPathCompUnionExpr:
10601 * @ctxt: the XPath Parser context 10608 * @ctxt: the XPath Parser context
10602 * 10609 *
10603 * [18] UnionExpr ::= PathExpr 10610 * [18] UnionExpr ::= PathExpr
10604 * | UnionExpr '|' PathExpr 10611 * | UnionExpr '|' PathExpr
10605 * 10612 *
10606 * Compile an union expression. 10613 * Compile an union expression.
10607 */ 10614 */
10608 10615
10609 static void 10616 static void
10610 xmlXPathCompUnionExpr(xmlXPathParserContextPtr ctxt) { 10617 xmlXPathCompUnionExpr(xmlXPathParserContextPtr ctxt) {
10611 xmlXPathCompPathExpr(ctxt); 10618 xmlXPathCompPathExpr(ctxt);
10612 CHECK_ERROR; 10619 CHECK_ERROR;
10613 SKIP_BLANKS; 10620 SKIP_BLANKS;
10614 while (CUR == '|') { 10621 while (CUR == '|') {
10615 int op1 = ctxt->comp->last; 10622 int op1 = ctxt->comp->last;
10616 PUSH_LEAVE_EXPR(XPATH_OP_NODE, 0, 0); 10623 PUSH_LEAVE_EXPR(XPATH_OP_NODE, 0, 0);
10617 10624
10618 NEXT; 10625 NEXT;
10619 SKIP_BLANKS; 10626 SKIP_BLANKS;
10620 xmlXPathCompPathExpr(ctxt); 10627 xmlXPathCompPathExpr(ctxt);
10621 10628
10622 PUSH_BINARY_EXPR(XPATH_OP_UNION, op1, ctxt->comp->last, 0, 0); 10629 PUSH_BINARY_EXPR(XPATH_OP_UNION, op1, ctxt->comp->last, 0, 0);
10623 10630
10624 SKIP_BLANKS; 10631 SKIP_BLANKS;
10625 } 10632 }
10626 } 10633 }
10627 10634
10628 /** 10635 /**
10629 * xmlXPathCompUnaryExpr: 10636 * xmlXPathCompUnaryExpr:
10630 * @ctxt: the XPath Parser context 10637 * @ctxt: the XPath Parser context
10631 * 10638 *
10632 * [27] UnaryExpr ::= UnionExpr 10639 * [27] UnaryExpr ::= UnionExpr
10633 * | '-' UnaryExpr 10640 * | '-' UnaryExpr
10634 * 10641 *
10635 * Compile an unary expression. 10642 * Compile an unary expression.
10636 */ 10643 */
10637 10644
10638 static void 10645 static void
10639 xmlXPathCompUnaryExpr(xmlXPathParserContextPtr ctxt) { 10646 xmlXPathCompUnaryExpr(xmlXPathParserContextPtr ctxt) {
10640 int minus = 0; 10647 int minus = 0;
10641 int found = 0; 10648 int found = 0;
10642 10649
10643 SKIP_BLANKS; 10650 SKIP_BLANKS;
(...skipping 11 matching lines...) Expand all
10655 PUSH_UNARY_EXPR(XPATH_OP_PLUS, ctxt->comp->last, 2, 0); 10662 PUSH_UNARY_EXPR(XPATH_OP_PLUS, ctxt->comp->last, 2, 0);
10656 else 10663 else
10657 PUSH_UNARY_EXPR(XPATH_OP_PLUS, ctxt->comp->last, 3, 0); 10664 PUSH_UNARY_EXPR(XPATH_OP_PLUS, ctxt->comp->last, 3, 0);
10658 } 10665 }
10659 } 10666 }
10660 10667
10661 /** 10668 /**
10662 * xmlXPathCompMultiplicativeExpr: 10669 * xmlXPathCompMultiplicativeExpr:
10663 * @ctxt: the XPath Parser context 10670 * @ctxt: the XPath Parser context
10664 * 10671 *
10665 * [26] MultiplicativeExpr ::= UnaryExpr 10672 * [26] MultiplicativeExpr ::= UnaryExpr
10666 * | MultiplicativeExpr MultiplyOperator UnaryExpr 10673 * | MultiplicativeExpr MultiplyOperator UnaryExpr
10667 * | MultiplicativeExpr 'div' UnaryExpr 10674 * | MultiplicativeExpr 'div' UnaryExpr
10668 * | MultiplicativeExpr 'mod' UnaryExpr 10675 * | MultiplicativeExpr 'mod' UnaryExpr
10669 * [34] MultiplyOperator ::= '*' 10676 * [34] MultiplyOperator ::= '*'
10670 * 10677 *
10671 * Compile an Additive expression. 10678 * Compile an Additive expression.
10672 */ 10679 */
10673 10680
10674 static void 10681 static void
10675 xmlXPathCompMultiplicativeExpr(xmlXPathParserContextPtr ctxt) { 10682 xmlXPathCompMultiplicativeExpr(xmlXPathParserContextPtr ctxt) {
10676 xmlXPathCompUnaryExpr(ctxt); 10683 xmlXPathCompUnaryExpr(ctxt);
10677 CHECK_ERROR; 10684 CHECK_ERROR;
10678 SKIP_BLANKS; 10685 SKIP_BLANKS;
10679 while ((CUR == '*') || 10686 while ((CUR == '*') ||
10680 ((CUR == 'd') && (NXT(1) == 'i') && (NXT(2) == 'v')) || 10687 ((CUR == 'd') && (NXT(1) == 'i') && (NXT(2) == 'v')) ||
10681 ((CUR == 'm') && (NXT(1) == 'o') && (NXT(2) == 'd'))) { 10688 ((CUR == 'm') && (NXT(1) == 'o') && (NXT(2) == 'd'))) {
10682 int op = -1; 10689 int op = -1;
10683 int op1 = ctxt->comp->last; 10690 int op1 = ctxt->comp->last;
10684 10691
10685 if (CUR == '*') { 10692 if (CUR == '*') {
10686 op = 0; 10693 op = 0;
10687 NEXT; 10694 NEXT;
10688 } else if (CUR == 'd') { 10695 } else if (CUR == 'd') {
10689 op = 1; 10696 op = 1;
10690 SKIP(3); 10697 SKIP(3);
10691 } else if (CUR == 'm') { 10698 } else if (CUR == 'm') {
10692 op = 2; 10699 op = 2;
10693 SKIP(3); 10700 SKIP(3);
10694 } 10701 }
10695 SKIP_BLANKS; 10702 SKIP_BLANKS;
10696 xmlXPathCompUnaryExpr(ctxt); 10703 xmlXPathCompUnaryExpr(ctxt);
10697 CHECK_ERROR; 10704 CHECK_ERROR;
10698 PUSH_BINARY_EXPR(XPATH_OP_MULT, op1, ctxt->comp->last, op, 0); 10705 PUSH_BINARY_EXPR(XPATH_OP_MULT, op1, ctxt->comp->last, op, 0);
10699 SKIP_BLANKS; 10706 SKIP_BLANKS;
10700 } 10707 }
10701 } 10708 }
10702 10709
10703 /** 10710 /**
10704 * xmlXPathCompAdditiveExpr: 10711 * xmlXPathCompAdditiveExpr:
10705 * @ctxt: the XPath Parser context 10712 * @ctxt: the XPath Parser context
10706 * 10713 *
10707 * [25] AdditiveExpr ::= MultiplicativeExpr 10714 * [25] AdditiveExpr ::= MultiplicativeExpr
10708 * | AdditiveExpr '+' MultiplicativeExpr 10715 * | AdditiveExpr '+' MultiplicativeExpr
10709 * | AdditiveExpr '-' MultiplicativeExpr 10716 * | AdditiveExpr '-' MultiplicativeExpr
10710 * 10717 *
10711 * Compile an Additive expression. 10718 * Compile an Additive expression.
10712 */ 10719 */
10713 10720
10714 static void 10721 static void
10715 xmlXPathCompAdditiveExpr(xmlXPathParserContextPtr ctxt) { 10722 xmlXPathCompAdditiveExpr(xmlXPathParserContextPtr ctxt) {
10716 10723
10717 xmlXPathCompMultiplicativeExpr(ctxt); 10724 xmlXPathCompMultiplicativeExpr(ctxt);
10718 CHECK_ERROR; 10725 CHECK_ERROR;
10719 SKIP_BLANKS; 10726 SKIP_BLANKS;
10720 while ((CUR == '+') || (CUR == '-')) { 10727 while ((CUR == '+') || (CUR == '-')) {
10721 int plus; 10728 int plus;
10722 int op1 = ctxt->comp->last; 10729 int op1 = ctxt->comp->last;
10723 10730
10724 if (CUR == '+') plus = 1; 10731 if (CUR == '+') plus = 1;
10725 else plus = 0; 10732 else plus = 0;
10726 NEXT; 10733 NEXT;
10727 SKIP_BLANKS; 10734 SKIP_BLANKS;
10728 xmlXPathCompMultiplicativeExpr(ctxt); 10735 xmlXPathCompMultiplicativeExpr(ctxt);
10729 CHECK_ERROR; 10736 CHECK_ERROR;
10730 PUSH_BINARY_EXPR(XPATH_OP_PLUS, op1, ctxt->comp->last, plus, 0); 10737 PUSH_BINARY_EXPR(XPATH_OP_PLUS, op1, ctxt->comp->last, plus, 0);
10731 SKIP_BLANKS; 10738 SKIP_BLANKS;
10732 } 10739 }
10733 } 10740 }
10734 10741
10735 /** 10742 /**
10736 * xmlXPathCompRelationalExpr: 10743 * xmlXPathCompRelationalExpr:
10737 * @ctxt: the XPath Parser context 10744 * @ctxt: the XPath Parser context
10738 * 10745 *
10739 * [24] RelationalExpr ::= AdditiveExpr 10746 * [24] RelationalExpr ::= AdditiveExpr
10740 * | RelationalExpr '<' AdditiveExpr 10747 * | RelationalExpr '<' AdditiveExpr
10741 * | RelationalExpr '>' AdditiveExpr 10748 * | RelationalExpr '>' AdditiveExpr
10742 * | RelationalExpr '<=' AdditiveExpr 10749 * | RelationalExpr '<=' AdditiveExpr
10743 * | RelationalExpr '>=' AdditiveExpr 10750 * | RelationalExpr '>=' AdditiveExpr
10744 * 10751 *
10745 * A <= B > C is allowed ? Answer from James, yes with 10752 * A <= B > C is allowed ? Answer from James, yes with
10746 * (AdditiveExpr <= AdditiveExpr) > AdditiveExpr 10753 * (AdditiveExpr <= AdditiveExpr) > AdditiveExpr
10747 * which is basically what got implemented. 10754 * which is basically what got implemented.
10748 * 10755 *
10749 * Compile a Relational expression, then push the result 10756 * Compile a Relational expression, then push the result
10750 * on the stack 10757 * on the stack
10751 */ 10758 */
10752 10759
10753 static void 10760 static void
(...skipping 19 matching lines...) Expand all
10773 CHECK_ERROR; 10780 CHECK_ERROR;
10774 PUSH_BINARY_EXPR(XPATH_OP_CMP, op1, ctxt->comp->last, inf, strict); 10781 PUSH_BINARY_EXPR(XPATH_OP_CMP, op1, ctxt->comp->last, inf, strict);
10775 SKIP_BLANKS; 10782 SKIP_BLANKS;
10776 } 10783 }
10777 } 10784 }
10778 10785
10779 /** 10786 /**
10780 * xmlXPathCompEqualityExpr: 10787 * xmlXPathCompEqualityExpr:
10781 * @ctxt: the XPath Parser context 10788 * @ctxt: the XPath Parser context
10782 * 10789 *
10783 * [23] EqualityExpr ::= RelationalExpr 10790 * [23] EqualityExpr ::= RelationalExpr
10784 * | EqualityExpr '=' RelationalExpr 10791 * | EqualityExpr '=' RelationalExpr
10785 * | EqualityExpr '!=' RelationalExpr 10792 * | EqualityExpr '!=' RelationalExpr
10786 * 10793 *
10787 * A != B != C is allowed ? Answer from James, yes with 10794 * A != B != C is allowed ? Answer from James, yes with
10788 * (RelationalExpr = RelationalExpr) = RelationalExpr 10795 * (RelationalExpr = RelationalExpr) = RelationalExpr
10789 * (RelationalExpr != RelationalExpr) != RelationalExpr 10796 * (RelationalExpr != RelationalExpr) != RelationalExpr
10790 * which is basically what got implemented. 10797 * which is basically what got implemented.
10791 * 10798 *
10792 * Compile an Equality expression. 10799 * Compile an Equality expression.
10793 * 10800 *
10794 */ 10801 */
10795 static void 10802 static void
(...skipping 14 matching lines...) Expand all
10810 CHECK_ERROR; 10817 CHECK_ERROR;
10811 PUSH_BINARY_EXPR(XPATH_OP_EQUAL, op1, ctxt->comp->last, eq, 0); 10818 PUSH_BINARY_EXPR(XPATH_OP_EQUAL, op1, ctxt->comp->last, eq, 0);
10812 SKIP_BLANKS; 10819 SKIP_BLANKS;
10813 } 10820 }
10814 } 10821 }
10815 10822
10816 /** 10823 /**
10817 * xmlXPathCompAndExpr: 10824 * xmlXPathCompAndExpr:
10818 * @ctxt: the XPath Parser context 10825 * @ctxt: the XPath Parser context
10819 * 10826 *
10820 * [22] AndExpr ::= EqualityExpr 10827 * [22] AndExpr ::= EqualityExpr
10821 * | AndExpr 'and' EqualityExpr 10828 * | AndExpr 'and' EqualityExpr
10822 * 10829 *
10823 * Compile an AND expression. 10830 * Compile an AND expression.
10824 * 10831 *
10825 */ 10832 */
10826 static void 10833 static void
10827 xmlXPathCompAndExpr(xmlXPathParserContextPtr ctxt) { 10834 xmlXPathCompAndExpr(xmlXPathParserContextPtr ctxt) {
10828 xmlXPathCompEqualityExpr(ctxt); 10835 xmlXPathCompEqualityExpr(ctxt);
10829 CHECK_ERROR; 10836 CHECK_ERROR;
10830 SKIP_BLANKS; 10837 SKIP_BLANKS;
10831 while ((CUR == 'a') && (NXT(1) == 'n') && (NXT(2) == 'd')) { 10838 while ((CUR == 'a') && (NXT(1) == 'n') && (NXT(2) == 'd')) {
10832 int op1 = ctxt->comp->last; 10839 int op1 = ctxt->comp->last;
10833 SKIP(3); 10840 SKIP(3);
10834 SKIP_BLANKS; 10841 SKIP_BLANKS;
10835 xmlXPathCompEqualityExpr(ctxt); 10842 xmlXPathCompEqualityExpr(ctxt);
10836 CHECK_ERROR; 10843 CHECK_ERROR;
10837 PUSH_BINARY_EXPR(XPATH_OP_AND, op1, ctxt->comp->last, 0, 0); 10844 PUSH_BINARY_EXPR(XPATH_OP_AND, op1, ctxt->comp->last, 0, 0);
10838 SKIP_BLANKS; 10845 SKIP_BLANKS;
10839 } 10846 }
10840 } 10847 }
10841 10848
10842 /** 10849 /**
10843 * xmlXPathCompileExpr: 10850 * xmlXPathCompileExpr:
10844 * @ctxt: the XPath Parser context 10851 * @ctxt: the XPath Parser context
10845 * 10852 *
10846 * [14] Expr ::= OrExpr 10853 * [14] Expr ::= OrExpr
10847 * [21] OrExpr ::= AndExpr 10854 * [21] OrExpr ::= AndExpr
10848 * | OrExpr 'or' AndExpr 10855 * | OrExpr 'or' AndExpr
10849 * 10856 *
10850 * Parse and compile an expression 10857 * Parse and compile an expression
10851 */ 10858 */
10852 static void 10859 static void
10853 xmlXPathCompileExpr(xmlXPathParserContextPtr ctxt, int sort) { 10860 xmlXPathCompileExpr(xmlXPathParserContextPtr ctxt, int sort) {
10854 xmlXPathCompAndExpr(ctxt); 10861 xmlXPathCompAndExpr(ctxt);
10855 CHECK_ERROR; 10862 CHECK_ERROR;
10856 SKIP_BLANKS; 10863 SKIP_BLANKS;
10857 while ((CUR == 'o') && (NXT(1) == 'r')) { 10864 while ((CUR == 'o') && (NXT(1) == 'r')) {
10858 int op1 = ctxt->comp->last; 10865 int op1 = ctxt->comp->last;
10859 SKIP(2); 10866 SKIP(2);
10860 SKIP_BLANKS; 10867 SKIP_BLANKS;
10861 xmlXPathCompAndExpr(ctxt); 10868 xmlXPathCompAndExpr(ctxt);
10862 CHECK_ERROR; 10869 CHECK_ERROR;
10863 PUSH_BINARY_EXPR(XPATH_OP_OR, op1, ctxt->comp->last, 0, 0); 10870 PUSH_BINARY_EXPR(XPATH_OP_OR, op1, ctxt->comp->last, 0, 0);
10864 op1 = ctxt->comp->nbStep;
10865 SKIP_BLANKS; 10871 SKIP_BLANKS;
10866 } 10872 }
10867 if ((sort) && (ctxt->comp->steps[ctxt->comp->last].op != XPATH_OP_VALUE)) { 10873 if ((sort) && (ctxt->comp->steps[ctxt->comp->last].op != XPATH_OP_VALUE)) {
10868 /* more ops could be optimized too */ 10874 /* more ops could be optimized too */
10869 /* 10875 /*
10870 * This is the main place to eliminate sorting for 10876 * This is the main place to eliminate sorting for
10871 * operations which don't require a sorted node-set. 10877 * operations which don't require a sorted node-set.
10872 * E.g. count(). 10878 * E.g. count().
10873 */ 10879 */
10874 PUSH_UNARY_EXPR(XPATH_OP_SORT, ctxt->comp->last , 0, 0); 10880 PUSH_UNARY_EXPR(XPATH_OP_SORT, ctxt->comp->last , 0, 0);
10875 } 10881 }
10876 } 10882 }
10877 10883
10878 /** 10884 /**
10879 * xmlXPathCompPredicate: 10885 * xmlXPathCompPredicate:
10880 * @ctxt: the XPath Parser context 10886 * @ctxt: the XPath Parser context
10881 * @filter: act as a filter 10887 * @filter: act as a filter
10882 * 10888 *
10883 * [8] Predicate ::= '[' PredicateExpr ']' 10889 * [8] Predicate ::= '[' PredicateExpr ']'
10884 * [9] PredicateExpr ::= Expr 10890 * [9] PredicateExpr ::= Expr
10885 * 10891 *
10886 * Compile a predicate expression 10892 * Compile a predicate expression
10887 */ 10893 */
10888 static void 10894 static void
10889 xmlXPathCompPredicate(xmlXPathParserContextPtr ctxt, int filter) { 10895 xmlXPathCompPredicate(xmlXPathParserContextPtr ctxt, int filter) {
10890 int op1 = ctxt->comp->last; 10896 int op1 = ctxt->comp->last;
10891 10897
10892 SKIP_BLANKS; 10898 SKIP_BLANKS;
10893 if (CUR != '[') { 10899 if (CUR != '[') {
10894 XP_ERROR(XPATH_INVALID_PREDICATE_ERROR); 10900 XP_ERROR(XPATH_INVALID_PREDICATE_ERROR);
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
10991 *type = NODE_TYPE_PI; 10997 *type = NODE_TYPE_PI;
10992 else if (xmlStrEqual(name, BAD_CAST "text")) 10998 else if (xmlStrEqual(name, BAD_CAST "text"))
10993 *type = NODE_TYPE_TEXT; 10999 *type = NODE_TYPE_TEXT;
10994 else { 11000 else {
10995 if (name != NULL) 11001 if (name != NULL)
10996 xmlFree(name); 11002 xmlFree(name);
10997 XP_ERRORNULL(XPATH_EXPR_ERROR); 11003 XP_ERRORNULL(XPATH_EXPR_ERROR);
10998 } 11004 }
10999 11005
11000 *test = NODE_TEST_TYPE; 11006 *test = NODE_TEST_TYPE;
11001 » 11007
11002 SKIP_BLANKS; 11008 SKIP_BLANKS;
11003 if (*type == NODE_TYPE_PI) { 11009 if (*type == NODE_TYPE_PI) {
11004 /* 11010 /*
11005 * Specific case: search a PI by name. 11011 * Specific case: search a PI by name.
11006 */ 11012 */
11007 if (name != NULL) 11013 if (name != NULL)
11008 xmlFree(name); 11014 xmlFree(name);
11009 name = NULL; 11015 name = NULL;
11010 if (CUR != ')') { 11016 if (CUR != ')') {
11011 name = xmlXPathParseLiteral(ctxt); 11017 name = xmlXPathParseLiteral(ctxt);
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
11127 break; 11133 break;
11128 } 11134 }
11129 return(ret); 11135 return(ret);
11130 } 11136 }
11131 11137
11132 /** 11138 /**
11133 * xmlXPathCompStep: 11139 * xmlXPathCompStep:
11134 * @ctxt: the XPath Parser context 11140 * @ctxt: the XPath Parser context
11135 * 11141 *
11136 * [4] Step ::= AxisSpecifier NodeTest Predicate* 11142 * [4] Step ::= AxisSpecifier NodeTest Predicate*
11137 * | AbbreviatedStep 11143 * | AbbreviatedStep
11138 * 11144 *
11139 * [12] AbbreviatedStep ::= '.' | '..' 11145 * [12] AbbreviatedStep ::= '.' | '..'
11140 * 11146 *
11141 * [5] AxisSpecifier ::= AxisName '::' 11147 * [5] AxisSpecifier ::= AxisName '::'
11142 * | AbbreviatedAxisSpecifier 11148 * | AbbreviatedAxisSpecifier
11143 * 11149 *
11144 * [13] AbbreviatedAxisSpecifier ::= '@'? 11150 * [13] AbbreviatedAxisSpecifier ::= '@'?
11145 * 11151 *
11146 * Modified for XPtr range support as: 11152 * Modified for XPtr range support as:
11147 * 11153 *
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
11299 else 11305 else
11300 xmlGenericErrorContextNodeSet(xmlGenericErrorContext, 11306 xmlGenericErrorContextNodeSet(xmlGenericErrorContext,
11301 ctxt->value->nodesetval); 11307 ctxt->value->nodesetval);
11302 #endif 11308 #endif
11303 } 11309 }
11304 11310
11305 /** 11311 /**
11306 * xmlXPathCompRelativeLocationPath: 11312 * xmlXPathCompRelativeLocationPath:
11307 * @ctxt: the XPath Parser context 11313 * @ctxt: the XPath Parser context
11308 * 11314 *
11309 * [3] RelativeLocationPath ::= Step 11315 * [3] RelativeLocationPath ::= Step
11310 * | RelativeLocationPath '/' Step 11316 * | RelativeLocationPath '/' Step
11311 * | AbbreviatedRelativeLocationPath 11317 * | AbbreviatedRelativeLocationPath
11312 * [11] AbbreviatedRelativeLocationPath ::= RelativeLocationPath '//' Step 11318 * [11] AbbreviatedRelativeLocationPath ::= RelativeLocationPath '//' Step
11313 * 11319 *
11314 * Compile a relative location path. 11320 * Compile a relative location path.
11315 */ 11321 */
11316 static void 11322 static void
11317 xmlXPathCompRelativeLocationPath 11323 xmlXPathCompRelativeLocationPath
11318 (xmlXPathParserContextPtr ctxt) { 11324 (xmlXPathParserContextPtr ctxt) {
11319 SKIP_BLANKS; 11325 SKIP_BLANKS;
11320 if ((CUR == '/') && (NXT(1) == '/')) { 11326 if ((CUR == '/') && (NXT(1) == '/')) {
11321 SKIP(2); 11327 SKIP(2);
11322 SKIP_BLANKS; 11328 SKIP_BLANKS;
11323 PUSH_LONG_EXPR(XPATH_OP_COLLECT, AXIS_DESCENDANT_OR_SELF, 11329 PUSH_LONG_EXPR(XPATH_OP_COLLECT, AXIS_DESCENDANT_OR_SELF,
11324 NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL); 11330 NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL);
11325 } else if (CUR == '/') { 11331 } else if (CUR == '/') {
11326 NEXT; 11332 NEXT;
11327 SKIP_BLANKS; 11333 SKIP_BLANKS;
11328 } 11334 }
11329 xmlXPathCompStep(ctxt); 11335 xmlXPathCompStep(ctxt);
11336 CHECK_ERROR;
11330 SKIP_BLANKS; 11337 SKIP_BLANKS;
11331 while (CUR == '/') { 11338 while (CUR == '/') {
11332 if ((CUR == '/') && (NXT(1) == '/')) { 11339 if ((CUR == '/') && (NXT(1) == '/')) {
11333 SKIP(2); 11340 SKIP(2);
11334 SKIP_BLANKS; 11341 SKIP_BLANKS;
11335 PUSH_LONG_EXPR(XPATH_OP_COLLECT, AXIS_DESCENDANT_OR_SELF, 11342 PUSH_LONG_EXPR(XPATH_OP_COLLECT, AXIS_DESCENDANT_OR_SELF,
11336 NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL); 11343 NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL);
11337 xmlXPathCompStep(ctxt); 11344 xmlXPathCompStep(ctxt);
11338 } else if (CUR == '/') { 11345 } else if (CUR == '/') {
11339 NEXT; 11346 NEXT;
11340 SKIP_BLANKS; 11347 SKIP_BLANKS;
11341 xmlXPathCompStep(ctxt); 11348 xmlXPathCompStep(ctxt);
11342 } 11349 }
11343 SKIP_BLANKS; 11350 SKIP_BLANKS;
11344 } 11351 }
11345 } 11352 }
11346 11353
11347 /** 11354 /**
11348 * xmlXPathCompLocationPath: 11355 * xmlXPathCompLocationPath:
11349 * @ctxt: the XPath Parser context 11356 * @ctxt: the XPath Parser context
11350 * 11357 *
11351 * [1] LocationPath ::= RelativeLocationPath 11358 * [1] LocationPath ::= RelativeLocationPath
11352 * | AbsoluteLocationPath 11359 * | AbsoluteLocationPath
11353 * [2] AbsoluteLocationPath ::= '/' RelativeLocationPath? 11360 * [2] AbsoluteLocationPath ::= '/' RelativeLocationPath?
11354 * | AbbreviatedAbsoluteLocationPath 11361 * | AbbreviatedAbsoluteLocationPath
11355 * [10] AbbreviatedAbsoluteLocationPath ::= 11362 * [10] AbbreviatedAbsoluteLocationPath ::=
11356 * '//' RelativeLocationPath 11363 * '//' RelativeLocationPath
11357 * 11364 *
11358 * Compile a location path 11365 * Compile a location path
11359 * 11366 *
11360 * // is short for /descendant-or-self::node()/. For example, 11367 * // is short for /descendant-or-self::node()/. For example,
11361 * //para is short for /descendant-or-self::node()/child::para and 11368 * //para is short for /descendant-or-self::node()/child::para and
11362 * so will select any para element in the document (even a para element 11369 * so will select any para element in the document (even a para element
11363 * that is a document element will be selected by //para since the 11370 * that is a document element will be selected by //para since the
11364 * document element node is a child of the root node); div//para is 11371 * document element node is a child of the root node); div//para is
11365 * short for div/descendant-or-self::node()/child::para and so will 11372 * short for div/descendant-or-self::node()/child::para and so will
11366 * select all para descendants of div children. 11373 * select all para descendants of div children.
(...skipping 12 matching lines...) Expand all
11379 NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL); 11386 NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL);
11380 xmlXPathCompRelativeLocationPath(ctxt); 11387 xmlXPathCompRelativeLocationPath(ctxt);
11381 } else if (CUR == '/') { 11388 } else if (CUR == '/') {
11382 NEXT; 11389 NEXT;
11383 SKIP_BLANKS; 11390 SKIP_BLANKS;
11384 if ((CUR != 0 ) && 11391 if ((CUR != 0 ) &&
11385 ((IS_ASCII_LETTER(CUR)) || (CUR == '_') || (CUR == '.') || 11392 ((IS_ASCII_LETTER(CUR)) || (CUR == '_') || (CUR == '.') ||
11386 (CUR == '@') || (CUR == '*'))) 11393 (CUR == '@') || (CUR == '*')))
11387 xmlXPathCompRelativeLocationPath(ctxt); 11394 xmlXPathCompRelativeLocationPath(ctxt);
11388 } 11395 }
11396 CHECK_ERROR;
11389 } 11397 }
11390 } 11398 }
11391 } 11399 }
11392 11400
11393 /************************************************************************ 11401 /************************************************************************
11394 * * 11402 * *
11395 * » » XPath precompiled expression evaluation»» » * 11403 *» » XPath precompiled expression evaluation»» » *
11396 * * 11404 * *
11397 ************************************************************************/ 11405 ************************************************************************/
11398 11406
11399 static int 11407 static int
11400 xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op); 11408 xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op);
11401 11409
11402 #ifdef DEBUG_STEP 11410 #ifdef DEBUG_STEP
11403 static void 11411 static void
11404 xmlXPathDebugDumpStepAxis(xmlXPathAxisVal axis, 11412 xmlXPathDebugDumpStepAxis(xmlXPathStepOpPtr op,
11405 » » » xmlXPathTestVal test,
11406 int nbNodes) 11413 int nbNodes)
11407 { 11414 {
11408 xmlGenericError(xmlGenericErrorContext, "new step : "); 11415 xmlGenericError(xmlGenericErrorContext, "new step : ");
11409 switch (axis) { 11416 switch (op->value) {
11410 case AXIS_ANCESTOR: 11417 case AXIS_ANCESTOR:
11411 xmlGenericError(xmlGenericErrorContext, "axis 'ancestors' "); 11418 xmlGenericError(xmlGenericErrorContext, "axis 'ancestors' ");
11412 break; 11419 break;
11413 case AXIS_ANCESTOR_OR_SELF: 11420 case AXIS_ANCESTOR_OR_SELF:
11414 xmlGenericError(xmlGenericErrorContext, 11421 xmlGenericError(xmlGenericErrorContext,
11415 "axis 'ancestors-or-self' "); 11422 "axis 'ancestors-or-self' ");
11416 break; 11423 break;
11417 case AXIS_ATTRIBUTE: 11424 case AXIS_ATTRIBUTE:
11418 xmlGenericError(xmlGenericErrorContext, "axis 'attributes' "); 11425 xmlGenericError(xmlGenericErrorContext, "axis 'attributes' ");
11419 break; 11426 break;
(...skipping 26 matching lines...) Expand all
11446 case AXIS_PRECEDING_SIBLING: 11453 case AXIS_PRECEDING_SIBLING:
11447 xmlGenericError(xmlGenericErrorContext, 11454 xmlGenericError(xmlGenericErrorContext,
11448 "axis 'preceding-sibling' "); 11455 "axis 'preceding-sibling' ");
11449 break; 11456 break;
11450 case AXIS_SELF: 11457 case AXIS_SELF:
11451 xmlGenericError(xmlGenericErrorContext, "axis 'self' "); 11458 xmlGenericError(xmlGenericErrorContext, "axis 'self' ");
11452 break; 11459 break;
11453 } 11460 }
11454 xmlGenericError(xmlGenericErrorContext, 11461 xmlGenericError(xmlGenericErrorContext,
11455 " context contains %d nodes\n", nbNodes); 11462 " context contains %d nodes\n", nbNodes);
11456 switch (test) { 11463 switch (op->value2) {
11457 case NODE_TEST_NONE: 11464 case NODE_TEST_NONE:
11458 xmlGenericError(xmlGenericErrorContext, 11465 xmlGenericError(xmlGenericErrorContext,
11459 " searching for none !!!\n"); 11466 " searching for none !!!\n");
11460 break; 11467 break;
11461 case NODE_TEST_TYPE: 11468 case NODE_TEST_TYPE:
11462 xmlGenericError(xmlGenericErrorContext, 11469 xmlGenericError(xmlGenericErrorContext,
11463 " searching for type %d\n", type); 11470 " searching for type %d\n", op->value3);
11464 break; 11471 break;
11465 case NODE_TEST_PI: 11472 case NODE_TEST_PI:
11466 xmlGenericError(xmlGenericErrorContext, 11473 xmlGenericError(xmlGenericErrorContext,
11467 " searching for PI !!!\n"); 11474 " searching for PI !!!\n");
11468 break; 11475 break;
11469 case NODE_TEST_ALL: 11476 case NODE_TEST_ALL:
11470 xmlGenericError(xmlGenericErrorContext, 11477 xmlGenericError(xmlGenericErrorContext,
11471 " searching for *\n"); 11478 " searching for *\n");
11472 break; 11479 break;
11473 case NODE_TEST_NS: 11480 case NODE_TEST_NS:
11474 xmlGenericError(xmlGenericErrorContext, 11481 xmlGenericError(xmlGenericErrorContext,
11475 " searching for namespace %s\n", 11482 " searching for namespace %s\n",
11476 prefix); 11483 op->value5);
11477 break; 11484 break;
11478 case NODE_TEST_NAME: 11485 case NODE_TEST_NAME:
11479 xmlGenericError(xmlGenericErrorContext, 11486 xmlGenericError(xmlGenericErrorContext,
11480 " searching for name %s\n", name); 11487 " searching for name %s\n", op->value5);
11481 if (prefix != NULL) 11488 if (op->value4)
11482 xmlGenericError(xmlGenericErrorContext, 11489 xmlGenericError(xmlGenericErrorContext,
11483 " with namespace %s\n", prefix); 11490 " with namespace %s\n", op->value4);
11484 break; 11491 break;
11485 } 11492 }
11486 xmlGenericError(xmlGenericErrorContext, "Testing : "); 11493 xmlGenericError(xmlGenericErrorContext, "Testing : ");
11487 } 11494 }
11488 #endif /* DEBUG_STEP */ 11495 #endif /* DEBUG_STEP */
11489 11496
11490 static int 11497 static int
11491 xmlXPathCompOpEvalPredicate(xmlXPathParserContextPtr ctxt, 11498 xmlXPathCompOpEvalPredicate(xmlXPathParserContextPtr ctxt,
11492 xmlXPathStepOpPtr op, 11499 xmlXPathStepOpPtr op,
11493 xmlNodeSetPtr set, 11500 xmlNodeSetPtr set,
11494 int contextSize, 11501 int contextSize,
11495 int hasNsNodes) 11502 int hasNsNodes)
11496 { 11503 {
11497 if (op->ch1 != -1) { 11504 if (op->ch1 != -1) {
11498 xmlXPathCompExprPtr comp = ctxt->comp; 11505 xmlXPathCompExprPtr comp = ctxt->comp;
11499 /* 11506 /*
11500 * Process inner predicates first. 11507 * Process inner predicates first.
11501 */ 11508 */
11502 if (comp->steps[op->ch1].op != XPATH_OP_PREDICATE) { 11509 if (comp->steps[op->ch1].op != XPATH_OP_PREDICATE) {
11503 /* 11510 /*
11504 * TODO: raise an internal error. 11511 * TODO: raise an internal error.
11505 */ 11512 */
11506 } 11513 }
11507 contextSize = xmlXPathCompOpEvalPredicate(ctxt, 11514 contextSize = xmlXPathCompOpEvalPredicate(ctxt,
11508 &comp->steps[op->ch1], set, contextSize, hasNsNodes); 11515 &comp->steps[op->ch1], set, contextSize, hasNsNodes);
11509 CHECK_ERROR0; 11516 CHECK_ERROR0;
11510 if (contextSize <= 0) 11517 if (contextSize <= 0)
11511 return(0); 11518 return(0);
11512 } 11519 }
11513 if (op->ch2 != -1) { 11520 if (op->ch2 != -1) {
11514 xmlXPathContextPtr xpctxt = ctxt->context; 11521 xmlXPathContextPtr xpctxt = ctxt->context;
11515 xmlNodePtr contextNode, oldContextNode; 11522 xmlNodePtr contextNode, oldContextNode;
11516 xmlDocPtr oldContextDoc; 11523 xmlDocPtr oldContextDoc;
11517 int i, res, contextPos = 0, newContextSize; 11524 int i, res, contextPos = 0, newContextSize;
11518 xmlXPathStepOpPtr exprOp; 11525 xmlXPathStepOpPtr exprOp;
11519 xmlXPathObjectPtr contextObj = NULL, exprRes = NULL; 11526 xmlXPathObjectPtr contextObj = NULL, exprRes = NULL;
11520 11527
11521 #ifdef LIBXML_XPTR_ENABLED 11528 #ifdef LIBXML_XPTR_ENABLED
11522 /* 11529 /*
(...skipping 23 matching lines...) Expand all
11546 * After applying predicate [position() > 1] : 11553 * After applying predicate [position() > 1] :
11547 * node-set context pos 11554 * node-set context pos
11548 * nB 1 11555 * nB 1
11549 * nC 2 11556 * nC 2
11550 */ 11557 */
11551 oldContextNode = xpctxt->node; 11558 oldContextNode = xpctxt->node;
11552 oldContextDoc = xpctxt->doc; 11559 oldContextDoc = xpctxt->doc;
11553 /* 11560 /*
11554 * Get the expression of this predicate. 11561 * Get the expression of this predicate.
11555 */ 11562 */
11556 » exprOp = &ctxt->comp->steps[op->ch2];» 11563 » exprOp = &ctxt->comp->steps[op->ch2];
11557 newContextSize = 0; 11564 newContextSize = 0;
11558 for (i = 0; i < set->nodeNr; i++) { 11565 for (i = 0; i < set->nodeNr; i++) {
11559 if (set->nodeTab[i] == NULL) 11566 if (set->nodeTab[i] == NULL)
11560 continue; 11567 continue;
11561 11568
11562 contextNode = set->nodeTab[i]; 11569 contextNode = set->nodeTab[i];
11563 xpctxt->node = contextNode; 11570 xpctxt->node = contextNode;
11564 xpctxt->contextSize = contextSize; 11571 xpctxt->contextSize = contextSize;
11565 xpctxt->proximityPosition = ++contextPos; 11572 xpctxt->proximityPosition = ++contextPos;
11566 » 11573
11567 » /*» 11574 » /*
11568 * Also set the xpath document in case things like 11575 * Also set the xpath document in case things like
11569 * key() are evaluated in the predicate. 11576 * key() are evaluated in the predicate.
11570 */ 11577 */
11571 if ((contextNode->type != XML_NAMESPACE_DECL) && 11578 if ((contextNode->type != XML_NAMESPACE_DECL) &&
11572 (contextNode->doc != NULL)) 11579 (contextNode->doc != NULL))
11573 xpctxt->doc = contextNode->doc; 11580 xpctxt->doc = contextNode->doc;
11574 /* 11581 /*
11575 * Evaluate the predicate expression with 1 context node 11582 * Evaluate the predicate expression with 1 context node
11576 * at a time; this node is packaged into a node set; this 11583 * at a time; this node is packaged into a node set; this
11577 * node set is handed over to the evaluation mechanism. 11584 * node set is handed over to the evaluation mechanism.
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
11616 * Can this happen? Maybe in internal-error cases. 11623 * Can this happen? Maybe in internal-error cases.
11617 */ 11624 */
11618 contextObj = NULL; 11625 contextObj = NULL;
11619 } 11626 }
11620 } 11627 }
11621 11628
11622 if (contextObj != NULL) { 11629 if (contextObj != NULL) {
11623 if (ctxt->value == contextObj) 11630 if (ctxt->value == contextObj)
11624 valuePop(ctxt); 11631 valuePop(ctxt);
11625 xmlXPathReleaseObject(xpctxt, contextObj); 11632 xmlXPathReleaseObject(xpctxt, contextObj);
11626 » }» 11633 » }
11627 evaluation_exit: 11634 evaluation_exit:
11628 if (exprRes != NULL) 11635 if (exprRes != NULL)
11629 xmlXPathReleaseObject(ctxt->context, exprRes); 11636 xmlXPathReleaseObject(ctxt->context, exprRes);
11630 /* 11637 /*
11631 * Reset/invalidate the context. 11638 * Reset/invalidate the context.
11632 */ 11639 */
11633 xpctxt->node = oldContextNode; 11640 xpctxt->node = oldContextNode;
11634 xpctxt->doc = oldContextDoc; 11641 xpctxt->doc = oldContextDoc;
11635 xpctxt->contextSize = -1; 11642 xpctxt->contextSize = -1;
11636 xpctxt->proximityPosition = -1; 11643 xpctxt->proximityPosition = -1;
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
11700 */ 11707 */
11701 exprOp = &ctxt->comp->steps[op->ch2]; 11708 exprOp = &ctxt->comp->steps[op->ch2];
11702 for (i = 0; i < set->nodeNr; i++) { 11709 for (i = 0; i < set->nodeNr; i++) {
11703 if (set->nodeTab[i] == NULL) 11710 if (set->nodeTab[i] == NULL)
11704 continue; 11711 continue;
11705 11712
11706 contextNode = set->nodeTab[i]; 11713 contextNode = set->nodeTab[i];
11707 xpctxt->node = contextNode; 11714 xpctxt->node = contextNode;
11708 xpctxt->contextSize = contextSize; 11715 xpctxt->contextSize = contextSize;
11709 xpctxt->proximityPosition = ++contextPos; 11716 xpctxt->proximityPosition = ++contextPos;
11710 » 11717
11711 /* 11718 /*
11712 * Initialize the new set. 11719 * Initialize the new set.
11713 * Also set the xpath document in case things like 11720 * Also set the xpath document in case things like
11714 * key() evaluation are attempted on the predicate 11721 * key() evaluation are attempted on the predicate
11715 */ 11722 */
11716 if ((contextNode->type != XML_NAMESPACE_DECL) && 11723 if ((contextNode->type != XML_NAMESPACE_DECL) &&
11717 (contextNode->doc != NULL)) 11724 (contextNode->doc != NULL))
11718 xpctxt->doc = contextNode->doc; 11725 xpctxt->doc = contextNode->doc;
11719 /* 11726 /*
11720 * Evaluate the predicate expression with 1 context node 11727 * Evaluate the predicate expression with 1 context node
11721 * at a time; this node is packaged into a node set; this 11728 * at a time; this node is packaged into a node set; this
11722 * node set is handed over to the evaluation mechanism. 11729 * node set is handed over to the evaluation mechanism.
11723 */ 11730 */
11724 if (contextObj == NULL) 11731 if (contextObj == NULL)
11725 contextObj = xmlXPathCacheNewNodeSet(xpctxt, contextNode); 11732 contextObj = xmlXPathCacheNewNodeSet(xpctxt, contextNode);
11726 else 11733 else
11727 xmlXPathNodeSetAddUnique(contextObj->nodesetval, 11734 xmlXPathNodeSetAddUnique(contextObj->nodesetval,
11728 contextNode); 11735 contextNode);
11729 11736
11730 valuePush(ctxt, contextObj); 11737 valuePush(ctxt, contextObj);
11731 res = xmlXPathCompOpEvalToBoolean(ctxt, exprOp, 1); 11738 res = xmlXPathCompOpEvalToBoolean(ctxt, exprOp, 1);
11732 » 11739
11733 if ((ctxt->error != XPATH_EXPRESSION_OK) || (res == -1)) { 11740 if ((ctxt->error != XPATH_EXPRESSION_OK) || (res == -1)) {
11734 xmlXPathObjectPtr tmp; 11741 xmlXPathObjectPtr tmp;
11735 /* pop the result */ 11742 /* pop the result */
11736 tmp = valuePop(ctxt); 11743 tmp = valuePop(ctxt);
11737 xmlXPathReleaseObject(xpctxt, tmp); 11744 xmlXPathReleaseObject(xpctxt, tmp);
11738 /* then pop off contextObj, which will be freed later */ 11745 /* then pop off contextObj, which will be freed later */
11739 valuePop(ctxt); 11746 valuePop(ctxt);
11740 goto evaluation_error; 11747 goto evaluation_error;
11741 } 11748 }
11742 11749
(...skipping 11 matching lines...) Expand all
11754 */ 11761 */
11755 if (contextNode->type == XML_NAMESPACE_DECL) { 11762 if (contextNode->type == XML_NAMESPACE_DECL) {
11756 /* 11763 /*
11757 * As always: take care of those nasty 11764 * As always: take care of those nasty
11758 * namespace nodes. 11765 * namespace nodes.
11759 */ 11766 */
11760 set->nodeTab[i] = NULL; 11767 set->nodeTab[i] = NULL;
11761 } 11768 }
11762 xmlXPathNodeSetClear(set, hasNsNodes); 11769 xmlXPathNodeSetClear(set, hasNsNodes);
11763 set->nodeNr = 1; 11770 set->nodeNr = 1;
11764 » » set->nodeTab[0] = contextNode;» » 11771 » » set->nodeTab[0] = contextNode;
11765 goto evaluation_exit; 11772 goto evaluation_exit;
11766 » » }» » 11773 » » }
11767 if (pos == maxPos) { 11774 if (pos == maxPos) {
11768 /* 11775 /*
11769 * We are done. 11776 * We are done.
11770 */ 11777 */
11771 xmlXPathNodeSetClearFromPos(set, i +1, hasNsNodes); 11778 xmlXPathNodeSetClearFromPos(set, i +1, hasNsNodes);
11772 goto evaluation_exit; 11779 goto evaluation_exit;
11773 } 11780 }
11774 } else { 11781 } else {
11775 /* 11782 /*
11776 * Remove the entry from the initial node set. 11783 * Remove the entry from the initial node set.
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
11820 xpctxt->doc = oldContextDoc; 11827 xpctxt->doc = oldContextDoc;
11821 xpctxt->contextSize = -1; 11828 xpctxt->contextSize = -1;
11822 xpctxt->proximityPosition = -1; 11829 xpctxt->proximityPosition = -1;
11823 return(newContextSize); 11830 return(newContextSize);
11824 } 11831 }
11825 return(contextSize); 11832 return(contextSize);
11826 } 11833 }
11827 11834
11828 static int 11835 static int
11829 xmlXPathIsPositionalPredicate(xmlXPathParserContextPtr ctxt, 11836 xmlXPathIsPositionalPredicate(xmlXPathParserContextPtr ctxt,
11830 » » » xmlXPathStepOpPtr op,» » » 11837 » » » xmlXPathStepOpPtr op,
11831 int *maxPos) 11838 int *maxPos)
11832 { 11839 {
11833 11840
11834 xmlXPathStepOpPtr exprOp; 11841 xmlXPathStepOpPtr exprOp;
11835 11842
11836 /* 11843 /*
11837 * BIG NOTE: This is not intended for XPATH_OP_FILTER yet! 11844 * BIG NOTE: This is not intended for XPATH_OP_FILTER yet!
11838 */ 11845 */
11839 11846
11840 /* 11847 /*
11841 * If not -1, then ch1 will point to: 11848 * If not -1, then ch1 will point to:
11842 * 1) For predicates (XPATH_OP_PREDICATE): 11849 * 1) For predicates (XPATH_OP_PREDICATE):
11843 * - an inner predicate operator 11850 * - an inner predicate operator
11844 * 2) For filters (XPATH_OP_FILTER): 11851 * 2) For filters (XPATH_OP_FILTER):
11845 * - an inner filter operater OR 11852 * - an inner filter operater OR
11846 * - an expression selecting the node set. 11853 * - an expression selecting the node set.
11847 * E.g. "key('a', 'b')" or "(//foo | //bar)". 11854 * E.g. "key('a', 'b')" or "(//foo | //bar)".
11848 */ 11855 */
11849 if ((op->op != XPATH_OP_PREDICATE) && (op->op != XPATH_OP_FILTER)) 11856 if ((op->op != XPATH_OP_PREDICATE) && (op->op != XPATH_OP_FILTER))
11850 return(0); 11857 return(0);
11851 11858
11852 if (op->ch2 != -1) { 11859 if (op->ch2 != -1) {
11853 exprOp = &ctxt->comp->steps[op->ch2]; 11860 exprOp = &ctxt->comp->steps[op->ch2];
11854 } else» 11861 } else
11855 return(0); 11862 return(0);
11856 11863
11857 if ((exprOp != NULL) && 11864 if ((exprOp != NULL) &&
11858 (exprOp->op == XPATH_OP_VALUE) && 11865 (exprOp->op == XPATH_OP_VALUE) &&
11859 (exprOp->value4 != NULL) && 11866 (exprOp->value4 != NULL) &&
11860 (((xmlXPathObjectPtr) exprOp->value4)->type == XPATH_NUMBER)) 11867 (((xmlXPathObjectPtr) exprOp->value4)->type == XPATH_NUMBER))
11861 { 11868 {
11862 /* 11869 /*
11863 * We have a "[n]" predicate here. 11870 * We have a "[n]" predicate here.
11864 * TODO: Unfortunately this simplistic test here is not 11871 * TODO: Unfortunately this simplistic test here is not
11865 * able to detect a position() predicate in compound 11872 * able to detect a position() predicate in compound
11866 * expressions like "[@attr = 'a" and position() = 1], 11873 * expressions like "[@attr = 'a" and position() = 1],
11867 * and even not the usage of position() in 11874 * and even not the usage of position() in
11868 * "[position() = 1]"; thus - obviously - a position-range, 11875 * "[position() = 1]"; thus - obviously - a position-range,
11869 * like it "[position() < 5]", is also not detected. 11876 * like it "[position() < 5]", is also not detected.
11870 * Maybe we could rewrite the AST to ease the optimization. 11877 * Maybe we could rewrite the AST to ease the optimization.
11871 */ 11878 */
11872 *maxPos = (int) ((xmlXPathObjectPtr) exprOp->value4)->floatval; 11879 *maxPos = (int) ((xmlXPathObjectPtr) exprOp->value4)->floatval;
11873 » 11880
11874 if (((xmlXPathObjectPtr) exprOp->value4)->floatval == 11881 if (((xmlXPathObjectPtr) exprOp->value4)->floatval ==
11875 (float) *maxPos) 11882 (float) *maxPos)
11876 » {» 11883 » {
11877 return(1); 11884 return(1);
11878 } 11885 }
11879 } 11886 }
11880 return(0); 11887 return(0);
11881 } 11888 }
11882 11889
11883 static int 11890 static int
11884 xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt, 11891 xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt,
11885 xmlXPathStepOpPtr op, 11892 xmlXPathStepOpPtr op,
11886 xmlNodePtr * first, xmlNodePtr * last, 11893 xmlNodePtr * first, xmlNodePtr * last,
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
11927 xmlNodePtr contextNode; 11934 xmlNodePtr contextNode;
11928 /* The context node for a compound traversal */ 11935 /* The context node for a compound traversal */
11929 xmlNodePtr outerContextNode; 11936 xmlNodePtr outerContextNode;
11930 /* The final resulting node set wrt to all context nodes */ 11937 /* The final resulting node set wrt to all context nodes */
11931 xmlNodeSetPtr outSeq; 11938 xmlNodeSetPtr outSeq;
11932 /* 11939 /*
11933 * The temporary resulting node set wrt 1 context node. 11940 * The temporary resulting node set wrt 1 context node.
11934 * Used to feed predicate evaluation. 11941 * Used to feed predicate evaluation.
11935 */ 11942 */
11936 xmlNodeSetPtr seq; 11943 xmlNodeSetPtr seq;
11937 xmlNodePtr cur; 11944 xmlNodePtr cur;
11938 /* First predicate operator */ 11945 /* First predicate operator */
11939 xmlXPathStepOpPtr predOp; 11946 xmlXPathStepOpPtr predOp;
11940 int maxPos; /* The requested position() (when a "[n]" predicate) */ 11947 int maxPos; /* The requested position() (when a "[n]" predicate) */
11941 int hasPredicateRange, hasAxisRange, pos, size, newSize; 11948 int hasPredicateRange, hasAxisRange, pos, size, newSize;
11942 int breakOnFirstHit; 11949 int breakOnFirstHit;
11943 11950
11944 xmlXPathTraversalFunction next = NULL; 11951 xmlXPathTraversalFunction next = NULL;
11945 /* compound axis traversal */ 11952 /* compound axis traversal */
11946 xmlXPathTraversalFunctionExt outerNext = NULL; 11953 xmlXPathTraversalFunctionExt outerNext = NULL;
11947 void (*addNode) (xmlNodeSetPtr, xmlNodePtr); 11954 void (*addNode) (xmlNodeSetPtr, xmlNodePtr);
11948 xmlXPathNodeSetMergeFunction mergeAndClear; 11955 xmlXPathNodeSetMergeFunction mergeAndClear;
11949 xmlNodePtr oldContextNode; 11956 xmlNodePtr oldContextNode;
11950 xmlXPathContextPtr xpctxt = ctxt->context; 11957 xmlXPathContextPtr xpctxt = ctxt->context;
11951 11958
11952 11959
11953 CHECK_TYPE0(XPATH_NODESET); 11960 CHECK_TYPE0(XPATH_NODESET);
11954 obj = valuePop(ctxt); 11961 obj = valuePop(ctxt);
11955 /* 11962 /*
11956 * Setup namespaces. 11963 * Setup namespaces.
11957 */ 11964 */
11958 if (prefix != NULL) { 11965 if (prefix != NULL) {
11959 URI = xmlXPathNsLookup(xpctxt, prefix); 11966 URI = xmlXPathNsLookup(xpctxt, prefix);
11960 if (URI == NULL) { 11967 if (URI == NULL) {
11961 xmlXPathReleaseObject(xpctxt, obj); 11968 xmlXPathReleaseObject(xpctxt, obj);
11962 XP_ERROR0(XPATH_UNDEF_PREFIX_ERROR); 11969 XP_ERROR0(XPATH_UNDEF_PREFIX_ERROR);
11963 } 11970 }
11964 } 11971 }
11965 /* 11972 /*
11966 * Setup axis. 11973 * Setup axis.
11967 * 11974 *
11968 * MAYBE FUTURE TODO: merging optimizations: 11975 * MAYBE FUTURE TODO: merging optimizations:
11969 * - If the nodes to be traversed wrt to the initial nodes and 11976 * - If the nodes to be traversed wrt to the initial nodes and
11970 * the current axis cannot overlap, then we could avoid searching 11977 * the current axis cannot overlap, then we could avoid searching
11971 * for duplicates during the merge. 11978 * for duplicates during the merge.
11972 * But the question is how/when to evaluate if they cannot overlap. 11979 * But the question is how/when to evaluate if they cannot overlap.
11973 * Example: if we know that for two initial nodes, the one is 11980 * Example: if we know that for two initial nodes, the one is
11974 * not in the ancestor-or-self axis of the other, then we could safely 11981 * not in the ancestor-or-self axis of the other, then we could safely
11975 * avoid a duplicate-aware merge, if the axis to be traversed is e.g. 11982 * avoid a duplicate-aware merge, if the axis to be traversed is e.g.
11976 * the descendant-or-self axis. 11983 * the descendant-or-self axis.
11977 */ 11984 */
11978 addNode = xmlXPathNodeSetAdd;
11979 mergeAndClear = xmlXPathNodeSetMergeAndClear; 11985 mergeAndClear = xmlXPathNodeSetMergeAndClear;
11980 switch (axis) { 11986 switch (axis) {
11981 case AXIS_ANCESTOR: 11987 case AXIS_ANCESTOR:
11982 first = NULL; 11988 first = NULL;
11983 next = xmlXPathNextAncestor; 11989 next = xmlXPathNextAncestor;
11984 break; 11990 break;
11985 case AXIS_ANCESTOR_OR_SELF: 11991 case AXIS_ANCESTOR_OR_SELF:
11986 first = NULL; 11992 first = NULL;
11987 next = xmlXPathNextAncestorOrSelf; 11993 next = xmlXPathNextAncestorOrSelf;
11988 break; 11994 break;
11989 case AXIS_ATTRIBUTE: 11995 case AXIS_ATTRIBUTE:
11990 first = NULL; 11996 first = NULL;
11991 last = NULL; 11997 last = NULL;
11992 next = xmlXPathNextAttribute; 11998 next = xmlXPathNextAttribute;
11993 mergeAndClear = xmlXPathNodeSetMergeAndClearNoDupls; 11999 mergeAndClear = xmlXPathNodeSetMergeAndClearNoDupls;
11994 break; 12000 break;
11995 case AXIS_CHILD: 12001 case AXIS_CHILD:
11996 last = NULL; 12002 last = NULL;
11997 if (op->rewriteType == XP_REWRITE_DOS_CHILD_ELEM) { 12003 if (op->rewriteType == XP_REWRITE_DOS_CHILD_ELEM) {
11998 /* 12004 /*
11999 * This iterator will give us only nodes which can 12005 * This iterator will give us only nodes which can
12000 * hold element nodes. 12006 * hold element nodes.
12001 */ 12007 */
12002 » » outerNext = xmlXPathNextDescendantOrSelfElemParent;» » 12008 » » outerNext = xmlXPathNextDescendantOrSelfElemParent;
12003 » }» 12009 » }
12004 if (((test == NODE_TEST_NAME) || (test == NODE_TEST_ALL)) && 12010 if (((test == NODE_TEST_NAME) || (test == NODE_TEST_ALL)) &&
12005 (type == NODE_TYPE_NODE)) 12011 (type == NODE_TYPE_NODE))
12006 { 12012 {
12007 /* 12013 /*
12008 * Optimization if an element node type is 'element'. 12014 * Optimization if an element node type is 'element'.
12009 */ 12015 */
12010 next = xmlXPathNextChildElement; 12016 next = xmlXPathNextChildElement;
12011 } else 12017 } else
12012 next = xmlXPathNextChild; 12018 next = xmlXPathNextChild;
12013 mergeAndClear = xmlXPathNodeSetMergeAndClearNoDupls; 12019 mergeAndClear = xmlXPathNodeSetMergeAndClearNoDupls;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
12048 break; 12054 break;
12049 case AXIS_SELF: 12055 case AXIS_SELF:
12050 first = NULL; 12056 first = NULL;
12051 last = NULL; 12057 last = NULL;
12052 next = xmlXPathNextSelf; 12058 next = xmlXPathNextSelf;
12053 mergeAndClear = xmlXPathNodeSetMergeAndClearNoDupls; 12059 mergeAndClear = xmlXPathNodeSetMergeAndClearNoDupls;
12054 break; 12060 break;
12055 } 12061 }
12056 12062
12057 #ifdef DEBUG_STEP 12063 #ifdef DEBUG_STEP
12058 xmlXPathDebugDumpStepAxis(axis, test, 12064 xmlXPathDebugDumpStepAxis(op,
12059 » (obj->nodesetval != NULL) ? obj->nodsetval->nodeNr : 0); 12065 » (obj->nodesetval != NULL) ? obj->nodesetval->nodeNr : 0);
12060 #endif 12066 #endif
12061 12067
12062 if (next == NULL) { 12068 if (next == NULL) {
12063 » xmlXPathReleaseObject(xpctxt, obj); 12069 » xmlXPathReleaseObject(xpctxt, obj);
12064 return(0); 12070 return(0);
12065 } 12071 }
12066 contextSeq = obj->nodesetval; 12072 contextSeq = obj->nodesetval;
12067 if ((contextSeq == NULL) || (contextSeq->nodeNr <= 0)) { 12073 if ((contextSeq == NULL) || (contextSeq->nodeNr <= 0)) {
12068 xmlXPathReleaseObject(xpctxt, obj); 12074 xmlXPathReleaseObject(xpctxt, obj);
12069 valuePush(ctxt, xmlXPathCacheWrapNodeSet(xpctxt, NULL)); 12075 valuePush(ctxt, xmlXPathCacheWrapNodeSet(xpctxt, NULL));
12070 return(0); 12076 return(0);
12071 } 12077 }
12072 /* 12078 /*
12073 * Predicate optimization --------------------------------------------- 12079 * Predicate optimization ---------------------------------------------
12074 * If this step has a last predicate, which contains a position(), 12080 * If this step has a last predicate, which contains a position(),
12075 * then we'll optimize (although not exactly "position()", but only 12081 * then we'll optimize (although not exactly "position()", but only
12076 * the short-hand form, i.e., "[n]". 12082 * the short-hand form, i.e., "[n]".
12077 * 12083 *
12078 * Example - expression "/foo[parent::bar][1]": 12084 * Example - expression "/foo[parent::bar][1]":
12079 * 12085 *
12080 * COLLECT 'child' 'name' 'node' foo -- op (we are here) 12086 * COLLECT 'child' 'name' 'node' foo -- op (we are here)
12081 * ROOT -- op->ch1 12087 * ROOT -- op->ch1
12082 * PREDICATE -- op->ch2 (predOp) 12088 * PREDICATE -- op->ch2 (predOp)
12083 * PREDICATE -- predOp->ch1 = [parent::bar] 12089 * PREDICATE -- predOp->ch1 = [parent::bar]
12084 * SORT 12090 * SORT
12085 * COLLECT 'parent' 'name' 'node' bar 12091 * COLLECT 'parent' 'name' 'node' bar
12086 * NODE 12092 * NODE
12087 * ELEM Object is a number : 1 -- predOp->ch2 = [1] 12093 * ELEM Object is a number : 1 -- predOp->ch2 = [1]
12088 * 12094 *
12089 */ 12095 */
(...skipping 12 matching lines...) Expand all
12102 * Use the next inner predicate operator. 12108 * Use the next inner predicate operator.
12103 */ 12109 */
12104 predOp = &ctxt->comp->steps[predOp->ch1]; 12110 predOp = &ctxt->comp->steps[predOp->ch1];
12105 hasPredicateRange = 1; 12111 hasPredicateRange = 1;
12106 } else { 12112 } else {
12107 /* 12113 /*
12108 * There's no other predicate than the [n] predicate. 12114 * There's no other predicate than the [n] predicate.
12109 */ 12115 */
12110 predOp = NULL; 12116 predOp = NULL;
12111 hasAxisRange = 1; 12117 hasAxisRange = 1;
12112 » }» 12118 » }
12113 } 12119 }
12114 } 12120 }
12115 breakOnFirstHit = ((toBool) && (predOp == NULL)) ? 1 : 0; 12121 breakOnFirstHit = ((toBool) && (predOp == NULL)) ? 1 : 0;
12116 /* 12122 /*
12117 * Axis traversal ----------------------------------------------------- 12123 * Axis traversal -----------------------------------------------------
12118 */ 12124 */
12119 /* 12125 /*
12120 * 2.3 Node Tests 12126 * 2.3 Node Tests
12121 * - For the attribute axis, the principal node type is attribute. 12127 * - For the attribute axis, the principal node type is attribute.
12122 * - For the namespace axis, the principal node type is namespace. 12128 * - For the namespace axis, the principal node type is namespace.
12123 * - For other axes, the principal node type is element. 12129 * - For other axes, the principal node type is element.
12124 * 12130 *
12125 * A node test * is true for any node of the 12131 * A node test * is true for any node of the
12126 * principal node type. For example, child::* will 12132 * principal node type. For example, child::* will
12127 * select all element children of the context node 12133 * select all element children of the context node
12128 */ 12134 */
12129 oldContextNode = xpctxt->node; 12135 oldContextNode = xpctxt->node;
12130 addNode = xmlXPathNodeSetAddUnique; 12136 addNode = xmlXPathNodeSetAddUnique;
12131 outSeq = NULL; 12137 outSeq = NULL;
(...skipping 16 matching lines...) Expand all
12148 contextNode = outerNext(NULL, outerContextNode); 12154 contextNode = outerNext(NULL, outerContextNode);
12149 } else 12155 } else
12150 contextNode = outerNext(contextNode, outerContextNode); 12156 contextNode = outerNext(contextNode, outerContextNode);
12151 if (contextNode == NULL) 12157 if (contextNode == NULL)
12152 continue; 12158 continue;
12153 /* 12159 /*
12154 * Set the context for the main traversal. 12160 * Set the context for the main traversal.
12155 */ 12161 */
12156 xpctxt->node = contextNode; 12162 xpctxt->node = contextNode;
12157 } else 12163 } else
12158 » xpctxt->node = contextSeq->nodeTab[contextIdx++];» 12164 » xpctxt->node = contextSeq->nodeTab[contextIdx++];
12159 12165
12160 if (seq == NULL) { 12166 if (seq == NULL) {
12161 seq = xmlXPathNodeSetCreate(NULL); 12167 seq = xmlXPathNodeSetCreate(NULL);
12162 if (seq == NULL) { 12168 if (seq == NULL) {
12163 total = 0; 12169 total = 0;
12164 goto error; 12170 goto error;
12165 } 12171 }
12166 } 12172 }
12167 /* 12173 /*
12168 * Traverse the axis and test the nodes. 12174 * Traverse the axis and test the nodes.
12169 */ 12175 */
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
12203 { 12209 {
12204 break; 12210 break;
12205 } 12211 }
12206 } 12212 }
12207 12213
12208 total++; 12214 total++;
12209 12215
12210 #ifdef DEBUG_STEP 12216 #ifdef DEBUG_STEP
12211 xmlGenericError(xmlGenericErrorContext, " %s", cur->name); 12217 xmlGenericError(xmlGenericErrorContext, " %s", cur->name);
12212 #endif 12218 #endif
12213 12219
12214 switch (test) { 12220 switch (test) {
12215 case NODE_TEST_NONE: 12221 case NODE_TEST_NONE:
12216 total = 0; 12222 total = 0;
12217 STRANGE 12223 STRANGE
12218 goto error; 12224 goto error;
12219 case NODE_TEST_TYPE: 12225 case NODE_TEST_TYPE:
12220 /* 12226 /*
12221 * TODO: Don't we need to use 12227 * TODO: Don't we need to use
12222 * xmlXPathNodeSetAddNs() for namespace nodes here? 12228 * xmlXPathNodeSetAddNs() for namespace nodes here?
12223 * Surprisingly, some c14n tests fail, if we do this. 12229 * Surprisingly, some c14n tests fail, if we do this.
12224 */ 12230 */
12225 if (type == NODE_TYPE_NODE) { 12231 if (type == NODE_TYPE_NODE) {
12226 switch (cur->type) { 12232 switch (cur->type) {
12227 case XML_DOCUMENT_NODE: 12233 case XML_DOCUMENT_NODE:
12228 case XML_HTML_DOCUMENT_NODE: 12234 case XML_HTML_DOCUMENT_NODE:
12229 #ifdef LIBXML_DOCB_ENABLED 12235 #ifdef LIBXML_DOCB_ENABLED
12230 case XML_DOCB_DOCUMENT_NODE: 12236 case XML_DOCB_DOCUMENT_NODE:
12231 #endif 12237 #endif
12232 » » » case XML_ELEMENT_NODE:» » » 12238 » » » case XML_ELEMENT_NODE:
12233 case XML_ATTRIBUTE_NODE: 12239 case XML_ATTRIBUTE_NODE:
12234 case XML_PI_NODE: 12240 case XML_PI_NODE:
12235 case XML_COMMENT_NODE: 12241 case XML_COMMENT_NODE:
12236 case XML_CDATA_SECTION_NODE: 12242 case XML_CDATA_SECTION_NODE:
12237 case XML_TEXT_NODE: 12243 case XML_TEXT_NODE:
12238 case XML_NAMESPACE_DECL: 12244 case XML_NAMESPACE_DECL:
12239 XP_TEST_HIT 12245 XP_TEST_HIT
12240 break; 12246 break;
12241 default: 12247 default:
12242 break; 12248 break;
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
12350 break; 12356 break;
12351 default: 12357 default:
12352 break; 12358 break;
12353 } 12359 }
12354 break; 12360 break;
12355 } /* switch(test) */ 12361 } /* switch(test) */
12356 } while (cur != NULL); 12362 } while (cur != NULL);
12357 12363
12358 goto apply_predicates; 12364 goto apply_predicates;
12359 12365
12360 axis_range_end: /* ----------------------------------------------------- */» 12366 axis_range_end: /* ----------------------------------------------------- */
12361 /* 12367 /*
12362 * We have a "/foo[n]", and position() = n was reached. 12368 * We have a "/foo[n]", and position() = n was reached.
12363 * Note that we can have as well "/foo/::parent::foo[1]", so 12369 * Note that we can have as well "/foo/::parent::foo[1]", so
12364 * a duplicate-aware merge is still needed. 12370 * a duplicate-aware merge is still needed.
12365 * Merge with the result. 12371 * Merge with the result.
12366 */ 12372 */
12367 if (outSeq == NULL) { 12373 if (outSeq == NULL) {
12368 outSeq = seq; 12374 outSeq = seq;
12369 seq = NULL; 12375 seq = NULL;
12370 } else 12376 } else
(...skipping 18 matching lines...) Expand all
12389 break; 12395 break;
12390 12396
12391 #ifdef DEBUG_STEP 12397 #ifdef DEBUG_STEP
12392 if (seq != NULL) 12398 if (seq != NULL)
12393 nbMatches += seq->nodeNr; 12399 nbMatches += seq->nodeNr;
12394 #endif 12400 #endif
12395 12401
12396 apply_predicates: /* --------------------------------------------------- */ 12402 apply_predicates: /* --------------------------------------------------- */
12397 /* 12403 /*
12398 * Apply predicates. 12404 * Apply predicates.
12399 » */» 12405 » */
12400 if ((predOp != NULL) && (seq->nodeNr > 0)) { 12406 if ((predOp != NULL) && (seq->nodeNr > 0)) {
12401 /* 12407 /*
12402 * E.g. when we have a "/foo[some expression][n]". 12408 * E.g. when we have a "/foo[some expression][n]".
12403 » */» » 12409 » */»
12404 /* 12410 /*
12405 * QUESTION TODO: The old predicate evaluation took into 12411 * QUESTION TODO: The old predicate evaluation took into
12406 * account location-sets. 12412 * account location-sets.
12407 * (E.g. ctxt->value->type == XPATH_LOCATIONSET) 12413 * (E.g. ctxt->value->type == XPATH_LOCATIONSET)
12408 * Do we expect such a set here? 12414 * Do we expect such a set here?
12409 * All what I learned now from the evaluation semantics 12415 * All what I learned now from the evaluation semantics
12410 * does not indicate that a location-set will be processed 12416 * does not indicate that a location-set will be processed
12411 * here, so this looks OK. 12417 * here, so this looks OK.
12412 » */» » 12418 » */»
12413 /* 12419 /*
12414 * Iterate over all predicates, starting with the outermost 12420 * Iterate over all predicates, starting with the outermost
12415 * predicate. 12421 * predicate.
12416 * TODO: Problem: we cannot execute the inner predicates first 12422 * TODO: Problem: we cannot execute the inner predicates first
12417 * since we cannot go back *up* the operator tree! 12423 * since we cannot go back *up* the operator tree!
12418 * Options we have: 12424 * Options we have:
12419 * 1) Use of recursive functions (like is it currently done 12425 * 1) Use of recursive functions (like is it currently done
12420 * via xmlXPathCompOpEval()) 12426 * via xmlXPathCompOpEval())
12421 * 2) Add a predicate evaluation information stack to the 12427 * 2) Add a predicate evaluation information stack to the
12422 * context struct 12428 * context struct
12423 * 3) Change the way the operators are linked; we need a 12429 * 3) Change the way the operators are linked; we need a
12424 * "parent" field on xmlXPathStepOp 12430 * "parent" field on xmlXPathStepOp
12425 * 12431 *
12426 * For the moment, I'll try to solve this with a recursive 12432 * For the moment, I'll try to solve this with a recursive
12427 * function: xmlXPathCompOpEvalPredicate(). 12433 * function: xmlXPathCompOpEvalPredicate().
12428 » */» 12434 » */
12429 size = seq->nodeNr; 12435 size = seq->nodeNr;
12430 if (hasPredicateRange != 0) 12436 if (hasPredicateRange != 0)
12431 newSize = xmlXPathCompOpEvalPositionalPredicate(ctxt, 12437 newSize = xmlXPathCompOpEvalPositionalPredicate(ctxt,
12432 predOp, seq, size, maxPos, maxPos, hasNsNodes); 12438 predOp, seq, size, maxPos, maxPos, hasNsNodes);
12433 else 12439 else
12434 newSize = xmlXPathCompOpEvalPredicate(ctxt, 12440 newSize = xmlXPathCompOpEvalPredicate(ctxt,
12435 predOp, seq, size, hasNsNodes); 12441 predOp, seq, size, hasNsNodes);
12436 12442
12437 if (ctxt->error != XPATH_EXPRESSION_OK) { 12443 if (ctxt->error != XPATH_EXPRESSION_OK) {
12438 total = 0; 12444 total = 0;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
12473 } else if (seq->nodeNr > 0) { 12479 } else if (seq->nodeNr > 0) {
12474 /* 12480 /*
12475 * Add to result set. 12481 * Add to result set.
12476 */ 12482 */
12477 if (outSeq == NULL) { 12483 if (outSeq == NULL) {
12478 outSeq = seq; 12484 outSeq = seq;
12479 seq = NULL; 12485 seq = NULL;
12480 } else { 12486 } else {
12481 outSeq = mergeAndClear(outSeq, seq, 0); 12487 outSeq = mergeAndClear(outSeq, seq, 0);
12482 } 12488 }
12483 » }» 12489 » }
12484 } 12490 }
12485 12491
12486 error: 12492 error:
12487 if ((obj->boolval) && (obj->user != NULL)) { 12493 if ((obj->boolval) && (obj->user != NULL)) {
12488 /* 12494 /*
12489 * QUESTION TODO: What does this do and why? 12495 * QUESTION TODO: What does this do and why?
12490 * TODO: Do we have to do this also for the "error" 12496 * TODO: Do we have to do this also for the "error"
12491 * cleanup further down? 12497 * cleanup further down?
12492 */ 12498 */
12493 ctxt->value->boolval = 1; 12499 ctxt->value->boolval = 1;
12494 ctxt->value->user = obj->user; 12500 ctxt->value->user = obj->user;
12495 obj->user = NULL; 12501 obj->user = NULL;
12496 obj->boolval = 0; 12502 obj->boolval = 0;
12497 } 12503 }
12498 xmlXPathReleaseObject(xpctxt, obj); 12504 xmlXPathReleaseObject(xpctxt, obj);
12499 12505
12500 /* 12506 /*
12501 * Ensure we return at least an emtpy set. 12507 * Ensure we return at least an emtpy set.
12502 */ 12508 */
12503 if (outSeq == NULL) { 12509 if (outSeq == NULL) {
12504 if ((seq != NULL) && (seq->nodeNr == 0)) 12510 if ((seq != NULL) && (seq->nodeNr == 0))
12505 outSeq = seq; 12511 outSeq = seq;
12506 else 12512 else
12507 outSeq = xmlXPathNodeSetCreate(NULL); 12513 outSeq = xmlXPathNodeSetCreate(NULL);
12508 /* XXX what if xmlXPathNodeSetCreate returned NULL here? */ 12514 /* XXX what if xmlXPathNodeSetCreate returned NULL here? */
12509 } 12515 }
12510 if ((seq != NULL) && (seq != outSeq)) { 12516 if ((seq != NULL) && (seq != outSeq)) {
12511 xmlXPathFreeNodeSet(seq); 12517 xmlXPathFreeNodeSet(seq);
12512 } 12518 }
12513 /* 12519 /*
12514 * Hand over the result. Better to push the set also in 12520 * Hand over the result. Better to push the set also in
12515 * case of errors. 12521 * case of errors.
12516 */ 12522 */
12517 valuePush(ctxt, xmlXPathCacheWrapNodeSet(xpctxt, outSeq)); 12523 valuePush(ctxt, xmlXPathCacheWrapNodeSet(xpctxt, outSeq));
12518 /* 12524 /*
12519 * Reset the context node. 12525 * Reset the context node.
12520 */ 12526 */
12521 xpctxt->node = oldContextNode; 12527 xpctxt->node = oldContextNode;
12522 12528
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
12786 return (xmlXPathCompOpEval(ctxt, op)); 12792 return (xmlXPathCompOpEval(ctxt, op));
12787 } 12793 }
12788 } 12794 }
12789 12795
12790 #ifdef XP_OPTIMIZED_FILTER_FIRST 12796 #ifdef XP_OPTIMIZED_FILTER_FIRST
12791 static int 12797 static int
12792 xmlXPathCompOpEvalFilterFirst(xmlXPathParserContextPtr ctxt, 12798 xmlXPathCompOpEvalFilterFirst(xmlXPathParserContextPtr ctxt,
12793 xmlXPathStepOpPtr op, xmlNodePtr * first) 12799 xmlXPathStepOpPtr op, xmlNodePtr * first)
12794 { 12800 {
12795 int total = 0; 12801 int total = 0;
12796 xmlXPathCompExprPtr comp; 12802 xmlXPathCompExprPtr comp;
12797 xmlXPathObjectPtr res; 12803 xmlXPathObjectPtr res;
12798 xmlXPathObjectPtr obj; 12804 xmlXPathObjectPtr obj;
12799 xmlNodeSetPtr oldset; 12805 xmlNodeSetPtr oldset;
12800 xmlNodePtr oldnode; 12806 xmlNodePtr oldnode;
12801 xmlDocPtr oldDoc; 12807 xmlDocPtr oldDoc;
12802 int i; 12808 int i;
12803 12809
12804 CHECK_ERROR0; 12810 CHECK_ERROR0;
12805 comp = ctxt->comp; 12811 comp = ctxt->comp;
12806 /* 12812 /*
12807 * Optimization for ()[last()] selection i.e. the last elem 12813 * Optimization for ()[last()] selection i.e. the last elem
12808 */ 12814 */
12809 if ((op->ch1 != -1) && (op->ch2 != -1) && 12815 if ((op->ch1 != -1) && (op->ch2 != -1) &&
12810 (comp->steps[op->ch1].op == XPATH_OP_SORT) && 12816 (comp->steps[op->ch1].op == XPATH_OP_SORT) &&
12811 (comp->steps[op->ch2].op == XPATH_OP_SORT)) { 12817 (comp->steps[op->ch2].op == XPATH_OP_SORT)) {
12812 int f = comp->steps[op->ch2].ch1; 12818 int f = comp->steps[op->ch2].ch1;
12813 » 12819
12814 if ((f != -1) && 12820 if ((f != -1) &&
12815 (comp->steps[f].op == XPATH_OP_FUNCTION) && 12821 (comp->steps[f].op == XPATH_OP_FUNCTION) &&
12816 (comp->steps[f].value5 == NULL) && 12822 (comp->steps[f].value5 == NULL) &&
12817 (comp->steps[f].value == 0) && 12823 (comp->steps[f].value == 0) &&
12818 (comp->steps[f].value4 != NULL) && 12824 (comp->steps[f].value4 != NULL) &&
12819 (xmlStrEqual 12825 (xmlStrEqual
12820 (comp->steps[f].value4, BAD_CAST "last"))) { 12826 (comp->steps[f].value4, BAD_CAST "last"))) {
12821 xmlNodePtr last = NULL; 12827 xmlNodePtr last = NULL;
12822 » 12828
12823 total += 12829 total +=
12824 xmlXPathCompOpEvalLast(ctxt, 12830 xmlXPathCompOpEvalLast(ctxt,
12825 &comp->steps[op->ch1], 12831 &comp->steps[op->ch1],
12826 &last); 12832 &last);
12827 CHECK_ERROR0; 12833 CHECK_ERROR0;
12828 /* 12834 /*
12829 * The nodeset should be in document order, 12835 * The nodeset should be in document order,
12830 * Keep only the last value 12836 * Keep only the last value
12831 */ 12837 */
12832 if ((ctxt->value != NULL) && 12838 if ((ctxt->value != NULL) &&
12833 (ctxt->value->type == XPATH_NODESET) && 12839 (ctxt->value->type == XPATH_NODESET) &&
12834 (ctxt->value->nodesetval != NULL) && 12840 (ctxt->value->nodesetval != NULL) &&
12835 (ctxt->value->nodesetval->nodeTab != NULL) && 12841 (ctxt->value->nodesetval->nodeTab != NULL) &&
12836 (ctxt->value->nodesetval->nodeNr > 1)) { 12842 (ctxt->value->nodesetval->nodeNr > 1)) {
12837 ctxt->value->nodesetval->nodeTab[0] = 12843 ctxt->value->nodesetval->nodeTab[0] =
12838 ctxt->value->nodesetval->nodeTab[ctxt-> 12844 ctxt->value->nodesetval->nodeTab[ctxt->
12839 value-> 12845 value->
12840 nodesetval-> 12846 nodesetval->
12841 nodeNr - 12847 nodeNr -
12842 1]; 12848 1];
12843 ctxt->value->nodesetval->nodeNr = 1; 12849 ctxt->value->nodesetval->nodeNr = 1;
12844 *first = *(ctxt->value->nodesetval->nodeTab); 12850 *first = *(ctxt->value->nodesetval->nodeTab);
12845 } 12851 }
12846 return (total); 12852 return (total);
12847 } 12853 }
12848 } 12854 }
12849 12855
12850 if (op->ch1 != -1) 12856 if (op->ch1 != -1)
12851 total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 12857 total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
12852 CHECK_ERROR0; 12858 CHECK_ERROR0;
12853 if (op->ch2 == -1) 12859 if (op->ch2 == -1)
12854 return (total); 12860 return (total);
12855 if (ctxt->value == NULL) 12861 if (ctxt->value == NULL)
12856 return (total); 12862 return (total);
12857 12863
12858 #ifdef LIBXML_XPTR_ENABLED 12864 #ifdef LIBXML_XPTR_ENABLED
12859 oldnode = ctxt->context->node; 12865 oldnode = ctxt->context->node;
12860 /* 12866 /*
12861 * Hum are we filtering the result of an XPointer expression 12867 * Hum are we filtering the result of an XPointer expression
12862 */ 12868 */
12863 if (ctxt->value->type == XPATH_LOCATIONSET) { 12869 if (ctxt->value->type == XPATH_LOCATIONSET) {
12864 xmlXPathObjectPtr tmp = NULL; 12870 xmlXPathObjectPtr tmp = NULL;
12865 xmlLocationSetPtr newlocset = NULL; 12871 xmlLocationSetPtr newlocset = NULL;
12866 xmlLocationSetPtr oldlocset; 12872 xmlLocationSetPtr oldlocset;
12867 » 12873
12868 /* 12874 /*
12869 * Extract the old locset, and then evaluate the result of the 12875 * Extract the old locset, and then evaluate the result of the
12870 * expression for all the element in the locset. use it to grow 12876 * expression for all the element in the locset. use it to grow
12871 * up a new locset. 12877 * up a new locset.
12872 */ 12878 */
12873 CHECK_TYPE0(XPATH_LOCATIONSET); 12879 CHECK_TYPE0(XPATH_LOCATIONSET);
12874 obj = valuePop(ctxt); 12880 obj = valuePop(ctxt);
12875 oldlocset = obj->user; 12881 oldlocset = obj->user;
12876 ctxt->context->node = NULL; 12882 ctxt->context->node = NULL;
12877 » 12883
12878 if ((oldlocset == NULL) || (oldlocset->locNr == 0)) { 12884 if ((oldlocset == NULL) || (oldlocset->locNr == 0)) {
12879 ctxt->context->contextSize = 0; 12885 ctxt->context->contextSize = 0;
12880 ctxt->context->proximityPosition = 0; 12886 ctxt->context->proximityPosition = 0;
12881 if (op->ch2 != -1) 12887 if (op->ch2 != -1)
12882 total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); 12888 total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
12883 res = valuePop(ctxt); 12889 res = valuePop(ctxt);
12884 if (res != NULL) { 12890 if (res != NULL) {
12885 xmlXPathReleaseObject(ctxt->context, res); 12891 xmlXPathReleaseObject(ctxt->context, res);
12886 } 12892 }
12887 valuePush(ctxt, obj); 12893 valuePush(ctxt, obj);
12888 CHECK_ERROR0; 12894 CHECK_ERROR0;
12889 return (total); 12895 return (total);
12890 } 12896 }
12891 newlocset = xmlXPtrLocationSetCreate(NULL); 12897 newlocset = xmlXPtrLocationSetCreate(NULL);
12892 » 12898
12893 for (i = 0; i < oldlocset->locNr; i++) { 12899 for (i = 0; i < oldlocset->locNr; i++) {
12894 /* 12900 /*
12895 * Run the evaluation with a node list made of a 12901 * Run the evaluation with a node list made of a
12896 * single item in the nodelocset. 12902 * single item in the nodelocset.
12897 */ 12903 */
12898 ctxt->context->node = oldlocset->locTab[i]->user; 12904 ctxt->context->node = oldlocset->locTab[i]->user;
12899 ctxt->context->contextSize = oldlocset->locNr; 12905 ctxt->context->contextSize = oldlocset->locNr;
12900 ctxt->context->proximityPosition = i + 1; 12906 ctxt->context->proximityPosition = i + 1;
12901 if (tmp == NULL) { 12907 if (tmp == NULL) {
12902 tmp = xmlXPathCacheNewNodeSet(ctxt->context, 12908 tmp = xmlXPathCacheNewNodeSet(ctxt->context,
12903 ctxt->context->node); 12909 ctxt->context->node);
12904 } else { 12910 } else {
12905 xmlXPathNodeSetAddUnique(tmp->nodesetval, 12911 xmlXPathNodeSetAddUnique(tmp->nodesetval,
12906 ctxt->context->node); 12912 ctxt->context->node);
12907 » }» 12913 » }
12908 valuePush(ctxt, tmp); 12914 valuePush(ctxt, tmp);
12909 if (op->ch2 != -1) 12915 if (op->ch2 != -1)
12910 total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); 12916 total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
12911 if (ctxt->error != XPATH_EXPRESSION_OK) { 12917 if (ctxt->error != XPATH_EXPRESSION_OK) {
12912 xmlXPathFreeObject(obj); 12918 xmlXPathFreeObject(obj);
12913 return(0); 12919 return(0);
12914 } 12920 }
12915 /* 12921 /*
12916 * The result of the evaluation need to be tested to 12922 * The result of the evaluation need to be tested to
12917 * decided whether the filter succeeded or not 12923 * decided whether the filter succeeded or not
12918 */ 12924 */
12919 res = valuePop(ctxt); 12925 res = valuePop(ctxt);
12920 if (xmlXPathEvaluatePredicateResult(ctxt, res)) { 12926 if (xmlXPathEvaluatePredicateResult(ctxt, res)) {
12921 xmlXPtrLocationSetAdd(newlocset, 12927 xmlXPtrLocationSetAdd(newlocset,
12922 xmlXPathCacheObjectCopy(ctxt->context, 12928 xmlXPathCacheObjectCopy(ctxt->context,
12923 oldlocset->locTab[i])); 12929 oldlocset->locTab[i]));
12924 } 12930 }
12925 /* 12931 /*
12926 * Cleanup 12932 * Cleanup
12927 */ 12933 */
12928 if (res != NULL) { 12934 if (res != NULL) {
12929 xmlXPathReleaseObject(ctxt->context, res); 12935 xmlXPathReleaseObject(ctxt->context, res);
12930 } 12936 }
12931 if (ctxt->value == tmp) { 12937 if (ctxt->value == tmp) {
12932 valuePop(ctxt); 12938 valuePop(ctxt);
12933 » » xmlXPathNodeSetClear(tmp->nodesetval, 1);» » 12939 » » xmlXPathNodeSetClear(tmp->nodesetval, 1);
12934 /* 12940 /*
12935 * REVISIT TODO: Don't create a temporary nodeset 12941 * REVISIT TODO: Don't create a temporary nodeset
12936 * for everly iteration. 12942 * for everly iteration.
12937 */ 12943 */
12938 /* OLD: xmlXPathFreeObject(res); */ 12944 /* OLD: xmlXPathFreeObject(res); */
12939 } else 12945 } else
12940 » » tmp = NULL;» 12946 » » tmp = NULL;
12941 ctxt->context->node = NULL; 12947 ctxt->context->node = NULL;
12942 /* 12948 /*
12943 * Only put the first node in the result, then leave. 12949 * Only put the first node in the result, then leave.
12944 */ 12950 */
12945 if (newlocset->locNr > 0) { 12951 if (newlocset->locNr > 0) {
12946 *first = (xmlNodePtr) oldlocset->locTab[i]->user; 12952 *first = (xmlNodePtr) oldlocset->locTab[i]->user;
12947 break; 12953 break;
12948 } 12954 }
12949 } 12955 }
12950 if (tmp != NULL) { 12956 if (tmp != NULL) {
12951 xmlXPathReleaseObject(ctxt->context, tmp); 12957 xmlXPathReleaseObject(ctxt->context, tmp);
12952 } 12958 }
12953 /* 12959 /*
12954 * The result is used as the new evaluation locset. 12960 * The result is used as the new evaluation locset.
12955 */ 12961 */
12956 xmlXPathReleaseObject(ctxt->context, obj); 12962 xmlXPathReleaseObject(ctxt->context, obj);
12957 ctxt->context->node = NULL; 12963 ctxt->context->node = NULL;
12958 ctxt->context->contextSize = -1; 12964 ctxt->context->contextSize = -1;
12959 ctxt->context->proximityPosition = -1; 12965 ctxt->context->proximityPosition = -1;
12960 valuePush(ctxt, xmlXPtrWrapLocationSet(newlocset)); 12966 valuePush(ctxt, xmlXPtrWrapLocationSet(newlocset));
12961 ctxt->context->node = oldnode; 12967 ctxt->context->node = oldnode;
12962 return (total); 12968 return (total);
12963 } 12969 }
12964 #endif /* LIBXML_XPTR_ENABLED */ 12970 #endif /* LIBXML_XPTR_ENABLED */
12965 12971
12966 /* 12972 /*
12967 * Extract the old set, and then evaluate the result of the 12973 * Extract the old set, and then evaluate the result of the
12968 * expression for all the element in the set. use it to grow 12974 * expression for all the element in the set. use it to grow
12969 * up a new set. 12975 * up a new set.
12970 */ 12976 */
12971 CHECK_TYPE0(XPATH_NODESET); 12977 CHECK_TYPE0(XPATH_NODESET);
12972 obj = valuePop(ctxt); 12978 obj = valuePop(ctxt);
12973 oldset = obj->nodesetval; 12979 oldset = obj->nodesetval;
12974 12980
12975 oldnode = ctxt->context->node; 12981 oldnode = ctxt->context->node;
12976 oldDoc = ctxt->context->doc; 12982 oldDoc = ctxt->context->doc;
12977 ctxt->context->node = NULL; 12983 ctxt->context->node = NULL;
12978 12984
12979 if ((oldset == NULL) || (oldset->nodeNr == 0)) { 12985 if ((oldset == NULL) || (oldset->nodeNr == 0)) {
12980 ctxt->context->contextSize = 0; 12986 ctxt->context->contextSize = 0;
12981 ctxt->context->proximityPosition = 0; 12987 ctxt->context->proximityPosition = 0;
12982 /* QUESTION TODO: Why was this code commented out? 12988 /* QUESTION TODO: Why was this code commented out?
12983 if (op->ch2 != -1) 12989 if (op->ch2 != -1)
12984 total += 12990 total +=
12985 xmlXPathCompOpEval(ctxt, 12991 xmlXPathCompOpEval(ctxt,
12986 &comp->steps[op->ch2]); 12992 &comp->steps[op->ch2]);
12987 CHECK_ERROR0; 12993 CHECK_ERROR0;
12988 res = valuePop(ctxt); 12994 res = valuePop(ctxt);
12989 if (res != NULL) 12995 if (res != NULL)
12990 xmlXPathFreeObject(res); 12996 xmlXPathFreeObject(res);
12991 */ 12997 */
12992 valuePush(ctxt, obj); 12998 valuePush(ctxt, obj);
12993 ctxt->context->node = oldnode; 12999 ctxt->context->node = oldnode;
12994 CHECK_ERROR0; 13000 CHECK_ERROR0;
12995 } else { 13001 } else {
12996 xmlNodeSetPtr newset; 13002 xmlNodeSetPtr newset;
12997 xmlXPathObjectPtr tmp = NULL; 13003 xmlXPathObjectPtr tmp = NULL;
12998 /* 13004 /*
12999 * Initialize the new set. 13005 * Initialize the new set.
13000 * Also set the xpath document in case things like 13006 * Also set the xpath document in case things like
13001 * key() evaluation are attempted on the predicate 13007 * key() evaluation are attempted on the predicate
13002 » */» 13008 » */
13003 newset = xmlXPathNodeSetCreate(NULL); 13009 newset = xmlXPathNodeSetCreate(NULL);
13004 /* XXX what if xmlXPathNodeSetCreate returned NULL? */ 13010 /* XXX what if xmlXPathNodeSetCreate returned NULL? */
13005 » 13011
13006 for (i = 0; i < oldset->nodeNr; i++) { 13012 for (i = 0; i < oldset->nodeNr; i++) {
13007 /* 13013 /*
13008 * Run the evaluation with a node list made of 13014 * Run the evaluation with a node list made of
13009 * a single item in the nodeset. 13015 * a single item in the nodeset.
13010 */ 13016 */
13011 ctxt->context->node = oldset->nodeTab[i]; 13017 ctxt->context->node = oldset->nodeTab[i];
13012 if ((oldset->nodeTab[i]->type != XML_NAMESPACE_DECL) && 13018 if ((oldset->nodeTab[i]->type != XML_NAMESPACE_DECL) &&
13013 (oldset->nodeTab[i]->doc != NULL)) 13019 (oldset->nodeTab[i]->doc != NULL))
13014 ctxt->context->doc = oldset->nodeTab[i]->doc; 13020 ctxt->context->doc = oldset->nodeTab[i]->doc;
13015 if (tmp == NULL) { 13021 if (tmp == NULL) {
13016 tmp = xmlXPathCacheNewNodeSet(ctxt->context, 13022 tmp = xmlXPathCacheNewNodeSet(ctxt->context,
13017 ctxt->context->node); 13023 ctxt->context->node);
13018 } else { 13024 } else {
13019 xmlXPathNodeSetAddUnique(tmp->nodesetval, 13025 xmlXPathNodeSetAddUnique(tmp->nodesetval,
13020 ctxt->context->node); 13026 ctxt->context->node);
13021 } 13027 }
13022 valuePush(ctxt, tmp); 13028 valuePush(ctxt, tmp);
13023 ctxt->context->contextSize = oldset->nodeNr; 13029 ctxt->context->contextSize = oldset->nodeNr;
13024 ctxt->context->proximityPosition = i + 1; 13030 ctxt->context->proximityPosition = i + 1;
13025 if (op->ch2 != -1) 13031 if (op->ch2 != -1)
13026 total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); 13032 total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
13027 if (ctxt->error != XPATH_EXPRESSION_OK) { 13033 if (ctxt->error != XPATH_EXPRESSION_OK) {
13028 xmlXPathFreeNodeSet(newset); 13034 xmlXPathFreeNodeSet(newset);
13029 xmlXPathFreeObject(obj); 13035 xmlXPathFreeObject(obj);
13030 return(0); 13036 return(0);
13031 » }» 13037 » }
13032 /* 13038 /*
13033 * The result of the evaluation needs to be tested to 13039 * The result of the evaluation needs to be tested to
13034 * decide whether the filter succeeded or not 13040 * decide whether the filter succeeded or not
13035 */ 13041 */
13036 res = valuePop(ctxt); 13042 res = valuePop(ctxt);
13037 if (xmlXPathEvaluatePredicateResult(ctxt, res)) { 13043 if (xmlXPathEvaluatePredicateResult(ctxt, res)) {
13038 xmlXPathNodeSetAdd(newset, oldset->nodeTab[i]); 13044 xmlXPathNodeSetAdd(newset, oldset->nodeTab[i]);
13039 » }» 13045 » }
13040 /* 13046 /*
13041 * Cleanup 13047 * Cleanup
13042 */ 13048 */
13043 if (res != NULL) { 13049 if (res != NULL) {
13044 xmlXPathReleaseObject(ctxt->context, res); 13050 xmlXPathReleaseObject(ctxt->context, res);
13045 } 13051 }
13046 if (ctxt->value == tmp) { 13052 if (ctxt->value == tmp) {
13047 valuePop(ctxt); 13053 valuePop(ctxt);
13048 /* 13054 /*
13049 * Don't free the temporary nodeset 13055 * Don't free the temporary nodeset
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
13165 cs = ctxt->context->contextSize; 13171 cs = ctxt->context->contextSize;
13166 total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 13172 total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
13167 CHECK_ERROR0; 13173 CHECK_ERROR0;
13168 ctxt->context->doc = bakd; 13174 ctxt->context->doc = bakd;
13169 ctxt->context->node = bak; 13175 ctxt->context->node = bak;
13170 ctxt->context->proximityPosition = pp; 13176 ctxt->context->proximityPosition = pp;
13171 ctxt->context->contextSize = cs; 13177 ctxt->context->contextSize = cs;
13172 total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); 13178 total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
13173 CHECK_ERROR0; 13179 CHECK_ERROR0;
13174 if (op->value) 13180 if (op->value)
13175 » equal = xmlXPathEqualValues(ctxt); 13181 » » equal = xmlXPathEqualValues(ctxt);
13176 else 13182 else
13177 equal = xmlXPathNotEqualValues(ctxt); 13183 equal = xmlXPathNotEqualValues(ctxt);
13178 valuePush(ctxt, xmlXPathCacheNewBoolean(ctxt->context, equal)); 13184 valuePush(ctxt, xmlXPathCacheNewBoolean(ctxt->context, equal));
13179 return (total); 13185 return (total);
13180 case XPATH_OP_CMP: 13186 case XPATH_OP_CMP:
13181 bakd = ctxt->context->doc; 13187 bakd = ctxt->context->doc;
13182 bak = ctxt->context->node; 13188 bak = ctxt->context->node;
13183 pp = ctxt->context->proximityPosition; 13189 pp = ctxt->context->proximityPosition;
13184 cs = ctxt->context->contextSize; 13190 cs = ctxt->context->contextSize;
13185 total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); 13191 total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
13318 ctxt->error = XPATH_UNDEF_VARIABLE_ERROR; 13324 ctxt->error = XPATH_UNDEF_VARIABLE_ERROR;
13319 return(0); 13325 return(0);
13320 } 13326 }
13321 valuePush(ctxt, val); 13327 valuePush(ctxt, val);
13322 } else { 13328 } else {
13323 const xmlChar *URI; 13329 const xmlChar *URI;
13324 13330
13325 URI = xmlXPathNsLookup(ctxt->context, op->value5); 13331 URI = xmlXPathNsLookup(ctxt->context, op->value5);
13326 if (URI == NULL) { 13332 if (URI == NULL) {
13327 xmlGenericError(xmlGenericErrorContext, 13333 xmlGenericError(xmlGenericErrorContext,
13328 "xmlXPathCompOpEval: variable %s bound t o undefined prefix %s\n", 13334 "xmlXPathCompOpEval: variable %s bound to undefined prefix %s\n",
13329 op->value4, op->value5); 13335 (char *) op->value4, (char *)op->value5);
13330 return (total); 13336 return (total);
13331 } 13337 }
13332 val = xmlXPathVariableLookupNS(ctxt->context, 13338 val = xmlXPathVariableLookupNS(ctxt->context,
13333 op->value4, URI); 13339 op->value4, URI);
13334 if (val == NULL) { 13340 if (val == NULL) {
13335 ctxt->error = XPATH_UNDEF_VARIABLE_ERROR; 13341 ctxt->error = XPATH_UNDEF_VARIABLE_ERROR;
13336 return(0); 13342 return(0);
13337 } 13343 }
13338 valuePush(ctxt, val); 13344 valuePush(ctxt, val);
13339 } 13345 }
(...skipping 26 matching lines...) Expand all
13366 const xmlChar *URI = NULL; 13372 const xmlChar *URI = NULL;
13367 13373
13368 if (op->value5 == NULL) 13374 if (op->value5 == NULL)
13369 func = 13375 func =
13370 xmlXPathFunctionLookup(ctxt->context, 13376 xmlXPathFunctionLookup(ctxt->context,
13371 op->value4); 13377 op->value4);
13372 else { 13378 else {
13373 URI = xmlXPathNsLookup(ctxt->context, op->value5); 13379 URI = xmlXPathNsLookup(ctxt->context, op->value5);
13374 if (URI == NULL) { 13380 if (URI == NULL) {
13375 xmlGenericError(xmlGenericErrorContext, 13381 xmlGenericError(xmlGenericErrorContext,
13376 "xmlXPathCompOpEval: function %s bou nd to undefined prefix %s\n", 13382 "xmlXPathCompOpEval: function %s bound to undefined prefix %s\n",
13377 op->value4, op->value5); 13383 (char *)op->value4, (char *)op->value5);
13378 return (total); 13384 return (total);
13379 } 13385 }
13380 func = xmlXPathFunctionLookupNS(ctxt->context, 13386 func = xmlXPathFunctionLookupNS(ctxt->context,
13381 op->value4, URI); 13387 op->value4, URI);
13382 } 13388 }
13383 if (func == NULL) { 13389 if (func == NULL) {
13384 xmlGenericError(xmlGenericErrorContext, 13390 xmlGenericError(xmlGenericErrorContext,
13385 "xmlXPathCompOpEval: function %s not fou nd\n", 13391 "xmlXPathCompOpEval: function %s not found\n",
13386 op->value4); 13392 (char *)op->value4);
13387 XP_ERROR0(XPATH_UNKNOWN_FUNC_ERROR); 13393 XP_ERROR0(XPATH_UNKNOWN_FUNC_ERROR);
13388 } 13394 }
13389 op->cache = XML_CAST_FPTR(func); 13395 op->cache = XML_CAST_FPTR(func);
13390 op->cacheURI = (void *) URI; 13396 op->cacheURI = (void *) URI;
13391 } 13397 }
13392 oldFunc = ctxt->context->function; 13398 oldFunc = ctxt->context->function;
13393 oldFuncURI = ctxt->context->functionURI; 13399 oldFuncURI = ctxt->context->functionURI;
13394 ctxt->context->function = op->value4; 13400 ctxt->context->function = op->value4;
13395 ctxt->context->functionURI = op->cacheURI; 13401 ctxt->context->functionURI = op->cacheURI;
13396 func(ctxt, op->value); 13402 func(ctxt, op->value);
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
13574 /* 13580 /*
13575 * Run the evaluation with a node list made of a 13581 * Run the evaluation with a node list made of a
13576 * single item in the nodelocset. 13582 * single item in the nodelocset.
13577 */ 13583 */
13578 ctxt->context->node = oldlocset->locTab[i]->user; 13584 ctxt->context->node = oldlocset->locTab[i]->user;
13579 ctxt->context->contextSize = oldlocset->locNr; 13585 ctxt->context->contextSize = oldlocset->locNr;
13580 ctxt->context->proximityPosition = i + 1; 13586 ctxt->context->proximityPosition = i + 1;
13581 tmp = xmlXPathCacheNewNodeSet(ctxt->context, 13587 tmp = xmlXPathCacheNewNodeSet(ctxt->context,
13582 ctxt->context->node); 13588 ctxt->context->node);
13583 valuePush(ctxt, tmp); 13589 valuePush(ctxt, tmp);
13584 » » » 13590
13585 if (op->ch2 != -1) 13591 if (op->ch2 != -1)
13586 total += 13592 total +=
13587 xmlXPathCompOpEval(ctxt, 13593 xmlXPathCompOpEval(ctxt,
13588 &comp->steps[op->ch2]); 13594 &comp->steps[op->ch2]);
13589 if (ctxt->error != XPATH_EXPRESSION_OK) { 13595 if (ctxt->error != XPATH_EXPRESSION_OK) {
13590 xmlXPathFreeObject(obj); 13596 xmlXPathFreeObject(obj);
13591 return(0); 13597 return(0);
13592 } 13598 }
13593 13599
13594 /* 13600 /*
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
13683 * node-set context pos 13689 * node-set context pos
13684 * nA 1 13690 * nA 1
13685 * nB 2 13691 * nB 2
13686 * nC 3 13692 * nC 3
13687 * After applying predicate [position() > 1] : 13693 * After applying predicate [position() > 1] :
13688 * node-set context pos 13694 * node-set context pos
13689 * nB 1 13695 * nB 1
13690 * nC 2 13696 * nC 2
13691 * 13697 *
13692 * removed the first node in the node-set, then 13698 * removed the first node in the node-set, then
13693 » » * the context position of the 13699 » » * the context position of the
13694 */ 13700 */
13695 for (i = 0; i < oldset->nodeNr; i++) { 13701 for (i = 0; i < oldset->nodeNr; i++) {
13696 /* 13702 /*
13697 * Run the evaluation with a node list made of 13703 * Run the evaluation with a node list made of
13698 * a single item in the nodeset. 13704 * a single item in the nodeset.
13699 */ 13705 */
13700 ctxt->context->node = oldset->nodeTab[i]; 13706 ctxt->context->node = oldset->nodeTab[i];
13701 if ((oldset->nodeTab[i]->type != XML_NAMESPACE_DECL) && 13707 if ((oldset->nodeTab[i]->type != XML_NAMESPACE_DECL) &&
13702 (oldset->nodeTab[i]->doc != NULL)) 13708 (oldset->nodeTab[i]->doc != NULL))
13703 ctxt->context->doc = oldset->nodeTab[i]->doc; 13709 ctxt->context->doc = oldset->nodeTab[i]->doc;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
13740 } 13746 }
13741 13747
13742 /* 13748 /*
13743 * Cleanup 13749 * Cleanup
13744 */ 13750 */
13745 if (res != NULL) { 13751 if (res != NULL) {
13746 xmlXPathReleaseObject(ctxt->context, res); 13752 xmlXPathReleaseObject(ctxt->context, res);
13747 } 13753 }
13748 if (ctxt->value == tmp) { 13754 if (ctxt->value == tmp) {
13749 valuePop(ctxt); 13755 valuePop(ctxt);
13750 » » » xmlXPathNodeSetClear(tmp->nodesetval, 1);» » » 13756 » » » xmlXPathNodeSetClear(tmp->nodesetval, 1);
13751 /* 13757 /*
13752 * Don't free the temporary nodeset 13758 * Don't free the temporary nodeset
13753 * in order to avoid massive recreation inside this 13759 * in order to avoid massive recreation inside this
13754 * loop. 13760 * loop.
13755 */ 13761 */
13756 } else 13762 } else
13757 tmp = NULL; 13763 tmp = NULL;
13758 ctxt->context->node = NULL; 13764 ctxt->context->node = NULL;
13759 } 13765 }
13760 if (tmp != NULL) 13766 if (tmp != NULL)
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
13843 total += 13849 total +=
13844 xmlXPathCompOpEval(ctxt, 13850 xmlXPathCompOpEval(ctxt,
13845 &comp->steps[op->ch2]); 13851 &comp->steps[op->ch2]);
13846 if (ctxt->error != XPATH_EXPRESSION_OK) { 13852 if (ctxt->error != XPATH_EXPRESSION_OK) {
13847 xmlXPathFreeObject(obj); 13853 xmlXPathFreeObject(obj);
13848 return(0); 13854 return(0);
13849 } 13855 }
13850 13856
13851 res = valuePop(ctxt); 13857 res = valuePop(ctxt);
13852 if (res->type == XPATH_LOCATIONSET) { 13858 if (res->type == XPATH_LOCATIONSET) {
13853 » » » xmlLocationSetPtr rloc = 13859 » » » xmlLocationSetPtr rloc =
13854 (xmlLocationSetPtr)res->user; 13860 (xmlLocationSetPtr)res->user;
13855 for (j=0; j<rloc->locNr; j++) { 13861 for (j=0; j<rloc->locNr; j++) {
13856 range = xmlXPtrNewRange( 13862 range = xmlXPtrNewRange(
13857 oldlocset->locTab[i]->user, 13863 oldlocset->locTab[i]->user,
13858 oldlocset->locTab[i]->index, 13864 oldlocset->locTab[i]->index,
13859 rloc->locTab[j]->user2, 13865 rloc->locTab[j]->user2,
13860 rloc->locTab[j]->index2); 13866 rloc->locTab[j]->index2);
13861 if (range != NULL) { 13867 if (range != NULL) {
13862 xmlXPtrLocationSetAdd(newlocset, range); 13868 xmlXPtrLocationSetAdd(newlocset, range);
13863 } 13869 }
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
14005 if (resObj == NULL) 14011 if (resObj == NULL)
14006 return(-1); 14012 return(-1);
14007 break; 14013 break;
14008 default: 14014 default:
14009 /* 14015 /*
14010 * Fallback to call xmlXPathCompOpEval(). 14016 * Fallback to call xmlXPathCompOpEval().
14011 */ 14017 */
14012 xmlXPathCompOpEval(ctxt, op); 14018 xmlXPathCompOpEval(ctxt, op);
14013 if (ctxt->error != XPATH_EXPRESSION_OK) 14019 if (ctxt->error != XPATH_EXPRESSION_OK)
14014 return(-1); 14020 return(-1);
14015 » 14021
14016 resObj = valuePop(ctxt); 14022 resObj = valuePop(ctxt);
14017 if (resObj == NULL) 14023 if (resObj == NULL)
14018 return(-1); 14024 return(-1);
14019 break; 14025 break;
14020 } 14026 }
14021 14027
14022 if (resObj) { 14028 if (resObj) {
14023 int res; 14029 int res;
14024 14030
14025 if (resObj->type == XPATH_BOOLEAN) { 14031 if (resObj->type == XPATH_BOOLEAN) {
14026 res = resObj->boolval; 14032 res = resObj->boolval;
14027 } else if (isPredicate) { 14033 } else if (isPredicate) {
14028 /* 14034 /*
14029 * For predicates a result of type "number" is handled 14035 * For predicates a result of type "number" is handled
14030 * differently: 14036 * differently:
14031 * SPEC XPath 1.0: 14037 * SPEC XPath 1.0:
14032 * "If the result is a number, the result will be converted 14038 * "If the result is a number, the result will be converted
14033 * to true if the number is equal to the context position 14039 * to true if the number is equal to the context position
14034 * and will be converted to false otherwise;" 14040 * and will be converted to false otherwise;"
14035 */ 14041 */
14036 » res = xmlXPathEvaluatePredicateResult(ctxt, resObj); 14042 » res = xmlXPathEvaluatePredicateResult(ctxt, resObj);
14037 } else { 14043 } else {
14038 res = xmlXPathCastToBoolean(resObj); 14044 res = xmlXPathCastToBoolean(resObj);
14039 } 14045 }
14040 xmlXPathReleaseObject(ctxt->context, resObj); 14046 xmlXPathReleaseObject(ctxt->context, resObj);
14041 return(res); 14047 return(res);
14042 } 14048 }
14043 14049
14044 return(0); 14050 return(0);
14045 } 14051 }
14046 14052
14047 #ifdef XPATH_STREAMING 14053 #ifdef XPATH_STREAMING
14048 /** 14054 /**
14049 * xmlXPathRunStreamEval: 14055 * xmlXPathRunStreamEval:
14050 * @ctxt: the XPath parser context with the compiled expression 14056 * @ctxt: the XPath parser context with the compiled expression
14051 * 14057 *
14052 * Evaluate the Precompiled Streamable XPath expression in the given context. 14058 * Evaluate the Precompiled Streamable XPath expression in the given context.
14053 */ 14059 */
14054 static int 14060 static int
14055 xmlXPathRunStreamEval(xmlXPathContextPtr ctxt, xmlPatternPtr comp, 14061 xmlXPathRunStreamEval(xmlXPathContextPtr ctxt, xmlPatternPtr comp,
14056 xmlXPathObjectPtr *resultSeq, int toBool) 14062 xmlXPathObjectPtr *resultSeq, int toBool)
14057 { 14063 {
14058 int max_depth, min_depth; 14064 int max_depth, min_depth;
14059 int from_root; 14065 int from_root;
14060 int ret, depth; 14066 int ret, depth;
14061 int eval_all_nodes; 14067 int eval_all_nodes;
14062 xmlNodePtr cur = NULL, limit = NULL; 14068 xmlNodePtr cur = NULL, limit = NULL;
14063 xmlStreamCtxtPtr patstream = NULL; 14069 xmlStreamCtxtPtr patstream = NULL;
14064 14070
14065 int nb_nodes = 0; 14071 int nb_nodes = 0;
14066 14072
14067 if ((ctxt == NULL) || (comp == NULL)) 14073 if ((ctxt == NULL) || (comp == NULL))
14068 return(-1); 14074 return(-1);
14069 max_depth = xmlPatternMaxDepth(comp); 14075 max_depth = xmlPatternMaxDepth(comp);
14070 if (max_depth == -1) 14076 if (max_depth == -1)
14071 return(-1); 14077 return(-1);
14072 if (max_depth == -2) 14078 if (max_depth == -2)
14073 max_depth = 10000; 14079 max_depth = 10000;
14074 min_depth = xmlPatternMinDepth(comp); 14080 min_depth = xmlPatternMinDepth(comp);
14075 if (min_depth == -1) 14081 if (min_depth == -1)
14076 return(-1); 14082 return(-1);
14077 from_root = xmlPatternFromRoot(comp); 14083 from_root = xmlPatternFromRoot(comp);
14078 if (from_root < 0) 14084 if (from_root < 0)
14079 return(-1); 14085 return(-1);
14080 #if 0 14086 #if 0
14081 printf("stream eval: depth %d from root %d\n", max_depth, from_root); 14087 printf("stream eval: depth %d from root %d\n", max_depth, from_root);
14082 #endif 14088 #endif
14083 14089
14084 if (! toBool) { 14090 if (! toBool) {
14085 if (resultSeq == NULL) 14091 if (resultSeq == NULL)
14086 return(-1); 14092 return(-1);
14087 *resultSeq = xmlXPathCacheNewNodeSet(ctxt, NULL); 14093 *resultSeq = xmlXPathCacheNewNodeSet(ctxt, NULL);
14088 if (*resultSeq == NULL) 14094 if (*resultSeq == NULL)
14089 return(-1); 14095 return(-1);
14090 } 14096 }
14091 14097
14092 /* 14098 /*
14093 * handle the special cases of "/" amd "." being matched 14099 * handle the special cases of "/" amd "." being matched
14094 */ 14100 */
14095 if (min_depth == 0) { 14101 if (min_depth == 0) {
14096 if (from_root) { 14102 if (from_root) {
14097 /* Select "/" */ 14103 /* Select "/" */
14098 if (toBool) 14104 if (toBool)
14099 return(1); 14105 return(1);
14100 xmlXPathNodeSetAddUnique((*resultSeq)->nodesetval, 14106 xmlXPathNodeSetAddUnique((*resultSeq)->nodesetval,
14101 (xmlNodePtr) ctxt->doc); 14107 (xmlNodePtr) ctxt->doc);
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
14178 case XML_CDATA_SECTION_NODE: 14184 case XML_CDATA_SECTION_NODE:
14179 case XML_COMMENT_NODE: 14185 case XML_COMMENT_NODE:
14180 case XML_PI_NODE: 14186 case XML_PI_NODE:
14181 if (cur->type == XML_ELEMENT_NODE) { 14187 if (cur->type == XML_ELEMENT_NODE) {
14182 ret = xmlStreamPush(patstream, cur->name, 14188 ret = xmlStreamPush(patstream, cur->name,
14183 (cur->ns ? cur->ns->href : NULL)); 14189 (cur->ns ? cur->ns->href : NULL));
14184 } else if (eval_all_nodes) 14190 } else if (eval_all_nodes)
14185 ret = xmlStreamPushNode(patstream, NULL, NULL, cur->type); 14191 ret = xmlStreamPushNode(patstream, NULL, NULL, cur->type);
14186 else 14192 else
14187 break; 14193 break;
14188 » » 14194
14189 if (ret < 0) { 14195 if (ret < 0) {
14190 /* NOP. */ 14196 /* NOP. */
14191 } else if (ret == 1) { 14197 } else if (ret == 1) {
14192 if (toBool) 14198 if (toBool)
14193 goto return_1; 14199 goto return_1;
14194 xmlXPathNodeSetAddUnique((*resultSeq)->nodesetval, cur); 14200 xmlXPathNodeSetAddUnique((*resultSeq)->nodesetval, cur);
14195 } 14201 }
14196 if ((cur->children == NULL) || (depth >= max_depth)) { 14202 if ((cur->children == NULL) || (depth >= max_depth)) {
14197 ret = xmlStreamPop(patstream); 14203 ret = xmlStreamPop(patstream);
14198 while (cur->next != NULL) { 14204 while (cur->next != NULL) {
14199 cur = cur->next; 14205 cur = cur->next;
14200 if ((cur->type != XML_ENTITY_DECL) && 14206 if ((cur->type != XML_ENTITY_DECL) &&
14201 (cur->type != XML_DTD_NODE)) 14207 (cur->type != XML_DTD_NODE))
14202 goto next_node; 14208 goto next_node;
14203 } 14209 }
14204 } 14210 }
14205 default: 14211 default:
14206 break; 14212 break;
14207 } 14213 }
14208 14214
14209 scan_children: 14215 scan_children:
14210 if ((cur->children != NULL) && (depth < max_depth)) { 14216 if ((cur->children != NULL) && (depth < max_depth)) {
14211 /* 14217 /*
14212 » * Do not descend on entities declarations» 14218 » * Do not descend on entities declarations
14213 */ 14219 */
14214 if (cur->children->type != XML_ENTITY_DECL) { 14220 if (cur->children->type != XML_ENTITY_DECL) {
14215 cur = cur->children; 14221 cur = cur->children;
14216 depth++; 14222 depth++;
14217 /* 14223 /*
14218 * Skip DTDs 14224 * Skip DTDs
14219 */ 14225 */
14220 if (cur->type != XML_DTD_NODE) 14226 if (cur->type != XML_DTD_NODE)
14221 continue; 14227 continue;
14222 } 14228 }
14223 } 14229 }
14224 14230
14225 if (cur == limit) 14231 if (cur == limit)
14226 break; 14232 break;
14227 14233
14228 while (cur->next != NULL) { 14234 while (cur->next != NULL) {
14229 cur = cur->next; 14235 cur = cur->next;
14230 if ((cur->type != XML_ENTITY_DECL) && 14236 if ((cur->type != XML_ENTITY_DECL) &&
14231 (cur->type != XML_DTD_NODE)) 14237 (cur->type != XML_DTD_NODE))
14232 goto next_node; 14238 goto next_node;
14233 } 14239 }
14234 » 14240
14235 do { 14241 do {
14236 cur = cur->parent; 14242 cur = cur->parent;
14237 depth--; 14243 depth--;
14238 if ((cur == NULL) || (cur == limit)) 14244 if ((cur == NULL) || (cur == limit))
14239 goto done; 14245 goto done;
14240 if (cur->type == XML_ELEMENT_NODE) { 14246 if (cur->type == XML_ELEMENT_NODE) {
14241 ret = xmlStreamPop(patstream); 14247 ret = xmlStreamPop(patstream);
14242 } else if ((eval_all_nodes) && 14248 } else if ((eval_all_nodes) &&
14243 ((cur->type == XML_TEXT_NODE) || 14249 ((cur->type == XML_TEXT_NODE) ||
14244 (cur->type == XML_CDATA_SECTION_NODE) || 14250 (cur->type == XML_CDATA_SECTION_NODE) ||
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
14283 static int 14289 static int
14284 xmlXPathRunEval(xmlXPathParserContextPtr ctxt, int toBool) 14290 xmlXPathRunEval(xmlXPathParserContextPtr ctxt, int toBool)
14285 { 14291 {
14286 xmlXPathCompExprPtr comp; 14292 xmlXPathCompExprPtr comp;
14287 14293
14288 if ((ctxt == NULL) || (ctxt->comp == NULL)) 14294 if ((ctxt == NULL) || (ctxt->comp == NULL))
14289 return(-1); 14295 return(-1);
14290 14296
14291 if (ctxt->valueTab == NULL) { 14297 if (ctxt->valueTab == NULL) {
14292 /* Allocate the value stack */ 14298 /* Allocate the value stack */
14293 » ctxt->valueTab = (xmlXPathObjectPtr *) 14299 » ctxt->valueTab = (xmlXPathObjectPtr *)
14294 xmlMalloc(10 * sizeof(xmlXPathObjectPtr)); 14300 xmlMalloc(10 * sizeof(xmlXPathObjectPtr));
14295 if (ctxt->valueTab == NULL) { 14301 if (ctxt->valueTab == NULL) {
14296 xmlXPathPErrMemory(ctxt, "creating evaluation context\n"); 14302 xmlXPathPErrMemory(ctxt, "creating evaluation context\n");
14297 xmlFree(ctxt); 14303 xmlFree(ctxt);
14298 } 14304 }
14299 ctxt->valueNr = 0; 14305 ctxt->valueNr = 0;
14300 ctxt->valueMax = 10; 14306 ctxt->valueMax = 10;
14301 ctxt->value = NULL; 14307 ctxt->value = NULL;
14302 } 14308 }
14303 #ifdef XPATH_STREAMING 14309 #ifdef XPATH_STREAMING
14304 if (ctxt->comp->stream) { 14310 if (ctxt->comp->stream) {
14305 int res; 14311 int res;
14306 14312
14307 if (toBool) { 14313 if (toBool) {
14308 /* 14314 /*
14309 * Evaluation to boolean result. 14315 * Evaluation to boolean result.
14310 */ 14316 */
14311 res = xmlXPathRunStreamEval(ctxt->context, 14317 res = xmlXPathRunStreamEval(ctxt->context,
14312 ctxt->comp->stream, NULL, 1); 14318 ctxt->comp->stream, NULL, 1);
14313 if (res != -1) 14319 if (res != -1)
14314 return(res); 14320 return(res);
14315 } else { 14321 } else {
14316 » xmlXPathObjectPtr resObj = NULL;» 14322 » xmlXPathObjectPtr resObj = NULL;
14317 14323
14318 /* 14324 /*
14319 * Evaluation to a sequence. 14325 * Evaluation to a sequence.
14320 */ 14326 */
14321 res = xmlXPathRunStreamEval(ctxt->context, 14327 res = xmlXPathRunStreamEval(ctxt->context,
14322 ctxt->comp->stream, &resObj, 0); 14328 ctxt->comp->stream, &resObj, 0);
14323 14329
14324 if ((res != -1) && (resObj != NULL)) { 14330 if ((res != -1) && (resObj != NULL)) {
14325 valuePush(ctxt, resObj); 14331 valuePush(ctxt, resObj);
14326 return(0); 14332 return(0);
14327 } 14333 }
14328 if (resObj != NULL) 14334 if (resObj != NULL)
14329 » » xmlXPathReleaseObject(ctxt->context, resObj);» 14335 » » xmlXPathReleaseObject(ctxt->context, resObj);
14330 } 14336 }
14331 /* 14337 /*
14332 * QUESTION TODO: This falls back to normal XPath evaluation 14338 * QUESTION TODO: This falls back to normal XPath evaluation
14333 * if res == -1. Is this intended? 14339 * if res == -1. Is this intended?
14334 */ 14340 */
14335 } 14341 }
14336 #endif 14342 #endif
14337 comp = ctxt->comp; 14343 comp = ctxt->comp;
14338 if (comp->last < 0) { 14344 if (comp->last < 0) {
14339 xmlGenericError(xmlGenericErrorContext, 14345 xmlGenericError(xmlGenericErrorContext,
14340 "xmlXPathRunEval: last is less than zero\n"); 14346 "xmlXPathRunEval: last is less than zero\n");
14341 return(-1); 14347 return(-1);
14342 } 14348 }
14343 if (toBool) 14349 if (toBool)
14344 return(xmlXPathCompOpEvalToBoolean(ctxt, 14350 return(xmlXPathCompOpEvalToBoolean(ctxt,
14345 &comp->steps[comp->last], 0)); 14351 &comp->steps[comp->last], 0));
14346 else 14352 else
14347 xmlXPathCompOpEval(ctxt, &comp->steps[comp->last]); 14353 xmlXPathCompOpEval(ctxt, &comp->steps[comp->last]);
14348 14354
14349 return(0); 14355 return(0);
14350 } 14356 }
14351 14357
14352 /************************************************************************ 14358 /************************************************************************
14353 * * 14359 * *
14354 * » » » Public interfaces» » » » * 14360 *» » » Public interfaces» » » » *
14355 * * 14361 * *
14356 ************************************************************************/ 14362 ************************************************************************/
14357 14363
14358 /** 14364 /**
14359 * xmlXPathEvalPredicate: 14365 * xmlXPathEvalPredicate:
14360 * @ctxt: the XPath context 14366 * @ctxt: the XPath context
14361 * @res: the Predicate Expression evaluation result 14367 * @res: the Predicate Expression evaluation result
14362 * 14368 *
14363 * Evaluate a predicate result for the current node. 14369 * Evaluate a predicate result for the current node.
14364 * A PredicateExpr is evaluated by evaluating the Expr and converting 14370 * A PredicateExpr is evaluated by evaluating the Expr and converting
14365 * the result to a boolean. If the result is a number, the result will 14371 * the result to a boolean. If the result is a number, the result will
14366 * be converted to true if the number is equal to the position of the 14372 * be converted to true if the number is equal to the position of the
14367 * context node in the context node list (as returned by the position 14373 * context node in the context node list (as returned by the position
14368 * function) and will be converted to false otherwise; if the result 14374 * function) and will be converted to false otherwise; if the result
14369 * is not a number, then the result will be converted as if by a call 14375 * is not a number, then the result will be converted as if by a call
14370 * to the boolean function. 14376 * to the boolean function.
14371 * 14377 *
14372 * Returns 1 if predicate is true, 0 otherwise 14378 * Returns 1 if predicate is true, 0 otherwise
14373 */ 14379 */
14374 int 14380 int
14375 xmlXPathEvalPredicate(xmlXPathContextPtr ctxt, xmlXPathObjectPtr res) { 14381 xmlXPathEvalPredicate(xmlXPathContextPtr ctxt, xmlXPathObjectPtr res) {
14376 if ((ctxt == NULL) || (res == NULL)) return(0); 14382 if ((ctxt == NULL) || (res == NULL)) return(0);
14377 switch (res->type) { 14383 switch (res->type) {
14378 case XPATH_BOOLEAN: 14384 case XPATH_BOOLEAN:
14379 return(res->boolval); 14385 return(res->boolval);
14380 case XPATH_NUMBER: 14386 case XPATH_NUMBER:
(...skipping 17 matching lines...) Expand all
14398 * @ctxt: the XPath Parser context 14404 * @ctxt: the XPath Parser context
14399 * @res: the Predicate Expression evaluation result 14405 * @res: the Predicate Expression evaluation result
14400 * 14406 *
14401 * Evaluate a predicate result for the current node. 14407 * Evaluate a predicate result for the current node.
14402 * A PredicateExpr is evaluated by evaluating the Expr and converting 14408 * A PredicateExpr is evaluated by evaluating the Expr and converting
14403 * the result to a boolean. If the result is a number, the result will 14409 * the result to a boolean. If the result is a number, the result will
14404 * be converted to true if the number is equal to the position of the 14410 * be converted to true if the number is equal to the position of the
14405 * context node in the context node list (as returned by the position 14411 * context node in the context node list (as returned by the position
14406 * function) and will be converted to false otherwise; if the result 14412 * function) and will be converted to false otherwise; if the result
14407 * is not a number, then the result will be converted as if by a call 14413 * is not a number, then the result will be converted as if by a call
14408 * to the boolean function. 14414 * to the boolean function.
14409 * 14415 *
14410 * Returns 1 if predicate is true, 0 otherwise 14416 * Returns 1 if predicate is true, 0 otherwise
14411 */ 14417 */
14412 int 14418 int
14413 xmlXPathEvaluatePredicateResult(xmlXPathParserContextPtr ctxt, 14419 xmlXPathEvaluatePredicateResult(xmlXPathParserContextPtr ctxt,
14414 xmlXPathObjectPtr res) { 14420 xmlXPathObjectPtr res) {
14415 if ((ctxt == NULL) || (res == NULL)) return(0); 14421 if ((ctxt == NULL) || (res == NULL)) return(0);
14416 switch (res->type) { 14422 switch (res->type) {
14417 case XPATH_BOOLEAN: 14423 case XPATH_BOOLEAN:
14418 return(res->boolval); 14424 return(res->boolval);
14419 case XPATH_NUMBER: 14425 case XPATH_NUMBER:
14420 #if defined(__BORLANDC__) || (defined(_MSC_VER) && (_MSC_VER == 1200)) 14426 #if defined(__BORLANDC__) || (defined(_MSC_VER) && (_MSC_VER == 1200))
14421 return((res->floatval == ctxt->context->proximityPosition) && 14427 return((res->floatval == ctxt->context->proximityPosition) &&
14422 (!xmlXPathIsNaN(res->floatval))); /* MSC pbm Mark Vakoc !*/ 14428 (!xmlXPathIsNaN(res->floatval))); /* MSC pbm Mark Vakoc !*/
14423 #else 14429 #else
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
14476 * specifiers ("::"), just the simplied form at this point. 14482 * specifiers ("::"), just the simplied form at this point.
14477 * Additionally, if there is no list of namespaces available and 14483 * Additionally, if there is no list of namespaces available and
14478 * there's a ":" in the expression, indicating a prefixed QName, 14484 * there's a ":" in the expression, indicating a prefixed QName,
14479 * then we won't try to compile either. xmlPatterncompile() needs 14485 * then we won't try to compile either. xmlPatterncompile() needs
14480 * to have a list of namespaces at compilation time in order to 14486 * to have a list of namespaces at compilation time in order to
14481 * compile prefixed name tests. 14487 * compile prefixed name tests.
14482 */ 14488 */
14483 tmp = xmlStrchr(str, ':'); 14489 tmp = xmlStrchr(str, ':');
14484 if ((tmp != NULL) && 14490 if ((tmp != NULL) &&
14485 ((ctxt == NULL) || (ctxt->nsNr == 0) || (tmp[1] == ':'))) 14491 ((ctxt == NULL) || (ctxt->nsNr == 0) || (tmp[1] == ':')))
14486 » return(NULL);» 14492 » return(NULL);
14487 14493
14488 if (ctxt != NULL) { 14494 if (ctxt != NULL) {
14489 dict = ctxt->dict; 14495 dict = ctxt->dict;
14490 if (ctxt->nsNr > 0) { 14496 if (ctxt->nsNr > 0) {
14491 namespaces = xmlMalloc(2 * (ctxt->nsNr + 1) * sizeof(xmlChar*)); 14497 namespaces = xmlMalloc(2 * (ctxt->nsNr + 1) * sizeof(xmlChar*));
14492 if (namespaces == NULL) { 14498 if (namespaces == NULL) {
14493 xmlXPathErrMemory(ctxt, "allocating namespaces array\n"); 14499 xmlXPathErrMemory(ctxt, "allocating namespaces array\n");
14494 return(NULL); 14500 return(NULL);
14495 } 14501 }
14496 for (i = 0, j = 0; (j < ctxt->nsNr); j++) { 14502 for (i = 0, j = 0; (j < ctxt->nsNr); j++) {
14497 ns = ctxt->namespaces[j]; 14503 ns = ctxt->namespaces[j];
14498 namespaces[i++] = ns->href; 14504 namespaces[i++] = ns->href;
14499 namespaces[i++] = ns->prefix; 14505 namespaces[i++] = ns->prefix;
14500 } 14506 }
14501 namespaces[i++] = NULL; 14507 namespaces[i++] = NULL;
14502 » » namespaces[i++] = NULL; 14508 » » namespaces[i] = NULL;
14503 } 14509 }
14504 } 14510 }
14505 14511
14506 stream = xmlPatterncompile(str, dict, XML_PATTERN_XPATH, 14512 stream = xmlPatterncompile(str, dict, XML_PATTERN_XPATH,
14507 &namespaces[0]); 14513 &namespaces[0]);
14508 if (namespaces != NULL) { 14514 if (namespaces != NULL) {
14509 xmlFree((xmlChar **)namespaces); 14515 xmlFree((xmlChar **)namespaces);
14510 » } 14516 » }
14511 if ((stream != NULL) && (xmlPatternStreamable(stream) == 1)) { 14517 if ((stream != NULL) && (xmlPatternStreamable(stream) == 1)) {
14512 comp = xmlXPathNewCompExpr(); 14518 comp = xmlXPathNewCompExpr();
14513 if (comp == NULL) { 14519 if (comp == NULL) {
14514 xmlXPathErrMemory(ctxt, "allocating streamable expression\n"); 14520 xmlXPathErrMemory(ctxt, "allocating streamable expression\n");
14515 return(NULL); 14521 return(NULL);
14516 } 14522 }
14517 comp->stream = stream; 14523 comp->stream = stream;
14518 comp->dict = dict; 14524 comp->dict = dict;
14519 if (comp->dict) 14525 if (comp->dict)
14520 xmlDictReference(comp->dict); 14526 xmlDictReference(comp->dict);
(...skipping 18 matching lines...) Expand all
14539 } 14545 }
14540 static void 14546 static void
14541 xmlXPathRewriteDOSExpression(xmlXPathCompExprPtr comp, xmlXPathStepOpPtr op) 14547 xmlXPathRewriteDOSExpression(xmlXPathCompExprPtr comp, xmlXPathStepOpPtr op)
14542 { 14548 {
14543 /* 14549 /*
14544 * Try to rewrite "descendant-or-self::node()/foo" to an optimized 14550 * Try to rewrite "descendant-or-self::node()/foo" to an optimized
14545 * internal representation. 14551 * internal representation.
14546 */ 14552 */
14547 if (op->ch1 != -1) { 14553 if (op->ch1 != -1) {
14548 if ((op->op == XPATH_OP_COLLECT /* 11 */) && 14554 if ((op->op == XPATH_OP_COLLECT /* 11 */) &&
14549 » ((xmlXPathAxisVal) op->value == AXIS_CHILD /* 4 */) &&» 14555 » ((xmlXPathAxisVal) op->value == AXIS_CHILD /* 4 */) &&
14550 ((xmlXPathTestVal) op->value2 == NODE_TEST_NAME /* 5 */) && 14556 ((xmlXPathTestVal) op->value2 == NODE_TEST_NAME /* 5 */) &&
14551 ((xmlXPathTypeVal) op->value3 == NODE_TYPE_NODE /* 0 */)) 14557 ((xmlXPathTypeVal) op->value3 == NODE_TYPE_NODE /* 0 */))
14552 { 14558 {
14553 /* 14559 /*
14554 * This is a "child::foo" 14560 * This is a "child::foo"
14555 */ 14561 */
14556 » xmlXPathStepOpPtr prevop = &comp->steps[op->ch1];» 14562 » xmlXPathStepOpPtr prevop = &comp->steps[op->ch1];
14557 14563
14558 if ((prevop->op == XPATH_OP_COLLECT /* 11 */) && 14564 if ((prevop->op == XPATH_OP_COLLECT /* 11 */) &&
14559 » » (prevop->ch1 != -1) &&» 14565 » » (prevop->ch1 != -1) &&
14560 ((xmlXPathAxisVal) prevop->value == 14566 ((xmlXPathAxisVal) prevop->value ==
14561 AXIS_DESCENDANT_OR_SELF) && 14567 AXIS_DESCENDANT_OR_SELF) &&
14562 (prevop->ch2 == -1) && 14568 (prevop->ch2 == -1) &&
14563 ((xmlXPathTestVal) prevop->value2 == NODE_TEST_TYPE) && 14569 ((xmlXPathTestVal) prevop->value2 == NODE_TEST_TYPE) &&
14564 ((xmlXPathTypeVal) prevop->value3 == NODE_TYPE_NODE) && 14570 ((xmlXPathTypeVal) prevop->value3 == NODE_TYPE_NODE) &&
14565 (comp->steps[prevop->ch1].op == XPATH_OP_ROOT)) 14571 (comp->steps[prevop->ch1].op == XPATH_OP_ROOT))
14566 » {» » 14572 » {
14567 /* 14573 /*
14568 * This is a "/descendant-or-self::node()" without predicates. 14574 * This is a "/descendant-or-self::node()" without predicates.
14569 * Eliminate it. 14575 * Eliminate it.
14570 */ 14576 */
14571 op->ch1 = prevop->ch1; 14577 op->ch1 = prevop->ch1;
14572 » » op->rewriteType = XP_REWRITE_DOS_CHILD_ELEM;» » 14578 » » op->rewriteType = XP_REWRITE_DOS_CHILD_ELEM;
14573 } 14579 }
14574 } 14580 }
14575 if (op->ch1 != -1) 14581 if (op->ch1 != -1)
14576 xmlXPathRewriteDOSExpression(comp, &comp->steps[op->ch1]); 14582 xmlXPathRewriteDOSExpression(comp, &comp->steps[op->ch1]);
14577 } 14583 }
14578 if (op->ch2 != -1) 14584 if (op->ch2 != -1)
14579 xmlXPathRewriteDOSExpression(comp, &comp->steps[op->ch2]); 14585 xmlXPathRewriteDOSExpression(comp, &comp->steps[op->ch2]);
14580 } 14586 }
14581 14587
14582 /** 14588 /**
(...skipping 24 matching lines...) Expand all
14607 return NULL; 14613 return NULL;
14608 xmlXPathCompileExpr(pctxt, 1); 14614 xmlXPathCompileExpr(pctxt, 1);
14609 14615
14610 if( pctxt->error != XPATH_EXPRESSION_OK ) 14616 if( pctxt->error != XPATH_EXPRESSION_OK )
14611 { 14617 {
14612 xmlXPathFreeParserContext(pctxt); 14618 xmlXPathFreeParserContext(pctxt);
14613 return(NULL); 14619 return(NULL);
14614 } 14620 }
14615 14621
14616 if (*pctxt->cur != 0) { 14622 if (*pctxt->cur != 0) {
14617 » /* 14623 » /*
14618 * aleksey: in some cases this line prints *second* error message 14624 * aleksey: in some cases this line prints *second* error message
14619 * (see bug #78858) and probably this should be fixed. 14625 * (see bug #78858) and probably this should be fixed.
14620 * However, we are not sure that all error messages are printed 14626 * However, we are not sure that all error messages are printed
14621 * out in other places. It's not critical so we leave it as-is for now 14627 * out in other places. It's not critical so we leave it as-is for now
14622 */ 14628 */
14623 xmlXPatherror(pctxt, __FILE__, __LINE__, XPATH_EXPR_ERROR); 14629 xmlXPatherror(pctxt, __FILE__, __LINE__, XPATH_EXPR_ERROR);
14624 comp = NULL; 14630 comp = NULL;
14625 } else { 14631 } else {
14626 comp = pctxt->comp; 14632 comp = pctxt->comp;
14627 pctxt->comp = NULL; 14633 pctxt->comp = NULL;
14628 } 14634 }
14629 xmlXPathFreeParserContext(pctxt); 14635 xmlXPathFreeParserContext(pctxt);
14630 14636
14631 if (comp != NULL) { 14637 if (comp != NULL) {
14632 comp->expr = xmlStrdup(str); 14638 comp->expr = xmlStrdup(str);
14633 #ifdef DEBUG_EVAL_COUNTS 14639 #ifdef DEBUG_EVAL_COUNTS
14634 comp->string = xmlStrdup(str); 14640 comp->string = xmlStrdup(str);
14635 comp->nb = 0; 14641 comp->nb = 0;
14636 #endif 14642 #endif
14637 if ((comp->expr != NULL) && 14643 if ((comp->expr != NULL) &&
14638 (comp->nbStep > 2) && 14644 (comp->nbStep > 2) &&
14639 (comp->last >= 0) && 14645 (comp->last >= 0) &&
14640 (xmlXPathCanRewriteDosExpression(comp->expr) == 1)) 14646 (xmlXPathCanRewriteDosExpression(comp->expr) == 1))
14641 { 14647 {
14642 xmlXPathRewriteDOSExpression(comp, &comp->steps[comp->last]); 14648 xmlXPathRewriteDOSExpression(comp, &comp->steps[comp->last]);
14643 } 14649 }
14644 } 14650 }
14645 return(comp); 14651 return(comp);
14646 } 14652 }
(...skipping 24 matching lines...) Expand all
14671 * 14677 *
14672 * Returns the xmlXPathObjectPtr resulting from the evaluation or NULL. 14678 * Returns the xmlXPathObjectPtr resulting from the evaluation or NULL.
14673 * the caller has to free the object. 14679 * the caller has to free the object.
14674 */ 14680 */
14675 static int 14681 static int
14676 xmlXPathCompiledEvalInternal(xmlXPathCompExprPtr comp, 14682 xmlXPathCompiledEvalInternal(xmlXPathCompExprPtr comp,
14677 xmlXPathContextPtr ctxt, 14683 xmlXPathContextPtr ctxt,
14678 xmlXPathObjectPtr *resObj, 14684 xmlXPathObjectPtr *resObj,
14679 int toBool) 14685 int toBool)
14680 { 14686 {
14681 xmlXPathParserContextPtr pctxt; 14687 xmlXPathParserContextPtr pctxt;
14682 #ifndef LIBXML_THREAD_ENABLED 14688 #ifndef LIBXML_THREAD_ENABLED
14683 static int reentance = 0; 14689 static int reentance = 0;
14684 #endif 14690 #endif
14685 int res; 14691 int res;
14686 14692
14687 CHECK_CTXT_NEG(ctxt) 14693 CHECK_CTXT_NEG(ctxt)
14688 14694
14689 if (comp == NULL) 14695 if (comp == NULL)
14690 return(-1); 14696 return(-1);
14691 xmlXPathInit(); 14697 xmlXPathInit();
14692 14698
14693 #ifndef LIBXML_THREAD_ENABLED 14699 #ifndef LIBXML_THREAD_ENABLED
14694 reentance++; 14700 reentance++;
14695 if (reentance > 1) 14701 if (reentance > 1)
14696 xmlXPathDisableOptimizer = 1; 14702 xmlXPathDisableOptimizer = 1;
14697 #endif 14703 #endif
14698 14704
14699 #ifdef DEBUG_EVAL_COUNTS 14705 #ifdef DEBUG_EVAL_COUNTS
14700 comp->nb++; 14706 comp->nb++;
14701 if ((comp->string != NULL) && (comp->nb > 100)) { 14707 if ((comp->string != NULL) && (comp->nb > 100)) {
14702 fprintf(stderr, "100 x %s\n", comp->string); 14708 fprintf(stderr, "100 x %s\n", comp->string);
14703 comp->nb = 0; 14709 comp->nb = 0;
14704 } 14710 }
14705 #endif 14711 #endif
14706 pctxt = xmlXPathCompParserContext(comp, ctxt); 14712 pctxt = xmlXPathCompParserContext(comp, ctxt);
14707 res = xmlXPathRunEval(pctxt, toBool); 14713 res = xmlXPathRunEval(pctxt, toBool);
14708 14714
14709 if (resObj) { 14715 if (resObj) {
14710 » if (pctxt->value == NULL) {» 14716 » if (pctxt->value == NULL) {
14711 xmlGenericError(xmlGenericErrorContext, 14717 xmlGenericError(xmlGenericErrorContext,
14712 "xmlXPathCompiledEval: evaluation failed\n"); 14718 "xmlXPathCompiledEval: evaluation failed\n");
14713 » *resObj = NULL;» 14719 » *resObj = NULL;
14714 } else { 14720 } else {
14715 *resObj = valuePop(pctxt); 14721 *resObj = valuePop(pctxt);
14716 } 14722 }
14717 } 14723 }
14718 14724
14719 /* 14725 /*
14720 * Pop all remaining objects from the stack. 14726 * Pop all remaining objects from the stack.
14721 */ 14727 */
14722 if (pctxt->valueNr > 0) { 14728 if (pctxt->valueNr > 0) {
14723 xmlXPathObjectPtr tmp; 14729 xmlXPathObjectPtr tmp;
14724 int stack = 0; 14730 int stack = 0;
14725 14731
14726 do { 14732 do {
14727 tmp = valuePop(pctxt); 14733 tmp = valuePop(pctxt);
14728 if (tmp != NULL) { 14734 if (tmp != NULL) {
14729 » » stack++; 14735 » » stack++;
14730 xmlXPathReleaseObject(ctxt, tmp); 14736 xmlXPathReleaseObject(ctxt, tmp);
14731 } 14737 }
14732 } while (tmp != NULL); 14738 } while (tmp != NULL);
14733 if ((stack != 0) && 14739 if ((stack != 0) &&
14734 ((toBool) || ((resObj) && (*resObj)))) 14740 ((toBool) || ((resObj) && (*resObj))))
14735 { 14741 {
14736 xmlGenericError(xmlGenericErrorContext, 14742 xmlGenericError(xmlGenericErrorContext,
14737 "xmlXPathCompiledEval: %d objects left on the stack.\n", 14743 "xmlXPathCompiledEval: %d objects left on the stack.\n",
14738 stack); 14744 stack);
14739 } 14745 }
14740 } 14746 }
14741 14747
14742 if ((pctxt->error != XPATH_EXPRESSION_OK) && (resObj) && (*resObj)) { 14748 if ((pctxt->error != XPATH_EXPRESSION_OK) && (resObj) && (*resObj)) {
14743 xmlXPathFreeObject(*resObj); 14749 xmlXPathFreeObject(*resObj);
14744 *resObj = NULL; 14750 *resObj = NULL;
14745 } 14751 }
14746 pctxt->comp = NULL; 14752 pctxt->comp = NULL;
14747 xmlXPathFreeParserContext(pctxt); 14753 xmlXPathFreeParserContext(pctxt);
14748 #ifndef LIBXML_THREAD_ENABLED 14754 #ifndef LIBXML_THREAD_ENABLED
14749 reentance--; 14755 reentance--;
14750 #endif 14756 #endif
14751 14757
14752 return(res); 14758 return(res);
14753 } 14759 }
14754 14760
14755 /** 14761 /**
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
14796 * Parse and evaluate an XPath expression in the given context, 14802 * Parse and evaluate an XPath expression in the given context,
14797 * then push the result on the context stack 14803 * then push the result on the context stack
14798 */ 14804 */
14799 void 14805 void
14800 xmlXPathEvalExpr(xmlXPathParserContextPtr ctxt) { 14806 xmlXPathEvalExpr(xmlXPathParserContextPtr ctxt) {
14801 #ifdef XPATH_STREAMING 14807 #ifdef XPATH_STREAMING
14802 xmlXPathCompExprPtr comp; 14808 xmlXPathCompExprPtr comp;
14803 #endif 14809 #endif
14804 14810
14805 if (ctxt == NULL) return; 14811 if (ctxt == NULL) return;
14806 14812
14807 #ifdef XPATH_STREAMING 14813 #ifdef XPATH_STREAMING
14808 comp = xmlXPathTryStreamCompile(ctxt->context, ctxt->base); 14814 comp = xmlXPathTryStreamCompile(ctxt->context, ctxt->base);
14809 if (comp != NULL) { 14815 if (comp != NULL) {
14810 if (ctxt->comp != NULL) 14816 if (ctxt->comp != NULL)
14811 xmlXPathFreeCompExpr(ctxt->comp); 14817 xmlXPathFreeCompExpr(ctxt->comp);
14812 ctxt->comp = comp; 14818 ctxt->comp = comp;
14813 if (ctxt->cur != NULL) 14819 if (ctxt->cur != NULL)
14814 while (*ctxt->cur != 0) ctxt->cur++; 14820 while (*ctxt->cur != 0) ctxt->cur++;
14815 } else 14821 } else
14816 #endif 14822 #endif
14817 { 14823 {
14818 xmlXPathCompileExpr(ctxt, 1); 14824 xmlXPathCompileExpr(ctxt, 1);
14819 /* 14825 /*
14820 * In this scenario the expression string will sit in ctxt->base. 14826 * In this scenario the expression string will sit in ctxt->base.
14821 */ 14827 */
14822 if ((ctxt->error == XPATH_EXPRESSION_OK) && 14828 if ((ctxt->error == XPATH_EXPRESSION_OK) &&
14823 (ctxt->comp != NULL) && 14829 (ctxt->comp != NULL) &&
14824 (ctxt->base != NULL) && 14830 (ctxt->base != NULL) &&
14825 (ctxt->comp->nbStep > 2) && 14831 (ctxt->comp->nbStep > 2) &&
14826 (ctxt->comp->last >= 0) && 14832 (ctxt->comp->last >= 0) &&
14827 (xmlXPathCanRewriteDosExpression((xmlChar *) ctxt->base) == 1)) 14833 (xmlXPathCanRewriteDosExpression((xmlChar *) ctxt->base) == 1))
14828 { 14834 {
14829 xmlXPathRewriteDOSExpression(ctxt->comp, 14835 xmlXPathRewriteDOSExpression(ctxt->comp,
14830 &ctxt->comp->steps[ctxt->comp->last]); 14836 &ctxt->comp->steps[ctxt->comp->last]);
14831 } 14837 }
14832 } 14838 }
14833 CHECK_ERROR; 14839 CHECK_ERROR;
14834 xmlXPathRunEval(ctxt, 0); 14840 xmlXPathRunEval(ctxt, 0);
14835 } 14841 }
14836 14842
14837 /** 14843 /**
14838 * xmlXPathEval: 14844 * xmlXPathEval:
14839 * @str: the XPath expression 14845 * @str: the XPath expression
14840 * @ctx: the XPath context 14846 * @ctx: the XPath context
14841 * 14847 *
14842 * Evaluate the XPath Location Path in the given context. 14848 * Evaluate the XPath Location Path in the given context.
14843 * 14849 *
14844 * Returns the xmlXPathObjectPtr resulting from the evaluation or NULL. 14850 * Returns the xmlXPathObjectPtr resulting from the evaluation or NULL.
(...skipping 11 matching lines...) Expand all
14856 14862
14857 ctxt = xmlXPathNewParserContext(str, ctx); 14863 ctxt = xmlXPathNewParserContext(str, ctx);
14858 if (ctxt == NULL) 14864 if (ctxt == NULL)
14859 return NULL; 14865 return NULL;
14860 xmlXPathEvalExpr(ctxt); 14866 xmlXPathEvalExpr(ctxt);
14861 14867
14862 if (ctxt->value == NULL) { 14868 if (ctxt->value == NULL) {
14863 xmlGenericError(xmlGenericErrorContext, 14869 xmlGenericError(xmlGenericErrorContext,
14864 "xmlXPathEval: evaluation failed\n"); 14870 "xmlXPathEval: evaluation failed\n");
14865 res = NULL; 14871 res = NULL;
14866 } else if ((*ctxt->cur != 0) && (ctxt->comp != NULL) 14872 } else if ((*ctxt->cur != 0) && (ctxt->comp != NULL)
14867 #ifdef XPATH_STREAMING 14873 #ifdef XPATH_STREAMING
14868 && (ctxt->comp->stream == NULL) 14874 && (ctxt->comp->stream == NULL)
14869 #endif 14875 #endif
14870 ) { 14876 ) {
14871 xmlXPatherror(ctxt, __FILE__, __LINE__, XPATH_EXPR_ERROR); 14877 xmlXPatherror(ctxt, __FILE__, __LINE__, XPATH_EXPR_ERROR);
14872 res = NULL; 14878 res = NULL;
14873 } else { 14879 } else {
14874 res = valuePop(ctxt); 14880 res = valuePop(ctxt);
14875 } 14881 }
14876 14882
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
14969 * If $escape-reserved is true, all characters are escaped other than lower 14975 * If $escape-reserved is true, all characters are escaped other than lower
14970 * case letters a-z, upper case letters A-Z, digits 0-9, and the characters 14976 * case letters a-z, upper case letters A-Z, digits 0-9, and the characters
14971 * referred to in [RFC 2396] as "marks": specifically, "-" | "_" | "." | "!" 14977 * referred to in [RFC 2396] as "marks": specifically, "-" | "_" | "." | "!"
14972 * | "~" | "*" | "'" | "(" | ")". The "%" character itself is escaped only 14978 * | "~" | "*" | "'" | "(" | ")". The "%" character itself is escaped only
14973 * if it is not followed by two hexadecimal digits (that is, 0-9, a-f, and 14979 * if it is not followed by two hexadecimal digits (that is, 0-9, a-f, and
14974 * A-F). 14980 * A-F).
14975 * 14981 *
14976 * If $escape-reserved is false, the behavior differs in that characters 14982 * If $escape-reserved is false, the behavior differs in that characters
14977 * referred to in [RFC 2396] as reserved characters are not escaped. These 14983 * referred to in [RFC 2396] as reserved characters are not escaped. These
14978 * characters are ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ",". 14984 * characters are ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ",".
14979 * 14985 *
14980 * [RFC 2396] does not define whether escaped URIs should use lower case or 14986 * [RFC 2396] does not define whether escaped URIs should use lower case or
14981 * upper case for hexadecimal digits. To ensure that escaped URIs can be 14987 * upper case for hexadecimal digits. To ensure that escaped URIs can be
14982 * compared using string comparison functions, this function must always use 14988 * compared using string comparison functions, this function must always use
14983 * the upper-case letters A-F. 14989 * the upper-case letters A-F.
14984 * 14990 *
14985 * Generally, $escape-reserved should be set to true when escaping a string 14991 * Generally, $escape-reserved should be set to true when escaping a string
14986 * that is to form a single part of a URI, and to false when escaping an 14992 * that is to form a single part of a URI, and to false when escaping an
14987 * entire URI or URI reference. 14993 * entire URI or URI reference.
14988 * 14994 *
14989 * In the case of non-ascii characters, the string is encoded according to 14995 * In the case of non-ascii characters, the string is encoded according to
14990 * utf-8 and then converted according to RFC 2396. 14996 * utf-8 and then converted according to RFC 2396.
14991 * 14997 *
14992 * Examples 14998 * Examples
14993 * xf:escape-uri ("gopher://spinaltap.micro.umn.edu/00/Weather/California/Los%2 0Angeles#ocean"), true()) 14999 * xf:escape-uri ("gopher://spinaltap.micro.umn.edu/00/Weather/California/Los%2 0Angeles#ocean"), true())
14994 * returns "gopher%3A%2F%2Fspinaltap.micro.umn.edu%2F00%2FWeather%2FCalifornia% 2FLos%20Angeles%23ocean" 15000 * returns "gopher%3A%2F%2Fspinaltap.micro.umn.edu%2F00%2FWeather%2FCalifornia% 2FLos%20Angeles%23ocean"
14995 * xf:escape-uri ("gopher://spinaltap.micro.umn.edu/00/Weather/California/Los%2 0Angeles#ocean"), false()) 15001 * xf:escape-uri ("gopher://spinaltap.micro.umn.edu/00/Weather/California/Los%2 0Angeles#ocean"), false())
14996 * returns "gopher://spinaltap.micro.umn.edu/00/Weather/California/Los%20Angele s%23ocean" 15002 * returns "gopher://spinaltap.micro.umn.edu/00/Weather/California/Los%20Angele s%23ocean"
14997 * 15003 *
14998 */ 15004 */
14999 static void 15005 static void
15000 xmlXPathEscapeUriFunction(xmlXPathParserContextPtr ctxt, int nargs) { 15006 xmlXPathEscapeUriFunction(xmlXPathParserContextPtr ctxt, int nargs) {
15001 xmlXPathObjectPtr str; 15007 xmlXPathObjectPtr str;
15002 int escape_reserved; 15008 int escape_reserved;
15003 xmlBufferPtr target; 15009 xmlBufferPtr target;
15004 xmlChar *cptr; 15010 xmlChar *cptr;
15005 xmlChar escape[4]; 15011 xmlChar escape[4];
15006 15012
15007 CHECK_ARITY(2); 15013 CHECK_ARITY(2);
15008 15014
15009 escape_reserved = xmlXPathPopBoolean(ctxt); 15015 escape_reserved = xmlXPathPopBoolean(ctxt);
15010 15016
15011 CAST_TO_STRING; 15017 CAST_TO_STRING;
15012 str = valuePop(ctxt); 15018 str = valuePop(ctxt);
15013 15019
15014 target = xmlBufferCreate(); 15020 target = xmlBufferCreate();
15015 15021
15016 escape[0] = '%'; 15022 escape[0] = '%';
15017 escape[3] = 0; 15023 escape[3] = 0;
15018 15024
15019 if (target) { 15025 if (target) {
15020 for (cptr = str->stringval; *cptr; cptr++) { 15026 for (cptr = str->stringval; *cptr; cptr++) {
15021 if ((*cptr >= 'A' && *cptr <= 'Z') || 15027 if ((*cptr >= 'A' && *cptr <= 'Z') ||
15022 (*cptr >= 'a' && *cptr <= 'z') || 15028 (*cptr >= 'a' && *cptr <= 'z') ||
15023 (*cptr >= '0' && *cptr <= '9') || 15029 (*cptr >= '0' && *cptr <= '9') ||
15024 » » *cptr == '-' || *cptr == '_' || *cptr == '.' || 15030 » » *cptr == '-' || *cptr == '_' || *cptr == '.' ||
15025 *cptr == '!' || *cptr == '~' || *cptr == '*' || 15031 *cptr == '!' || *cptr == '~' || *cptr == '*' ||
15026 *cptr == '\''|| *cptr == '(' || *cptr == ')' || 15032 *cptr == '\''|| *cptr == '(' || *cptr == ')' ||
15027 » » (*cptr == '%' && 15033 » » (*cptr == '%' &&
15028 ((cptr[1] >= 'A' && cptr[1] <= 'F') || 15034 ((cptr[1] >= 'A' && cptr[1] <= 'F') ||
15029 (cptr[1] >= 'a' && cptr[1] <= 'f') || 15035 (cptr[1] >= 'a' && cptr[1] <= 'f') ||
15030 (cptr[1] >= '0' && cptr[1] <= '9')) && 15036 (cptr[1] >= '0' && cptr[1] <= '9')) &&
15031 ((cptr[2] >= 'A' && cptr[2] <= 'F') || 15037 ((cptr[2] >= 'A' && cptr[2] <= 'F') ||
15032 (cptr[2] >= 'a' && cptr[2] <= 'f') || 15038 (cptr[2] >= 'a' && cptr[2] <= 'f') ||
15033 (cptr[2] >= '0' && cptr[2] <= '9'))) || 15039 (cptr[2] >= '0' && cptr[2] <= '9'))) ||
15034 (!escape_reserved && 15040 (!escape_reserved &&
15035 (*cptr == ';' || *cptr == '/' || *cptr == '?' || 15041 (*cptr == ';' || *cptr == '/' || *cptr == '?' ||
15036 *cptr == ':' || *cptr == '@' || *cptr == '&' || 15042 *cptr == ':' || *cptr == '@' || *cptr == '&' ||
15037 *cptr == '=' || *cptr == '+' || *cptr == '$' || 15043 *cptr == '=' || *cptr == '+' || *cptr == '$' ||
15038 *cptr == ','))) { 15044 *cptr == ','))) {
15039 xmlBufferAdd(target, cptr, 1); 15045 xmlBufferAdd(target, cptr, 1);
15040 } else { 15046 } else {
15041 if ((*cptr >> 4) < 10) 15047 if ((*cptr >> 4) < 10)
15042 escape[1] = '0' + (*cptr >> 4); 15048 escape[1] = '0' + (*cptr >> 4);
15043 else 15049 else
15044 escape[1] = 'A' - 10 + (*cptr >> 4); 15050 escape[1] = 'A' - 10 + (*cptr >> 4);
15045 if ((*cptr & 0xF) < 10) 15051 if ((*cptr & 0xF) < 10)
15046 escape[2] = '0' + (*cptr & 0xF); 15052 escape[2] = '0' + (*cptr & 0xF);
15047 else 15053 else
15048 escape[2] = 'A' - 10 + (*cptr & 0xF); 15054 escape[2] = 'A' - 10 + (*cptr & 0xF);
15049 » » 15055
15050 xmlBufferAdd(target, &escape[0], 3); 15056 xmlBufferAdd(target, &escape[0], 3);
15051 } 15057 }
15052 } 15058 }
15053 } 15059 }
15054 valuePush(ctxt, xmlXPathCacheNewString(ctxt->context, 15060 valuePush(ctxt, xmlXPathCacheNewString(ctxt->context,
15055 xmlBufferContent(target))); 15061 xmlBufferContent(target)));
15056 xmlBufferFree(target); 15062 xmlBufferFree(target);
15057 xmlXPathReleaseObject(ctxt->context, str); 15063 xmlXPathReleaseObject(ctxt->context, str);
15058 } 15064 }
15059 15065
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
15122 xmlXPathTranslateFunction); 15128 xmlXPathTranslateFunction);
15123 15129
15124 xmlXPathRegisterFuncNS(ctxt, (const xmlChar *)"escape-uri", 15130 xmlXPathRegisterFuncNS(ctxt, (const xmlChar *)"escape-uri",
15125 (const xmlChar *)"http://www.w3.org/2002/08/xquery-functions", 15131 (const xmlChar *)"http://www.w3.org/2002/08/xquery-functions",
15126 xmlXPathEscapeUriFunction); 15132 xmlXPathEscapeUriFunction);
15127 } 15133 }
15128 15134
15129 #endif /* LIBXML_XPATH_ENABLED */ 15135 #endif /* LIBXML_XPATH_ENABLED */
15130 #define bottom_xpath 15136 #define bottom_xpath
15131 #include "elfgcchack.h" 15137 #include "elfgcchack.h"
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698