win32u: Implement NtGdiIcmBrushInfo and use it instead of __wine_get_brush_bitmap_info.
[wine.git] / dlls / msxml3 / xslpattern.y
blob9abf43cad35ff390f48eae198b73a404f69b6e08
1 /*
2 * XSLPattern parser (XSLPattern => XPath)
4 * Copyright 2010 Adam Martinson for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include "xslpattern.h"
23 #include <libxml/xpathInternals.h>
24 #include "wine/debug.h"
26 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
29 static const xmlChar NameTest_mod_pre[] = "*[name()='";
30 static const xmlChar NameTest_mod_post[] = "']";
32 #define U(str) BAD_CAST str
34 static inline BOOL is_literal(xmlChar const* tok)
36 return (tok && tok[0] && tok[1] &&
37 tok[0]== tok[xmlStrlen(tok)-1] &&
38 (tok[0] == '\'' || tok[0] == '"'));
41 static void xslpattern_error(parser_param* param, void const* scanner, char const* msg)
43 FIXME("%s:\n"
44 " param {\n"
45 " yyscanner=%p\n"
46 " ctx=%p\n"
47 " in=\"%s\"\n"
48 " pos=%i\n"
49 " len=%i\n"
50 " out=\"%s\"\n"
51 " err=%i\n"
52 " }\n"
53 " scanner=%p\n",
54 msg, param->yyscanner, param->ctx, param->in, param->pos,
55 param->len, param->out, ++param->err, scanner);
60 %token TOK_Parent TOK_Self TOK_DblFSlash TOK_FSlash TOK_Axis TOK_Colon
61 %token TOK_OpAnd TOK_OpOr TOK_OpNot
62 %token TOK_OpEq TOK_OpIEq TOK_OpNEq TOK_OpINEq
63 %token TOK_OpLt TOK_OpILt TOK_OpGt TOK_OpIGt TOK_OpLEq TOK_OpILEq TOK_OpGEq TOK_OpIGEq
64 %token TOK_OpAll TOK_OpAny
65 %token TOK_NCName TOK_Literal TOK_Number
67 %start XSLPattern
69 %define api.prefix {xslpattern_}
70 %define api.pure
71 %parse-param {parser_param* p}
72 %parse-param {void* scanner}
73 %lex-param {yyscan_t* scanner}
75 %left TOK_OpAnd TOK_OpOr
76 %left TOK_OpEq TOK_OpIEq TOK_OpNEq TOK_OpINEq
77 %left TOK_OpLt TOK_OpILt TOK_OpGt TOK_OpIGt TOK_OpLEq TOK_OpILEq TOK_OpGEq TOK_OpIGEq
79 %expect 14
83 XSLPattern : Expr
85 p->out = $1;
89 /* Mostly verbatim from the w3c XML Namespaces standard.
90 * <http://www.w3.org/TR/REC-xml-names/> */
92 /* [4] Qualified Names */
93 QName : PrefixedName
94 | UnprefixedName
96 PrefixedName : TOK_NCName TOK_Colon TOK_NCName
98 TRACE("Got PrefixedName: \"%s:%s\"\n", $1, $3);
99 $$=$1;
100 $$=xmlStrcat($$,U(":"));
101 $$=xmlStrcat($$,$3);
102 xmlFree($3);
105 UnprefixedName : TOK_NCName
107 TRACE("Got UnprefixedName: \"%s\"\n", $1);
108 $$=$1;
112 /* Based on the w3c XPath standard, adapted where needed.
113 * <http://www.w3.org/TR/xpath/> */
115 /* [2] Location Paths */
116 LocationPath : RelativeLocationPath
117 | AbsoluteLocationPath
119 AbsoluteLocationPath : TOK_FSlash RelativeLocationPath
121 TRACE("Got AbsoluteLocationPath: \"/%s\"\n", $2);
122 $$=xmlStrdup(U("/"));
123 $$=xmlStrcat($$,$2);
124 xmlFree($2);
126 | TOK_FSlash
128 TRACE("Got AbsoluteLocationPath: \"/\"\n");
129 $$=xmlStrdup(U("/"));
131 | AbbreviatedAbsoluteLocationPath
133 RelativeLocationPath : Step
134 | RelativeLocationPath TOK_FSlash Step
136 TRACE("Got RelativeLocationPath: \"%s/%s\"\n", $1, $3);
137 $$=$1;
138 $$=xmlStrcat($$,U("/"));
139 $$=xmlStrcat($$,$3);
140 xmlFree($3);
142 | AbbreviatedRelativeLocationPath
144 /* [2.1] Location Steps */
145 Step : AxisSpecifier NodeTest Predicates
147 TRACE("Got Step: \"%s%s%s\"\n", $1, $2, $3);
148 $$=$1;
149 $$=xmlStrcat($$,$2);
150 xmlFree($2);
151 $$=xmlStrcat($$,$3);
152 xmlFree($3);
154 | NodeTest Predicates
156 TRACE("Got Step: \"%s%s\"\n", $1, $2);
157 $$=$1;
158 $$=xmlStrcat($$,$2);
159 xmlFree($2);
161 | AxisSpecifier NodeTest
163 TRACE("Got Step: \"%s%s\"\n", $1, $2);
164 $$=$1;
165 $$=xmlStrcat($$,$2);
166 xmlFree($2);
168 | NodeTest
169 | Attribute
170 | AbbreviatedStep
172 AxisSpecifier : TOK_NCName TOK_Axis
174 TRACE("Got AxisSpecifier: \"%s::\"\n", $1);
175 $$=$1;
176 $$=xmlStrcat($$,U("::"));
179 Attribute : '@' QName
181 TRACE("Got Attribute: \"@%s\"\n", $2);
182 $$=xmlStrdup(U("@"));
183 $$=xmlStrcat($$,$2);
184 xmlFree($2);
186 | '@' '*'
188 TRACE("Got All attributes pattern: \"@*\"\n");
189 $$=xmlStrdup(U("@*"));
193 /* [2.3] Node Tests */
194 NodeTest : NameTest
195 | FunctionCall
197 NameTest : '*'
199 TRACE("Got NameTest: \"*\"\n");
200 $$=xmlStrdup(U("*"));
202 | TOK_NCName TOK_Colon '*'
204 TRACE("Got NameTest: \"%s:*\"\n", $1);
205 $$=$1;
206 $$=xmlStrcat($$,U(":*"));
208 | TOK_NCName TOK_Colon TOK_NCName
209 { /* PrefixedName */
210 xmlChar const* registeredNsURI = xmlXPathNsLookup(p->ctx, $1);
211 TRACE("Got PrefixedName: \"%s:%s\"\n", $1, $3);
213 if (registeredNsURI)
214 $$=xmlStrdup(U(""));
215 else
216 $$=xmlStrdup(NameTest_mod_pre);
218 $$=xmlStrcat($$,$1);
219 xmlFree($1);
220 $$=xmlStrcat($$,U(":"));
221 $$=xmlStrcat($$,$3);
222 xmlFree($3);
224 if (!registeredNsURI)
225 $$=xmlStrcat($$,NameTest_mod_post);
227 | UnprefixedName
229 $$=xmlStrdup(NameTest_mod_pre);
230 $$=xmlStrcat($$,$1);
231 xmlFree($1);
232 $$=xmlStrcat($$,NameTest_mod_post);
234 /* [2.4] Predicates */
235 Predicates : Predicates Predicate
237 $$=$1;
238 $$=xmlStrcat($$,$2);
239 xmlFree($2);
241 | Predicate
243 Predicate : '[' PredicateExpr ']'
245 TRACE("Got Predicate: \"[%s]\"\n", $2);
246 $$=xmlStrdup(U("["));
247 $$=xmlStrcat($$,$2);
248 xmlFree($2);
249 $$=xmlStrcat($$,U("]"));
252 PredicateExpr : TOK_Number
254 $$=xmlStrdup(U("index()="));
255 $$=xmlStrcat($$,$1);
256 xmlFree($1);
258 | BoolExpr
259 | Attribute
260 | TOK_NCName
262 /* [2.5] Abbreviated Syntax */
263 AbbreviatedAbsoluteLocationPath : TOK_DblFSlash RelativeLocationPath
265 TRACE("Got AbbreviatedAbsoluteLocationPath: \"//%s\"\n", $2);
266 $$=xmlStrdup(U("//"));
267 $$=xmlStrcat($$,$2);
268 xmlFree($2);
271 AbbreviatedRelativeLocationPath : RelativeLocationPath TOK_DblFSlash Step
273 TRACE("Got AbbreviatedRelativeLocationPath: \"%s//%s\"\n", $1, $3);
274 $$=$1;
275 $$=xmlStrcat($$,U("//"));
276 $$=xmlStrcat($$,$3);
277 xmlFree($3);
280 AbbreviatedStep : TOK_Parent
282 TRACE("Got AbbreviatedStep: \"..\"\n");
283 $$=xmlStrdup(U(".."));
285 | TOK_Self
287 TRACE("Got AbbreviatedStep: \".\"\n");
288 $$=xmlStrdup(U("."));
292 /* [3] Expressions */
293 /* [3.1] Basics */
294 Expr : OrExpr
296 BoolExpr : FunctionCall
297 | BoolUnaryExpr
298 | BoolRelationalExpr
299 | BoolEqualityExpr
300 | BoolAndExpr
301 | BoolOrExpr
303 PrimaryExpr : '(' Expr ')'
305 TRACE("Got PrimaryExpr: \"(%s)\"\n", $1);
306 $$=xmlStrdup(U("("));
307 $$=xmlStrcat($$,$2);
308 xmlFree($2);
309 $$=xmlStrcat($$,U(")"));
311 | PathExpr '!' FunctionCall
313 TRACE("Got PrimaryExpr: \"%s!%s\"\n", $1, $3);
314 $$=$1;
315 $$=xmlStrcat($$,U("/"));
316 $$=xmlStrcat($$,$3);
317 xmlFree($3);
319 | TOK_Literal
320 | TOK_Number
322 /* [3.2] Function Calls */
323 FunctionCall : QName '(' Arguments ')'
325 TRACE("Got FunctionCall: \"%s(%s)\"\n", $1, $3);
326 if (xmlStrEqual($1,U("ancestor")))
328 $$=$1;
329 $$=xmlStrcat($$,U("::"));
330 $$=xmlStrcat($$,$3);
331 xmlFree($3);
333 else if (xmlStrEqual($1,U("attribute")))
335 if (is_literal($3))
337 $$=xmlStrdup(U("@*[name()="));
338 xmlFree($1);
339 $$=xmlStrcat($$,$3);
340 xmlFree($3);
341 $$=xmlStrcat($$,U("]"));
343 else
345 /* XML_XPATH_INVALID_TYPE */
346 $$=xmlStrdup(U("error(1211, 'Error: attribute("));
347 xmlFree($1);
348 $$=xmlStrcat($$,$3);
349 xmlFree($3);
350 $$=xmlStrcat($$,U("): invalid argument')"));
353 else if (xmlStrEqual($1,U("element")))
355 if (is_literal($3))
357 $$=xmlStrdup(U("node()[nodeType()=1][name()="));
358 xmlFree($1);
359 $$=xmlStrcat($$,$3);
360 xmlFree($3);
361 $$=xmlStrcat($$,U("]"));
363 else
365 /* XML_XPATH_INVALID_TYPE */
366 $$=xmlStrdup(U("error(1211, 'Error: element("));
367 xmlFree($1);
368 $$=xmlStrcat($$,$3);
369 xmlFree($3);
370 $$=xmlStrcat($$,U("): invalid argument')"));
373 else
375 $$=$1;
376 $$=xmlStrcat($$,U("("));
377 $$=xmlStrcat($$,$3);
378 xmlFree($3);
379 $$=xmlStrcat($$,U(")"));
382 | QName '(' ')'
384 TRACE("Got FunctionCall: \"%s()\"\n", $1);
385 /* comment() & node() work the same in XPath */
386 if (xmlStrEqual($1,U("attribute")))
388 $$=xmlStrdup(U("@*"));
389 xmlFree($1);
391 else if (xmlStrEqual($1,U("element")))
393 $$=xmlStrdup(U("node()[nodeType()=1]"));
394 xmlFree($1);
396 else if (xmlStrEqual($1,U("pi")))
398 $$=xmlStrdup(U("processing-instruction()"));
399 xmlFree($1);
401 else if (xmlStrEqual($1,U("textnode")))
403 $$=xmlStrdup(U("text()"));
404 xmlFree($1);
406 else
408 $$=$1;
409 $$=xmlStrcat($$,U("()"));
413 Arguments : Argument ',' Arguments
415 $$=$1;
416 $$=xmlStrcat($$,U(","));
417 $$=xmlStrcat($$,$3);
418 xmlFree($3);
420 | Argument
422 Argument : Expr
424 /* [3.3] Node-sets */
425 UnionExpr : PathExpr
426 | UnionExpr '|' PathExpr
428 TRACE("Got UnionExpr: \"%s|%s\"\n", $1, $3);
429 $$=$1;
430 $$=xmlStrcat($$,U("|"));
431 $$=xmlStrcat($$,$3);
432 xmlFree($3);
435 PathExpr : LocationPath
436 | FilterExpr TOK_FSlash RelativeLocationPath
438 TRACE("Got PathExpr: \"%s/%s\"\n", $1, $3);
439 $$=$1;
440 $$=xmlStrcat($$,U("/"));
441 $$=xmlStrcat($$,$3);
442 xmlFree($3);
444 | FilterExpr TOK_DblFSlash RelativeLocationPath
446 TRACE("Got PathExpr: \"%s//%s\"\n", $1, $3);
447 $$=$1;
448 $$=xmlStrcat($$,U("//"));
449 $$=xmlStrcat($$,$3);
450 xmlFree($3);
452 | FilterExpr
454 FilterExpr : PrimaryExpr
455 | FilterExpr Predicate
457 TRACE("Got FilterExpr: \"%s%s\"\n", $1, $2);
458 $$=$1;
459 $$=xmlStrcat($$,$2);
460 xmlFree($2);
463 /* [3.4] Booleans */
464 OrExpr : AndExpr
465 | BoolOrExpr
467 BoolOrExpr : OrExpr TOK_OpOr AndExpr
469 TRACE("Got OrExpr: \"%s $or$ %s\"\n", $1, $3);
470 $$=$1;
471 $$=xmlStrcat($$,U(" or "));
472 $$=xmlStrcat($$,$3);
473 xmlFree($3);
476 AndExpr : EqualityExpr
477 | BoolAndExpr
479 BoolAndExpr : AndExpr TOK_OpAnd EqualityExpr
481 TRACE("Got AndExpr: \"%s $and$ %s\"\n", $1, $3);
482 $$=$1;
483 $$=xmlStrcat($$,U(" and "));
484 $$=xmlStrcat($$,$3);
485 xmlFree($3);
488 EqualityExpr : RelationalExpr
489 | BoolEqualityExpr
491 BoolEqualityExpr : EqualityExpr TOK_OpEq RelationalExpr
493 TRACE("Got EqualityExpr: \"%s $eq$ %s\"\n", $1, $3);
494 $$=$1;
495 $$=xmlStrcat($$,U("="));
496 $$=xmlStrcat($$,$3);
497 xmlFree($3);
499 | EqualityExpr TOK_OpIEq RelationalExpr
501 TRACE("Got EqualityExpr: \"%s $ieq$ %s\"\n", $1, $3);
502 $$=xmlStrdup(U("OP_IEq("));
503 $$=xmlStrcat($$,$1);
504 xmlFree($1);
505 $$=xmlStrcat($$,U(","));
506 $$=xmlStrcat($$,$3);
507 xmlFree($3);
508 $$=xmlStrcat($$,U(")"));
510 | EqualityExpr TOK_OpNEq RelationalExpr
512 TRACE("Got EqualityExpr: \"%s $ne$ %s\"\n", $1, $3);
513 $$=$1;
514 $$=xmlStrcat($$,U("!="));
515 $$=xmlStrcat($$,$3);
516 xmlFree($3);
518 | EqualityExpr TOK_OpINEq RelationalExpr
520 TRACE("Got EqualityExpr: \"%s $ine$ %s\"\n", $1, $3);
521 $$=xmlStrdup(U("OP_INEq("));
522 $$=xmlStrcat($$,$1);
523 xmlFree($1);
524 $$=xmlStrcat($$,U(","));
525 $$=xmlStrcat($$,$3);
526 xmlFree($3);
527 $$=xmlStrcat($$,U(")"));
530 RelationalExpr : UnaryExpr
531 | BoolRelationalExpr
533 BoolRelationalExpr : RelationalExpr TOK_OpLt UnaryExpr
535 TRACE("Got RelationalExpr: \"%s $lt$ %s\"\n", $1, $3);
536 $$=$1;
537 $$=xmlStrcat($$,U("<"));
538 $$=xmlStrcat($$,$3);
539 xmlFree($3);
541 | RelationalExpr TOK_OpILt UnaryExpr
543 TRACE("Got RelationalExpr: \"%s $ilt$ %s\"\n", $1, $3);
544 $$=xmlStrdup(U("OP_ILt("));
545 $$=xmlStrcat($$,$1);
546 xmlFree($1);
547 $$=xmlStrcat($$,U(","));
548 $$=xmlStrcat($$,$3);
549 xmlFree($3);
550 $$=xmlStrcat($$,U(")"));
552 | RelationalExpr TOK_OpGt UnaryExpr
554 TRACE("Got RelationalExpr: \"%s $gt$ %s\"\n", $1, $3);
555 $$=$1;
556 $$=xmlStrcat($$,U(">"));
557 $$=xmlStrcat($$,$3);
558 xmlFree($3);
560 | RelationalExpr TOK_OpIGt UnaryExpr
562 TRACE("Got RelationalExpr: \"%s $igt$ %s\"\n", $1, $3);
563 $$=xmlStrdup(U("OP_IGt("));
564 $$=xmlStrcat($$,$1);
565 xmlFree($1);
566 $$=xmlStrcat($$,U(","));
567 $$=xmlStrcat($$,$3);
568 xmlFree($3);
569 $$=xmlStrcat($$,U(")"));
571 | RelationalExpr TOK_OpLEq UnaryExpr
573 TRACE("Got RelationalExpr: \"%s $le$ %s\"\n", $1, $3);
574 $$=$1;
575 $$=xmlStrcat($$,U("<="));
576 $$=xmlStrcat($$,$3);
577 xmlFree($3);
579 | RelationalExpr TOK_OpILEq UnaryExpr
581 TRACE("Got RelationalExpr: \"%s $ile$ %s\"\n", $1, $3);
582 $$=xmlStrdup(U("OP_ILEq("));
583 $$=xmlStrcat($$,$1);
584 xmlFree($1);
585 $$=xmlStrcat($$,U(","));
586 $$=xmlStrcat($$,$3);
587 xmlFree($3);
588 $$=xmlStrcat($$,U(")"));
590 | RelationalExpr TOK_OpGEq UnaryExpr
592 TRACE("Got RelationalExpr: \"%s $ge$ %s\"\n", $1, $3);
593 $$=$1;
594 $$=xmlStrcat($$,U(">="));
595 $$=xmlStrcat($$,$3);
596 xmlFree($3);
598 | RelationalExpr TOK_OpIGEq UnaryExpr
600 TRACE("Got RelationalExpr: \"%s $ige$ %s\"\n", $1, $3);
601 $$=xmlStrdup(U("OP_IGEq("));
602 $$=xmlStrcat($$,$1);
603 xmlFree($1);
604 $$=xmlStrcat($$,U(","));
605 $$=xmlStrcat($$,$3);
606 xmlFree($3);
607 $$=xmlStrcat($$,U(")"));
611 /* [3.5] Numbers */
612 UnaryExpr : UnionExpr
613 | BoolUnaryExpr
615 BoolUnaryExpr : TOK_OpNot UnaryExpr
617 TRACE("Got UnaryExpr: \"$not$ %s\"\n", $2);
618 $$=xmlStrdup(U(" not("));
619 $$=xmlStrcat($$,$2);
620 xmlFree($2);
621 $$=xmlStrcat($$,U(")"));
623 | TOK_OpAny Expr
625 TRACE("Got UnaryExpr: \"$any$ %s\"\n", $2);
626 $$=xmlStrdup(U("boolean("));
627 $$=xmlStrcat($$,$2);
628 xmlFree($2);
629 $$=xmlStrcat($$,U(")"));
631 | TOK_OpAll AllExpr
633 TRACE("Got UnaryExpr: \"$all$ %s\"\n", $2);
634 $$=xmlStrdup(U("not("));
635 $$=xmlStrcat($$,$2);
636 xmlFree($2);
637 $$=xmlStrcat($$,U(")"));
639 | TOK_OpAll
641 FIXME("Unrecognized $all$ expression - ignoring\n");
642 $$=xmlStrdup(U(""));
645 AllExpr : PathExpr TOK_OpEq PathExpr
647 $$=$1;
648 $$=xmlStrcat($$,U("!="));
649 $$=xmlStrcat($$,$3);
650 xmlFree($3);
652 | PathExpr TOK_OpNEq PathExpr
654 $$=$1;
655 $$=xmlStrcat($$,U("="));
656 $$=xmlStrcat($$,$3);
657 xmlFree($3);
659 | PathExpr TOK_OpLt PathExpr
661 $$=$1;
662 $$=xmlStrcat($$,U(">="));
663 $$=xmlStrcat($$,$3);
664 xmlFree($3);
666 | PathExpr TOK_OpLEq PathExpr
668 $$=$1;
669 $$=xmlStrcat($$,U(">"));
670 $$=xmlStrcat($$,$3);
671 xmlFree($3);
673 | PathExpr TOK_OpGt PathExpr
675 $$=$1;
676 $$=xmlStrcat($$,U("<="));
677 $$=xmlStrcat($$,$3);
678 xmlFree($3);
680 | PathExpr TOK_OpGEq PathExpr
682 $$=$1;
683 $$=xmlStrcat($$,U("<"));
684 $$=xmlStrcat($$,$3);
685 xmlFree($3);
687 | PathExpr TOK_OpIEq PathExpr
689 $$=xmlStrdup(U("OP_INEq("));
690 $$=xmlStrcat($$,$1);
691 xmlFree($1);
692 $$=xmlStrcat($$,U(","));
693 $$=xmlStrcat($$,$3);
694 xmlFree($3);
695 $$=xmlStrcat($$,U(")"));
697 | PathExpr TOK_OpINEq PathExpr
699 $$=xmlStrdup(U("OP_IEq("));
700 $$=xmlStrcat($$,$1);
701 xmlFree($1);
702 $$=xmlStrcat($$,U(","));
703 $$=xmlStrcat($$,$3);
704 xmlFree($3);
705 $$=xmlStrcat($$,U(")"));
707 | PathExpr TOK_OpILt PathExpr
709 $$=xmlStrdup(U("OP_IGEq("));
710 $$=xmlStrcat($$,$1);
711 xmlFree($1);
712 $$=xmlStrcat($$,U(","));
713 $$=xmlStrcat($$,$3);
714 xmlFree($3);
715 $$=xmlStrcat($$,U(")"));
717 | PathExpr TOK_OpILEq PathExpr
719 $$=xmlStrdup(U("OP_IGt("));
720 $$=xmlStrcat($$,$1);
721 xmlFree($1);
722 $$=xmlStrcat($$,U(","));
723 $$=xmlStrcat($$,$3);
724 xmlFree($3);
725 $$=xmlStrcat($$,U(")"));
727 | PathExpr TOK_OpIGt PathExpr
729 $$=xmlStrdup(U("OP_ILEq("));
730 $$=xmlStrcat($$,$1);
731 xmlFree($1);
732 $$=xmlStrcat($$,U(","));
733 $$=xmlStrcat($$,$3);
734 xmlFree($3);
735 $$=xmlStrcat($$,U(")"));
737 | PathExpr TOK_OpIGEq PathExpr
739 $$=xmlStrdup(U("OP_ILt("));
740 $$=xmlStrcat($$,$1);
741 xmlFree($1);
742 $$=xmlStrcat($$,U(","));
743 $$=xmlStrcat($$,$3);
744 xmlFree($3);
745 $$=xmlStrcat($$,U(")"));