ReactOS 0.4.16-dev-2232-gc2aaa52
pattern.c
Go to the documentation of this file.
1/*
2 * pattern.c: Implementation of selectors for nodes
3 *
4 * Reference:
5 * http://www.w3.org/TR/2001/REC-xmlschema-1-20010502/
6 * to some extent
7 * http://www.w3.org/TR/1999/REC-xml-19991116
8 *
9 * See Copyright for the status of this software.
10 *
11 * daniel@veillard.com
12 */
13
14/*
15 * TODO:
16 * - compilation flags to check for specific syntaxes
17 * using flags of xmlPatterncompile()
18 * - making clear how pattern starting with / or . need to be handled,
19 * currently push(NULL, NULL) means a reset of the streaming context
20 * and indicating we are on / (the document node), probably need
21 * something similar for .
22 * - get rid of the "compile" starting with lowercase
23 * - DONE (2006-05-16): get rid of the Strdup/Strndup in case of dictionary
24 */
25
26#define IN_LIBXML
27#include "libxml.h"
28
29#include <string.h>
30#include <libxml/pattern.h>
31#include <libxml/xmlmemory.h>
32#include <libxml/tree.h>
33#include <libxml/dict.h>
34#include <libxml/xmlerror.h>
36
37#ifdef LIBXML_PATTERN_ENABLED
38
39#ifdef ERROR
40#undef ERROR
41#endif
42#define ERROR(a, b, c, d)
43#define ERROR5(a, b, c, d, e)
44
45#define XML_STREAM_STEP_DESC 1
46#define XML_STREAM_STEP_FINAL 2
47#define XML_STREAM_STEP_ROOT 4
48#define XML_STREAM_STEP_ATTR 8
49#define XML_STREAM_STEP_NODE 16
50#define XML_STREAM_STEP_IN_SET 32
51
52/*
53* NOTE: Those private flags (XML_STREAM_xxx) are used
54* in _xmlStreamCtxt->flag. They extend the public
55* xmlPatternFlags, so be careful not to interfere with the
56* reserved values for xmlPatternFlags.
57*/
58#define XML_STREAM_FINAL_IS_ANY_NODE 1<<14
59#define XML_STREAM_FROM_ROOT 1<<15
60#define XML_STREAM_DESC 1<<16
61
62/*
63* XML_STREAM_ANY_NODE is used for comparison against
64* xmlElementType enums, to indicate a node of any type.
65*/
66#define XML_STREAM_ANY_NODE 100
67
68#define XML_PATTERN_NOTPATTERN (XML_PATTERN_XPATH | \
69 XML_PATTERN_XSSEL | \
70 XML_PATTERN_XSFIELD)
71
72#define XML_STREAM_XS_IDC(c) ((c)->flags & \
73 (XML_PATTERN_XSSEL | XML_PATTERN_XSFIELD))
74
75#define XML_STREAM_XS_IDC_SEL(c) ((c)->flags & XML_PATTERN_XSSEL)
76
77#define XML_STREAM_XS_IDC_FIELD(c) ((c)->flags & XML_PATTERN_XSFIELD)
78
79#define XML_PAT_COPY_NSNAME(c, r, nsname) \
80 if ((c)->comp->dict) \
81 r = (xmlChar *) xmlDictLookup((c)->comp->dict, BAD_CAST nsname, -1); \
82 else r = xmlStrdup(BAD_CAST nsname);
83
84#define XML_PAT_FREE_STRING(c, r) if ((c)->comp->dict == NULL) xmlFree(r);
85
86typedef struct _xmlStreamStep xmlStreamStep;
87typedef xmlStreamStep *xmlStreamStepPtr;
88struct _xmlStreamStep {
89 int flags; /* properties of that step */
90 const xmlChar *name; /* first string value if NULL accept all */
91 const xmlChar *ns; /* second string value */
92 int nodeType; /* type of node */
93};
94
95typedef struct _xmlStreamComp xmlStreamComp;
96typedef xmlStreamComp *xmlStreamCompPtr;
97struct _xmlStreamComp {
98 xmlDict *dict; /* the dictionary if any */
99 int nbStep; /* number of steps in the automata */
100 int maxStep; /* allocated number of steps */
101 xmlStreamStepPtr steps; /* the array of steps */
102 int flags;
103};
104
105struct _xmlStreamCtxt {
106 struct _xmlStreamCtxt *next;/* link to next sub pattern if | */
107 xmlStreamCompPtr comp; /* the compiled stream */
108 int nbState; /* number of states in the automata */
109 int maxState; /* allocated number of states */
110 int level; /* how deep are we ? */
111 int *states; /* the array of step indexes */
112 int flags; /* validation options */
113 int blockLevel;
114};
115
116static void xmlFreeStreamComp(xmlStreamCompPtr comp);
117
118/*
119 * Types are private:
120 */
121
122typedef enum {
123 XML_OP_END=0,
124 XML_OP_ROOT,
125 XML_OP_ELEM,
126 XML_OP_CHILD,
127 XML_OP_ATTR,
128 XML_OP_PARENT,
129 XML_OP_ANCESTOR,
130 XML_OP_NS,
131 XML_OP_ALL
132} xmlPatOp;
133
134
135typedef struct _xmlStepState xmlStepState;
136typedef xmlStepState *xmlStepStatePtr;
137struct _xmlStepState {
138 int step;
139 xmlNodePtr node;
140};
141
142typedef struct _xmlStepStates xmlStepStates;
143typedef xmlStepStates *xmlStepStatesPtr;
144struct _xmlStepStates {
145 int nbstates;
146 int maxstates;
147 xmlStepStatePtr states;
148};
149
150typedef struct _xmlStepOp xmlStepOp;
151typedef xmlStepOp *xmlStepOpPtr;
152struct _xmlStepOp {
153 xmlPatOp op;
154 const xmlChar *value;
155 const xmlChar *value2; /* The namespace name */
156};
157
158#define PAT_FROM_ROOT (1<<8)
159#define PAT_FROM_CUR (1<<9)
160
161struct _xmlPattern {
162 void *data; /* the associated template */
163 xmlDictPtr dict; /* the optional dictionary */
164 struct _xmlPattern *next; /* next pattern if | is used */
165 const xmlChar *pattern; /* the pattern */
166 int flags; /* flags */
167 int nbStep;
168 int maxStep;
169 xmlStepOpPtr steps; /* ops for computation */
170 xmlStreamCompPtr stream; /* the streaming data if any */
171};
172
173typedef struct _xmlPatParserContext xmlPatParserContext;
174typedef xmlPatParserContext *xmlPatParserContextPtr;
175struct _xmlPatParserContext {
176 const xmlChar *cur; /* the current char being parsed */
177 const xmlChar *base; /* the full expression */
178 int error; /* error code */
179 xmlDictPtr dict; /* the dictionary if any */
180 xmlPatternPtr comp; /* the result */
181 xmlNodePtr elem; /* the current node if any */
182 const xmlChar **namespaces; /* the namespaces definitions */
183 int nb_namespaces; /* the number of namespaces */
184};
185
186/************************************************************************
187 * *
188 * Type functions *
189 * *
190 ************************************************************************/
191
199static xmlPatternPtr
200xmlNewPattern(void) {
201 xmlPatternPtr cur;
202
203 cur = (xmlPatternPtr) xmlMalloc(sizeof(xmlPattern));
204 if (cur == NULL) {
206 "xmlNewPattern : malloc failed\n");
207 return(NULL);
208 }
209 memset(cur, 0, sizeof(xmlPattern));
210 cur->maxStep = 10;
211 cur->steps = (xmlStepOpPtr) xmlMalloc(cur->maxStep * sizeof(xmlStepOp));
212 if (cur->steps == NULL) {
213 xmlFree(cur);
215 "xmlNewPattern : malloc failed\n");
216 return(NULL);
217 }
218 return(cur);
219}
220
227void
228xmlFreePattern(xmlPatternPtr comp) {
229 xmlFreePatternList(comp);
230}
231
232static void
233xmlFreePatternInternal(xmlPatternPtr comp) {
234 xmlStepOpPtr op;
235 int i;
236
237 if (comp == NULL)
238 return;
239 if (comp->stream != NULL)
240 xmlFreeStreamComp(comp->stream);
241 if (comp->pattern != NULL)
242 xmlFree((xmlChar *)comp->pattern);
243 if (comp->steps != NULL) {
244 if (comp->dict == NULL) {
245 for (i = 0;i < comp->nbStep;i++) {
246 op = &comp->steps[i];
247 if (op->value != NULL)
248 xmlFree((xmlChar *) op->value);
249 if (op->value2 != NULL)
250 xmlFree((xmlChar *) op->value2);
251 }
252 }
253 xmlFree(comp->steps);
254 }
255 if (comp->dict != NULL)
256 xmlDictFree(comp->dict);
257
258 memset(comp, -1, sizeof(xmlPattern));
259 xmlFree(comp);
260}
261
268void
269xmlFreePatternList(xmlPatternPtr comp) {
270 xmlPatternPtr cur;
271
272 while (comp != NULL) {
273 cur = comp;
274 comp = comp->next;
275 cur->next = NULL;
276 xmlFreePatternInternal(cur);
277 }
278}
279
291static xmlPatParserContextPtr
292xmlNewPatParserContext(const xmlChar *pattern, xmlDictPtr dict,
293 const xmlChar **namespaces) {
294 xmlPatParserContextPtr cur;
295
296 if (pattern == NULL)
297 return(NULL);
298
299 cur = (xmlPatParserContextPtr) xmlMalloc(sizeof(xmlPatParserContext));
300 if (cur == NULL) {
302 "xmlNewPatParserContext : malloc failed\n");
303 return(NULL);
304 }
305 memset(cur, 0, sizeof(xmlPatParserContext));
306 cur->dict = dict;
307 cur->cur = pattern;
308 cur->base = pattern;
309 if (namespaces != NULL) {
310 int i;
311 for (i = 0;namespaces[2 * i] != NULL;i++)
312 ;
313 cur->nb_namespaces = i;
314 } else {
315 cur->nb_namespaces = 0;
316 }
317 cur->namespaces = namespaces;
318 return(cur);
319}
320
327static void
328xmlFreePatParserContext(xmlPatParserContextPtr ctxt) {
329 if (ctxt == NULL)
330 return;
331 memset(ctxt, -1, sizeof(xmlPatParserContext));
332 xmlFree(ctxt);
333}
334
346static int
347xmlPatternAdd(xmlPatParserContextPtr ctxt ATTRIBUTE_UNUSED,
348 xmlPatternPtr comp,
349 xmlPatOp op, xmlChar * value, xmlChar * value2)
350{
351 if (comp->nbStep >= comp->maxStep) {
352 xmlStepOpPtr temp;
353 temp = (xmlStepOpPtr) xmlRealloc(comp->steps, comp->maxStep * 2 *
354 sizeof(xmlStepOp));
355 if (temp == NULL) {
356 ERROR(ctxt, NULL, NULL,
357 "xmlPatternAdd: realloc failed\n");
358 return (-1);
359 }
360 comp->steps = temp;
361 comp->maxStep *= 2;
362 }
363 comp->steps[comp->nbStep].op = op;
364 comp->steps[comp->nbStep].value = value;
365 comp->steps[comp->nbStep].value2 = value2;
366 comp->nbStep++;
367 return (0);
368}
369
370#if 0
377static void
378xsltSwapTopPattern(xmlPatternPtr comp) {
379 int i;
380 int j = comp->nbStep - 1;
381
382 if (j > 0) {
383 register const xmlChar *tmp;
384 register xmlPatOp op;
385 i = j - 1;
386 tmp = comp->steps[i].value;
387 comp->steps[i].value = comp->steps[j].value;
388 comp->steps[j].value = tmp;
389 tmp = comp->steps[i].value2;
390 comp->steps[i].value2 = comp->steps[j].value2;
391 comp->steps[j].value2 = tmp;
392 op = comp->steps[i].op;
393 comp->steps[i].op = comp->steps[j].op;
394 comp->steps[j].op = op;
395 }
396}
397#endif
398
407static int
408xmlReversePattern(xmlPatternPtr comp) {
409 int i, j;
410
411 /*
412 * remove the leading // for //a or .//a
413 */
414 if ((comp->nbStep > 0) && (comp->steps[0].op == XML_OP_ANCESTOR)) {
415 for (i = 0, j = 1;j < comp->nbStep;i++,j++) {
416 comp->steps[i].value = comp->steps[j].value;
417 comp->steps[i].value2 = comp->steps[j].value2;
418 comp->steps[i].op = comp->steps[j].op;
419 }
420 comp->nbStep--;
421 }
422 if (comp->nbStep >= comp->maxStep) {
423 xmlStepOpPtr temp;
424 temp = (xmlStepOpPtr) xmlRealloc(comp->steps, comp->maxStep * 2 *
425 sizeof(xmlStepOp));
426 if (temp == NULL) {
427 ERROR(ctxt, NULL, NULL,
428 "xmlReversePattern: realloc failed\n");
429 return (-1);
430 }
431 comp->steps = temp;
432 comp->maxStep *= 2;
433 }
434 i = 0;
435 j = comp->nbStep - 1;
436 while (j > i) {
437 register const xmlChar *tmp;
438 register xmlPatOp op;
439 tmp = comp->steps[i].value;
440 comp->steps[i].value = comp->steps[j].value;
441 comp->steps[j].value = tmp;
442 tmp = comp->steps[i].value2;
443 comp->steps[i].value2 = comp->steps[j].value2;
444 comp->steps[j].value2 = tmp;
445 op = comp->steps[i].op;
446 comp->steps[i].op = comp->steps[j].op;
447 comp->steps[j].op = op;
448 j--;
449 i++;
450 }
451 comp->steps[comp->nbStep].value = NULL;
452 comp->steps[comp->nbStep].value2 = NULL;
453 comp->steps[comp->nbStep++].op = XML_OP_END;
454 return(0);
455}
456
457/************************************************************************
458 * *
459 * The interpreter for the precompiled patterns *
460 * *
461 ************************************************************************/
462
463static int
464xmlPatPushState(xmlStepStates *states, int step, xmlNodePtr node) {
465 if ((states->states == NULL) || (states->maxstates <= 0)) {
466 states->maxstates = 4;
467 states->nbstates = 0;
468 states->states = xmlMalloc(4 * sizeof(xmlStepState));
469 }
470 else if (states->maxstates <= states->nbstates) {
471 xmlStepState *tmp;
472
473 tmp = (xmlStepStatePtr) xmlRealloc(states->states,
474 2 * states->maxstates * sizeof(xmlStepState));
475 if (tmp == NULL)
476 return(-1);
477 states->states = tmp;
478 states->maxstates *= 2;
479 }
480 states->states[states->nbstates].step = step;
481 states->states[states->nbstates++].node = node;
482#if 0
483 fprintf(stderr, "Push: %d, %s\n", step, node->name);
484#endif
485 return(0);
486}
487
497static int
498xmlPatMatch(xmlPatternPtr comp, xmlNodePtr node) {
499 int i;
500 xmlStepOpPtr step;
501 xmlStepStates states = {0, 0, NULL}; /* // may require backtrack */
502
503 if ((comp == NULL) || (node == NULL)) return(-1);
504 i = 0;
505restart:
506 for (;i < comp->nbStep;i++) {
507 step = &comp->steps[i];
508 switch (step->op) {
509 case XML_OP_END:
510 goto found;
511 case XML_OP_ROOT:
512 if (node->type == XML_NAMESPACE_DECL)
513 goto rollback;
514 node = node->parent;
515 if ((node->type == XML_DOCUMENT_NODE) ||
516 (node->type == XML_HTML_DOCUMENT_NODE))
517 continue;
518 goto rollback;
519 case XML_OP_ELEM:
520 if (node->type != XML_ELEMENT_NODE)
521 goto rollback;
522 if (step->value == NULL)
523 continue;
524 if (step->value[0] != node->name[0])
525 goto rollback;
526 if (!xmlStrEqual(step->value, node->name))
527 goto rollback;
528
529 /* Namespace test */
530 if (node->ns == NULL) {
531 if (step->value2 != NULL)
532 goto rollback;
533 } else if (node->ns->href != NULL) {
534 if (step->value2 == NULL)
535 goto rollback;
536 if (!xmlStrEqual(step->value2, node->ns->href))
537 goto rollback;
538 }
539 continue;
540 case XML_OP_CHILD: {
541 xmlNodePtr lst;
542
543 if ((node->type != XML_ELEMENT_NODE) &&
544 (node->type != XML_DOCUMENT_NODE) &&
545 (node->type != XML_HTML_DOCUMENT_NODE))
546 goto rollback;
547
548 lst = node->children;
549
550 if (step->value != NULL) {
551 while (lst != NULL) {
552 if ((lst->type == XML_ELEMENT_NODE) &&
553 (step->value[0] == lst->name[0]) &&
554 (xmlStrEqual(step->value, lst->name)))
555 break;
556 lst = lst->next;
557 }
558 if (lst != NULL)
559 continue;
560 }
561 goto rollback;
562 }
563 case XML_OP_ATTR:
564 if (node->type != XML_ATTRIBUTE_NODE)
565 goto rollback;
566 if (step->value != NULL) {
567 if (step->value[0] != node->name[0])
568 goto rollback;
569 if (!xmlStrEqual(step->value, node->name))
570 goto rollback;
571 }
572 /* Namespace test */
573 if (node->ns == NULL) {
574 if (step->value2 != NULL)
575 goto rollback;
576 } else if (step->value2 != NULL) {
577 if (!xmlStrEqual(step->value2, node->ns->href))
578 goto rollback;
579 }
580 continue;
581 case XML_OP_PARENT:
582 if ((node->type == XML_DOCUMENT_NODE) ||
583 (node->type == XML_HTML_DOCUMENT_NODE) ||
584 (node->type == XML_NAMESPACE_DECL))
585 goto rollback;
586 node = node->parent;
587 if (node == NULL)
588 goto rollback;
589 if (step->value == NULL)
590 continue;
591 if (step->value[0] != node->name[0])
592 goto rollback;
593 if (!xmlStrEqual(step->value, node->name))
594 goto rollback;
595 /* Namespace test */
596 if (node->ns == NULL) {
597 if (step->value2 != NULL)
598 goto rollback;
599 } else if (node->ns->href != NULL) {
600 if (step->value2 == NULL)
601 goto rollback;
602 if (!xmlStrEqual(step->value2, node->ns->href))
603 goto rollback;
604 }
605 continue;
606 case XML_OP_ANCESTOR:
607 /* TODO: implement coalescing of ANCESTOR/NODE ops */
608 if (step->value == NULL) {
609 i++;
610 step = &comp->steps[i];
611 if (step->op == XML_OP_ROOT)
612 goto found;
613 if (step->op != XML_OP_ELEM)
614 goto rollback;
615 if (step->value == NULL)
616 return(-1);
617 }
618 if (node == NULL)
619 goto rollback;
620 if ((node->type == XML_DOCUMENT_NODE) ||
621 (node->type == XML_HTML_DOCUMENT_NODE) ||
622 (node->type == XML_NAMESPACE_DECL))
623 goto rollback;
624 node = node->parent;
625 while (node != NULL) {
626 if ((node->type == XML_ELEMENT_NODE) &&
627 (step->value[0] == node->name[0]) &&
628 (xmlStrEqual(step->value, node->name))) {
629 /* Namespace test */
630 if (node->ns == NULL) {
631 if (step->value2 == NULL)
632 break;
633 } else if (node->ns->href != NULL) {
634 if ((step->value2 != NULL) &&
635 (xmlStrEqual(step->value2, node->ns->href)))
636 break;
637 }
638 }
639 node = node->parent;
640 }
641 if (node == NULL)
642 goto rollback;
643 /*
644 * prepare a potential rollback from here
645 * for ancestors of that node.
646 */
647 if (step->op == XML_OP_ANCESTOR)
648 xmlPatPushState(&states, i, node);
649 else
650 xmlPatPushState(&states, i - 1, node);
651 continue;
652 case XML_OP_NS:
653 if (node->type != XML_ELEMENT_NODE)
654 goto rollback;
655 if (node->ns == NULL) {
656 if (step->value != NULL)
657 goto rollback;
658 } else if (node->ns->href != NULL) {
659 if (step->value == NULL)
660 goto rollback;
661 if (!xmlStrEqual(step->value, node->ns->href))
662 goto rollback;
663 }
664 break;
665 case XML_OP_ALL:
666 if (node->type != XML_ELEMENT_NODE)
667 goto rollback;
668 break;
669 }
670 }
671found:
672 if (states.states != NULL) {
673 /* Free the rollback states */
674 xmlFree(states.states);
675 }
676 return(1);
678 /* got an error try to rollback */
679 if (states.states == NULL)
680 return(0);
681 if (states.nbstates <= 0) {
682 xmlFree(states.states);
683 return(0);
684 }
685 states.nbstates--;
686 i = states.states[states.nbstates].step;
687 node = states.states[states.nbstates].node;
688#if 0
689 fprintf(stderr, "Pop: %d, %s\n", i, node->name);
690#endif
691 goto restart;
692}
693
694/************************************************************************
695 * *
696 * Dedicated parser for templates *
697 * *
698 ************************************************************************/
699
700#define TODO \
701 xmlGenericError(xmlGenericErrorContext, \
702 "Unimplemented block at %s:%d\n", \
703 __FILE__, __LINE__);
704#define CUR (*ctxt->cur)
705#define SKIP(val) ctxt->cur += (val)
706#define NXT(val) ctxt->cur[(val)]
707#define PEEKPREV(val) ctxt->cur[-(val)]
708#define CUR_PTR ctxt->cur
709
710#define SKIP_BLANKS \
711 while (IS_BLANK_CH(CUR)) NEXT
712
713#define CURRENT (*ctxt->cur)
714#define NEXT ((*ctxt->cur) ? ctxt->cur++: ctxt->cur)
715
716
717#define PUSH(op, val, val2) \
718 if (xmlPatternAdd(ctxt, ctxt->comp, (op), (val), (val2))) goto error;
719
720#define XSLT_ERROR(X) \
721 { xsltError(ctxt, __FILE__, __LINE__, X); \
722 ctxt->error = (X); return; }
723
724#define XSLT_ERROR0(X) \
725 { xsltError(ctxt, __FILE__, __LINE__, X); \
726 ctxt->error = (X); return(0); }
727
728#if 0
741static xmlChar *
742xmlPatScanLiteral(xmlPatParserContextPtr ctxt) {
743 const xmlChar *q, *cur;
744 xmlChar *ret = NULL;
745 int val, len;
746
748 if (CUR == '"') {
749 NEXT;
750 cur = q = CUR_PTR;
752 while ((IS_CHAR(val)) && (val != '"')) {
753 cur += len;
755 }
756 if (!IS_CHAR(val)) {
757 ctxt->error = 1;
758 return(NULL);
759 } else {
760 if (ctxt->dict)
761 ret = (xmlChar *) xmlDictLookup(ctxt->dict, q, cur - q);
762 else
763 ret = xmlStrndup(q, cur - q);
764 }
765 cur += len;
766 CUR_PTR = cur;
767 } else if (CUR == '\'') {
768 NEXT;
769 cur = q = CUR_PTR;
771 while ((IS_CHAR(val)) && (val != '\'')) {
772 cur += len;
774 }
775 if (!IS_CHAR(val)) {
776 ctxt->error = 1;
777 return(NULL);
778 } else {
779 if (ctxt->dict)
780 ret = (xmlChar *) xmlDictLookup(ctxt->dict, q, cur - q);
781 else
782 ret = xmlStrndup(q, cur - q);
783 }
784 cur += len;
785 CUR_PTR = cur;
786 } else {
787 /* XP_ERROR(XPATH_START_LITERAL_ERROR); */
788 ctxt->error = 1;
789 return(NULL);
790 }
791 return(ret);
792}
793#endif
794
809static xmlChar *
810xmlPatScanName(xmlPatParserContextPtr ctxt) {
811 const xmlChar *q, *cur;
812 xmlChar *ret = NULL;
813 int val, len;
814
816
817 cur = q = CUR_PTR;
819 if (!IS_LETTER(val) && (val != '_') && (val != ':'))
820 return(NULL);
821
822 while ((IS_LETTER(val)) || (IS_DIGIT(val)) ||
823 (val == '.') || (val == '-') ||
824 (val == '_') ||
825 (IS_COMBINING(val)) ||
826 (IS_EXTENDER(val))) {
827 cur += len;
829 }
830 if (ctxt->dict)
831 ret = (xmlChar *) xmlDictLookup(ctxt->dict, q, cur - q);
832 else
833 ret = xmlStrndup(q, cur - q);
834 CUR_PTR = cur;
835 return(ret);
836}
837
847static xmlChar *
848xmlPatScanNCName(xmlPatParserContextPtr ctxt) {
849 const xmlChar *q, *cur;
850 xmlChar *ret = NULL;
851 int val, len;
852
854
855 cur = q = CUR_PTR;
857 if (!IS_LETTER(val) && (val != '_'))
858 return(NULL);
859
860 while ((IS_LETTER(val)) || (IS_DIGIT(val)) ||
861 (val == '.') || (val == '-') ||
862 (val == '_') ||
863 (IS_COMBINING(val)) ||
864 (IS_EXTENDER(val))) {
865 cur += len;
867 }
868 if (ctxt->dict)
869 ret = (xmlChar *) xmlDictLookup(ctxt->dict, q, cur - q);
870 else
871 ret = xmlStrndup(q, cur - q);
872 CUR_PTR = cur;
873 return(ret);
874}
875
876#if 0
887static xmlChar *
888xmlPatScanQName(xmlPatParserContextPtr ctxt, xmlChar **prefix) {
889 xmlChar *ret = NULL;
890
891 *prefix = NULL;
892 ret = xmlPatScanNCName(ctxt);
893 if (CUR == ':') {
894 *prefix = ret;
895 NEXT;
896 ret = xmlPatScanNCName(ctxt);
897 }
898 return(ret);
899}
900#endif
901
908static void
909xmlCompileAttributeTest(xmlPatParserContextPtr ctxt) {
910 xmlChar *token = NULL;
911 xmlChar *name = NULL;
912 xmlChar *URL = NULL;
913
915 name = xmlPatScanNCName(ctxt);
916 if (name == NULL) {
917 if (CUR == '*') {
918 PUSH(XML_OP_ATTR, NULL, NULL);
919 NEXT;
920 } else {
922 "xmlCompileAttributeTest : Name expected\n");
923 ctxt->error = 1;
924 }
925 return;
926 }
927 if (CUR == ':') {
928 int i;
930
931 NEXT;
932
933 if (IS_BLANK_CH(CUR)) {
934 ERROR5(NULL, NULL, NULL, "Invalid QName.\n", NULL);
935 ctxt->error = 1;
936 goto error;
937 }
938 /*
939 * This is a namespace match
940 */
941 token = xmlPatScanName(ctxt);
942 if ((prefix[0] == 'x') &&
943 (prefix[1] == 'm') &&
944 (prefix[2] == 'l') &&
945 (prefix[3] == 0))
946 {
947 XML_PAT_COPY_NSNAME(ctxt, URL, XML_XML_NAMESPACE);
948 } else {
949 for (i = 0;i < ctxt->nb_namespaces;i++) {
950 if (xmlStrEqual(ctxt->namespaces[2 * i + 1], prefix)) {
951 XML_PAT_COPY_NSNAME(ctxt, URL, ctxt->namespaces[2 * i])
952 break;
953 }
954 }
955 if (i >= ctxt->nb_namespaces) {
956 ERROR5(NULL, NULL, NULL,
957 "xmlCompileAttributeTest : no namespace bound to prefix %s\n",
958 prefix);
959 ctxt->error = 1;
960 goto error;
961 }
962 }
963 XML_PAT_FREE_STRING(ctxt, name);
964 name = NULL;
965 if (token == NULL) {
966 if (CUR == '*') {
967 NEXT;
968 PUSH(XML_OP_ATTR, NULL, URL);
969 } else {
971 "xmlCompileAttributeTest : Name expected\n");
972 ctxt->error = 1;
973 goto error;
974 }
975 } else {
976 PUSH(XML_OP_ATTR, token, URL);
977 }
978 } else {
979 PUSH(XML_OP_ATTR, name, NULL);
980 }
981 return;
982error:
983 if (name != NULL)
984 XML_PAT_FREE_STRING(ctxt, name);
985 if (URL != NULL)
986 XML_PAT_FREE_STRING(ctxt, URL)
987 if (token != NULL)
988 XML_PAT_FREE_STRING(ctxt, token);
989}
990
1002static void
1003xmlCompileStepPattern(xmlPatParserContextPtr ctxt) {
1004 xmlChar *token = NULL;
1005 xmlChar *name = NULL;
1006 xmlChar *URL = NULL;
1007 int hasBlanks = 0;
1008
1010 if (CUR == '.') {
1011 /*
1012 * Context node.
1013 */
1014 NEXT;
1015 PUSH(XML_OP_ELEM, NULL, NULL);
1016 return;
1017 }
1018 if (CUR == '@') {
1019 /*
1020 * Attribute test.
1021 */
1022 if (XML_STREAM_XS_IDC_SEL(ctxt->comp)) {
1023 ERROR5(NULL, NULL, NULL,
1024 "Unexpected attribute axis in '%s'.\n", ctxt->base);
1025 ctxt->error = 1;
1026 return;
1027 }
1028 NEXT;
1029 xmlCompileAttributeTest(ctxt);
1030 if (ctxt->error != 0)
1031 goto error;
1032 return;
1033 }
1034 name = xmlPatScanNCName(ctxt);
1035 if (name == NULL) {
1036 if (CUR == '*') {
1037 NEXT;
1038 PUSH(XML_OP_ALL, NULL, NULL);
1039 return;
1040 } else {
1041 ERROR(NULL, NULL, NULL,
1042 "xmlCompileStepPattern : Name expected\n");
1043 ctxt->error = 1;
1044 return;
1045 }
1046 }
1047 if (IS_BLANK_CH(CUR)) {
1048 hasBlanks = 1;
1050 }
1051 if (CUR == ':') {
1052 NEXT;
1053 if (CUR != ':') {
1054 xmlChar *prefix = name;
1055 int i;
1056
1057 if (hasBlanks || IS_BLANK_CH(CUR)) {
1058 ERROR5(NULL, NULL, NULL, "Invalid QName.\n", NULL);
1059 ctxt->error = 1;
1060 goto error;
1061 }
1062 /*
1063 * This is a namespace match
1064 */
1065 token = xmlPatScanName(ctxt);
1066 if ((prefix[0] == 'x') &&
1067 (prefix[1] == 'm') &&
1068 (prefix[2] == 'l') &&
1069 (prefix[3] == 0))
1070 {
1071 XML_PAT_COPY_NSNAME(ctxt, URL, XML_XML_NAMESPACE)
1072 } else {
1073 for (i = 0;i < ctxt->nb_namespaces;i++) {
1074 if (xmlStrEqual(ctxt->namespaces[2 * i + 1], prefix)) {
1075 XML_PAT_COPY_NSNAME(ctxt, URL, ctxt->namespaces[2 * i])
1076 break;
1077 }
1078 }
1079 if (i >= ctxt->nb_namespaces) {
1080 ERROR5(NULL, NULL, NULL,
1081 "xmlCompileStepPattern : no namespace bound to prefix %s\n",
1082 prefix);
1083 ctxt->error = 1;
1084 goto error;
1085 }
1086 }
1087 XML_PAT_FREE_STRING(ctxt, prefix);
1088 name = NULL;
1089 if (token == NULL) {
1090 if (CUR == '*') {
1091 NEXT;
1092 PUSH(XML_OP_NS, URL, NULL);
1093 } else {
1094 ERROR(NULL, NULL, NULL,
1095 "xmlCompileStepPattern : Name expected\n");
1096 ctxt->error = 1;
1097 goto error;
1098 }
1099 } else {
1100 PUSH(XML_OP_ELEM, token, URL);
1101 }
1102 } else {
1103 NEXT;
1104 if (xmlStrEqual(name, (const xmlChar *) "child")) {
1105 XML_PAT_FREE_STRING(ctxt, name);
1106 name = xmlPatScanName(ctxt);
1107 if (name == NULL) {
1108 if (CUR == '*') {
1109 NEXT;
1110 PUSH(XML_OP_ALL, NULL, NULL);
1111 return;
1112 } else {
1113 ERROR(NULL, NULL, NULL,
1114 "xmlCompileStepPattern : QName expected\n");
1115 ctxt->error = 1;
1116 goto error;
1117 }
1118 }
1119 if (CUR == ':') {
1120 xmlChar *prefix = name;
1121 int i;
1122
1123 NEXT;
1124 if (IS_BLANK_CH(CUR)) {
1125 ERROR5(NULL, NULL, NULL, "Invalid QName.\n", NULL);
1126 ctxt->error = 1;
1127 goto error;
1128 }
1129 /*
1130 * This is a namespace match
1131 */
1132 token = xmlPatScanName(ctxt);
1133 if ((prefix[0] == 'x') &&
1134 (prefix[1] == 'm') &&
1135 (prefix[2] == 'l') &&
1136 (prefix[3] == 0))
1137 {
1138 XML_PAT_COPY_NSNAME(ctxt, URL, XML_XML_NAMESPACE)
1139 } else {
1140 for (i = 0;i < ctxt->nb_namespaces;i++) {
1141 if (xmlStrEqual(ctxt->namespaces[2 * i + 1], prefix)) {
1142 XML_PAT_COPY_NSNAME(ctxt, URL, ctxt->namespaces[2 * i])
1143 break;
1144 }
1145 }
1146 if (i >= ctxt->nb_namespaces) {
1147 ERROR5(NULL, NULL, NULL,
1148 "xmlCompileStepPattern : no namespace bound "
1149 "to prefix %s\n", prefix);
1150 ctxt->error = 1;
1151 goto error;
1152 }
1153 }
1154 XML_PAT_FREE_STRING(ctxt, prefix);
1155 name = NULL;
1156 if (token == NULL) {
1157 if (CUR == '*') {
1158 NEXT;
1159 PUSH(XML_OP_NS, URL, NULL);
1160 } else {
1161 ERROR(NULL, NULL, NULL,
1162 "xmlCompileStepPattern : Name expected\n");
1163 ctxt->error = 1;
1164 goto error;
1165 }
1166 } else {
1167 PUSH(XML_OP_CHILD, token, URL);
1168 }
1169 } else
1170 PUSH(XML_OP_CHILD, name, NULL);
1171 return;
1172 } else if (xmlStrEqual(name, (const xmlChar *) "attribute")) {
1173 XML_PAT_FREE_STRING(ctxt, name)
1174 name = NULL;
1175 if (XML_STREAM_XS_IDC_SEL(ctxt->comp)) {
1176 ERROR5(NULL, NULL, NULL,
1177 "Unexpected attribute axis in '%s'.\n", ctxt->base);
1178 ctxt->error = 1;
1179 goto error;
1180 }
1181 xmlCompileAttributeTest(ctxt);
1182 if (ctxt->error != 0)
1183 goto error;
1184 return;
1185 } else {
1186 ERROR5(NULL, NULL, NULL,
1187 "The 'element' or 'attribute' axis is expected.\n", NULL);
1188 ctxt->error = 1;
1189 goto error;
1190 }
1191 }
1192 } else if (CUR == '*') {
1193 if (name != NULL) {
1194 ctxt->error = 1;
1195 goto error;
1196 }
1197 NEXT;
1198 PUSH(XML_OP_ALL, token, NULL);
1199 } else {
1200 PUSH(XML_OP_ELEM, name, NULL);
1201 }
1202 return;
1203error:
1204 if (URL != NULL)
1205 XML_PAT_FREE_STRING(ctxt, URL)
1206 if (token != NULL)
1207 XML_PAT_FREE_STRING(ctxt, token)
1208 if (name != NULL)
1209 XML_PAT_FREE_STRING(ctxt, name)
1210}
1211
1221static void
1222xmlCompilePathPattern(xmlPatParserContextPtr ctxt) {
1224 if (CUR == '/') {
1225 ctxt->comp->flags |= PAT_FROM_ROOT;
1226 } else if ((CUR == '.') || (ctxt->comp->flags & XML_PATTERN_NOTPATTERN)) {
1227 ctxt->comp->flags |= PAT_FROM_CUR;
1228 }
1229
1230 if ((CUR == '/') && (NXT(1) == '/')) {
1231 PUSH(XML_OP_ANCESTOR, NULL, NULL);
1232 NEXT;
1233 NEXT;
1234 } else if ((CUR == '.') && (NXT(1) == '/') && (NXT(2) == '/')) {
1235 PUSH(XML_OP_ANCESTOR, NULL, NULL);
1236 NEXT;
1237 NEXT;
1238 NEXT;
1239 /* Check for incompleteness. */
1241 if (CUR == 0) {
1242 ERROR5(NULL, NULL, NULL,
1243 "Incomplete expression '%s'.\n", ctxt->base);
1244 ctxt->error = 1;
1245 goto error;
1246 }
1247 }
1248 if (CUR == '@') {
1249 NEXT;
1250 xmlCompileAttributeTest(ctxt);
1252 /* TODO: check for incompleteness */
1253 if (CUR != 0) {
1254 xmlCompileStepPattern(ctxt);
1255 if (ctxt->error != 0)
1256 goto error;
1257 }
1258 } else {
1259 if (CUR == '/') {
1260 PUSH(XML_OP_ROOT, NULL, NULL);
1261 NEXT;
1262 /* Check for incompleteness. */
1264 if (CUR == 0) {
1265 ERROR5(NULL, NULL, NULL,
1266 "Incomplete expression '%s'.\n", ctxt->base);
1267 ctxt->error = 1;
1268 goto error;
1269 }
1270 }
1271 xmlCompileStepPattern(ctxt);
1272 if (ctxt->error != 0)
1273 goto error;
1275 while (CUR == '/') {
1276 if (NXT(1) == '/') {
1277 PUSH(XML_OP_ANCESTOR, NULL, NULL);
1278 NEXT;
1279 NEXT;
1281 xmlCompileStepPattern(ctxt);
1282 if (ctxt->error != 0)
1283 goto error;
1284 } else {
1285 PUSH(XML_OP_PARENT, NULL, NULL);
1286 NEXT;
1288 if (CUR == 0) {
1289 ERROR5(NULL, NULL, NULL,
1290 "Incomplete expression '%s'.\n", ctxt->base);
1291 ctxt->error = 1;
1292 goto error;
1293 }
1294 xmlCompileStepPattern(ctxt);
1295 if (ctxt->error != 0)
1296 goto error;
1297 }
1298 }
1299 }
1300 if (CUR != 0) {
1301 ERROR5(NULL, NULL, NULL,
1302 "Failed to compile pattern %s\n", ctxt->base);
1303 ctxt->error = 1;
1304 }
1305error:
1306 return;
1307}
1308
1318static void
1319xmlCompileIDCXPathPath(xmlPatParserContextPtr ctxt) {
1321 if (CUR == '/') {
1322 ERROR5(NULL, NULL, NULL,
1323 "Unexpected selection of the document root in '%s'.\n",
1324 ctxt->base);
1325 goto error;
1326 }
1327 ctxt->comp->flags |= PAT_FROM_CUR;
1328
1329 if (CUR == '.') {
1330 /* "." - "self::node()" */
1331 NEXT;
1333 if (CUR == 0) {
1334 /*
1335 * Selection of the context node.
1336 */
1337 PUSH(XML_OP_ELEM, NULL, NULL);
1338 return;
1339 }
1340 if (CUR != '/') {
1341 /* TODO: A more meaningful error message. */
1342 ERROR5(NULL, NULL, NULL,
1343 "Unexpected token after '.' in '%s'.\n", ctxt->base);
1344 goto error;
1345 }
1346 /* "./" - "self::node()/" */
1347 NEXT;
1349 if (CUR == '/') {
1350 if (IS_BLANK_CH(PEEKPREV(1))) {
1351 /*
1352 * Disallow "./ /"
1353 */
1354 ERROR5(NULL, NULL, NULL,
1355 "Unexpected '/' token in '%s'.\n", ctxt->base);
1356 goto error;
1357 }
1358 /* ".//" - "self:node()/descendant-or-self::node()/" */
1359 PUSH(XML_OP_ANCESTOR, NULL, NULL);
1360 NEXT;
1362 }
1363 if (CUR == 0)
1364 goto error_unfinished;
1365 }
1366 /*
1367 * Process steps.
1368 */
1369 do {
1370 xmlCompileStepPattern(ctxt);
1371 if (ctxt->error != 0)
1372 goto error;
1374 if (CUR != '/')
1375 break;
1376 PUSH(XML_OP_PARENT, NULL, NULL);
1377 NEXT;
1379 if (CUR == '/') {
1380 /*
1381 * Disallow subsequent '//'.
1382 */
1383 ERROR5(NULL, NULL, NULL,
1384 "Unexpected subsequent '//' in '%s'.\n",
1385 ctxt->base);
1386 goto error;
1387 }
1388 if (CUR == 0)
1389 goto error_unfinished;
1390
1391 } while (CUR != 0);
1392
1393 if (CUR != 0) {
1394 ERROR5(NULL, NULL, NULL,
1395 "Failed to compile expression '%s'.\n", ctxt->base);
1396 ctxt->error = 1;
1397 }
1398 return;
1399error:
1400 ctxt->error = 1;
1401 return;
1402
1403error_unfinished:
1404 ctxt->error = 1;
1405 ERROR5(NULL, NULL, NULL,
1406 "Unfinished expression '%s'.\n", ctxt->base);
1407 return;
1408}
1409
1410/************************************************************************
1411 * *
1412 * The streaming code *
1413 * *
1414 ************************************************************************/
1415
1424static xmlStreamCompPtr
1425xmlNewStreamComp(int size) {
1426 xmlStreamCompPtr cur;
1427
1428 if (size < 4)
1429 size = 4;
1430
1431 cur = (xmlStreamCompPtr) xmlMalloc(sizeof(xmlStreamComp));
1432 if (cur == NULL) {
1433 ERROR(NULL, NULL, NULL,
1434 "xmlNewStreamComp: malloc failed\n");
1435 return(NULL);
1436 }
1437 memset(cur, 0, sizeof(xmlStreamComp));
1438 cur->steps = (xmlStreamStepPtr) xmlMalloc(size * sizeof(xmlStreamStep));
1439 if (cur->steps == NULL) {
1440 xmlFree(cur);
1441 ERROR(NULL, NULL, NULL,
1442 "xmlNewStreamComp: malloc failed\n");
1443 return(NULL);
1444 }
1445 cur->nbStep = 0;
1446 cur->maxStep = size;
1447 return(cur);
1448}
1449
1456static void
1457xmlFreeStreamComp(xmlStreamCompPtr comp) {
1458 if (comp != NULL) {
1459 if (comp->steps != NULL)
1460 xmlFree(comp->steps);
1461 if (comp->dict != NULL)
1462 xmlDictFree(comp->dict);
1463 xmlFree(comp);
1464 }
1465}
1466
1478static int
1479xmlStreamCompAddStep(xmlStreamCompPtr comp, const xmlChar *name,
1480 const xmlChar *ns, int nodeType, int flags) {
1481 xmlStreamStepPtr cur;
1482
1483 if (comp->nbStep >= comp->maxStep) {
1484 cur = (xmlStreamStepPtr) xmlRealloc(comp->steps,
1485 comp->maxStep * 2 * sizeof(xmlStreamStep));
1486 if (cur == NULL) {
1487 ERROR(NULL, NULL, NULL,
1488 "xmlNewStreamComp: malloc failed\n");
1489 return(-1);
1490 }
1491 comp->steps = cur;
1492 comp->maxStep *= 2;
1493 }
1494 cur = &comp->steps[comp->nbStep++];
1495 cur->flags = flags;
1496 cur->name = name;
1497 cur->ns = ns;
1498 cur->nodeType = nodeType;
1499 return(comp->nbStep - 1);
1500}
1501
1510static int
1511xmlStreamCompile(xmlPatternPtr comp) {
1512 xmlStreamCompPtr stream;
1513 int i, s = 0, root = 0, flags = 0, prevs = -1;
1514 xmlStepOp step;
1515
1516 if ((comp == NULL) || (comp->steps == NULL))
1517 return(-1);
1518 /*
1519 * special case for .
1520 */
1521 if ((comp->nbStep == 1) &&
1522 (comp->steps[0].op == XML_OP_ELEM) &&
1523 (comp->steps[0].value == NULL) &&
1524 (comp->steps[0].value2 == NULL)) {
1525 stream = xmlNewStreamComp(0);
1526 if (stream == NULL)
1527 return(-1);
1528 /* Note that the stream will have no steps in this case. */
1529 stream->flags |= XML_STREAM_FINAL_IS_ANY_NODE;
1530 comp->stream = stream;
1531 return(0);
1532 }
1533
1534 stream = xmlNewStreamComp((comp->nbStep / 2) + 1);
1535 if (stream == NULL)
1536 return(-1);
1537 if (comp->dict != NULL) {
1538 stream->dict = comp->dict;
1539 xmlDictReference(stream->dict);
1540 }
1541
1542 i = 0;
1543 if (comp->flags & PAT_FROM_ROOT)
1544 stream->flags |= XML_STREAM_FROM_ROOT;
1545
1546 for (;i < comp->nbStep;i++) {
1547 step = comp->steps[i];
1548 switch (step.op) {
1549 case XML_OP_END:
1550 break;
1551 case XML_OP_ROOT:
1552 if (i != 0)
1553 goto error;
1554 root = 1;
1555 break;
1556 case XML_OP_NS:
1557 s = xmlStreamCompAddStep(stream, NULL, step.value,
1558 XML_ELEMENT_NODE, flags);
1559 if (s < 0)
1560 goto error;
1561 prevs = s;
1562 flags = 0;
1563 break;
1564 case XML_OP_ATTR:
1565 flags |= XML_STREAM_STEP_ATTR;
1566 prevs = -1;
1567 s = xmlStreamCompAddStep(stream,
1568 step.value, step.value2, XML_ATTRIBUTE_NODE, flags);
1569 flags = 0;
1570 if (s < 0)
1571 goto error;
1572 break;
1573 case XML_OP_ELEM:
1574 if ((step.value == NULL) && (step.value2 == NULL)) {
1575 /*
1576 * We have a "." or "self::node()" here.
1577 * Eliminate redundant self::node() tests like in "/./."
1578 * or "//./"
1579 * The only case we won't eliminate is "//.", i.e. if
1580 * self::node() is the last node test and we had
1581 * continuation somewhere beforehand.
1582 */
1583 if ((comp->nbStep == i + 1) &&
1584 (flags & XML_STREAM_STEP_DESC)) {
1585 /*
1586 * Mark the special case where the expression resolves
1587 * to any type of node.
1588 */
1589 if (comp->nbStep == i + 1) {
1590 stream->flags |= XML_STREAM_FINAL_IS_ANY_NODE;
1591 }
1592 flags |= XML_STREAM_STEP_NODE;
1593 s = xmlStreamCompAddStep(stream, NULL, NULL,
1594 XML_STREAM_ANY_NODE, flags);
1595 if (s < 0)
1596 goto error;
1597 flags = 0;
1598 /*
1599 * If there was a previous step, mark it to be added to
1600 * the result node-set; this is needed since only
1601 * the last step will be marked as "final" and only
1602 * "final" nodes are added to the resulting set.
1603 */
1604 if (prevs != -1) {
1605 stream->steps[prevs].flags |= XML_STREAM_STEP_IN_SET;
1606 prevs = -1;
1607 }
1608 break;
1609
1610 } else {
1611 /* Just skip this one. */
1612 continue;
1613 }
1614 }
1615 /* An element node. */
1616 s = xmlStreamCompAddStep(stream, step.value, step.value2,
1617 XML_ELEMENT_NODE, flags);
1618 if (s < 0)
1619 goto error;
1620 prevs = s;
1621 flags = 0;
1622 break;
1623 case XML_OP_CHILD:
1624 /* An element node child. */
1625 s = xmlStreamCompAddStep(stream, step.value, step.value2,
1626 XML_ELEMENT_NODE, flags);
1627 if (s < 0)
1628 goto error;
1629 prevs = s;
1630 flags = 0;
1631 break;
1632 case XML_OP_ALL:
1633 s = xmlStreamCompAddStep(stream, NULL, NULL,
1634 XML_ELEMENT_NODE, flags);
1635 if (s < 0)
1636 goto error;
1637 prevs = s;
1638 flags = 0;
1639 break;
1640 case XML_OP_PARENT:
1641 break;
1642 case XML_OP_ANCESTOR:
1643 /* Skip redundant continuations. */
1644 if (flags & XML_STREAM_STEP_DESC)
1645 break;
1646 flags |= XML_STREAM_STEP_DESC;
1647 /*
1648 * Mark the expression as having "//".
1649 */
1650 if ((stream->flags & XML_STREAM_DESC) == 0)
1651 stream->flags |= XML_STREAM_DESC;
1652 break;
1653 }
1654 }
1655 if ((! root) && (comp->flags & XML_PATTERN_NOTPATTERN) == 0) {
1656 /*
1657 * If this should behave like a real pattern, we will mark
1658 * the first step as having "//", to be reentrant on every
1659 * tree level.
1660 */
1661 if ((stream->flags & XML_STREAM_DESC) == 0)
1662 stream->flags |= XML_STREAM_DESC;
1663
1664 if (stream->nbStep > 0) {
1665 if ((stream->steps[0].flags & XML_STREAM_STEP_DESC) == 0)
1666 stream->steps[0].flags |= XML_STREAM_STEP_DESC;
1667 }
1668 }
1669 if (stream->nbStep <= s)
1670 goto error;
1671 stream->steps[s].flags |= XML_STREAM_STEP_FINAL;
1672 if (root)
1673 stream->steps[0].flags |= XML_STREAM_STEP_ROOT;
1674 comp->stream = stream;
1675 return(0);
1676error:
1677 xmlFreeStreamComp(stream);
1678 return(0);
1679}
1680
1689static xmlStreamCtxtPtr
1690xmlNewStreamCtxt(xmlStreamCompPtr stream) {
1691 xmlStreamCtxtPtr cur;
1692
1693 cur = (xmlStreamCtxtPtr) xmlMalloc(sizeof(xmlStreamCtxt));
1694 if (cur == NULL) {
1695 ERROR(NULL, NULL, NULL,
1696 "xmlNewStreamCtxt: malloc failed\n");
1697 return(NULL);
1698 }
1699 memset(cur, 0, sizeof(xmlStreamCtxt));
1700 cur->states = (int *) xmlMalloc(4 * 2 * sizeof(int));
1701 if (cur->states == NULL) {
1702 xmlFree(cur);
1703 ERROR(NULL, NULL, NULL,
1704 "xmlNewStreamCtxt: malloc failed\n");
1705 return(NULL);
1706 }
1707 cur->nbState = 0;
1708 cur->maxState = 4;
1709 cur->level = 0;
1710 cur->comp = stream;
1711 cur->blockLevel = -1;
1712 return(cur);
1713}
1714
1721void
1722xmlFreeStreamCtxt(xmlStreamCtxtPtr stream) {
1723 xmlStreamCtxtPtr next;
1724
1725 while (stream != NULL) {
1726 next = stream->next;
1727 if (stream->states != NULL)
1728 xmlFree(stream->states);
1729 xmlFree(stream);
1730 stream = next;
1731 }
1732}
1733
1743static int
1744xmlStreamCtxtAddState(xmlStreamCtxtPtr comp, int idx, int level) {
1745 int i;
1746 for (i = 0;i < comp->nbState;i++) {
1747 if (comp->states[2 * i] < 0) {
1748 comp->states[2 * i] = idx;
1749 comp->states[2 * i + 1] = level;
1750 return(i);
1751 }
1752 }
1753 if (comp->nbState >= comp->maxState) {
1754 int *cur;
1755
1756 cur = (int *) xmlRealloc(comp->states,
1757 comp->maxState * 4 * sizeof(int));
1758 if (cur == NULL) {
1759 ERROR(NULL, NULL, NULL,
1760 "xmlNewStreamCtxt: malloc failed\n");
1761 return(-1);
1762 }
1763 comp->states = cur;
1764 comp->maxState *= 2;
1765 }
1766 comp->states[2 * comp->nbState] = idx;
1767 comp->states[2 * comp->nbState++ + 1] = level;
1768 return(comp->nbState - 1);
1769}
1770
1787static int
1788xmlStreamPushInternal(xmlStreamCtxtPtr stream,
1789 const xmlChar *name, const xmlChar *ns,
1790 int nodeType) {
1791 int ret = 0, err = 0, final = 0, tmp, i, m, match, stepNr, desc;
1792 xmlStreamCompPtr comp;
1793 xmlStreamStep step;
1794
1795 if ((stream == NULL) || (stream->nbState < 0))
1796 return(-1);
1797
1798 while (stream != NULL) {
1799 comp = stream->comp;
1800
1801 if ((nodeType == XML_ELEMENT_NODE) &&
1802 (name == NULL) && (ns == NULL)) {
1803 /* We have a document node here (or a reset). */
1804 stream->nbState = 0;
1805 stream->level = 0;
1806 stream->blockLevel = -1;
1807 if (comp->flags & XML_STREAM_FROM_ROOT) {
1808 if (comp->nbStep == 0) {
1809 /* TODO: We have a "/." here? */
1810 ret = 1;
1811 } else {
1812 if ((comp->nbStep == 1) &&
1813 (comp->steps[0].nodeType == XML_STREAM_ANY_NODE) &&
1814 (comp->steps[0].flags & XML_STREAM_STEP_DESC))
1815 {
1816 /*
1817 * In the case of "//." the document node will match
1818 * as well.
1819 */
1820 ret = 1;
1821 } else if (comp->steps[0].flags & XML_STREAM_STEP_ROOT) {
1822 /* TODO: Do we need this ? */
1823 tmp = xmlStreamCtxtAddState(stream, 0, 0);
1824 if (tmp < 0)
1825 err++;
1826 }
1827 }
1828 }
1829 stream = stream->next;
1830 continue; /* while */
1831 }
1832
1833 /*
1834 * Fast check for ".".
1835 */
1836 if (comp->nbStep == 0) {
1837 /*
1838 * / and . are handled at the XPath node set creation
1839 * level by checking min depth
1840 */
1841 if (stream->flags & XML_PATTERN_XPATH) {
1842 stream = stream->next;
1843 continue; /* while */
1844 }
1845 /*
1846 * For non-pattern like evaluation like XML Schema IDCs
1847 * or traditional XPath expressions, this will match if
1848 * we are at the first level only, otherwise on every level.
1849 */
1850 if ((nodeType != XML_ATTRIBUTE_NODE) &&
1851 (((stream->flags & XML_PATTERN_NOTPATTERN) == 0) ||
1852 (stream->level == 0))) {
1853 ret = 1;
1854 }
1855 stream->level++;
1856 goto stream_next;
1857 }
1858 if (stream->blockLevel != -1) {
1859 /*
1860 * Skip blocked expressions.
1861 */
1862 stream->level++;
1863 goto stream_next;
1864 }
1865
1866 if ((nodeType != XML_ELEMENT_NODE) &&
1867 (nodeType != XML_ATTRIBUTE_NODE) &&
1868 ((comp->flags & XML_STREAM_FINAL_IS_ANY_NODE) == 0)) {
1869 /*
1870 * No need to process nodes of other types if we don't
1871 * resolve to those types.
1872 * TODO: Do we need to block the context here?
1873 */
1874 stream->level++;
1875 goto stream_next;
1876 }
1877
1878 /*
1879 * Check evolution of existing states
1880 */
1881 i = 0;
1882 m = stream->nbState;
1883 while (i < m) {
1884 if ((comp->flags & XML_STREAM_DESC) == 0) {
1885 /*
1886 * If there is no "//", then only the last
1887 * added state is of interest.
1888 */
1889 stepNr = stream->states[2 * (stream->nbState -1)];
1890 /*
1891 * TODO: Security check, should not happen, remove it.
1892 */
1893 if (stream->states[(2 * (stream->nbState -1)) + 1] <
1894 stream->level) {
1895 return (-1);
1896 }
1897 desc = 0;
1898 /* loop-stopper */
1899 i = m;
1900 } else {
1901 /*
1902 * If there are "//", then we need to process every "//"
1903 * occurring in the states, plus any other state for this
1904 * level.
1905 */
1906 stepNr = stream->states[2 * i];
1907
1908 /* TODO: should not happen anymore: dead states */
1909 if (stepNr < 0)
1910 goto next_state;
1911
1912 tmp = stream->states[(2 * i) + 1];
1913
1914 /* skip new states just added */
1915 if (tmp > stream->level)
1916 goto next_state;
1917
1918 /* skip states at ancestor levels, except if "//" */
1919 desc = comp->steps[stepNr].flags & XML_STREAM_STEP_DESC;
1920 if ((tmp < stream->level) && (!desc))
1921 goto next_state;
1922 }
1923 /*
1924 * Check for correct node-type.
1925 */
1926 step = comp->steps[stepNr];
1927 if (step.nodeType != nodeType) {
1928 if (step.nodeType == XML_ATTRIBUTE_NODE) {
1929 /*
1930 * Block this expression for deeper evaluation.
1931 */
1932 if ((comp->flags & XML_STREAM_DESC) == 0)
1933 stream->blockLevel = stream->level +1;
1934 goto next_state;
1935 } else if (step.nodeType != XML_STREAM_ANY_NODE)
1936 goto next_state;
1937 }
1938 /*
1939 * Compare local/namespace-name.
1940 */
1941 match = 0;
1942 if (step.nodeType == XML_STREAM_ANY_NODE) {
1943 match = 1;
1944 } else if (step.name == NULL) {
1945 if (step.ns == NULL) {
1946 /*
1947 * This lets through all elements/attributes.
1948 */
1949 match = 1;
1950 } else if (ns != NULL)
1951 match = xmlStrEqual(step.ns, ns);
1952 } else if (((step.ns != NULL) == (ns != NULL)) &&
1953 (name != NULL) &&
1954 (step.name[0] == name[0]) &&
1955 xmlStrEqual(step.name, name) &&
1956 ((step.ns == ns) || xmlStrEqual(step.ns, ns)))
1957 {
1958 match = 1;
1959 }
1960#if 0
1961/*
1962* TODO: Pointer comparison won't work, since not guaranteed that the given
1963* values are in the same dict; especially if it's the namespace name,
1964* normally coming from ns->href. We need a namespace dict mechanism !
1965*/
1966 } else if (comp->dict) {
1967 if (step.name == NULL) {
1968 if (step.ns == NULL)
1969 match = 1;
1970 else
1971 match = (step.ns == ns);
1972 } else {
1973 match = ((step.name == name) && (step.ns == ns));
1974 }
1975#endif /* if 0 ------------------------------------------------------- */
1976 if (match) {
1977 final = step.flags & XML_STREAM_STEP_FINAL;
1978 if (final) {
1979 ret = 1;
1980 } else {
1981 xmlStreamCtxtAddState(stream, stepNr + 1,
1982 stream->level + 1);
1983 }
1984 if ((ret != 1) && (step.flags & XML_STREAM_STEP_IN_SET)) {
1985 /*
1986 * Check if we have a special case like "foo/bar//.", where
1987 * "foo" is selected as well.
1988 */
1989 ret = 1;
1990 }
1991 }
1992 if (((comp->flags & XML_STREAM_DESC) == 0) &&
1993 ((! match) || final)) {
1994 /*
1995 * Mark this expression as blocked for any evaluation at
1996 * deeper levels. Note that this includes "/foo"
1997 * expressions if the *pattern* behaviour is used.
1998 */
1999 stream->blockLevel = stream->level +1;
2000 }
2001next_state:
2002 i++;
2003 }
2004
2005 stream->level++;
2006
2007 /*
2008 * Re/enter the expression.
2009 * Don't reenter if it's an absolute expression like "/foo",
2010 * except "//foo".
2011 */
2012 step = comp->steps[0];
2013 if (step.flags & XML_STREAM_STEP_ROOT)
2014 goto stream_next;
2015
2016 desc = step.flags & XML_STREAM_STEP_DESC;
2017 if (stream->flags & XML_PATTERN_NOTPATTERN) {
2018 /*
2019 * Re/enter the expression if it is a "descendant" one,
2020 * or if we are at the 1st level of evaluation.
2021 */
2022
2023 if (stream->level == 1) {
2024 if (XML_STREAM_XS_IDC(stream)) {
2025 /*
2026 * XS-IDC: The missing "self::node()" will always
2027 * match the first given node.
2028 */
2029 goto stream_next;
2030 } else
2031 goto compare;
2032 }
2033 /*
2034 * A "//" is always reentrant.
2035 */
2036 if (desc)
2037 goto compare;
2038
2039 /*
2040 * XS-IDC: Process the 2nd level, since the missing
2041 * "self::node()" is responsible for the 2nd level being
2042 * the real start level.
2043 */
2044 if ((stream->level == 2) && XML_STREAM_XS_IDC(stream))
2045 goto compare;
2046
2047 goto stream_next;
2048 }
2049
2050compare:
2051 /*
2052 * Check expected node-type.
2053 */
2054 if (step.nodeType != nodeType) {
2055 if (nodeType == XML_ATTRIBUTE_NODE)
2056 goto stream_next;
2057 else if (step.nodeType != XML_STREAM_ANY_NODE)
2058 goto stream_next;
2059 }
2060 /*
2061 * Compare local/namespace-name.
2062 */
2063 match = 0;
2064 if (step.nodeType == XML_STREAM_ANY_NODE) {
2065 match = 1;
2066 } else if (step.name == NULL) {
2067 if (step.ns == NULL) {
2068 /*
2069 * This lets through all elements/attributes.
2070 */
2071 match = 1;
2072 } else if (ns != NULL)
2073 match = xmlStrEqual(step.ns, ns);
2074 } else if (((step.ns != NULL) == (ns != NULL)) &&
2075 (name != NULL) &&
2076 (step.name[0] == name[0]) &&
2077 xmlStrEqual(step.name, name) &&
2078 ((step.ns == ns) || xmlStrEqual(step.ns, ns)))
2079 {
2080 match = 1;
2081 }
2082 final = step.flags & XML_STREAM_STEP_FINAL;
2083 if (match) {
2084 if (final)
2085 ret = 1;
2086 else
2087 xmlStreamCtxtAddState(stream, 1, stream->level);
2088 if ((ret != 1) && (step.flags & XML_STREAM_STEP_IN_SET)) {
2089 /*
2090 * Check if we have a special case like "foo//.", where
2091 * "foo" is selected as well.
2092 */
2093 ret = 1;
2094 }
2095 }
2096 if (((comp->flags & XML_STREAM_DESC) == 0) &&
2097 ((! match) || final)) {
2098 /*
2099 * Mark this expression as blocked for any evaluation at
2100 * deeper levels.
2101 */
2102 stream->blockLevel = stream->level;
2103 }
2104
2105stream_next:
2106 stream = stream->next;
2107 } /* while stream != NULL */
2108
2109 if (err > 0)
2110 ret = -1;
2111 return(ret);
2112}
2113
2130int
2131xmlStreamPush(xmlStreamCtxtPtr stream,
2132 const xmlChar *name, const xmlChar *ns) {
2133 return (xmlStreamPushInternal(stream, name, ns, XML_ELEMENT_NODE));
2134}
2135
2155int
2156xmlStreamPushNode(xmlStreamCtxtPtr stream,
2157 const xmlChar *name, const xmlChar *ns,
2158 int nodeType)
2159{
2160 return (xmlStreamPushInternal(stream, name, ns,
2161 nodeType));
2162}
2163
2180int
2181xmlStreamPushAttr(xmlStreamCtxtPtr stream,
2182 const xmlChar *name, const xmlChar *ns) {
2183 return (xmlStreamPushInternal(stream, name, ns, XML_ATTRIBUTE_NODE));
2184}
2185
2194int
2195xmlStreamPop(xmlStreamCtxtPtr stream) {
2196 int i, lev;
2197
2198 if (stream == NULL)
2199 return(-1);
2200 while (stream != NULL) {
2201 /*
2202 * Reset block-level.
2203 */
2204 if (stream->blockLevel == stream->level)
2205 stream->blockLevel = -1;
2206
2207 /*
2208 * stream->level can be zero when XML_FINAL_IS_ANY_NODE is set
2209 * (see the thread at
2210 * http://mail.gnome.org/archives/xslt/2008-July/msg00027.html)
2211 */
2212 if (stream->level)
2213 stream->level--;
2214 /*
2215 * Check evolution of existing states
2216 */
2217 for (i = stream->nbState -1; i >= 0; i--) {
2218 /* discard obsoleted states */
2219 lev = stream->states[(2 * i) + 1];
2220 if (lev > stream->level)
2221 stream->nbState--;
2222 if (lev <= stream->level)
2223 break;
2224 }
2225 stream = stream->next;
2226 }
2227 return(0);
2228}
2229
2242int
2243xmlStreamWantsAnyNode(xmlStreamCtxtPtr streamCtxt)
2244{
2245 if (streamCtxt == NULL)
2246 return(-1);
2247 while (streamCtxt != NULL) {
2248 if (streamCtxt->comp->flags & XML_STREAM_FINAL_IS_ANY_NODE)
2249 return(1);
2250 streamCtxt = streamCtxt->next;
2251 }
2252 return(0);
2253}
2254
2255/************************************************************************
2256 * *
2257 * The public interfaces *
2258 * *
2259 ************************************************************************/
2260
2272xmlPatternPtr
2273xmlPatterncompile(const xmlChar *pattern, xmlDict *dict, int flags,
2274 const xmlChar **namespaces) {
2275 xmlPatternPtr ret = NULL, cur;
2276 xmlPatParserContextPtr ctxt = NULL;
2277 const xmlChar *or, *start;
2278 xmlChar *tmp = NULL;
2279 int type = 0;
2280 int streamable = 1;
2281
2282 if (pattern == NULL)
2283 return(NULL);
2284
2285 start = pattern;
2286 or = start;
2287 while (*or != 0) {
2288 tmp = NULL;
2289 while ((*or != 0) && (*or != '|')) or++;
2290 if (*or == 0)
2291 ctxt = xmlNewPatParserContext(start, dict, namespaces);
2292 else {
2293 tmp = xmlStrndup(start, or - start);
2294 if (tmp != NULL) {
2295 ctxt = xmlNewPatParserContext(tmp, dict, namespaces);
2296 }
2297 or++;
2298 }
2299 if (ctxt == NULL) goto error;
2300 cur = xmlNewPattern();
2301 if (cur == NULL) goto error;
2302 /*
2303 * Assign string dict.
2304 */
2305 if (dict) {
2306 cur->dict = dict;
2307 xmlDictReference(dict);
2308 }
2309 if (ret == NULL)
2310 ret = cur;
2311 else {
2312 cur->next = ret->next;
2313 ret->next = cur;
2314 }
2315 cur->flags = flags;
2316 ctxt->comp = cur;
2317
2318 if (XML_STREAM_XS_IDC(cur))
2319 xmlCompileIDCXPathPath(ctxt);
2320 else
2321 xmlCompilePathPattern(ctxt);
2322 if (ctxt->error != 0)
2323 goto error;
2324 xmlFreePatParserContext(ctxt);
2325 ctxt = NULL;
2326
2327
2328 if (streamable) {
2329 if (type == 0) {
2330 type = cur->flags & (PAT_FROM_ROOT | PAT_FROM_CUR);
2331 } else if (type == PAT_FROM_ROOT) {
2332 if (cur->flags & PAT_FROM_CUR)
2333 streamable = 0;
2334 } else if (type == PAT_FROM_CUR) {
2335 if (cur->flags & PAT_FROM_ROOT)
2336 streamable = 0;
2337 }
2338 }
2339 if (streamable)
2340 xmlStreamCompile(cur);
2341 if (xmlReversePattern(cur) < 0)
2342 goto error;
2343 if (tmp != NULL) {
2344 xmlFree(tmp);
2345 tmp = NULL;
2346 }
2347 start = or;
2348 }
2349 if (streamable == 0) {
2350 cur = ret;
2351 while (cur != NULL) {
2352 if (cur->stream != NULL) {
2353 xmlFreeStreamComp(cur->stream);
2354 cur->stream = NULL;
2355 }
2356 cur = cur->next;
2357 }
2358 }
2359
2360 return(ret);
2361error:
2362 if (ctxt != NULL) xmlFreePatParserContext(ctxt);
2363 if (ret != NULL) xmlFreePattern(ret);
2364 if (tmp != NULL) xmlFree(tmp);
2365 return(NULL);
2366}
2367
2377int
2378xmlPatternMatch(xmlPatternPtr comp, xmlNodePtr node)
2379{
2380 int ret = 0;
2381
2382 if ((comp == NULL) || (node == NULL))
2383 return(-1);
2384
2385 while (comp != NULL) {
2386 ret = xmlPatMatch(comp, node);
2387 if (ret != 0)
2388 return(ret);
2389 comp = comp->next;
2390 }
2391 return(ret);
2392}
2393
2403xmlStreamCtxtPtr
2404xmlPatternGetStreamCtxt(xmlPatternPtr comp)
2405{
2406 xmlStreamCtxtPtr ret = NULL, cur;
2407
2408 if ((comp == NULL) || (comp->stream == NULL))
2409 return(NULL);
2410
2411 while (comp != NULL) {
2412 if (comp->stream == NULL)
2413 goto failed;
2414 cur = xmlNewStreamCtxt(comp->stream);
2415 if (cur == NULL)
2416 goto failed;
2417 if (ret == NULL)
2418 ret = cur;
2419 else {
2420 cur->next = ret->next;
2421 ret->next = cur;
2422 }
2423 cur->flags = comp->flags;
2424 comp = comp->next;
2425 }
2426 return(ret);
2427failed:
2428 xmlFreeStreamCtxt(ret);
2429 return(NULL);
2430}
2431
2441int
2442xmlPatternStreamable(xmlPatternPtr comp) {
2443 if (comp == NULL)
2444 return(-1);
2445 while (comp != NULL) {
2446 if (comp->stream == NULL)
2447 return(0);
2448 comp = comp->next;
2449 }
2450 return(1);
2451}
2452
2462int
2463xmlPatternMaxDepth(xmlPatternPtr comp) {
2464 int ret = 0, i;
2465 if (comp == NULL)
2466 return(-1);
2467 while (comp != NULL) {
2468 if (comp->stream == NULL)
2469 return(-1);
2470 for (i = 0;i < comp->stream->nbStep;i++)
2471 if (comp->stream->steps[i].flags & XML_STREAM_STEP_DESC)
2472 return(-2);
2473 if (comp->stream->nbStep > ret)
2474 ret = comp->stream->nbStep;
2475 comp = comp->next;
2476 }
2477 return(ret);
2478}
2479
2490int
2491xmlPatternMinDepth(xmlPatternPtr comp) {
2492 int ret = 12345678;
2493 if (comp == NULL)
2494 return(-1);
2495 while (comp != NULL) {
2496 if (comp->stream == NULL)
2497 return(-1);
2498 if (comp->stream->nbStep < ret)
2499 ret = comp->stream->nbStep;
2500 if (ret == 0)
2501 return(0);
2502 comp = comp->next;
2503 }
2504 return(ret);
2505}
2506
2515int
2516xmlPatternFromRoot(xmlPatternPtr comp) {
2517 if (comp == NULL)
2518 return(-1);
2519 while (comp != NULL) {
2520 if (comp->stream == NULL)
2521 return(-1);
2522 if (comp->flags & PAT_FROM_ROOT)
2523 return(1);
2524 comp = comp->next;
2525 }
2526 return(0);
2527
2528}
2529
2530#endif /* LIBXML_PATTERN_ENABLED */
#define compare
void restart(int argc, const char *argv[])
Definition: cmds.c:2115
_In_ fcb _In_ chunk _In_ uint64_t _In_ uint64_t _In_ bool _In_opt_ void _In_opt_ PIRP _In_ LIST_ENTRY * rollback
Definition: btrfs_drv.h:1365
#define NULL
Definition: types.h:112
#define NEXT
Definition: pattern.c:1190
#define SKIP_BLANKS
Definition: pattern.c:1186
#define NXT(val)
Definition: pattern.c:1183
#define PUSH(op, val, val2, novar)
Definition: pattern.c:1193
#define CUR_PTR
Definition: pattern.c:1184
#define CUR
Definition: pattern.c:1181
UINT op
Definition: effect.c:236
unsigned int idx
Definition: utils.c:41
int WINAPIV fprintf(FILE *file, const char *format,...)
Definition: file.c:5549
#define stderr
return ret
Definition: mutex.c:146
#define ERROR(name)
Definition: error_private.h:53
FxCollectionEntry * cur
GLuint start
Definition: gl.h:1545
GLint level
Definition: gl.h:1546
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLdouble s
Definition: gl.h:2039
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLdouble GLdouble GLdouble GLdouble q
Definition: gl.h:2063
GLsizeiptr size
Definition: glext.h:5919
GLubyte * pattern
Definition: glext.h:7787
GLbitfield flags
Definition: glext.h:7161
GLuint GLfloat * val
Definition: glext.h:7180
GLenum GLsizei len
Definition: glext.h:6722
const GLfloat * m
Definition: glext.h:10848
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat token
Definition: glfuncs.h:210
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define ATTRIBUTE_UNUSED
Definition: i386-dis.c:36
#define error(str)
Definition: mkdosfs.c:1605
D3D11_SHADER_VARIABLE_DESC desc
Definition: reflection.c:1204
static size_t elem
Definition: string.c:71
static DWORD DWORD DWORD DWORD * steps
Definition: cursoricon.c:1638
#define IS_COMBINING(c)
#define IS_DIGIT(c)
#define IS_CHAR(c)
#define IS_EXTENDER(c)
#define IS_LETTER(c)
XML_DEPRECATED XMLPUBFUN int xmlStringCurrentChar(xmlParserCtxtPtr ctxt, const xmlChar *cur, int *len)
#define IS_BLANK_CH(c)
static unsigned __int64 next
Definition: rand_nt.c:6
#define err(...)
static calc_node_t temp
Definition: rpn_ieee.c:38
void xmlDictFree(xmlDictPtr dict)
Definition: dict.c:333
int xmlDictReference(xmlDictPtr dict)
Definition: dict.c:317
const xmlChar * xmlDictLookup(xmlDictPtr dict, const xmlChar *name, int len)
Definition: dict.c:824
xmlReallocFunc xmlRealloc
Definition: globals.c:214
xmlFreeFunc xmlFree
Definition: globals.c:184
xmlMallocFunc xmlMalloc
Definition: globals.c:193
#define memset(x, y, z)
Definition: compat.h:39
Definition: dict.c:59
char * value
Definition: compiler.c:67
Definition: match.c:28
Definition: name.c:39
Definition: mxnamespace.c:38
Definition: parse.h:23
Character const *const prefix
Definition: tempnam.cpp:195
Definition: dlist.c:348
void * next
Definition: dlist.c:360
Definition: pdh_main.c:96
XMLPUBFUN xmlChar * xmlStrndup(const xmlChar *cur, int len)
Definition: xmlstring.c:45
XMLPUBFUN int xmlStrEqual(const xmlChar *str1, const xmlChar *str2)
Definition: xmlstring.c:162
unsigned char xmlChar
Definition: xmlstring.h:28