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