Line data Source code
1 : /* A Bison parser, made by GNU Bison 3.0.4. */
2 :
3 : /* Bison implementation for Yacc-like parsers in C
4 :
5 : Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
6 :
7 : This program is free software: you can redistribute it and/or modify
8 : it under the terms of the GNU General Public License as published by
9 : the Free Software Foundation, either version 3 of the License, or
10 : (at your option) any later version.
11 :
12 : This program is distributed in the hope that it will be useful,
13 : but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 : GNU General Public License for more details.
16 :
17 : You should have received a copy of the GNU General Public License
18 : along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 :
20 : /* As a special exception, you may create a larger work that contains
21 : part or all of the Bison parser skeleton and distribute that work
22 : under terms of your choice, so long as that work isn't itself a
23 : parser generator using the skeleton or a modified version thereof
24 : as a parser skeleton. Alternatively, if you modify or redistribute
25 : the parser skeleton itself, you may (at your option) remove this
26 : special exception, which will cause the skeleton and the resulting
27 : Bison output files to be licensed under the GNU General Public
28 : License without this special exception.
29 :
30 : This special exception was added by the Free Software Foundation in
31 : version 2.2 of Bison. */
32 :
33 : /* C LALR(1) parser skeleton written by Richard Stallman, by
34 : simplifying the original so-called "semantic" parser. */
35 :
36 : /* All symbols defined below should begin with yy or YY, to avoid
37 : infringing on user name space. This should be done even for local
38 : variables, as they might otherwise be expanded by user macros.
39 : There are some unavoidable exceptions within include files to
40 : define necessary library symbols; they are noted "INFRINGES ON
41 : USER NAME SPACE" below. */
42 :
43 : /* Identify Bison output. */
44 : #define YYBISON 1
45 :
46 : /* Bison version. */
47 : #define YYBISON_VERSION "3.0.4"
48 :
49 : /* Skeleton name. */
50 : #define YYSKELETON_NAME "yacc.c"
51 :
52 : /* Pure parsers. */
53 : #define YYPURE 0
54 :
55 : /* Push parsers. */
56 : #define YYPUSH 0
57 :
58 : /* Pull parsers. */
59 : #define YYPULL 1
60 :
61 :
62 : /* Substitute the variable and function names. */
63 : #define yyparse mdsyylparse
64 : #define yylex mdsyyllex
65 : #define yyerror mdsyylerror
66 : #define yydebug mdsyyldebug
67 : #define yynerrs mdsyylnerrs
68 :
69 : #define yylval mdsyyllval
70 : #define yychar mdsyylchar
71 :
72 : /* Copy the first part of user declarations. */
73 :
74 :
75 : #include "includes.h"
76 : #include "rpc_server/mdssvc/mdssvc.h"
77 : #include "rpc_server/mdssvc/mdssvc_es.h"
78 : #include "rpc_server/mdssvc/es_parser.tab.h"
79 : #include "rpc_server/mdssvc/es_mapping.h"
80 : #include "lib/util/smb_strtox.h"
81 : #include <jansson.h>
82 :
83 : /*
84 : * allow building with -O3 -Wp,-D_FORTIFY_SOURCE=2
85 : *
86 : * /tmp/samba-testbase/.../mdssvc/es_parser.y: In function
87 : * ‘mdsyylparse’:
88 : * es_parser.tab.c:1124:6: error: assuming pointer wraparound
89 : * does not occur when comparing P +- C1 with P +- C2
90 : * [-Werror=strict-overflow]
91 : *
92 : * The generated code in es_parser.tab.c looks like this:
93 : *
94 : * if (yyss + yystacksize - 1 <= yyssp)
95 : */
96 : #pragma GCC diagnostic ignored "-Wstrict-overflow"
97 :
98 : #define YYMALLOC SMB_MALLOC
99 : #define YYREALLOC SMB_REALLOC
100 :
101 : struct yy_buffer_state;
102 : typedef struct yy_buffer_state *YY_BUFFER_STATE;
103 : int mdsyyllex(void);
104 : void mdsyylerror(char const *);
105 : void *mdsyylterminate(void);
106 : YY_BUFFER_STATE mdsyyl_scan_string(const char *str);
107 : void mdsyyl_delete_buffer(YY_BUFFER_STATE buffer);
108 :
109 : /* forward declarations */
110 : static char *isodate_to_sldate(const char *s);
111 : static char *map_expr(const struct es_attr_map *attr,
112 : char op,
113 : const char *val1,
114 : const char *val2);
115 :
116 : /* global vars, eg needed by the lexer */
117 : struct es_parser_state {
118 : TALLOC_CTX *frame;
119 : json_t *kmd_map;
120 : json_t *mime_map;
121 : YY_BUFFER_STATE s;
122 : const char *result;
123 : } *global_es_parser_state;
124 :
125 :
126 :
127 : # ifndef YY_NULLPTR
128 : # if defined __cplusplus && 201103L <= __cplusplus
129 : # define YY_NULLPTR nullptr
130 : # else
131 : # define YY_NULLPTR 0
132 : # endif
133 : # endif
134 :
135 : /* Enabling verbose error messages. */
136 : #ifdef YYERROR_VERBOSE
137 : # undef YYERROR_VERBOSE
138 : # define YYERROR_VERBOSE 1
139 : #else
140 : # define YYERROR_VERBOSE 1
141 : #endif
142 :
143 : /* In a future release of Bison, this section will be replaced
144 : by #include "es_parser.tab.h". */
145 : #ifndef YY_MDSYYL_ES_PARSER_TAB_H_INCLUDED
146 : # define YY_MDSYYL_ES_PARSER_TAB_H_INCLUDED
147 : /* Debug traces. */
148 : #ifndef YYDEBUG
149 : # define YYDEBUG 0
150 : #endif
151 : #if YYDEBUG
152 : extern int mdsyyldebug;
153 : #endif
154 :
155 : /* Token type. */
156 : #ifndef YYTOKENTYPE
157 : # define YYTOKENTYPE
158 : enum yytokentype
159 : {
160 : WORD = 258,
161 : PHRASE = 259,
162 : BOOLEAN = 260,
163 : FUNC_INRANGE = 261,
164 : DATE_ISO = 262,
165 : OBRACE = 263,
166 : CBRACE = 264,
167 : EQUAL = 265,
168 : UNEQUAL = 266,
169 : GT = 267,
170 : LT = 268,
171 : COMMA = 269,
172 : QUOTE = 270,
173 : OR = 271,
174 : AND = 272
175 : };
176 : #endif
177 :
178 : /* Value type. */
179 : #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
180 :
181 : union YYSTYPE
182 : {
183 :
184 :
185 : bool bval;
186 : const char *sval;
187 : struct es_attr_map *attr_map;
188 :
189 :
190 : };
191 :
192 : typedef union YYSTYPE YYSTYPE;
193 : # define YYSTYPE_IS_TRIVIAL 1
194 : # define YYSTYPE_IS_DECLARED 1
195 : #endif
196 :
197 :
198 : extern YYSTYPE mdsyyllval;
199 :
200 : int mdsyylparse (void);
201 : /* "%code provides" blocks. */
202 :
203 :
204 : #include <stdbool.h>
205 : #include <jansson.h>
206 : #include "rpc_server/mdssvc/mdssvc.h"
207 :
208 : /* 2001-01-01T00:00:00Z - Unix Epoch = SP_RAW_TIME_OFFSET */
209 : #define SP_RAW_TIME_OFFSET 978307200
210 :
211 : int mdsyylwrap(void);
212 : bool map_spotlight_to_es_query(TALLOC_CTX *mem_ctx,
213 : json_t *mappings,
214 : const char *path_scope,
215 : const char *query_string,
216 : char **_es_query);
217 :
218 :
219 :
220 : #endif /* !YY_MDSYYL_ES_PARSER_TAB_H_INCLUDED */
221 :
222 : /* Copy the second part of user declarations. */
223 :
224 :
225 :
226 : #ifdef short
227 : # undef short
228 : #endif
229 :
230 : #ifdef YYTYPE_UINT8
231 : typedef YYTYPE_UINT8 yytype_uint8;
232 : #else
233 : typedef unsigned char yytype_uint8;
234 : #endif
235 :
236 : #ifdef YYTYPE_INT8
237 : typedef YYTYPE_INT8 yytype_int8;
238 : #else
239 : typedef signed char yytype_int8;
240 : #endif
241 :
242 : #ifdef YYTYPE_UINT16
243 : typedef YYTYPE_UINT16 yytype_uint16;
244 : #else
245 : typedef unsigned short int yytype_uint16;
246 : #endif
247 :
248 : #ifdef YYTYPE_INT16
249 : typedef YYTYPE_INT16 yytype_int16;
250 : #else
251 : typedef short int yytype_int16;
252 : #endif
253 :
254 : #ifndef YYSIZE_T
255 : # ifdef __SIZE_TYPE__
256 : # define YYSIZE_T __SIZE_TYPE__
257 : # elif defined size_t
258 : # define YYSIZE_T size_t
259 : # elif ! defined YYSIZE_T
260 : # include <stddef.h> /* INFRINGES ON USER NAME SPACE */
261 : # define YYSIZE_T size_t
262 : # else
263 : # define YYSIZE_T unsigned int
264 : # endif
265 : #endif
266 :
267 : #define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
268 :
269 : #ifndef YY_
270 : # if defined YYENABLE_NLS && YYENABLE_NLS
271 : # if ENABLE_NLS
272 : # include <libintl.h> /* INFRINGES ON USER NAME SPACE */
273 : # define YY_(Msgid) dgettext ("bison-runtime", Msgid)
274 : # endif
275 : # endif
276 : # ifndef YY_
277 : # define YY_(Msgid) Msgid
278 : # endif
279 : #endif
280 :
281 : #ifndef YY_ATTRIBUTE
282 : # if (defined __GNUC__ \
283 : && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \
284 : || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C
285 : # define YY_ATTRIBUTE(Spec) __attribute__(Spec)
286 : # else
287 : # define YY_ATTRIBUTE(Spec) /* empty */
288 : # endif
289 : #endif
290 :
291 : #ifndef YY_ATTRIBUTE_PURE
292 : # define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__))
293 : #endif
294 :
295 : #ifndef YY_ATTRIBUTE_UNUSED
296 : # define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__))
297 : #endif
298 :
299 : #if !defined _Noreturn \
300 : && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112)
301 : # if defined _MSC_VER && 1200 <= _MSC_VER
302 : # define _Noreturn __declspec (noreturn)
303 : # else
304 : # define _Noreturn YY_ATTRIBUTE ((__noreturn__))
305 : # endif
306 : #endif
307 :
308 : /* Suppress unused-variable warnings by "using" E. */
309 : #if ! defined lint || defined __GNUC__
310 : # define YYUSE(E) ((void) (E))
311 : #else
312 : # define YYUSE(E) /* empty */
313 : #endif
314 :
315 : #if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
316 : /* Suppress an incorrect diagnostic about yylval being uninitialized. */
317 : # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
318 : _Pragma ("GCC diagnostic push") \
319 : _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\
320 : _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
321 : # define YY_IGNORE_MAYBE_UNINITIALIZED_END \
322 : _Pragma ("GCC diagnostic pop")
323 : #else
324 : # define YY_INITIAL_VALUE(Value) Value
325 : #endif
326 : #ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
327 : # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
328 : # define YY_IGNORE_MAYBE_UNINITIALIZED_END
329 : #endif
330 : #ifndef YY_INITIAL_VALUE
331 : # define YY_INITIAL_VALUE(Value) /* Nothing. */
332 : #endif
333 :
334 :
335 : #if ! defined yyoverflow || YYERROR_VERBOSE
336 :
337 : /* The parser invokes alloca or malloc; define the necessary symbols. */
338 :
339 : # ifdef YYSTACK_USE_ALLOCA
340 : # if YYSTACK_USE_ALLOCA
341 : # ifdef __GNUC__
342 : # define YYSTACK_ALLOC __builtin_alloca
343 : # elif defined __BUILTIN_VA_ARG_INCR
344 : # include <alloca.h> /* INFRINGES ON USER NAME SPACE */
345 : # elif defined _AIX
346 : # define YYSTACK_ALLOC __alloca
347 : # elif defined _MSC_VER
348 : # include <malloc.h> /* INFRINGES ON USER NAME SPACE */
349 : # define alloca _alloca
350 : # else
351 : # define YYSTACK_ALLOC alloca
352 : # if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS
353 : # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
354 : /* Use EXIT_SUCCESS as a witness for stdlib.h. */
355 : # ifndef EXIT_SUCCESS
356 : # define EXIT_SUCCESS 0
357 : # endif
358 : # endif
359 : # endif
360 : # endif
361 : # endif
362 :
363 : # ifdef YYSTACK_ALLOC
364 : /* Pacify GCC's 'empty if-body' warning. */
365 : # define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
366 : # ifndef YYSTACK_ALLOC_MAXIMUM
367 : /* The OS might guarantee only one guard page at the bottom of the stack,
368 : and a page size can be as small as 4096 bytes. So we cannot safely
369 : invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
370 : to allow for a few compiler-allocated temporary stack slots. */
371 : # define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
372 : # endif
373 : # else
374 : # define YYSTACK_ALLOC YYMALLOC
375 : # define YYSTACK_FREE YYFREE
376 : # ifndef YYSTACK_ALLOC_MAXIMUM
377 : # define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
378 : # endif
379 : # if (defined __cplusplus && ! defined EXIT_SUCCESS \
380 : && ! ((defined YYMALLOC || defined malloc) \
381 : && (defined YYFREE || defined free)))
382 : # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
383 : # ifndef EXIT_SUCCESS
384 : # define EXIT_SUCCESS 0
385 : # endif
386 : # endif
387 : # ifndef YYMALLOC
388 : # define YYMALLOC malloc
389 : # if ! defined malloc && ! defined EXIT_SUCCESS
390 : void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
391 : # endif
392 : # endif
393 : # ifndef YYFREE
394 : # define YYFREE free
395 : # if ! defined free && ! defined EXIT_SUCCESS
396 : void free (void *); /* INFRINGES ON USER NAME SPACE */
397 : # endif
398 : # endif
399 : # endif
400 : #endif /* ! defined yyoverflow || YYERROR_VERBOSE */
401 :
402 :
403 : #if (! defined yyoverflow \
404 : && (! defined __cplusplus \
405 : || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
406 :
407 : /* A type that is properly aligned for any stack member. */
408 : union yyalloc
409 : {
410 : yytype_int16 yyss_alloc;
411 : YYSTYPE yyvs_alloc;
412 : };
413 :
414 : /* The size of the maximum gap between one aligned stack and the next. */
415 : # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
416 :
417 : /* The size of an array large to enough to hold all stacks, each with
418 : N elements. */
419 : # define YYSTACK_BYTES(N) \
420 : ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
421 : + YYSTACK_GAP_MAXIMUM)
422 :
423 : # define YYCOPY_NEEDED 1
424 :
425 : /* Relocate STACK from its old location to the new one. The
426 : local variables YYSIZE and YYSTACKSIZE give the old and new number of
427 : elements in the stack, and YYPTR gives the new location of the
428 : stack. Advance YYPTR to a properly aligned location for the next
429 : stack. */
430 : # define YYSTACK_RELOCATE(Stack_alloc, Stack) \
431 : do \
432 : { \
433 : YYSIZE_T yynewbytes; \
434 : YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \
435 : Stack = &yyptr->Stack_alloc; \
436 : yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
437 : yyptr += yynewbytes / sizeof (*yyptr); \
438 : } \
439 : while (0)
440 :
441 : #endif
442 :
443 : #if defined YYCOPY_NEEDED && YYCOPY_NEEDED
444 : /* Copy COUNT objects from SRC to DST. The source and destination do
445 : not overlap. */
446 : # ifndef YYCOPY
447 : # if defined __GNUC__ && 1 < __GNUC__
448 : # define YYCOPY(Dst, Src, Count) \
449 : __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src)))
450 : # else
451 : # define YYCOPY(Dst, Src, Count) \
452 : do \
453 : { \
454 : YYSIZE_T yyi; \
455 : for (yyi = 0; yyi < (Count); yyi++) \
456 : (Dst)[yyi] = (Src)[yyi]; \
457 : } \
458 : while (0)
459 : # endif
460 : # endif
461 : #endif /* !YYCOPY_NEEDED */
462 :
463 : /* YYFINAL -- State number of the termination state. */
464 : #define YYFINAL 2
465 : /* YYLAST -- Last index in YYTABLE. */
466 : #define YYLAST 38
467 :
468 : /* YYNTOKENS -- Number of terminals. */
469 : #define YYNTOKENS 18
470 : /* YYNNTS -- Number of nonterminals. */
471 : #define YYNNTS 9
472 : /* YYNRULES -- Number of rules. */
473 : #define YYNRULES 20
474 : /* YYNSTATES -- Number of states. */
475 : #define YYNSTATES 40
476 :
477 : /* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
478 : by yylex, with out-of-bounds checking. */
479 : #define YYUNDEFTOK 2
480 : #define YYMAXUTOK 272
481 :
482 : #define YYTRANSLATE(YYX) \
483 : ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
484 :
485 : /* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
486 : as returned by yylex, without out-of-bounds checking. */
487 : static const yytype_uint8 yytranslate[] =
488 : {
489 : 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
490 : 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
491 : 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
492 : 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
493 : 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
494 : 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
495 : 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
496 : 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
497 : 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
498 : 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
499 : 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
500 : 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
501 : 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
502 : 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
503 : 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
504 : 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
505 : 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
506 : 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
507 : 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
508 : 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
509 : 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
510 : 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
511 : 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
512 : 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
513 : 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
514 : 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
515 : 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
516 : 15, 16, 17
517 : };
518 :
519 : #if YYDEBUG
520 : /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
521 : static const yytype_uint8 yyrline[] =
522 : {
523 : 0, 111, 111, 113, 117, 123, 128, 132, 136, 139,
524 : 152, 156, 160, 164, 168, 171, 176, 182, 190, 193,
525 : 198
526 : };
527 : #endif
528 :
529 : #if YYDEBUG || YYERROR_VERBOSE || 1
530 : /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
531 : First, the terminals, then, starting at YYNTOKENS, nonterminals. */
532 : static const char *const yytname[] =
533 : {
534 : "$end", "error", "$undefined", "WORD", "PHRASE", "BOOLEAN",
535 : "FUNC_INRANGE", "DATE_ISO", "OBRACE", "CBRACE", "EQUAL", "UNEQUAL", "GT",
536 : "LT", "COMMA", "QUOTE", "OR", "AND", "$accept", "input", "line", "expr",
537 : "match", "function", "attribute", "value", "isodate", YY_NULLPTR
538 : };
539 : #endif
540 :
541 : # ifdef YYPRINT
542 : /* YYTOKNUM[NUM] -- (External) token number corresponding to the
543 : (internal) symbol number NUM (which must be that of a token). */
544 : static const yytype_uint16 yytoknum[] =
545 : {
546 : 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
547 : 265, 266, 267, 268, 269, 270, 271, 272
548 : };
549 : # endif
550 :
551 : #define YYPACT_NINF -7
552 :
553 : #define yypact_value_is_default(Yystate) \
554 : (!!((Yystate) == (-7)))
555 :
556 : #define YYTABLE_NINF -1
557 :
558 : #define yytable_value_is_error(Yytable_value) \
559 : 0
560 :
561 : /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
562 : STATE-NUM. */
563 : static const yytype_int8 yypact[] =
564 : {
565 : -7, 7, -7, -7, -7, -3, -2, -7, 0, -1,
566 : -7, 10, 22, 2, -2, -2, -7, 20, 20, 20,
567 : 20, 12, -7, 15, -7, -7, 6, -7, -7, -7,
568 : -7, -7, 25, 30, 21, 27, 31, -7, 28, -7
569 : };
570 :
571 : /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
572 : Performed when YYTABLE does not specify something else to do. Zero
573 : means the default is an error. */
574 : static const yytype_uint8 yydefact[] =
575 : {
576 0 : 2, 0, 1, 17, 9, 0, 0, 3, 4, 8,
577 : 14, 0, 0, 0, 0, 0, 15, 0, 0, 0,
578 0 : 0, 0, 5, 7, 6, 18, 0, 10, 19, 11,
579 : 13, 12, 0, 0, 0, 0, 0, 20, 0, 16
580 : };
581 :
582 : /* YYPGOTO[NTERM-NUM]. */
583 : static const yytype_int8 yypgoto[] =
584 : {
585 : -7, -7, -7, -6, -7, -7, 26, 11, -7
586 : };
587 :
588 : /* YYDEFGOTO[NTERM-NUM]. */
589 : static const yytype_int8 yydefgoto[] =
590 : {
591 : -1, 1, 7, 8, 9, 10, 11, 27, 28
592 : };
593 :
594 : /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If
595 : positive, shift that token. If negative, reduce the rule whose
596 : number is the opposite. If YYTABLE_NINF, syntax error. */
597 : static const yytype_uint8 yytable[] =
598 : {
599 : 13, 3, 16, 4, 5, 12, 6, 2, 23, 24,
600 : 3, 22, 4, 5, 33, 6, 14, 15, 14, 15,
601 : 17, 18, 19, 20, 25, 3, 32, 26, 34, 29,
602 : 30, 31, 15, 35, 38, 36, 37, 39, 21
603 : };
604 :
605 : static const yytype_uint8 yycheck[] =
606 : {
607 : 6, 3, 3, 5, 6, 8, 8, 0, 14, 15,
608 : 3, 9, 5, 6, 8, 8, 16, 17, 16, 17,
609 : 10, 11, 12, 13, 4, 3, 14, 7, 3, 18,
610 : 19, 20, 17, 3, 3, 14, 9, 9, 12
611 : };
612 :
613 : /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
614 : symbol of state STATE-NUM. */
615 : static const yytype_uint8 yystos[] =
616 : {
617 : 0, 19, 0, 3, 5, 6, 8, 20, 21, 22,
618 : 23, 24, 8, 21, 16, 17, 3, 10, 11, 12,
619 : 13, 24, 9, 21, 21, 4, 7, 25, 26, 25,
620 : 25, 25, 14, 8, 3, 3, 14, 9, 3, 9
621 : };
622 :
623 : /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
624 : static const yytype_uint8 yyr1[] =
625 : {
626 : 0, 18, 19, 19, 20, 21, 21, 21, 21, 21,
627 : 22, 22, 22, 22, 22, 22, 23, 24, 25, 25,
628 : 26
629 : };
630 :
631 : /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */
632 : static const yytype_uint8 yyr2[] =
633 : {
634 : 0, 2, 0, 2, 1, 3, 3, 3, 1, 1,
635 : 3, 3, 3, 3, 1, 2, 8, 1, 1, 1,
636 : 4
637 : };
638 :
639 :
640 : #define yyerrok (yyerrstatus = 0)
641 : #define yyclearin (yychar = YYEMPTY)
642 : #define YYEMPTY (-2)
643 : #define YYEOF 0
644 :
645 : #define YYACCEPT goto yyacceptlab
646 : #define YYABORT goto yyabortlab
647 : #define YYERROR goto yyerrorlab
648 :
649 :
650 : #define YYRECOVERING() (!!yyerrstatus)
651 :
652 : #define YYBACKUP(Token, Value) \
653 : do \
654 : if (yychar == YYEMPTY) \
655 : { \
656 : yychar = (Token); \
657 : yylval = (Value); \
658 : YYPOPSTACK (yylen); \
659 : yystate = *yyssp; \
660 : goto yybackup; \
661 : } \
662 : else \
663 : { \
664 : yyerror (YY_("syntax error: cannot back up")); \
665 : YYERROR; \
666 : } \
667 : while (0)
668 :
669 : /* Error token number */
670 : #define YYTERROR 1
671 : #define YYERRCODE 256
672 :
673 :
674 :
675 : /* Enable debugging if requested. */
676 : #if YYDEBUG
677 :
678 : # ifndef YYFPRINTF
679 : # include <stdio.h> /* INFRINGES ON USER NAME SPACE */
680 : # define YYFPRINTF fprintf
681 : # endif
682 :
683 : # define YYDPRINTF(Args) \
684 : do { \
685 : if (yydebug) \
686 : YYFPRINTF Args; \
687 : } while (0)
688 :
689 : /* This macro is provided for backward compatibility. */
690 : #ifndef YY_LOCATION_PRINT
691 : # define YY_LOCATION_PRINT(File, Loc) ((void) 0)
692 : #endif
693 :
694 :
695 : # define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
696 : do { \
697 : if (yydebug) \
698 : { \
699 : YYFPRINTF (stderr, "%s ", Title); \
700 : yy_symbol_print (stderr, \
701 : Type, Value); \
702 : YYFPRINTF (stderr, "\n"); \
703 : } \
704 : } while (0)
705 :
706 :
707 : /*----------------------------------------.
708 : | Print this symbol's value on YYOUTPUT. |
709 : `----------------------------------------*/
710 :
711 : static void
712 : yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
713 : {
714 : FILE *yyo = yyoutput;
715 : YYUSE (yyo);
716 : if (!yyvaluep)
717 : return;
718 : # ifdef YYPRINT
719 : if (yytype < YYNTOKENS)
720 : YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
721 : # endif
722 : YYUSE (yytype);
723 : }
724 :
725 :
726 : /*--------------------------------.
727 : | Print this symbol on YYOUTPUT. |
728 : `--------------------------------*/
729 :
730 : static void
731 : yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
732 : {
733 : YYFPRINTF (yyoutput, "%s %s (",
734 : yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]);
735 :
736 : yy_symbol_value_print (yyoutput, yytype, yyvaluep);
737 : YYFPRINTF (yyoutput, ")");
738 : }
739 :
740 : /*------------------------------------------------------------------.
741 : | yy_stack_print -- Print the state stack from its BOTTOM up to its |
742 : | TOP (included). |
743 : `------------------------------------------------------------------*/
744 :
745 : static void
746 : yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
747 : {
748 : YYFPRINTF (stderr, "Stack now");
749 : for (; yybottom <= yytop; yybottom++)
750 : {
751 : int yybot = *yybottom;
752 : YYFPRINTF (stderr, " %d", yybot);
753 : }
754 : YYFPRINTF (stderr, "\n");
755 : }
756 :
757 : # define YY_STACK_PRINT(Bottom, Top) \
758 : do { \
759 : if (yydebug) \
760 : yy_stack_print ((Bottom), (Top)); \
761 : } while (0)
762 :
763 :
764 : /*------------------------------------------------.
765 : | Report that the YYRULE is going to be reduced. |
766 : `------------------------------------------------*/
767 :
768 : static void
769 : yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule)
770 : {
771 : unsigned long int yylno = yyrline[yyrule];
772 : int yynrhs = yyr2[yyrule];
773 : int yyi;
774 : YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
775 : yyrule - 1, yylno);
776 : /* The symbols being reduced. */
777 : for (yyi = 0; yyi < yynrhs; yyi++)
778 : {
779 : YYFPRINTF (stderr, " $%d = ", yyi + 1);
780 : yy_symbol_print (stderr,
781 : yystos[yyssp[yyi + 1 - yynrhs]],
782 : &(yyvsp[(yyi + 1) - (yynrhs)])
783 : );
784 : YYFPRINTF (stderr, "\n");
785 : }
786 : }
787 :
788 : # define YY_REDUCE_PRINT(Rule) \
789 : do { \
790 : if (yydebug) \
791 : yy_reduce_print (yyssp, yyvsp, Rule); \
792 : } while (0)
793 :
794 : /* Nonzero means print parse trace. It is left uninitialized so that
795 : multiple parsers can coexist. */
796 : int yydebug;
797 : #else /* !YYDEBUG */
798 : # define YYDPRINTF(Args)
799 : # define YY_SYMBOL_PRINT(Title, Type, Value, Location)
800 : # define YY_STACK_PRINT(Bottom, Top)
801 : # define YY_REDUCE_PRINT(Rule)
802 : #endif /* !YYDEBUG */
803 :
804 :
805 : /* YYINITDEPTH -- initial size of the parser's stacks. */
806 : #ifndef YYINITDEPTH
807 : # define YYINITDEPTH 200
808 : #endif
809 :
810 : /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
811 : if the built-in stack extension method is used).
812 :
813 : Do not make this value too large; the results are undefined if
814 : YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
815 : evaluated with infinite-precision integer arithmetic. */
816 :
817 : #ifndef YYMAXDEPTH
818 : # define YYMAXDEPTH 10000
819 : #endif
820 :
821 :
822 : #if YYERROR_VERBOSE
823 :
824 : # ifndef yystrlen
825 : # if defined __GLIBC__ && defined _STRING_H
826 : # define yystrlen strlen
827 : # else
828 : /* Return the length of YYSTR. */
829 : static YYSIZE_T
830 : yystrlen (const char *yystr)
831 : {
832 : YYSIZE_T yylen;
833 : for (yylen = 0; yystr[yylen]; yylen++)
834 : continue;
835 : return yylen;
836 : }
837 : # endif
838 : # endif
839 :
840 : # ifndef yystpcpy
841 : # if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
842 : # define yystpcpy stpcpy
843 : # else
844 : /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
845 : YYDEST. */
846 : static char *
847 : yystpcpy (char *yydest, const char *yysrc)
848 : {
849 : char *yyd = yydest;
850 : const char *yys = yysrc;
851 :
852 : while ((*yyd++ = *yys++) != '\0')
853 : continue;
854 :
855 : return yyd - 1;
856 : }
857 : # endif
858 : # endif
859 :
860 : # ifndef yytnamerr
861 : /* Copy to YYRES the contents of YYSTR after stripping away unnecessary
862 : quotes and backslashes, so that it's suitable for yyerror. The
863 : heuristic is that double-quoting is unnecessary unless the string
864 : contains an apostrophe, a comma, or backslash (other than
865 : backslash-backslash). YYSTR is taken from yytname. If YYRES is
866 : null, do not copy; instead, return the length of what the result
867 : would have been. */
868 : static YYSIZE_T
869 0 : yytnamerr (char *yyres, const char *yystr)
870 : {
871 0 : if (*yystr == '"')
872 : {
873 0 : YYSIZE_T yyn = 0;
874 0 : char const *yyp = yystr;
875 :
876 : for (;;)
877 0 : switch (*++yyp)
878 : {
879 0 : case '\'':
880 0 : case ',':
881 0 : goto do_not_strip_quotes;
882 :
883 0 : case '\\':
884 0 : if (*++yyp != '\\')
885 0 : goto do_not_strip_quotes;
886 0 : /* Fall through. */
887 : default:
888 0 : if (yyres)
889 0 : yyres[yyn] = *yyp;
890 0 : yyn++;
891 0 : break;
892 :
893 0 : case '"':
894 0 : if (yyres)
895 0 : yyres[yyn] = '\0';
896 0 : return yyn;
897 0 : }
898 0 : do_not_strip_quotes: ;
899 : }
900 0 :
901 0 : if (! yyres)
902 0 : return yystrlen (yystr);
903 0 :
904 0 : return yystpcpy (yyres, yystr) - yyres;
905 0 : }
906 : # endif
907 :
908 0 : /* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
909 0 : about the unexpected token YYTOKEN for the state stack whose top is
910 0 : YYSSP.
911 :
912 : Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is
913 : not large enough to hold the message. In that case, also set
914 : *YYMSG_ALLOC to the required number of bytes. Return 2 if the
915 : required number of bytes is too large to store. */
916 : static int
917 0 : yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
918 : yytype_int16 *yyssp, int yytoken)
919 : {
920 0 : YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]);
921 0 : YYSIZE_T yysize = yysize0;
922 : enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
923 : /* Internationalized format string. */
924 0 : const char *yyformat = YY_NULLPTR;
925 : /* Arguments of yyformat. */
926 : char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
927 : /* Number of reported tokens (one for the "unexpected", one per
928 : "expected"). */
929 0 : int yycount = 0;
930 :
931 : /* There are many possibilities here to consider:
932 : - If this state is a consistent state with a default action, then
933 : the only way this function was invoked is if the default action
934 : is an error action. In that case, don't check for expected
935 : tokens because there are none.
936 : - The only way there can be no lookahead present (in yychar) is if
937 : this state is a consistent state with a default action. Thus,
938 : detecting the absence of a lookahead is sufficient to determine
939 : that there is no unexpected or expected token to report. In that
940 : case, just report a simple "syntax error".
941 : - Don't assume there isn't a lookahead just because this state is a
942 : consistent state with a default action. There might have been a
943 : previous inconsistent state, consistent state with a non-default
944 : action, or user semantic action that manipulated yychar.
945 : - Of course, the expected token list depends on states to have
946 : correct lookahead information, and it depends on the parser not
947 : to perform extra reductions after fetching a lookahead from the
948 : scanner and before detecting a syntax error. Thus, state merging
949 : (from LALR or IELR) and default reductions corrupt the expected
950 : token list. However, the list is correct for canonical LR with
951 : one exception: it will still contain any token that will not be
952 : accepted due to an error action in a later state.
953 : */
954 0 : if (yytoken != YYEMPTY)
955 : {
956 0 : int yyn = yypact[*yyssp];
957 0 : yyarg[yycount++] = yytname[yytoken];
958 0 : if (!yypact_value_is_default (yyn))
959 : {
960 : /* Start YYX at -YYN if negative to avoid negative indexes in
961 0 : YYCHECK. In other words, skip the first -YYN actions for
962 : this state because they are default actions. */
963 0 : int yyxbegin = yyn < 0 ? -yyn : 0;
964 : /* Stay within bounds of both yycheck and yytname. */
965 0 : int yychecklim = YYLAST - yyn + 1;
966 0 : int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
967 : int yyx;
968 0 :
969 0 : for (yyx = yyxbegin; yyx < yyxend; ++yyx)
970 0 : if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
971 0 : && !yytable_value_is_error (yytable[yyx + yyn]))
972 0 : {
973 0 : if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
974 0 : {
975 0 : yycount = 1;
976 0 : yysize = yysize0;
977 0 : break;
978 0 : }
979 0 : yyarg[yycount++] = yytname[yyx];
980 0 : {
981 0 : YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]);
982 0 : if (! (yysize <= yysize1
983 0 : && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
984 0 : return 2;
985 0 : yysize = yysize1;
986 : }
987 0 : }
988 0 : }
989 0 : }
990 0 :
991 0 : switch (yycount)
992 0 : {
993 : # define YYCASE_(N, S) \
994 : case N: \
995 0 : yyformat = S; \
996 0 : break
997 0 : YYCASE_(0, YY_("syntax error"));
998 0 : YYCASE_(1, YY_("syntax error, unexpected %s"));
999 0 : YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
1000 0 : YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
1001 0 : YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
1002 0 : YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
1003 : # undef YYCASE_
1004 0 : }
1005 :
1006 : {
1007 0 : YYSIZE_T yysize1 = yysize + yystrlen (yyformat);
1008 0 : if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
1009 0 : return 2;
1010 0 : yysize = yysize1;
1011 : }
1012 :
1013 0 : if (*yymsg_alloc < yysize)
1014 : {
1015 0 : *yymsg_alloc = 2 * yysize;
1016 0 : if (! (yysize <= *yymsg_alloc
1017 : && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
1018 0 : *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
1019 0 : return 1;
1020 : }
1021 :
1022 : /* Avoid sprintf, as that infringes on the user's name space.
1023 : Don't have undefined behavior even if the translation
1024 : produced a string with the wrong number of "%s"s. */
1025 : {
1026 0 : char *yyp = *yymsg;
1027 0 : int yyi = 0;
1028 0 : while ((*yyp = *yyformat) != '\0')
1029 0 : if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
1030 : {
1031 0 : yyp += yytnamerr (yyp, yyarg[yyi++]);
1032 0 : yyformat += 2;
1033 : }
1034 : else
1035 0 : {
1036 0 : yyp++;
1037 0 : yyformat++;
1038 0 : }
1039 : }
1040 0 : return 0;
1041 0 : }
1042 : #endif /* YYERROR_VERBOSE */
1043 0 :
1044 : /*-----------------------------------------------.
1045 0 : | Release the memory associated to this symbol. |
1046 : `-----------------------------------------------*/
1047 :
1048 : static void
1049 12 : yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
1050 : {
1051 : YYUSE (yyvaluep);
1052 12 : if (!yymsg)
1053 0 : yymsg = "Deleting";
1054 : YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
1055 :
1056 : YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
1057 0 : YYUSE (yytype);
1058 : YY_IGNORE_MAYBE_UNINITIALIZED_END
1059 12 : }
1060 :
1061 :
1062 0 :
1063 :
1064 : /* The lookahead symbol. */
1065 : int yychar;
1066 :
1067 0 : /* The semantic value of the lookahead symbol. */
1068 : YYSTYPE yylval;
1069 : /* Number of syntax errors so far. */
1070 0 : int yynerrs;
1071 0 :
1072 0 :
1073 : /*----------.
1074 0 : | yyparse. |
1075 : `----------*/
1076 :
1077 : int
1078 47 : yyparse (void)
1079 : {
1080 0 : int yystate;
1081 0 : /* Number of tokens to shift before error messages enabled. */
1082 0 : int yyerrstatus;
1083 0 :
1084 0 : /* The stacks and their tools:
1085 0 : 'yyss': related to states.
1086 0 : 'yyvs': related to semantic values.
1087 :
1088 : Refer to the stacks through separate pointers, to allow yyoverflow
1089 : to reallocate them elsewhere. */
1090 :
1091 : /* The state stack. */
1092 0 : yytype_int16 yyssa[YYINITDEPTH];
1093 : yytype_int16 *yyss;
1094 : yytype_int16 *yyssp;
1095 0 :
1096 : /* The semantic value stack. */
1097 0 : YYSTYPE yyvsa[YYINITDEPTH];
1098 0 : YYSTYPE *yyvs;
1099 0 : YYSTYPE *yyvsp;
1100 0 :
1101 : YYSIZE_T yystacksize;
1102 0 :
1103 : int yyn;
1104 : int yyresult;
1105 : /* Lookahead token as an internal (translated) token number. */
1106 47 : int yytoken = 0;
1107 : /* The variables used to return semantic value and location from the
1108 0 : action routines. */
1109 0 : YYSTYPE yyval;
1110 :
1111 0 : #if YYERROR_VERBOSE
1112 0 : /* Buffer for error messages, and its allocated size. */
1113 : char yymsgbuf[128];
1114 47 : char *yymsg = yymsgbuf;
1115 47 : YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
1116 : #endif
1117 :
1118 : #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N))
1119 0 :
1120 0 : /* The number of symbols on the RHS of the reduced rule.
1121 0 : Keep to zero when no symbol should be popped. */
1122 47 : int yylen = 0;
1123 :
1124 47 : yyssp = yyss = yyssa;
1125 47 : yyvsp = yyvs = yyvsa;
1126 47 : yystacksize = YYINITDEPTH;
1127 :
1128 : YYDPRINTF ((stderr, "Starting parse\n"));
1129 0 :
1130 47 : yystate = 0;
1131 47 : yyerrstatus = 0;
1132 47 : yynerrs = 0;
1133 47 : yychar = YYEMPTY; /* Cause a token to be read. */
1134 47 : goto yysetstate;
1135 :
1136 : /*------------------------------------------------------------.
1137 : | yynewstate -- Push a new state, which is found in yystate. |
1138 : `------------------------------------------------------------*/
1139 693 : yynewstate:
1140 : /* In all cases, when you get here, the value and location stacks
1141 : have just been pushed. So pushing a state here evens the stacks. */
1142 693 : yyssp++;
1143 :
1144 740 : yysetstate:
1145 740 : *yyssp = yystate;
1146 0 :
1147 740 : if (yyss + yystacksize - 1 <= yyssp)
1148 : {
1149 : /* Get the current used size of the three stacks, in elements. */
1150 0 : YYSIZE_T yysize = yyssp - yyss + 1;
1151 :
1152 : #ifdef yyoverflow
1153 0 : {
1154 : /* Give user a chance to reallocate the stack. Use copies of
1155 : these so that the &'s don't force the real ones into
1156 : memory. */
1157 : YYSTYPE *yyvs1 = yyvs;
1158 : yytype_int16 *yyss1 = yyss;
1159 :
1160 : /* Each stack pointer address is followed by the size of the
1161 : data in use in that stack, in bytes. This used to be a
1162 : conditional around just the two extra args, but that might
1163 : be undefined if yyoverflow is a macro. */
1164 : yyoverflow (YY_("memory exhausted"),
1165 : &yyss1, yysize * sizeof (*yyssp),
1166 : &yyvs1, yysize * sizeof (*yyvsp),
1167 : &yystacksize);
1168 :
1169 : yyss = yyss1;
1170 : yyvs = yyvs1;
1171 : }
1172 0 : #else /* no yyoverflow */
1173 : # ifndef YYSTACK_RELOCATE
1174 0 : goto yyexhaustedlab;
1175 : # else
1176 0 : /* Extend the stack our own way. */
1177 0 : if (YYMAXDEPTH <= yystacksize)
1178 0 : goto yyexhaustedlab;
1179 0 : yystacksize *= 2;
1180 0 : if (YYMAXDEPTH < yystacksize)
1181 0 : yystacksize = YYMAXDEPTH;
1182 0 :
1183 : {
1184 0 : yytype_int16 *yyss1 = yyss;
1185 0 : union yyalloc *yyptr =
1186 0 : (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
1187 0 : if (! yyptr)
1188 0 : goto yyexhaustedlab;
1189 0 : YYSTACK_RELOCATE (yyss_alloc, yyss);
1190 0 : YYSTACK_RELOCATE (yyvs_alloc, yyvs);
1191 0 : # undef YYSTACK_RELOCATE
1192 0 : if (yyss1 != yyssa)
1193 0 : YYSTACK_FREE (yyss1);
1194 : }
1195 : # endif
1196 : #endif /* no yyoverflow */
1197 :
1198 0 : yyssp = yyss + yysize - 1;
1199 0 : yyvsp = yyvs + yysize - 1;
1200 :
1201 : YYDPRINTF ((stderr, "Stack size increased to %lu\n",
1202 : (unsigned long int) yystacksize));
1203 :
1204 0 : if (yyss + yystacksize - 1 <= yyssp)
1205 0 : YYABORT;
1206 0 : }
1207 :
1208 : YYDPRINTF ((stderr, "Entering state %d\n", yystate));
1209 :
1210 740 : if (yystate == YYFINAL)
1211 6 : YYACCEPT;
1212 0 :
1213 210 : goto yybackup;
1214 :
1215 : /*-----------.
1216 0 : | yybackup. |
1217 0 : `-----------*/
1218 693 : yybackup:
1219 :
1220 : /* Do appropriate processing given the current state. Read a
1221 : lookahead token if we need one and don't already have one. */
1222 :
1223 0 : /* First try to decide what to do without reference to lookahead token. */
1224 693 : yyn = yypact[yystate];
1225 693 : if (yypact_value_is_default (yyn))
1226 78 : goto yydefault;
1227 :
1228 : /* Not known => get a lookahead token if don't already have one. */
1229 :
1230 : /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
1231 402 : if (yychar == YYEMPTY)
1232 0 : {
1233 : YYDPRINTF ((stderr, "Reading a token: "));
1234 273 : yychar = yylex ();
1235 : }
1236 0 :
1237 402 : if (yychar <= YYEOF)
1238 : {
1239 144 : yychar = yytoken = YYEOF;
1240 0 : YYDPRINTF ((stderr, "Now at end of input.\n"));
1241 : }
1242 : else
1243 : {
1244 258 : yytoken = YYTRANSLATE (yychar);
1245 : YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
1246 0 : }
1247 :
1248 : /* If the proper action on seeing token YYTOKEN is to reduce or to
1249 : detect an error, take that action. */
1250 402 : yyn += yytoken;
1251 757 : if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
1252 : goto yydefault;
1253 273 : yyn = yytable[yyn];
1254 273 : if (yyn <= 0)
1255 : {
1256 : if (yytable_value_is_error (yyn))
1257 : goto yyerrlab;
1258 0 : yyn = -yyn;
1259 0 : goto yyreduce;
1260 : }
1261 :
1262 : /* Count tokens shifted since error; after three, turn off error
1263 : status. */
1264 273 : if (yyerrstatus)
1265 0 : yyerrstatus--;
1266 :
1267 : /* Shift the lookahead token. */
1268 : YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
1269 0 :
1270 0 : /* Discard the shifted token. */
1271 273 : yychar = YYEMPTY;
1272 0 :
1273 273 : yystate = yyn;
1274 : YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
1275 273 : *++yyvsp = yylval;
1276 0 : YY_IGNORE_MAYBE_UNINITIALIZED_END
1277 :
1278 273 : goto yynewstate;
1279 :
1280 0 :
1281 0 : /*-----------------------------------------------------------.
1282 0 : | yydefault -- do the default action for the current state. |
1283 0 : `-----------------------------------------------------------*/
1284 342 : yydefault:
1285 420 : yyn = yydefact[yystate];
1286 420 : if (yyn == 0)
1287 0 : goto yyerrlab;
1288 122 : goto yyreduce;
1289 :
1290 0 :
1291 0 : /*-----------------------------.
1292 : | yyreduce -- Do a reduction. |
1293 : `-----------------------------*/
1294 420 : yyreduce:
1295 : /* yyn is the number of a rule to reduce with. */
1296 420 : yylen = yyr2[yyn];
1297 :
1298 0 : /* If YYLEN is nonzero, implement the default value of the action:
1299 0 : '$$ = $1'.
1300 :
1301 : Otherwise, the following line sets YYVAL to garbage.
1302 : This behavior is undocumented and Bison
1303 0 : users should not rely upon it. Assigning to YYVAL
1304 0 : unconditionally makes the parser a bit smaller, and it avoids a
1305 : GCC warning that YYVAL may be used uninitialized. */
1306 420 : yyval = yyvsp[1-yylen];
1307 :
1308 :
1309 : YY_REDUCE_PRINT (yyn);
1310 420 : switch (yyn)
1311 : {
1312 47 : case 4:
1313 :
1314 : {
1315 47 : global_es_parser_state->result = (yyvsp[0].sval);
1316 : }
1317 0 :
1318 47 : break;
1319 0 :
1320 0 : case 5:
1321 :
1322 : {
1323 0 : if ((yyvsp[-1].sval) == NULL) YYABORT;
1324 0 : (yyval.sval) = talloc_asprintf(talloc_tos(), "(%s)", (yyvsp[-1].sval));
1325 0 : if ((yyval.sval) == NULL) YYABORT;
1326 : }
1327 0 :
1328 0 : break;
1329 :
1330 1 : case 6:
1331 :
1332 0 : {
1333 1 : (yyval.sval) = talloc_asprintf(talloc_tos(), "(%s) AND (%s)", (yyvsp[-2].sval), (yyvsp[0].sval));
1334 1 : if ((yyval.sval) == NULL) YYABORT;
1335 : }
1336 0 :
1337 0 : break;
1338 :
1339 17 : case 7:
1340 :
1341 : {
1342 17 : (yyval.sval) = talloc_asprintf(talloc_tos(), "%s OR %s", (yyvsp[-2].sval), (yyvsp[0].sval));
1343 17 : if ((yyval.sval) == NULL) YYABORT;
1344 0 : }
1345 :
1346 16 : break;
1347 :
1348 65 : case 8:
1349 :
1350 : {
1351 65 : (yyval.sval) = (yyvsp[0].sval);
1352 : }
1353 :
1354 65 : break;
1355 0 :
1356 0 : case 9:
1357 0 :
1358 0 : {
1359 : /*
1360 : * We can't properly handle these in expressions, fortunately this
1361 : * is probably only ever used by OS X as sole element in an
1362 0 : * expression ie "False" (when Finder window selected our share
1363 0 : * but no search string entered yet). Packet traces showed that OS
1364 : * X Spotlight server then returns a failure (ie -1) which is what
1365 : * we do here too by calling YYABORT.
1366 : */
1367 0 : YYABORT;
1368 0 : }
1369 0 :
1370 : break;
1371 :
1372 56 : case 10:
1373 0 :
1374 : {
1375 56 : (yyval.sval) = map_expr((yyvsp[-2].attr_map), '=', (yyvsp[0].sval), NULL);
1376 56 : if ((yyval.sval) == NULL) YYABORT;
1377 : }
1378 :
1379 22 : break;
1380 0 :
1381 3 : case 11:
1382 :
1383 : {
1384 3 : (yyval.sval) = map_expr((yyvsp[-2].attr_map), '!', (yyvsp[0].sval), NULL);
1385 3 : if ((yyval.sval) == NULL) YYABORT;
1386 0 : }
1387 0 :
1388 0 : break;
1389 0 :
1390 2 : case 12:
1391 :
1392 : {
1393 2 : (yyval.sval) = map_expr((yyvsp[-2].attr_map), '<', (yyvsp[0].sval), NULL);
1394 2 : if ((yyval.sval) == NULL) YYABORT;
1395 : }
1396 0 :
1397 0 : break;
1398 0 :
1399 2 : case 13:
1400 :
1401 : {
1402 2 : (yyval.sval) = map_expr((yyvsp[-2].attr_map), '>', (yyvsp[0].sval), NULL);
1403 2 : if ((yyval.sval) == NULL) YYABORT;
1404 : }
1405 :
1406 0 : break;
1407 :
1408 2 : case 14:
1409 :
1410 : {
1411 2 : (yyval.sval) = (yyvsp[0].sval);
1412 0 : }
1413 :
1414 2 : break;
1415 :
1416 0 : case 15:
1417 :
1418 0 : {
1419 0 : (yyval.sval) = (yyvsp[-1].sval);
1420 0 : }
1421 :
1422 0 : break;
1423 0 :
1424 2 : case 16:
1425 :
1426 0 : {
1427 2 : (yyval.sval) = map_expr((yyvsp[-5].attr_map), '~', (yyvsp[-3].sval), (yyvsp[-1].sval));
1428 2 : if ((yyval.sval) == NULL) YYABORT;
1429 : }
1430 0 :
1431 0 : break;
1432 :
1433 65 : case 17:
1434 :
1435 0 : {
1436 130 : (yyval.attr_map) = es_map_sl_attr(global_es_parser_state->frame,
1437 65 : global_es_parser_state->kmd_map,
1438 0 : (yyvsp[0].sval));
1439 65 : if ((yyval.attr_map) == NULL) YYABORT;
1440 0 : }
1441 :
1442 22 : break;
1443 :
1444 62 : case 18:
1445 :
1446 0 : {
1447 62 : (yyval.sval) = (yyvsp[0].sval);
1448 0 : }
1449 :
1450 62 : break;
1451 :
1452 1 : case 19:
1453 :
1454 : {
1455 1 : (yyval.sval) = (yyvsp[0].sval);
1456 : }
1457 :
1458 1 : break;
1459 :
1460 1 : case 20:
1461 :
1462 0 : {
1463 1 : (yyval.sval) = isodate_to_sldate((yyvsp[-1].sval));
1464 1 : if ((yyval.sval) == NULL) YYABORT;
1465 0 : }
1466 :
1467 0 : break;
1468 :
1469 0 :
1470 :
1471 12 : default: break;
1472 0 : }
1473 : /* User semantic actions sometimes alter yychar, and that requires
1474 0 : that yytoken be updated with the new translation. We take the
1475 : approach of translating immediately before every use of yytoken.
1476 0 : One alternative is translating here after every semantic action,
1477 : but that translation would be missed if the semantic action invokes
1478 0 : YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
1479 0 : if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an
1480 : incorrect destructor might then be invoked immediately. In the
1481 0 : case of YYERROR or YYBACKUP, subsequent parser actions might lead
1482 : to an incorrect destructor call or verbose syntax error message
1483 0 : before the lookahead is translated. */
1484 : YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
1485 0 :
1486 420 : YYPOPSTACK (yylen);
1487 420 : yylen = 0;
1488 0 : YY_STACK_PRINT (yyss, yyssp);
1489 :
1490 420 : *++yyvsp = yyval;
1491 :
1492 0 : /* Now 'shift' the result of the reduction. Determine what state
1493 : that goes to, based on the state we popped back to and the rule
1494 0 : number reduced by. */
1495 :
1496 420 : yyn = yyr1[yyn];
1497 :
1498 420 : yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
1499 420 : if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
1500 27 : yystate = yytable[yystate];
1501 : else
1502 393 : yystate = yydefgoto[yyn - YYNTOKENS];
1503 :
1504 122 : goto yynewstate;
1505 0 :
1506 :
1507 0 : /*--------------------------------------.
1508 : | yyerrlab -- here on detecting error. |
1509 0 : `--------------------------------------*/
1510 0 : yyerrlab:
1511 0 : /* Make sure we have latest lookahead translation. See comments at
1512 0 : user semantic actions for why this is necessary. */
1513 0 : yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
1514 0 :
1515 : /* If not already recovering from an error, report this error. */
1516 0 : if (!yyerrstatus)
1517 : {
1518 0 : ++yynerrs;
1519 : #if ! YYERROR_VERBOSE
1520 0 : yyerror (YY_("syntax error"));
1521 : #else
1522 0 : # define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
1523 : yyssp, yytoken)
1524 0 : {
1525 0 : char const *yymsgp = YY_("syntax error");
1526 0 : int yysyntax_error_status;
1527 0 : yysyntax_error_status = YYSYNTAX_ERROR;
1528 0 : if (yysyntax_error_status == 0)
1529 0 : yymsgp = yymsg;
1530 0 : else if (yysyntax_error_status == 1)
1531 : {
1532 0 : if (yymsg != yymsgbuf)
1533 0 : YYSTACK_FREE (yymsg);
1534 0 : yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
1535 0 : if (!yymsg)
1536 : {
1537 0 : yymsg = yymsgbuf;
1538 0 : yymsg_alloc = sizeof yymsgbuf;
1539 0 : yysyntax_error_status = 2;
1540 : }
1541 : else
1542 : {
1543 0 : yysyntax_error_status = YYSYNTAX_ERROR;
1544 0 : yymsgp = yymsg;
1545 : }
1546 : }
1547 0 : yyerror (yymsgp);
1548 0 : if (yysyntax_error_status == 2)
1549 0 : goto yyexhaustedlab;
1550 : }
1551 : # undef YYSYNTAX_ERROR
1552 : #endif
1553 : }
1554 0 :
1555 0 :
1556 :
1557 0 : if (yyerrstatus == 3)
1558 : {
1559 : /* If just tried and failed to reuse lookahead token after an
1560 : error, discard it. */
1561 :
1562 0 : if (yychar <= YYEOF)
1563 0 : {
1564 0 : /* Return failure if at end of input. */
1565 0 : if (yychar == YYEOF)
1566 0 : YYABORT;
1567 0 : }
1568 : else
1569 : {
1570 0 : yydestruct ("Error: discarding",
1571 : yytoken, &yylval);
1572 0 : yychar = YYEMPTY;
1573 : }
1574 : }
1575 :
1576 0 : /* Else will try to reuse lookahead token after shifting the error
1577 : token. */
1578 0 : goto yyerrlab1;
1579 0 :
1580 :
1581 0 : /*---------------------------------------------------.
1582 : | yyerrorlab -- error raised explicitly by YYERROR. |
1583 0 : `---------------------------------------------------*/
1584 : yyerrorlab:
1585 0 :
1586 : /* Pacify compilers like GCC when the user code never invokes
1587 0 : YYERROR and the label yyerrorlab therefore never appears in user
1588 : code. */
1589 0 : if (/*CONSTCOND*/ 0)
1590 0 : goto yyerrorlab;
1591 0 :
1592 0 : /* Do not reclaim the symbols of the rule whose action triggered
1593 : this YYERROR. */
1594 0 : YYPOPSTACK (yylen);
1595 0 : yylen = 0;
1596 0 : YY_STACK_PRINT (yyss, yyssp);
1597 : yystate = *yyssp;
1598 0 : goto yyerrlab1;
1599 :
1600 :
1601 0 : /*-------------------------------------------------------------.
1602 0 : | yyerrlab1 -- common code for both syntax error and YYERROR. |
1603 : `-------------------------------------------------------------*/
1604 0 : yyerrlab1:
1605 0 : yyerrstatus = 3; /* Each real token shifted decrements this. */
1606 0 :
1607 0 : for (;;)
1608 0 : {
1609 0 : yyn = yypact[yystate];
1610 0 : if (!yypact_value_is_default (yyn))
1611 0 : {
1612 0 : yyn += YYTERROR;
1613 0 : if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
1614 : {
1615 0 : yyn = yytable[yyn];
1616 0 : if (0 < yyn)
1617 0 : break;
1618 : }
1619 : }
1620 :
1621 : /* Pop the current state because it cannot handle the error token. */
1622 0 : if (yyssp == yyss)
1623 0 : YYABORT;
1624 :
1625 0 :
1626 0 : yydestruct ("Error: popping",
1627 0 : yystos[yystate], yyvsp);
1628 0 : YYPOPSTACK (1);
1629 0 : yystate = *yyssp;
1630 0 : YY_STACK_PRINT (yyss, yyssp);
1631 : }
1632 0 :
1633 : YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
1634 0 : *++yyvsp = yylval;
1635 : YY_IGNORE_MAYBE_UNINITIALIZED_END
1636 :
1637 :
1638 0 : /* Shift the error token. */
1639 : YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
1640 :
1641 0 : yystate = yyn;
1642 0 : goto yynewstate;
1643 :
1644 :
1645 : /*-------------------------------------.
1646 : | yyacceptlab -- YYACCEPT comes here. |
1647 : `-------------------------------------*/
1648 88 : yyacceptlab:
1649 6 : yyresult = 0;
1650 6 : goto yyreturn;
1651 :
1652 : /*-----------------------------------.
1653 : | yyabortlab -- YYABORT comes here. |
1654 : `-----------------------------------*/
1655 0 : yyabortlab:
1656 0 : yyresult = 1;
1657 0 : goto yyreturn;
1658 :
1659 : #if !defined yyoverflow || YYERROR_VERBOSE
1660 : /*-------------------------------------------------.
1661 : | yyexhaustedlab -- memory exhaustion comes here. |
1662 0 : `-------------------------------------------------*/
1663 0 : yyexhaustedlab:
1664 0 : yyerror (YY_("memory exhausted"));
1665 0 : yyresult = 2;
1666 : /* Fall through. */
1667 : #endif
1668 0 :
1669 47 : yyreturn:
1670 6 : if (yychar != YYEMPTY)
1671 0 : {
1672 0 : /* Make sure we have latest lookahead translation. See comments at
1673 : user semantic actions for why this is necessary. */
1674 0 : yytoken = YYTRANSLATE (yychar);
1675 0 : yydestruct ("Cleanup: discarding lookahead",
1676 0 : yytoken, &yylval);
1677 : }
1678 : /* Do not reclaim the symbols of the rule whose action triggered
1679 : this YYABORT or YYACCEPT. */
1680 47 : YYPOPSTACK (yylen);
1681 0 : YY_STACK_PRINT (yyss, yyssp);
1682 24 : while (yyssp != yyss)
1683 : {
1684 12 : yydestruct ("Cleanup: popping",
1685 12 : yystos[*yyssp], yyvsp);
1686 12 : YYPOPSTACK (1);
1687 0 : }
1688 0 : #ifndef yyoverflow
1689 47 : if (yyss != yyssa)
1690 0 : YYSTACK_FREE (yyss);
1691 : #endif
1692 : #if YYERROR_VERBOSE
1693 47 : if (yymsg != yymsgbuf)
1694 0 : YYSTACK_FREE (yymsg);
1695 : #endif
1696 47 : return yyresult;
1697 : }
1698 :
1699 :
1700 0 :
1701 0 : /*
1702 : * Spotlight has two date formats:
1703 : * - seconds since 2001-01-01 00:00:00Z
1704 : * - as string "$time.iso(%Y-%m-%dT%H:%M:%SZ)"
1705 : * This function converts the latter to the former as string, so the parser
1706 : * can work on a uniform format.
1707 0 : */
1708 1 : static char *isodate_to_sldate(const char *isodate)
1709 0 : {
1710 1 : struct es_parser_state *s = global_es_parser_state;
1711 : struct tm tm;
1712 1 : const char *p = NULL;
1713 1 : char *tstr = NULL;
1714 : time_t t;
1715 0 :
1716 1 : p = strptime(isodate, "%Y-%m-%dT%H:%M:%SZ", &tm);
1717 1 : if (p == NULL) {
1718 0 : DBG_ERR("strptime [%s] failed\n", isodate);
1719 0 : return NULL;
1720 : }
1721 :
1722 1 : t = timegm(&tm);
1723 1 : t -= SP_RAW_TIME_OFFSET;
1724 0 :
1725 1 : tstr = talloc_asprintf(s->frame, "%jd", (intmax_t)t);
1726 1 : if (tstr == NULL) {
1727 0 : return NULL;
1728 : }
1729 :
1730 1 : return tstr;
1731 : }
1732 :
1733 4 : static char *map_type(const struct es_attr_map *attr,
1734 0 : char op,
1735 0 : const char *val)
1736 : {
1737 4 : struct es_parser_state *s = global_es_parser_state;
1738 4 : const char *mime_type_list = NULL;
1739 4 : char *esc_mime_type_list = NULL;
1740 4 : const char *not = NULL;
1741 4 : const char *end = NULL;
1742 4 : char *es = NULL;
1743 :
1744 4 : mime_type_list = es_map_sl_type(s->mime_map, val);
1745 4 : if (mime_type_list == NULL) {
1746 0 : DBG_ERR("Mapping type [%s] failed\n", val);
1747 0 : return NULL;
1748 : }
1749 0 :
1750 4 : esc_mime_type_list = es_escape_str(s->frame,
1751 0 : mime_type_list,
1752 : "* ");
1753 4 : if (esc_mime_type_list == NULL) {
1754 0 : return NULL;
1755 0 : }
1756 :
1757 4 : switch (op) {
1758 0 : case '=':
1759 0 : not = "";
1760 0 : end = "";
1761 0 : break;
1762 0 : case '!':
1763 0 : not = "(NOT ";
1764 0 : end = ")";
1765 0 : break;
1766 0 : default:
1767 0 : DBG_ERR("Mapping type [%s] unexpected op [%c]\n", val, op);
1768 0 : return NULL;
1769 : }
1770 4 : es = talloc_asprintf(s->frame,
1771 0 : "%s%s:(%s)%s",
1772 : not,
1773 0 : attr->name,
1774 : esc_mime_type_list,
1775 0 : end);
1776 4 : if (es == NULL) {
1777 0 : return NULL;
1778 : }
1779 0 :
1780 4 : return es;
1781 0 : }
1782 0 :
1783 12 : static char *map_num(const struct es_attr_map *attr,
1784 : char op,
1785 0 : const char *val1,
1786 0 : const char *val2)
1787 : {
1788 12 : struct es_parser_state *s = global_es_parser_state;
1789 12 : char *es = NULL;
1790 0 :
1791 12 : switch (op) {
1792 1 : case '>':
1793 1 : es = talloc_asprintf(s->frame,
1794 : "%s:{%s TO *}",
1795 : attr->name,
1796 0 : val1);
1797 1 : break;
1798 1 : case '<':
1799 1 : es = talloc_asprintf(s->frame,
1800 0 : "%s:{* TO %s}",
1801 0 : attr->name,
1802 0 : val1);
1803 1 : break;
1804 1 : case '~':
1805 1 : es = talloc_asprintf(s->frame,
1806 : "%s:[%s TO %s]",
1807 0 : attr->name,
1808 0 : val1,
1809 0 : val2);
1810 1 : break;
1811 8 : case '=':
1812 8 : es = talloc_asprintf(s->frame,
1813 0 : "%s:%s",
1814 : attr->name,
1815 : val1);
1816 8 : break;
1817 1 : case '!':
1818 1 : es = talloc_asprintf(s->frame,
1819 : "(NOT %s:%s)",
1820 0 : attr->name,
1821 0 : val1);
1822 1 : break;
1823 0 : default:
1824 0 : DBG_ERR("Mapping num unexpected op [%c]\n", op);
1825 0 : return NULL;
1826 0 : }
1827 12 : if (es == NULL) {
1828 0 : return NULL;
1829 0 : }
1830 0 :
1831 12 : return es;
1832 : }
1833 0 :
1834 6 : static char *map_fts(const struct es_attr_map *attr,
1835 : char op,
1836 0 : const char *val)
1837 : {
1838 6 : struct es_parser_state *s = global_es_parser_state;
1839 6 : const char *not = NULL;
1840 6 : const char *end = NULL;
1841 6 : char *esval = NULL;
1842 6 : char *es = NULL;
1843 0 :
1844 6 : esval = es_escape_str(s->frame, val, "*\\\"");
1845 6 : if (esval == NULL) {
1846 0 : yyerror("es_escape_str failed");
1847 0 : return NULL;
1848 : }
1849 :
1850 6 : switch (op) {
1851 4 : case '=':
1852 4 : not = "";
1853 4 : end = "";
1854 4 : break;
1855 1 : case '!':
1856 1 : not = "(NOT ";
1857 1 : end = ")";
1858 1 : break;
1859 0 : default:
1860 0 : DBG_ERR("Mapping fts [%s] unexpected op [%c]\n", val, op);
1861 0 : return NULL;
1862 0 : }
1863 6 : es = talloc_asprintf(s->frame,
1864 0 : "%s%s%s",
1865 : not,
1866 0 : esval,
1867 0 : end);
1868 6 : if (es == NULL) {
1869 0 : return NULL;
1870 0 : }
1871 6 : return es;
1872 : }
1873 0 :
1874 33 : static char *map_str(const struct es_attr_map *attr,
1875 0 : char op,
1876 : const char *val)
1877 0 : {
1878 33 : struct es_parser_state *s = global_es_parser_state;
1879 33 : char *esval = NULL;
1880 33 : char *es = NULL;
1881 33 : const char *not = NULL;
1882 33 : const char *end = NULL;
1883 0 :
1884 33 : esval = es_escape_str(s->frame, val, "*\\\"");
1885 33 : if (esval == NULL) {
1886 0 : yyerror("es_escape_str failed");
1887 0 : return NULL;
1888 0 : }
1889 :
1890 33 : switch (op) {
1891 18 : case '=':
1892 18 : not = "";
1893 18 : end = "";
1894 18 : break;
1895 0 : case '!':
1896 0 : not = "(NOT ";
1897 0 : end = ")";
1898 0 : break;
1899 0 : default:
1900 0 : DBG_ERR("Mapping string [%s] unexpected op [%c]\n", val, op);
1901 0 : return NULL;
1902 0 : }
1903 0 :
1904 33 : es = talloc_asprintf(s->frame,
1905 0 : "%s%s:%s%s",
1906 : not,
1907 0 : attr->name,
1908 0 : esval,
1909 0 : end);
1910 33 : if (es == NULL) {
1911 0 : return NULL;
1912 : }
1913 33 : return es;
1914 0 : }
1915 0 :
1916 0 : /*
1917 0 : * Convert Spotlight date seconds since 2001-01-01 00:00:00Z
1918 0 : * to a date string in the format %Y-%m-%dT%H:%M:%SZ.
1919 0 : */
1920 11 : static char *map_sldate_to_esdate(TALLOC_CTX *mem_ctx,
1921 0 : const char *sldate)
1922 0 : {
1923 11 : struct tm *tm = NULL;
1924 11 : char *esdate = NULL;
1925 : char buf[21];
1926 0 : size_t len;
1927 : time_t t;
1928 : int error;
1929 :
1930 11 : t = (time_t)smb_strtoull(sldate, NULL, 10, &error, SMB_STR_STANDARD);
1931 11 : if (error != 0) {
1932 0 : DBG_ERR("smb_strtoull [%s] failed\n", sldate);
1933 0 : return NULL;
1934 0 : }
1935 11 : t += SP_RAW_TIME_OFFSET;
1936 :
1937 11 : tm = gmtime(&t);
1938 11 : if (tm == NULL) {
1939 0 : DBG_ERR("localtime [%s] failed\n", sldate);
1940 0 : return NULL;
1941 0 : }
1942 0 :
1943 11 : len = strftime(buf, sizeof(buf),
1944 0 : "%Y-%m-%dT%H:%M:%SZ", tm);
1945 11 : if (len != 20) {
1946 0 : DBG_ERR("strftime [%s] failed\n", sldate);
1947 0 : return NULL;
1948 0 : }
1949 0 :
1950 11 : esdate = es_escape_str(mem_ctx, buf, NULL);
1951 11 : if (esdate == NULL) {
1952 0 : yyerror("es_escape_str failed");
1953 0 : return NULL;
1954 0 : }
1955 0 : return esdate;
1956 0 : }
1957 0 :
1958 10 : static char *map_date(const struct es_attr_map *attr,
1959 0 : char op,
1960 0 : const char *sldate1,
1961 0 : const char *sldate2)
1962 0 : {
1963 10 : struct es_parser_state *s = global_es_parser_state;
1964 10 : char *esdate1 = NULL;
1965 10 : char *esdate2 = NULL;
1966 10 : char *es = NULL;
1967 0 :
1968 10 : if (op == '~' && sldate2 == NULL) {
1969 0 : DBG_ERR("Date range query, but second date is NULL\n");
1970 0 : return NULL;
1971 : }
1972 :
1973 10 : esdate1 = map_sldate_to_esdate(s->frame, sldate1);
1974 10 : if (esdate1 == NULL) {
1975 0 : DBG_ERR("map_sldate_to_esdate [%s] failed\n", sldate1);
1976 0 : return NULL;
1977 : }
1978 10 : if (sldate2 != NULL) {
1979 1 : esdate2 = map_sldate_to_esdate(s->frame, sldate2);
1980 1 : if (esdate2 == NULL) {
1981 0 : DBG_ERR("map_sldate_to_esdate [%s] failed\n", sldate2);
1982 0 : return NULL;
1983 0 : }
1984 : }
1985 :
1986 10 : switch (op) {
1987 1 : case '>':
1988 1 : es = talloc_asprintf(s->frame,
1989 : "%s:{%s TO *}",
1990 : attr->name,
1991 : esdate1);
1992 1 : break;
1993 1 : case '<':
1994 1 : es = talloc_asprintf(s->frame,
1995 0 : "%s:{* TO %s}",
1996 0 : attr->name,
1997 : esdate1);
1998 1 : break;
1999 1 : case '~':
2000 1 : es = talloc_asprintf(s->frame,
2001 0 : "%s:[%s TO %s]",
2002 0 : attr->name,
2003 0 : esdate1,
2004 : esdate2);
2005 1 : break;
2006 6 : case '=':
2007 6 : es = talloc_asprintf(s->frame,
2008 0 : "%s:%s",
2009 0 : attr->name,
2010 0 : esdate1);
2011 6 : break;
2012 1 : case '!':
2013 1 : es = talloc_asprintf(s->frame,
2014 0 : "(NOT %s:%s)",
2015 0 : attr->name,
2016 0 : esdate1);
2017 1 : break;
2018 0 : }
2019 10 : if (es == NULL) {
2020 0 : return NULL;
2021 0 : }
2022 10 : return es;
2023 : }
2024 :
2025 65 : static char *map_expr(const struct es_attr_map *attr,
2026 0 : char op,
2027 0 : const char *val1,
2028 0 : const char *val2)
2029 0 : {
2030 65 : char *es = NULL;
2031 0 :
2032 65 : switch (attr->type) {
2033 4 : case ssmt_type:
2034 4 : es = map_type(attr, op, val1);
2035 4 : break;
2036 12 : case ssmt_num:
2037 12 : es = map_num(attr, op, val1, val2);
2038 12 : break;
2039 6 : case ssmt_fts:
2040 6 : es = map_fts(attr, op, val1);
2041 6 : break;
2042 33 : case ssmt_str:
2043 33 : es = map_str(attr, op, val1);
2044 33 : break;
2045 10 : case ssmt_date:
2046 10 : es = map_date(attr, op, val1, val2);
2047 10 : break;
2048 0 : default:
2049 0 : break;
2050 0 : }
2051 65 : if (es == NULL) {
2052 0 : DBG_ERR("Mapping [%s %c %s (%s)] failed\n",
2053 0 : attr->name, op, val1, val2 ? val2 : "");
2054 0 : return NULL;
2055 0 : }
2056 0 :
2057 22 : return es;
2058 : }
2059 0 :
2060 0 : void mdsyylerror(const char *str)
2061 0 : {
2062 0 : DBG_ERR("Parser failed: %s\n", str);
2063 0 : }
2064 :
2065 47 : int mdsyylwrap(void)
2066 : {
2067 47 : return 1;
2068 0 : }
2069 0 :
2070 0 : /**
2071 : * Map a Spotlight RAW query string to a ES query string
2072 0 : **/
2073 47 : bool map_spotlight_to_es_query(TALLOC_CTX *mem_ctx,
2074 0 : json_t *mappings,
2075 0 : const char *path_scope,
2076 0 : const char *query_string,
2077 : char **_es_query)
2078 0 : {
2079 94 : struct es_parser_state s = {
2080 47 : .frame = talloc_stackframe(),
2081 : };
2082 0 : int result;
2083 47 : char *es_query = NULL;
2084 :
2085 47 : s.kmd_map = json_object_get(mappings, "attribute_mappings");
2086 47 : if (s.kmd_map == NULL) {
2087 0 : DBG_ERR("Failed to load attribute_mappings from JSON\n");
2088 0 : return false;
2089 : }
2090 47 : s.mime_map = json_object_get(mappings, "mime_mappings");
2091 47 : if (s.mime_map == NULL) {
2092 0 : DBG_ERR("Failed to load mime_mappings from JSON\n");
2093 0 : return false;
2094 : }
2095 0 :
2096 47 : s.s = mdsyyl_scan_string(query_string);
2097 47 : if (s.s == NULL) {
2098 0 : DBG_WARNING("Failed to parse [%s]\n", query_string);
2099 0 : TALLOC_FREE(s.frame);
2100 0 : return false;
2101 0 : }
2102 47 : global_es_parser_state = &s;
2103 47 : result = mdsyylparse();
2104 47 : global_es_parser_state = NULL;
2105 47 : mdsyyl_delete_buffer(s.s);
2106 0 :
2107 47 : if (result != 0) {
2108 0 : TALLOC_FREE(s.frame);
2109 0 : return false;
2110 0 : }
2111 0 :
2112 47 : es_query = talloc_asprintf(mem_ctx,
2113 : "(%s) AND path.real.fulltext:\\\"%s\\\"",
2114 0 : s.result, path_scope);
2115 47 : TALLOC_FREE(s.frame);
2116 47 : if (es_query == NULL) {
2117 0 : return false;
2118 : }
2119 :
2120 47 : *_es_query = es_query;
2121 47 : return true;
2122 : }
|