msxml3: Implement schema_cache_get_namespaceURI().
[wine] / dlls / msxml3 / xslpattern.y
1 /*
2  *    XSLPattern parser (XSLPattern => XPath)
3  *
4  * Copyright 2010 Adam Martinson for CodeWeavers
5  *
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.
10  *
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.
15  *
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
19  */
20
21 %{
22 #include "config.h"
23 #include "wine/port.h"
24
25 #ifdef HAVE_LIBXML2
26 #include "xslpattern.h"
27
28 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
29
30
31 static const xmlChar NameTest_mod_pre[] = "*[namespace-uri()=namespace::*[local-name()=''] or namespace-uri()=''][local-name()='";
32 static const xmlChar NameTest_mod_post[] = "']";
33
34 #define U(str) BAD_CAST str
35 #define DBG(str) wine_dbgstr_a((char const*)str)
36 %}
37
38 %token TOK_Parent TOK_Self TOK_DblFSlash TOK_FSlash TOK_Axis TOK_Colon
39 %token TOK_OpAnd TOK_OpOr TOK_OpNot
40 %token TOK_OpEq TOK_OpIEq TOK_OpNEq TOK_OpINEq
41 %token TOK_OpLt TOK_OpILt TOK_OpGt TOK_OpIGt TOK_OpLEq TOK_OpILEq TOK_OpGEq TOK_OpIGEq
42 %token TOK_OpAll TOK_OpAny
43 %token TOK_NCName TOK_Literal TOK_Number
44
45 %start XSLPattern
46
47 %pure_parser
48 %parse-param {parser_param* p}
49 %parse-param {void* scanner}
50 %lex-param {yyscan_t* scanner}
51
52 %left TOK_OpAnd TOK_OpOr
53 %left TOK_OpEq TOK_OpIEq TOK_OpNEq TOK_OpINEq
54 %left TOK_OpLt TOK_OpILt TOK_OpGt TOK_OpIGt TOK_OpLEq TOK_OpILEq TOK_OpGEq TOK_OpIGEq
55
56 %%
57
58     XSLPattern              : Expr
59                             {
60                                 p->out = $1;
61                             }
62     ;
63
64 /* Mostly verbatim from the w3c XML Namespaces standard.
65  * <http://www.w3.org/TR/REC-xml-names/> */
66
67     /* [4] Qualified Names */
68     QName                   : PrefixedName
69                             | UnprefixedName
70     ;
71     PrefixedName            : TOK_NCName TOK_Colon TOK_NCName
72                             {
73                                 TRACE("Got PrefixedName: %s:%s\n", DBG($1), DBG($3));
74                                 $$=$1;
75                                 $$=xmlStrcat($$, U(":"));
76                                 $$=xmlStrcat($$,$3);
77                                 xmlFree($3);
78                             }
79     ;
80     UnprefixedName          : TOK_NCName
81                             {
82                                 TRACE("Got UnprefixedName: %s\n", DBG($1));
83                                 $$=$1;
84                             }
85     ;
86
87 /* Based on the w3c XPath standard, adapted where needed.
88  * <http://www.w3.org/TR/xpath/> */
89
90     /* [2] Location Paths */
91     LocationPath            : RelativeLocationPath
92                             | AbsoluteLocationPath
93     ;
94     AbsoluteLocationPath    : TOK_FSlash RelativeLocationPath
95                             {
96                                 TRACE("Got AbsoluteLocationPath: /%s\n", DBG($1));
97                                 $$=xmlStrdup(U("/"));
98                                 $$=xmlStrcat($$,$2);
99                                 xmlFree($2);
100                             }
101                             | TOK_FSlash
102                             {
103                                 TRACE("Got AbsoluteLocationPath: /\n");
104                                 $$=xmlStrdup(U("/"));
105                             }
106                             | AbbreviatedAbsoluteLocationPath
107     ;
108     RelativeLocationPath    : Step
109                             | RelativeLocationPath TOK_FSlash Step
110                             {
111                                 TRACE("Got RelativeLocationPath: %s/%s\n", DBG($1), DBG($3));
112                                 $$=$1;
113                                 $$=xmlStrcat($$,U("/"));
114                                 $$=xmlStrcat($$,$3);
115                                 xmlFree($3);
116                             }
117                             | AbbreviatedRelativeLocationPath
118     ;
119     /* [2.1] Location Steps */
120     Step                    : AxisSpecifier NameTest Predicates
121                             {
122                                 TRACE("Got Step: %s%s%s\n", DBG($1), DBG($2), DBG($3));
123                                 $$=$1;
124                                 $$=xmlStrcat($$,$2);
125                                 xmlFree($2);
126                                 $$=xmlStrcat($$,$3);
127                                 xmlFree($3);
128                             }
129                             | NameTest Predicates
130                             {
131                                 TRACE("Got Step: %s%s\n", DBG($1), DBG($2));
132                                 $$=$1;
133                                 $$=xmlStrcat($$,$2);
134                                 xmlFree($2);
135                             }
136                             | AxisSpecifier NameTest
137                             {
138                                 TRACE("Got Step: %s%s\n", DBG($1), DBG($2));
139                                 $$=$1;
140                                 $$=xmlStrcat($$,$2);
141                                 xmlFree($2);
142                             }
143                             | NameTest
144                             | Attribute
145                             | AbbreviatedStep
146     ;
147     AxisSpecifier           : TOK_NCName TOK_Axis
148                             {
149                                 TRACE("Got AxisSpecifier: %s::\n", DBG($1));
150                                 $$=$1;
151                                 $$=xmlStrcat($$,U("::"));
152                             }
153     ;
154     Attribute               : '@' TOK_NCName
155                             {
156                                 TRACE("Got Attribute: @%s\n", DBG($2));
157                                 $$=xmlStrdup(U("@"));
158                                 $$=xmlStrcat($$,$2);
159                                 xmlFree($2);
160                             }
161     ;
162
163     /* [2.3] Node Tests */
164     NameTest                : '*'
165                             {
166                                 TRACE("Got NameTest: *\n");
167                                 $$=xmlStrdup(U("*"));
168                             }
169                             | TOK_NCName TOK_Colon '*'
170                             {
171                                 TRACE("Got NameTest: %s:*\n", DBG($1));
172                                 $$=$1;
173                                 $$=xmlStrcat($$,U(":*"));
174                             }
175                             | PrefixedName
176                             | UnprefixedName
177                             {
178                                 $$=xmlStrdup(NameTest_mod_pre);
179                                 $$=xmlStrcat($$,$1);
180                                 xmlFree($1);
181                                 $$=xmlStrcat($$,NameTest_mod_post);
182                             }
183     /* [2.4] Predicates */
184     Predicates              : Predicates Predicate
185                             {
186                                 $$=$1;
187                                 $$=xmlStrcat($$,$2);
188                                 xmlFree($2);
189                             }
190                             | Predicate
191     ;
192     Predicate               : '[' PredicateExpr ']'
193                             {
194                                 TRACE("Got Predicate: [%s]\n", DBG($2));
195                                 $$=xmlStrdup(U("["));
196                                 $$=xmlStrcat($$,$2);
197                                 xmlFree($2);
198                                 $$=xmlStrcat($$,U("]"));
199                             }
200     ;
201     PredicateExpr           : TOK_Number
202                             {
203                                 $$=xmlStrdup(U("index()="));
204                                 $$=xmlStrcat($$,$1);
205                                 xmlFree($1);
206                             }
207                             | BoolExpr
208                             | Attribute
209     ;
210     /* [2.5] Abbreviated Syntax */
211     AbbreviatedAbsoluteLocationPath : TOK_DblFSlash RelativeLocationPath
212                             {
213                                 TRACE("Got AbbreviatedAbsoluteLocationPath: //%s\n", DBG($2));
214                                 $$=xmlStrdup(U("//"));
215                                 $$=xmlStrcat($$,$2);
216                                 xmlFree($2);
217                             }
218     ;
219     AbbreviatedRelativeLocationPath : RelativeLocationPath TOK_DblFSlash Step
220                             {
221                                 TRACE("Got AbbreviatedRelativeLocationPath: %s//%s\n", DBG($1), DBG($2));
222                                 $$=$1;
223                                 $$=xmlStrcat($$,U("//"));
224                                 $$=xmlStrcat($$,$3);
225                                 xmlFree($3);
226                             }
227     ;
228     AbbreviatedStep         : TOK_Parent
229                             {
230                                 TRACE("Got AbbreviatedStep: ..\n");
231                                 $$=xmlStrdup(U(".."));
232                             }
233                             | TOK_Self
234                             {
235                                 TRACE("Got AbbreviatedStep: .\n");
236                                 $$=xmlStrdup(U("."));
237                             }
238     ;
239
240     /* [3] Expressions */
241     /* [3.1] Basics */
242     Expr                    : OrExpr
243     ;
244     BoolExpr                : FunctionCall
245                             | BoolUnaryExpr
246                             | BoolRelationalExpr
247                             | BoolEqualityExpr
248                             | BoolAndExpr
249                             | BoolOrExpr
250     ;
251     PrimaryExpr             : '(' Expr ')'
252                             {
253                                 TRACE("Got PrimaryExpr: (%s)\n", DBG($1));
254                                 $$=xmlStrdup(U("("));
255                                 $$=xmlStrcat($$,$2);
256                                 xmlFree($2);
257                                 $$=xmlStrcat($$,U(")"));
258                             }
259                             | PathExpr '!' FunctionCall
260                             {
261                                 TRACE("Got PrimaryExpr: %s!%s\n", DBG($1), DBG($3));
262                                 $$=$1;
263                                 $$=xmlStrcat($$,U("/"));
264                                 $$=xmlStrcat($$,$3);
265                                 xmlFree($3);
266                             }
267                             | TOK_Literal
268                             | TOK_Number
269                             | FunctionCall
270     ;
271     /* [3.2] Function Calls */
272     FunctionCall            : QName '(' Arguments ')'
273                             {
274                                 TRACE("Got FunctionCall: %s(%s)\n", DBG($1), DBG($3));
275                                 $$=$1;
276                                 $$=xmlStrcat($$,U("("));
277                                 $$=xmlStrcat($$,$3);
278                                 xmlFree($3);
279                                 $$=xmlStrcat($$,U(")"));
280                             }
281                             | QName '(' ')'
282                             {
283                                 TRACE("Got FunctionCall: %s()\n", DBG($1));
284                                 $$=$1;
285                                 $$=xmlStrcat($$,U("()"));
286                             }
287     ;
288     Arguments               : Argument ',' Arguments
289                             {
290                                 $$=$1;
291                                 $$=xmlStrcat($$,U(","));
292                                 $$=xmlStrcat($$,$3);
293                                 xmlFree($3);
294                             }
295                             | Argument
296     ;
297     Argument                : Expr
298     ;
299     /* [3.3] Node-sets */
300     UnionExpr               : PathExpr
301                             | UnionExpr '|' PathExpr
302                             {
303                                 TRACE("Got UnionExpr: %s|%s\n", DBG($1), DBG($3));
304                                 $$=$1;
305                                 $$=xmlStrcat($$,U("|"));
306                                 $$=xmlStrcat($$,$3);
307                                 xmlFree($3);
308                             }
309     ;
310     PathExpr                : LocationPath
311                             | FilterExpr TOK_FSlash RelativeLocationPath
312                             {
313                                 TRACE("Got PathExpr: %s/%s\n", DBG($1), DBG($3));
314                                 $$=$1;
315                                 $$=xmlStrcat($$,U("/"));
316                                 $$=xmlStrcat($$,$3);
317                                 xmlFree($3);
318                             }
319                             | FilterExpr TOK_DblFSlash RelativeLocationPath
320                             {
321                                 TRACE("Got PathExpr: %s//%s\n", DBG($1), DBG($3));
322                                 $$=$1;
323                                 $$=xmlStrcat($$,U("//"));
324                                 $$=xmlStrcat($$,$3);
325                                 xmlFree($3);
326                             }
327                             | FilterExpr
328     ;
329     FilterExpr              : PrimaryExpr
330                             | FilterExpr Predicate
331                             {
332                                 TRACE("Got FilterExpr: %s%s\n", DBG($1), DBG($2));
333                                 $$=$1;
334                                 $$=xmlStrcat($$,$2);
335                                 xmlFree($2);
336                             }
337     ;
338     /* [3.4] Booleans */
339     OrExpr                  : AndExpr
340                             | BoolOrExpr
341     ;
342     BoolOrExpr              : OrExpr TOK_OpOr AndExpr
343                             {
344                                 TRACE("Got OrExpr: %s or %s\n", DBG($1), DBG($3));
345                                 $$=$1;
346                                 $$=xmlStrcat($$,U(" or "));
347                                 $$=xmlStrcat($$,$3);
348                                 xmlFree($3);
349                             }
350     ;
351     AndExpr                 : EqualityExpr
352                             | BoolAndExpr
353     ;
354     BoolAndExpr             : AndExpr TOK_OpAnd EqualityExpr
355                             {
356                                 TRACE("Got AndExpr: %s and %s\n", DBG($1), DBG($3));
357                                 $$=$1;
358                                 $$=xmlStrcat($$,U(" and "));
359                                 $$=xmlStrcat($$,$3);
360                                 xmlFree($3);
361                             }
362     ;
363     EqualityExpr            : RelationalExpr
364                             | BoolEqualityExpr
365     ;
366     BoolEqualityExpr        : EqualityExpr TOK_OpEq RelationalExpr
367                             {
368                                 TRACE("Got EqualityExpr: %s $eq$ %s\n", DBG($1), DBG($3));
369                                 $$=$1;
370                                 $$=xmlStrcat($$,U("="));
371                                 $$=xmlStrcat($$,$3);
372                                 xmlFree($3);
373                             }
374                             | EqualityExpr TOK_OpIEq RelationalExpr
375                             {
376                                 TRACE("Got EqualityExpr: %s $ieq$ %s\n", DBG($1), DBG($3));
377                                 $$=xmlStrdup(U("OP_IEq("));
378                                 $$=xmlStrcat($$,$1);
379                                 xmlFree($1);
380                                 $$=xmlStrcat($$,U(","));
381                                 $$=xmlStrcat($$,$3);
382                                 xmlFree($3);
383                                 $$=xmlStrcat($$,U(")"));
384                             }
385                             | EqualityExpr TOK_OpNEq RelationalExpr
386                             {
387                                 TRACE("Got EqualityExpr: %s $ne$ %s\n", DBG($1), DBG($3));
388                                 $$=$1;
389                                 $$=xmlStrcat($$,U("!="));
390                                 $$=xmlStrcat($$,$3);
391                                 xmlFree($3);
392                             }
393                             | EqualityExpr TOK_OpINEq RelationalExpr
394                             {
395                                 TRACE("Got EqualityExpr: %s $ine$ %s\n", DBG($1), DBG($3));
396                                 $$=xmlStrdup(U("OP_INEq("));
397                                 $$=xmlStrcat($$,$1);
398                                 xmlFree($1);
399                                 $$=xmlStrcat($$,U(","));
400                                 $$=xmlStrcat($$,$3);
401                                 xmlFree($3);
402                                 $$=xmlStrcat($$,U(")"));
403                             }
404     ;
405     RelationalExpr          : UnaryExpr
406                             | BoolRelationalExpr
407     ;
408     BoolRelationalExpr      : RelationalExpr TOK_OpLt UnaryExpr
409                             {
410                                 TRACE("Got RelationalExpr: %s $lt$ %s\n", DBG($1), DBG($3));
411                                 $$=$1;
412                                 $$=xmlStrcat($$,U("<"));
413                                 $$=xmlStrcat($$,$3);
414                                 xmlFree($3);
415                             }
416                             | RelationalExpr TOK_OpILt UnaryExpr
417                             {
418                                 TRACE("Got RelationalExpr: %s $ilt$ %s\n", DBG($1), DBG($3));
419                                 $$=xmlStrdup(U("OP_ILt("));
420                                 $$=xmlStrcat($$,$1);
421                                 xmlFree($1);
422                                 $$=xmlStrcat($$,U(","));
423                                 $$=xmlStrcat($$,$3);
424                                 xmlFree($3);
425                                 $$=xmlStrcat($$,U(")"));
426                             }
427                             | RelationalExpr TOK_OpGt UnaryExpr
428                             {
429                                 TRACE("Got RelationalExpr: %s $gt$ %s\n", DBG($1), DBG($3));
430                                 $$=$1;
431                                 $$=xmlStrcat($$,U(">"));
432                                 $$=xmlStrcat($$,$3);
433                                 xmlFree($3);
434                             }
435                             | RelationalExpr TOK_OpIGt UnaryExpr
436                             {
437                                 TRACE("Got RelationalExpr: %s $igt$ %s\n", DBG($1), DBG($3));
438                                 $$=xmlStrdup(U("OP_IGt("));
439                                 $$=xmlStrcat($$,$1);
440                                 xmlFree($1);
441                                 $$=xmlStrcat($$,U(","));
442                                 $$=xmlStrcat($$,$3);
443                                 xmlFree($3);
444                                 $$=xmlStrcat($$,U(")"));
445                             }
446                             | RelationalExpr TOK_OpLEq UnaryExpr
447                             {
448                                 TRACE("Got RelationalExpr: %s $le$ %s\n", DBG($1), DBG($3));
449                                 $$=$1;
450                                 $$=xmlStrcat($$,U("<="));
451                                 $$=xmlStrcat($$,$3);
452                                 xmlFree($3);
453                             }
454                             | RelationalExpr TOK_OpILEq UnaryExpr
455                             {
456                                 TRACE("Got RelationalExpr: %s $ile$ %s\n", DBG($1), DBG($3));
457                                 $$=xmlStrdup(U("OP_ILEq("));
458                                 $$=xmlStrcat($$,$1);
459                                 xmlFree($1);
460                                 $$=xmlStrcat($$,U(","));
461                                 $$=xmlStrcat($$,$3);
462                                 xmlFree($3);
463                                 $$=xmlStrcat($$,U(")"));
464                             }
465                             | RelationalExpr TOK_OpGEq UnaryExpr
466                             {
467                                 TRACE("Got RelationalExpr: %s $ge$ %s\n", DBG($1), DBG($3));
468                                 $$=$1;
469                                 $$=xmlStrcat($$,U(">="));
470                                 $$=xmlStrcat($$,$3);
471                                 xmlFree($3);
472                             }
473                             | RelationalExpr TOK_OpIGEq UnaryExpr
474                             {
475                                 TRACE("Got RelationalExpr: %s $ige$ %s\n", DBG($1), DBG($3));
476                                 $$=xmlStrdup(U("OP_IGEq("));
477                                 $$=xmlStrcat($$,$1);
478                                 xmlFree($1);
479                                 $$=xmlStrcat($$,U(","));
480                                 $$=xmlStrcat($$,$3);
481                                 xmlFree($3);
482                                 $$=xmlStrcat($$,U(")"));
483                             }
484     ;
485
486     /* [3.5] Numbers */
487     UnaryExpr               : UnionExpr
488                             | BoolUnaryExpr
489     ;
490     BoolUnaryExpr           : TOK_OpNot UnaryExpr
491                             {
492                                 TRACE("Got UnaryExpr: $not$ %s\n", DBG($2));
493                                 $$=xmlStrdup(U(" not("));
494                                 $$=xmlStrcat($$,$2);
495                                 xmlFree($2);
496                                 $$=xmlStrcat($$,U(")"));
497                             }
498                             | TOK_OpAny Expr
499                             {
500                                 TRACE("Got UnaryExpr: $any$ %s\n", DBG($2));
501                                 $$=xmlStrdup(U("boolean("));
502                                 $$=xmlStrcat($$,$2);
503                                 xmlFree($2);
504                                 $$=xmlStrcat($$,U(")"));
505                             }
506                             | TOK_OpAll AllExpr
507                             {
508                                 TRACE("Got UnaryExpr: $all$ %s\n", DBG($2));
509                                 $$=xmlStrdup(U("not("));
510                                 $$=xmlStrcat($$,$2);
511                                 xmlFree($2);
512                                 $$=xmlStrcat($$,U(")"));
513                             }
514                             | TOK_OpAll
515                             {
516                                 FIXME("Unrecognized $all$ expression - ignoring\n");
517                                 $$=xmlStrdup(U(""));
518                             }
519     ;
520     AllExpr                 : PathExpr TOK_OpEq PathExpr
521                             {
522                                 $$=$1;
523                                 $$=xmlStrcat($$,U("!="));
524                                 $$=xmlStrcat($$,$3);
525                                 xmlFree($3);
526                             }
527                             | PathExpr TOK_OpNEq PathExpr
528                             {
529                                 $$=$1;
530                                 $$=xmlStrcat($$,U("="));
531                                 $$=xmlStrcat($$,$3);
532                                 xmlFree($3);
533                             }
534                             | PathExpr TOK_OpLt PathExpr
535                             {
536                                 $$=$1;
537                                 $$=xmlStrcat($$,U(">="));
538                                 $$=xmlStrcat($$,$3);
539                                 xmlFree($3);
540                             }
541                             | PathExpr TOK_OpLEq PathExpr
542                             {
543                                 $$=$1;
544                                 $$=xmlStrcat($$,U(">"));
545                                 $$=xmlStrcat($$,$3);
546                                 xmlFree($3);
547                             }
548                             | PathExpr TOK_OpGt PathExpr
549                             {
550                                 $$=$1;
551                                 $$=xmlStrcat($$,U("<="));
552                                 $$=xmlStrcat($$,$3);
553                                 xmlFree($3);
554                             }
555                             | PathExpr TOK_OpGEq PathExpr
556                             {
557                                 $$=$1;
558                                 $$=xmlStrcat($$,U("<"));
559                                 $$=xmlStrcat($$,$3);
560                                 xmlFree($3);
561                             }
562                             | PathExpr TOK_OpIEq PathExpr
563                             {
564                                 $$=xmlStrdup(U("OP_INEq("));
565                                 $$=xmlStrcat($$,$1);
566                                 xmlFree($1);
567                                 $$=xmlStrcat($$,U(","));
568                                 $$=xmlStrcat($$,$3);
569                                 xmlFree($3);
570                                 $$=xmlStrcat($$,U(")"));
571                             }
572                             | PathExpr TOK_OpINEq PathExpr
573                             {
574                                 $$=xmlStrdup(U("OP_IEq("));
575                                 $$=xmlStrcat($$,$1);
576                                 xmlFree($1);
577                                 $$=xmlStrcat($$,U(","));
578                                 $$=xmlStrcat($$,$3);
579                                 xmlFree($3);
580                                 $$=xmlStrcat($$,U(")"));
581                             }
582                             | PathExpr TOK_OpILt PathExpr
583                             {
584                                 $$=xmlStrdup(U("OP_IGEq("));
585                                 $$=xmlStrcat($$,$1);
586                                 xmlFree($1);
587                                 $$=xmlStrcat($$,U(","));
588                                 $$=xmlStrcat($$,$3);
589                                 xmlFree($3);
590                                 $$=xmlStrcat($$,U(")"));
591                             }
592                             | PathExpr TOK_OpILEq PathExpr
593                             {
594                                 $$=xmlStrdup(U("OP_IGt("));
595                                 $$=xmlStrcat($$,$1);
596                                 xmlFree($1);
597                                 $$=xmlStrcat($$,U(","));
598                                 $$=xmlStrcat($$,$3);
599                                 xmlFree($3);
600                                 $$=xmlStrcat($$,U(")"));
601                             }
602                             | PathExpr TOK_OpIGt PathExpr
603                             {
604                                 $$=xmlStrdup(U("OP_ILEq("));
605                                 $$=xmlStrcat($$,$1);
606                                 xmlFree($1);
607                                 $$=xmlStrcat($$,U(","));
608                                 $$=xmlStrcat($$,$3);
609                                 xmlFree($3);
610                                 $$=xmlStrcat($$,U(")"));
611                             }
612                             | PathExpr TOK_OpIGEq PathExpr
613                             {
614                                 $$=xmlStrdup(U("OP_ILt("));
615                                 $$=xmlStrcat($$,$1);
616                                 xmlFree($1);
617                                 $$=xmlStrcat($$,U(","));
618                                 $$=xmlStrcat($$,$3);
619                                 xmlFree($3);
620                                 $$=xmlStrcat($$,U(")"));
621                             }
622     ;
623
624 %%
625
626 void xslpattern_error(parser_param* param, void const* scanner, char const* msg)
627 {
628     FIXME("%s:\n"
629           "  param {\n"
630           "    yyscanner=%p\n"
631           "    in=\"%s\"\n"
632           "    pos=%i\n"
633           "    len=%i\n"
634           "    out=\"%s\"\n"
635           "    err=%i\n"
636           "  }\n"
637           "  scanner=%p\n",
638           msg, param->yyscanner, param->in, param->pos, param->len,
639           param->out, ++param->err, scanner);
640 }
641
642
643 #endif  /* HAVE_LIBXML2 */