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
63
64 /* Copy the first part of user declarations. */
65 #line 17 "msgset.y" /* yacc.c:339 */
66
67 #include "mail.h"
68
69 #include <stdio.h>
70 #include <stdlib.h>
71
72 /* Defined in <limits.h> on some systems, but redefined in <regex.h>
73 if we are using GNU's regex. So, undef it to avoid duplicate definition
74 warnings. */
75
76 #ifdef RE_DUP_MAX
77 # undef RE_DUP_MAX
78 #endif
79 #include <regex.h>
80
81 struct header_data
82 {
83 char *header;
84 char *expr;
85 };
86
87 static msgset_t *msgset_select (int (*sel) (mu_message_t, void *),
88 void *closure, int rev,
89 unsigned int max_matches);
90 static int select_header (mu_message_t msg, void *closure);
91 static int select_body (mu_message_t msg, void *closure);
92 static int select_sender (mu_message_t msg, void *closure);
93 static int select_deleted (mu_message_t msg, void *closure);
94 static int check_set (msgset_t **pset);
95
96 int yyerror (const char *);
97 int yylex (void);
98
99 static int msgset_flags = MSG_NODELETED;
100 static size_t message_count;
101 static msgset_t *result;
102 static mu_opool_t tokpool;
103
104 typedef int (*message_selector_t) (mu_message_t, void *);
105 static message_selector_t find_type_selector (int type);
106
107 #line 108 "msgset.c" /* yacc.c:339 */
108
109 # ifndef YY_NULLPTR
110 # if defined __cplusplus && 201103L <= __cplusplus
111 # define YY_NULLPTR nullptr
112 # else
113 # define YY_NULLPTR 0
114 # endif
115 # endif
116
117 /* Enabling verbose error messages. */
118 #ifdef YYERROR_VERBOSE
119 # undef YYERROR_VERBOSE
120 # define YYERROR_VERBOSE 1
121 #else
122 # define YYERROR_VERBOSE 0
123 #endif
124
125
126 /* Debug traces. */
127 #ifndef YYDEBUG
128 # define YYDEBUG 1
129 #endif
130 #if YYDEBUG
131 extern int yydebug;
132 #endif
133
134 /* Token type. */
135 #ifndef YYTOKENTYPE
136 # define YYTOKENTYPE
137 enum yytokentype
138 {
139 TYPE = 258,
140 IDENT = 259,
141 REGEXP = 260,
142 HEADER = 261,
143 BODY = 262,
144 NUMBER = 263
145 };
146 #endif
147 /* Tokens. */
148 #define TYPE 258
149 #define IDENT 259
150 #define REGEXP 260
151 #define HEADER 261
152 #define BODY 262
153 #define NUMBER 263
154
155 /* Value type. */
156 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
157
158 union YYSTYPE
159 {
160 #line 59 "msgset.y" /* yacc.c:355 */
161
162 char *string;
163 int number;
164 int type;
165 msgset_t *mset;
166
167 #line 168 "msgset.c" /* yacc.c:355 */
168 };
169
170 typedef union YYSTYPE YYSTYPE;
171 # define YYSTYPE_IS_TRIVIAL 1
172 # define YYSTYPE_IS_DECLARED 1
173 #endif
174
175
176 extern YYSTYPE yylval;
177
178 int yyparse (void);
179
180
181
182 /* Copy the second part of user declarations. */
183
184 #line 185 "msgset.c" /* yacc.c:358 */
185
186 #ifdef short
187 # undef short
188 #endif
189
190 #ifdef YYTYPE_UINT8
191 typedef YYTYPE_UINT8 yytype_uint8;
192 #else
193 typedef unsigned char yytype_uint8;
194 #endif
195
196 #ifdef YYTYPE_INT8
197 typedef YYTYPE_INT8 yytype_int8;
198 #else
199 typedef signed char yytype_int8;
200 #endif
201
202 #ifdef YYTYPE_UINT16
203 typedef YYTYPE_UINT16 yytype_uint16;
204 #else
205 typedef unsigned short int yytype_uint16;
206 #endif
207
208 #ifdef YYTYPE_INT16
209 typedef YYTYPE_INT16 yytype_int16;
210 #else
211 typedef short int yytype_int16;
212 #endif
213
214 #ifndef YYSIZE_T
215 # ifdef __SIZE_TYPE__
216 # define YYSIZE_T __SIZE_TYPE__
217 # elif defined size_t
218 # define YYSIZE_T size_t
219 # elif ! defined YYSIZE_T
220 # include <stddef.h> /* INFRINGES ON USER NAME SPACE */
221 # define YYSIZE_T size_t
222 # else
223 # define YYSIZE_T unsigned int
224 # endif
225 #endif
226
227 #define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
228
229 #ifndef YY_
230 # if defined YYENABLE_NLS && YYENABLE_NLS
231 # if ENABLE_NLS
232 # include <libintl.h> /* INFRINGES ON USER NAME SPACE */
233 # define YY_(Msgid) dgettext ("bison-runtime", Msgid)
234 # endif
235 # endif
236 # ifndef YY_
237 # define YY_(Msgid) Msgid
238 # endif
239 #endif
240
241 #ifndef YY_ATTRIBUTE
242 # if (defined __GNUC__ \
243 && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \
244 || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C
245 # define YY_ATTRIBUTE(Spec) __attribute__(Spec)
246 # else
247 # define YY_ATTRIBUTE(Spec) /* empty */
248 # endif
249 #endif
250
251 #ifndef YY_ATTRIBUTE_PURE
252 # define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__))
253 #endif
254
255 #ifndef YY_ATTRIBUTE_UNUSED
256 # define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__))
257 #endif
258
259 #if !defined _Noreturn \
260 && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112)
261 # if defined _MSC_VER && 1200 <= _MSC_VER
262 # define _Noreturn __declspec (noreturn)
263 # else
264 # define _Noreturn YY_ATTRIBUTE ((__noreturn__))
265 # endif
266 #endif
267
268 /* Suppress unused-variable warnings by "using" E. */
269 #if ! defined lint || defined __GNUC__
270 # define YYUSE(E) ((void) (E))
271 #else
272 # define YYUSE(E) /* empty */
273 #endif
274
275 #if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
276 /* Suppress an incorrect diagnostic about yylval being uninitialized. */
277 # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
278 _Pragma ("GCC diagnostic push") \
279 _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\
280 _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
281 # define YY_IGNORE_MAYBE_UNINITIALIZED_END \
282 _Pragma ("GCC diagnostic pop")
283 #else
284 # define YY_INITIAL_VALUE(Value) Value
285 #endif
286 #ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
287 # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
288 # define YY_IGNORE_MAYBE_UNINITIALIZED_END
289 #endif
290 #ifndef YY_INITIAL_VALUE
291 # define YY_INITIAL_VALUE(Value) /* Nothing. */
292 #endif
293
294
295 #if ! defined yyoverflow || YYERROR_VERBOSE
296
297 /* The parser invokes alloca or malloc; define the necessary symbols. */
298
299 # ifdef YYSTACK_USE_ALLOCA
300 # if YYSTACK_USE_ALLOCA
301 # ifdef __GNUC__
302 # define YYSTACK_ALLOC __builtin_alloca
303 # elif defined __BUILTIN_VA_ARG_INCR
304 # include <alloca.h> /* INFRINGES ON USER NAME SPACE */
305 # elif defined _AIX
306 # define YYSTACK_ALLOC __alloca
307 # elif defined _MSC_VER
308 # include <malloc.h> /* INFRINGES ON USER NAME SPACE */
309 # define alloca _alloca
310 # else
311 # define YYSTACK_ALLOC alloca
312 # if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS
313 # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
314 /* Use EXIT_SUCCESS as a witness for stdlib.h. */
315 # ifndef EXIT_SUCCESS
316 # define EXIT_SUCCESS 0
317 # endif
318 # endif
319 # endif
320 # endif
321 # endif
322
323 # ifdef YYSTACK_ALLOC
324 /* Pacify GCC's 'empty if-body' warning. */
325 # define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
326 # ifndef YYSTACK_ALLOC_MAXIMUM
327 /* The OS might guarantee only one guard page at the bottom of the stack,
328 and a page size can be as small as 4096 bytes. So we cannot safely
329 invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
330 to allow for a few compiler-allocated temporary stack slots. */
331 # define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
332 # endif
333 # else
334 # define YYSTACK_ALLOC YYMALLOC
335 # define YYSTACK_FREE YYFREE
336 # ifndef YYSTACK_ALLOC_MAXIMUM
337 # define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
338 # endif
339 # if (defined __cplusplus && ! defined EXIT_SUCCESS \
340 && ! ((defined YYMALLOC || defined malloc) \
341 && (defined YYFREE || defined free)))
342 # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
343 # ifndef EXIT_SUCCESS
344 # define EXIT_SUCCESS 0
345 # endif
346 # endif
347 # ifndef YYMALLOC
348 # define YYMALLOC malloc
349 # if ! defined malloc && ! defined EXIT_SUCCESS
350 void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
351 # endif
352 # endif
353 # ifndef YYFREE
354 # define YYFREE free
355 # if ! defined free && ! defined EXIT_SUCCESS
356 void free (void *); /* INFRINGES ON USER NAME SPACE */
357 # endif
358 # endif
359 # endif
360 #endif /* ! defined yyoverflow || YYERROR_VERBOSE */
361
362
363 #if (! defined yyoverflow \
364 && (! defined __cplusplus \
365 || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
366
367 /* A type that is properly aligned for any stack member. */
368 union yyalloc
369 {
370 yytype_int16 yyss_alloc;
371 YYSTYPE yyvs_alloc;
372 };
373
374 /* The size of the maximum gap between one aligned stack and the next. */
375 # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
376
377 /* The size of an array large to enough to hold all stacks, each with
378 N elements. */
379 # define YYSTACK_BYTES(N) \
380 ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
381 + YYSTACK_GAP_MAXIMUM)
382
383 # define YYCOPY_NEEDED 1
384
385 /* Relocate STACK from its old location to the new one. The
386 local variables YYSIZE and YYSTACKSIZE give the old and new number of
387 elements in the stack, and YYPTR gives the new location of the
388 stack. Advance YYPTR to a properly aligned location for the next
389 stack. */
390 # define YYSTACK_RELOCATE(Stack_alloc, Stack) \
391 do \
392 { \
393 YYSIZE_T yynewbytes; \
394 YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \
395 Stack = &yyptr->Stack_alloc; \
396 yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
397 yyptr += yynewbytes / sizeof (*yyptr); \
398 } \
399 while (0)
400
401 #endif
402
403 #if defined YYCOPY_NEEDED && YYCOPY_NEEDED
404 /* Copy COUNT objects from SRC to DST. The source and destination do
405 not overlap. */
406 # ifndef YYCOPY
407 # if defined __GNUC__ && 1 < __GNUC__
408 # define YYCOPY(Dst, Src, Count) \
409 __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src)))
410 # else
411 # define YYCOPY(Dst, Src, Count) \
412 do \
413 { \
414 YYSIZE_T yyi; \
415 for (yyi = 0; yyi < (Count); yyi++) \
416 (Dst)[yyi] = (Src)[yyi]; \
417 } \
418 while (0)
419 # endif
420 # endif
421 #endif /* !YYCOPY_NEEDED */
422
423 /* YYFINAL -- State number of the termination state. */
424 #define YYFINAL 29
425 /* YYLAST -- Last index in YYTABLE. */
426 #define YYLAST 102
427
428 /* YYNTOKENS -- Number of terminals. */
429 #define YYNTOKENS 23
430 /* YYNNTS -- Number of nonterminals. */
431 #define YYNNTS 11
432 /* YYNRULES -- Number of rules. */
433 #define YYNRULES 36
434 /* YYNSTATES -- Number of states. */
435 #define YYNSTATES 52
436
437 /* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
438 by yylex, with out-of-bounds checking. */
439 #define YYUNDEFTOK 2
440 #define YYMAXUTOK 263
441
442 #define YYTRANSLATE(YYX) \
443 ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
444
445 /* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
446 as returned by yylex, without out-of-bounds checking. */
447 static const yytype_uint8 yytranslate[] =
448 {
449 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
450 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
451 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
452 2, 2, 2, 18, 2, 2, 11, 2, 2, 2,
453 21, 22, 12, 14, 15, 13, 9, 2, 2, 2,
454 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
455 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
456 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
457 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
458 2, 19, 2, 20, 10, 2, 2, 2, 2, 2,
459 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
460 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
461 2, 2, 2, 16, 2, 17, 2, 2, 2, 2,
462 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
463 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
464 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
465 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
466 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
467 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
468 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
469 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
470 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
471 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
472 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
473 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
474 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
475 5, 6, 7, 8
476 };
477
478 #if YYDEBUG
479 /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
480 static const yytype_uint16 yyrline[] =
481 {
482 0, 75, 75, 78, 82, 86, 90, 94, 98, 102,
483 108, 109, 113, 119, 125, 129, 135, 136, 142, 148,
484 151, 166, 175, 190, 202, 205, 211, 212, 216, 222,
485 223, 237, 243, 246, 252, 260, 264
486 };
487 #endif
488
489 #if YYDEBUG || YYERROR_VERBOSE || 0
490 /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
491 First, the terminals, then, starting at YYNTOKENS, nonterminals. */
492 static const char *const yytname[] =
493 {
494 "$end", "error", "$undefined", "TYPE", "IDENT", "REGEXP", "HEADER",
495 "BODY", "NUMBER", "'.'", "'^'", "'$'", "'*'", "'-'", "'+'", "','", "'{'",
496 "'}'", "'!'", "'['", "']'", "'('", "')'", "$accept", "input", "msgset",
497 "msgexpr", "msgspec", "msg", "header", "rangeset", "range", "number",
498 "partno", YY_NULLPTR
499 };
500 #endif
501
502 # ifdef YYPRINT
503 /* YYTOKNUM[NUM] -- (External) token number corresponding to the
504 (internal) symbol number NUM (which must be that of a token). */
505 static const yytype_uint16 yytoknum[] =
506 {
507 0, 256, 257, 258, 259, 260, 261, 262, 263, 46,
508 94, 36, 42, 45, 43, 44, 123, 125, 33, 91,
509 93, 40, 41
510 };
511 # endif
512
513 #define YYPACT_NINF -15
514
515 #define yypact_value_is_default(Yystate) \
516 (!!((Yystate) == (-15)))
517
518 #define YYTABLE_NINF -25
519
520 #define yytable_value_is_error(Yytable_value) \
521 0
522
523 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
524 STATE-NUM. */
525 static const yytype_int8 yypact[] =
526 {
527 32, -15, -15, -15, -15, -12, -15, -15, -15, -15,
528 -15, -15, 54, 54, 3, 9, -1, -15, -15, 40,
529 5, -15, -15, 83, 70, 48, -15, 8, -15, -15,
530 54, -15, 3, 3, -15, 3, 3, -15, -15, -15,
531 -15, 3, -15, -15, -15, 69, 66, 69, 68, -15,
532 -15, -15
533 };
534
535 /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
536 Performed when YYTABLE does not specify something else to do. Zero
537 means the default is an error. */
538 static const yytype_uint8 yydefact[] =
539 {
540 2, 22, 23, 25, 21, 35, 3, 5, 6, 7,
541 8, 9, 24, 24, 0, 0, 4, 10, 13, 16,
542 0, 19, 29, 32, 0, 24, 15, 0, 26, 1,
543 24, 12, 0, 0, 20, 0, 0, 35, 31, 30,
544 14, 0, 36, 28, 11, 17, 0, 33, 0, 27,
545 18, 34
546 };
547
548 /* YYPGOTO[NTERM-NUM]. */
549 static const yytype_int8 yypgoto[] =
550 {
551 -15, -15, -4, 55, -15, -15, -15, 61, -14, 1,
552 -15
553 };
554
555 /* YYDEFGOTO[NTERM-NUM]. */
556 static const yytype_int8 yydefgoto[] =
557 {
558 -1, 15, 16, 17, 18, 19, 20, 27, 21, 22,
559 23
560 };
561
562 /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If
563 positive, shift that token. If negative, reduce the rule whose
564 number is the opposite. If YYTABLE_NINF, syntax error. */
565 static const yytype_int8 yytable[] =
566 {
567 28, 24, 1, 2, -24, 3, 4, 5, 25, 29,
568 34, 5, 0, 43, 30, 12, 5, 13, 28, 28,
569 14, 28, 28, 41, 14, 39, 0, 49, 0, 14,
570 42, 43, 43, 43, 43, 1, 2, -24, 3, 4,
571 5, 6, 7, 8, 9, 10, 11, 0, 12, 32,
572 13, 1, 2, 14, 3, 4, 5, 1, 2, 33,
573 3, 4, 5, 30, 12, 40, 13, 0, 26, 14,
574 12, 31, 13, 0, 5, 14, 5, 5, 37, 0,
575 31, 41, 38, 41, 41, 44, 50, 14, 51, 14,
576 14, 14, 35, 45, 46, 0, 47, 48, 0, 0,
577 0, 0, 36
578 };
579
580 static const yytype_int8 yycheck[] =
581 {
582 14, 13, 3, 4, 5, 6, 7, 8, 12, 0,
583 5, 8, -1, 27, 15, 16, 8, 18, 32, 33,
584 21, 35, 36, 15, 21, 24, -1, 41, -1, 21,
585 22, 45, 46, 47, 48, 3, 4, 5, 6, 7,
586 8, 9, 10, 11, 12, 13, 14, -1, 16, 9,
587 18, 3, 4, 21, 6, 7, 8, 3, 4, 19,
588 6, 7, 8, 15, 16, 17, 18, -1, 13, 21,
589 16, 16, 18, -1, 8, 21, 8, 8, 8, -1,
590 25, 15, 12, 15, 15, 30, 20, 21, 20, 21,
591 21, 21, 9, 32, 33, -1, 35, 36, -1, -1,
592 -1, -1, 19
593 };
594
595 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
596 symbol of state STATE-NUM. */
597 static const yytype_uint8 yystos[] =
598 {
599 0, 3, 4, 6, 7, 8, 9, 10, 11, 12,
600 13, 14, 16, 18, 21, 24, 25, 26, 27, 28,
601 29, 31, 32, 33, 13, 25, 26, 30, 31, 0,
602 15, 26, 9, 19, 5, 9, 19, 8, 12, 32,
603 17, 15, 22, 31, 26, 30, 30, 30, 30, 31,
604 20, 20
605 };
606
607 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
608 static const yytype_uint8 yyr1[] =
609 {
610 0, 23, 24, 24, 24, 24, 24, 24, 24, 24,
611 25, 25, 25, 26, 26, 26, 27, 27, 27, 27,
612 28, 28, 28, 28, 29, 29, 30, 30, 30, 31,
613 31, 31, 32, 32, 32, 33, 33
614 };
615
616 /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */
617 static const yytype_uint8 yyr2[] =
618 {
619 0, 2, 0, 1, 1, 1, 1, 1, 1, 1,
620 1, 3, 2, 1, 3, 2, 1, 3, 4, 1,
621 2, 1, 1, 1, 0, 1, 1, 3, 2, 1,
622 3, 3, 1, 3, 4, 1, 3
623 };
624
625
626 #define yyerrok (yyerrstatus = 0)
627 #define yyclearin (yychar = YYEMPTY)
628 #define YYEMPTY (-2)
629 #define YYEOF 0
630
631 #define YYACCEPT goto yyacceptlab
632 #define YYABORT goto yyabortlab
633 #define YYERROR goto yyerrorlab
634
635
636 #define YYRECOVERING() (!!yyerrstatus)
637
638 #define YYBACKUP(Token, Value) \
639 do \
640 if (yychar == YYEMPTY) \
641 { \
642 yychar = (Token); \
643 yylval = (Value); \
644 YYPOPSTACK (yylen); \
645 yystate = *yyssp; \
646 goto yybackup; \
647 } \
648 else \
649 { \
650 yyerror (YY_("syntax error: cannot back up")); \
651 YYERROR; \
652 } \
653 while (0)
654
655 /* Error token number */
656 #define YYTERROR 1
657 #define YYERRCODE 256
658
659
660
661 /* Enable debugging if requested. */
662 #if YYDEBUG
663
664 # ifndef YYFPRINTF
665 # include <stdio.h> /* INFRINGES ON USER NAME SPACE */
666 # define YYFPRINTF fprintf
667 # endif
668
669 # define YYDPRINTF(Args) \
670 do { \
671 if (yydebug) \
672 YYFPRINTF Args; \
673 } while (0)
674
675 /* This macro is provided for backward compatibility. */
676 #ifndef YY_LOCATION_PRINT
677 # define YY_LOCATION_PRINT(File, Loc) ((void) 0)
678 #endif
679
680
681 # define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
682 do { \
683 if (yydebug) \
684 { \
685 YYFPRINTF (stderr, "%s ", Title); \
686 yy_symbol_print (stderr, \
687 Type, Value); \
688 YYFPRINTF (stderr, "\n"); \
689 } \
690 } while (0)
691
692
693 /*----------------------------------------.
694 | Print this symbol's value on YYOUTPUT. |
695 `----------------------------------------*/
696
697 static void
yy_symbol_value_print(FILE * yyoutput,int yytype,YYSTYPE const * const yyvaluep)698 yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
699 {
700 FILE *yyo = yyoutput;
701 YYUSE (yyo);
702 if (!yyvaluep)
703 return;
704 # ifdef YYPRINT
705 if (yytype < YYNTOKENS)
706 YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
707 # endif
708 YYUSE (yytype);
709 }
710
711
712 /*--------------------------------.
713 | Print this symbol on YYOUTPUT. |
714 `--------------------------------*/
715
716 static void
yy_symbol_print(FILE * yyoutput,int yytype,YYSTYPE const * const yyvaluep)717 yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
718 {
719 YYFPRINTF (yyoutput, "%s %s (",
720 yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]);
721
722 yy_symbol_value_print (yyoutput, yytype, yyvaluep);
723 YYFPRINTF (yyoutput, ")");
724 }
725
726 /*------------------------------------------------------------------.
727 | yy_stack_print -- Print the state stack from its BOTTOM up to its |
728 | TOP (included). |
729 `------------------------------------------------------------------*/
730
731 static void
yy_stack_print(yytype_int16 * yybottom,yytype_int16 * yytop)732 yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
733 {
734 YYFPRINTF (stderr, "Stack now");
735 for (; yybottom <= yytop; yybottom++)
736 {
737 int yybot = *yybottom;
738 YYFPRINTF (stderr, " %d", yybot);
739 }
740 YYFPRINTF (stderr, "\n");
741 }
742
743 # define YY_STACK_PRINT(Bottom, Top) \
744 do { \
745 if (yydebug) \
746 yy_stack_print ((Bottom), (Top)); \
747 } while (0)
748
749
750 /*------------------------------------------------.
751 | Report that the YYRULE is going to be reduced. |
752 `------------------------------------------------*/
753
754 static void
yy_reduce_print(yytype_int16 * yyssp,YYSTYPE * yyvsp,int yyrule)755 yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule)
756 {
757 unsigned long int yylno = yyrline[yyrule];
758 int yynrhs = yyr2[yyrule];
759 int yyi;
760 YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
761 yyrule - 1, yylno);
762 /* The symbols being reduced. */
763 for (yyi = 0; yyi < yynrhs; yyi++)
764 {
765 YYFPRINTF (stderr, " $%d = ", yyi + 1);
766 yy_symbol_print (stderr,
767 yystos[yyssp[yyi + 1 - yynrhs]],
768 &(yyvsp[(yyi + 1) - (yynrhs)])
769 );
770 YYFPRINTF (stderr, "\n");
771 }
772 }
773
774 # define YY_REDUCE_PRINT(Rule) \
775 do { \
776 if (yydebug) \
777 yy_reduce_print (yyssp, yyvsp, Rule); \
778 } while (0)
779
780 /* Nonzero means print parse trace. It is left uninitialized so that
781 multiple parsers can coexist. */
782 int yydebug;
783 #else /* !YYDEBUG */
784 # define YYDPRINTF(Args)
785 # define YY_SYMBOL_PRINT(Title, Type, Value, Location)
786 # define YY_STACK_PRINT(Bottom, Top)
787 # define YY_REDUCE_PRINT(Rule)
788 #endif /* !YYDEBUG */
789
790
791 /* YYINITDEPTH -- initial size of the parser's stacks. */
792 #ifndef YYINITDEPTH
793 # define YYINITDEPTH 200
794 #endif
795
796 /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
797 if the built-in stack extension method is used).
798
799 Do not make this value too large; the results are undefined if
800 YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
801 evaluated with infinite-precision integer arithmetic. */
802
803 #ifndef YYMAXDEPTH
804 # define YYMAXDEPTH 10000
805 #endif
806
807
808 #if YYERROR_VERBOSE
809
810 # ifndef yystrlen
811 # if defined __GLIBC__ && defined _STRING_H
812 # define yystrlen strlen
813 # else
814 /* Return the length of YYSTR. */
815 static YYSIZE_T
yystrlen(const char * yystr)816 yystrlen (const char *yystr)
817 {
818 YYSIZE_T yylen;
819 for (yylen = 0; yystr[yylen]; yylen++)
820 continue;
821 return yylen;
822 }
823 # endif
824 # endif
825
826 # ifndef yystpcpy
827 # if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
828 # define yystpcpy stpcpy
829 # else
830 /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
831 YYDEST. */
832 static char *
yystpcpy(char * yydest,const char * yysrc)833 yystpcpy (char *yydest, const char *yysrc)
834 {
835 char *yyd = yydest;
836 const char *yys = yysrc;
837
838 while ((*yyd++ = *yys++) != '\0')
839 continue;
840
841 return yyd - 1;
842 }
843 # endif
844 # endif
845
846 # ifndef yytnamerr
847 /* Copy to YYRES the contents of YYSTR after stripping away unnecessary
848 quotes and backslashes, so that it's suitable for yyerror. The
849 heuristic is that double-quoting is unnecessary unless the string
850 contains an apostrophe, a comma, or backslash (other than
851 backslash-backslash). YYSTR is taken from yytname. If YYRES is
852 null, do not copy; instead, return the length of what the result
853 would have been. */
854 static YYSIZE_T
yytnamerr(char * yyres,const char * yystr)855 yytnamerr (char *yyres, const char *yystr)
856 {
857 if (*yystr == '"')
858 {
859 YYSIZE_T yyn = 0;
860 char const *yyp = yystr;
861
862 for (;;)
863 switch (*++yyp)
864 {
865 case '\'':
866 case ',':
867 goto do_not_strip_quotes;
868
869 case '\\':
870 if (*++yyp != '\\')
871 goto do_not_strip_quotes;
872 /* Fall through. */
873 default:
874 if (yyres)
875 yyres[yyn] = *yyp;
876 yyn++;
877 break;
878
879 case '"':
880 if (yyres)
881 yyres[yyn] = '\0';
882 return yyn;
883 }
884 do_not_strip_quotes: ;
885 }
886
887 if (! yyres)
888 return yystrlen (yystr);
889
890 return yystpcpy (yyres, yystr) - yyres;
891 }
892 # endif
893
894 /* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
895 about the unexpected token YYTOKEN for the state stack whose top is
896 YYSSP.
897
898 Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is
899 not large enough to hold the message. In that case, also set
900 *YYMSG_ALLOC to the required number of bytes. Return 2 if the
901 required number of bytes is too large to store. */
902 static int
yysyntax_error(YYSIZE_T * yymsg_alloc,char ** yymsg,yytype_int16 * yyssp,int yytoken)903 yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
904 yytype_int16 *yyssp, int yytoken)
905 {
906 YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]);
907 YYSIZE_T yysize = yysize0;
908 enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
909 /* Internationalized format string. */
910 const char *yyformat = YY_NULLPTR;
911 /* Arguments of yyformat. */
912 char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
913 /* Number of reported tokens (one for the "unexpected", one per
914 "expected"). */
915 int yycount = 0;
916
917 /* There are many possibilities here to consider:
918 - If this state is a consistent state with a default action, then
919 the only way this function was invoked is if the default action
920 is an error action. In that case, don't check for expected
921 tokens because there are none.
922 - The only way there can be no lookahead present (in yychar) is if
923 this state is a consistent state with a default action. Thus,
924 detecting the absence of a lookahead is sufficient to determine
925 that there is no unexpected or expected token to report. In that
926 case, just report a simple "syntax error".
927 - Don't assume there isn't a lookahead just because this state is a
928 consistent state with a default action. There might have been a
929 previous inconsistent state, consistent state with a non-default
930 action, or user semantic action that manipulated yychar.
931 - Of course, the expected token list depends on states to have
932 correct lookahead information, and it depends on the parser not
933 to perform extra reductions after fetching a lookahead from the
934 scanner and before detecting a syntax error. Thus, state merging
935 (from LALR or IELR) and default reductions corrupt the expected
936 token list. However, the list is correct for canonical LR with
937 one exception: it will still contain any token that will not be
938 accepted due to an error action in a later state.
939 */
940 if (yytoken != YYEMPTY)
941 {
942 int yyn = yypact[*yyssp];
943 yyarg[yycount++] = yytname[yytoken];
944 if (!yypact_value_is_default (yyn))
945 {
946 /* Start YYX at -YYN if negative to avoid negative indexes in
947 YYCHECK. In other words, skip the first -YYN actions for
948 this state because they are default actions. */
949 int yyxbegin = yyn < 0 ? -yyn : 0;
950 /* Stay within bounds of both yycheck and yytname. */
951 int yychecklim = YYLAST - yyn + 1;
952 int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
953 int yyx;
954
955 for (yyx = yyxbegin; yyx < yyxend; ++yyx)
956 if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
957 && !yytable_value_is_error (yytable[yyx + yyn]))
958 {
959 if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
960 {
961 yycount = 1;
962 yysize = yysize0;
963 break;
964 }
965 yyarg[yycount++] = yytname[yyx];
966 {
967 YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]);
968 if (! (yysize <= yysize1
969 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
970 return 2;
971 yysize = yysize1;
972 }
973 }
974 }
975 }
976
977 switch (yycount)
978 {
979 # define YYCASE_(N, S) \
980 case N: \
981 yyformat = S; \
982 break
983 YYCASE_(0, YY_("syntax error"));
984 YYCASE_(1, YY_("syntax error, unexpected %s"));
985 YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
986 YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
987 YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
988 YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
989 # undef YYCASE_
990 }
991
992 {
993 YYSIZE_T yysize1 = yysize + yystrlen (yyformat);
994 if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
995 return 2;
996 yysize = yysize1;
997 }
998
999 if (*yymsg_alloc < yysize)
1000 {
1001 *yymsg_alloc = 2 * yysize;
1002 if (! (yysize <= *yymsg_alloc
1003 && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
1004 *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
1005 return 1;
1006 }
1007
1008 /* Avoid sprintf, as that infringes on the user's name space.
1009 Don't have undefined behavior even if the translation
1010 produced a string with the wrong number of "%s"s. */
1011 {
1012 char *yyp = *yymsg;
1013 int yyi = 0;
1014 while ((*yyp = *yyformat) != '\0')
1015 if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
1016 {
1017 yyp += yytnamerr (yyp, yyarg[yyi++]);
1018 yyformat += 2;
1019 }
1020 else
1021 {
1022 yyp++;
1023 yyformat++;
1024 }
1025 }
1026 return 0;
1027 }
1028 #endif /* YYERROR_VERBOSE */
1029
1030 /*-----------------------------------------------.
1031 | Release the memory associated to this symbol. |
1032 `-----------------------------------------------*/
1033
1034 static void
yydestruct(const char * yymsg,int yytype,YYSTYPE * yyvaluep)1035 yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
1036 {
1037 YYUSE (yyvaluep);
1038 if (!yymsg)
1039 yymsg = "Deleting";
1040 YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
1041
1042 YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
1043 YYUSE (yytype);
1044 YY_IGNORE_MAYBE_UNINITIALIZED_END
1045 }
1046
1047
1048
1049
1050 /* The lookahead symbol. */
1051 int yychar;
1052
1053 /* The semantic value of the lookahead symbol. */
1054 YYSTYPE yylval;
1055 /* Number of syntax errors so far. */
1056 int yynerrs;
1057
1058
1059 /*----------.
1060 | yyparse. |
1061 `----------*/
1062
1063 int
yyparse(void)1064 yyparse (void)
1065 {
1066 int yystate;
1067 /* Number of tokens to shift before error messages enabled. */
1068 int yyerrstatus;
1069
1070 /* The stacks and their tools:
1071 'yyss': related to states.
1072 'yyvs': related to semantic values.
1073
1074 Refer to the stacks through separate pointers, to allow yyoverflow
1075 to reallocate them elsewhere. */
1076
1077 /* The state stack. */
1078 yytype_int16 yyssa[YYINITDEPTH];
1079 yytype_int16 *yyss;
1080 yytype_int16 *yyssp;
1081
1082 /* The semantic value stack. */
1083 YYSTYPE yyvsa[YYINITDEPTH];
1084 YYSTYPE *yyvs;
1085 YYSTYPE *yyvsp;
1086
1087 YYSIZE_T yystacksize;
1088
1089 int yyn;
1090 int yyresult;
1091 /* Lookahead token as an internal (translated) token number. */
1092 int yytoken = 0;
1093 /* The variables used to return semantic value and location from the
1094 action routines. */
1095 YYSTYPE yyval;
1096
1097 #if YYERROR_VERBOSE
1098 /* Buffer for error messages, and its allocated size. */
1099 char yymsgbuf[128];
1100 char *yymsg = yymsgbuf;
1101 YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
1102 #endif
1103
1104 #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N))
1105
1106 /* The number of symbols on the RHS of the reduced rule.
1107 Keep to zero when no symbol should be popped. */
1108 int yylen = 0;
1109
1110 yyssp = yyss = yyssa;
1111 yyvsp = yyvs = yyvsa;
1112 yystacksize = YYINITDEPTH;
1113
1114 YYDPRINTF ((stderr, "Starting parse\n"));
1115
1116 yystate = 0;
1117 yyerrstatus = 0;
1118 yynerrs = 0;
1119 yychar = YYEMPTY; /* Cause a token to be read. */
1120 goto yysetstate;
1121
1122 /*------------------------------------------------------------.
1123 | yynewstate -- Push a new state, which is found in yystate. |
1124 `------------------------------------------------------------*/
1125 yynewstate:
1126 /* In all cases, when you get here, the value and location stacks
1127 have just been pushed. So pushing a state here evens the stacks. */
1128 yyssp++;
1129
1130 yysetstate:
1131 *yyssp = yystate;
1132
1133 if (yyss + yystacksize - 1 <= yyssp)
1134 {
1135 /* Get the current used size of the three stacks, in elements. */
1136 YYSIZE_T yysize = yyssp - yyss + 1;
1137
1138 #ifdef yyoverflow
1139 {
1140 /* Give user a chance to reallocate the stack. Use copies of
1141 these so that the &'s don't force the real ones into
1142 memory. */
1143 YYSTYPE *yyvs1 = yyvs;
1144 yytype_int16 *yyss1 = yyss;
1145
1146 /* Each stack pointer address is followed by the size of the
1147 data in use in that stack, in bytes. This used to be a
1148 conditional around just the two extra args, but that might
1149 be undefined if yyoverflow is a macro. */
1150 yyoverflow (YY_("memory exhausted"),
1151 &yyss1, yysize * sizeof (*yyssp),
1152 &yyvs1, yysize * sizeof (*yyvsp),
1153 &yystacksize);
1154
1155 yyss = yyss1;
1156 yyvs = yyvs1;
1157 }
1158 #else /* no yyoverflow */
1159 # ifndef YYSTACK_RELOCATE
1160 goto yyexhaustedlab;
1161 # else
1162 /* Extend the stack our own way. */
1163 if (YYMAXDEPTH <= yystacksize)
1164 goto yyexhaustedlab;
1165 yystacksize *= 2;
1166 if (YYMAXDEPTH < yystacksize)
1167 yystacksize = YYMAXDEPTH;
1168
1169 {
1170 yytype_int16 *yyss1 = yyss;
1171 union yyalloc *yyptr =
1172 (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
1173 if (! yyptr)
1174 goto yyexhaustedlab;
1175 YYSTACK_RELOCATE (yyss_alloc, yyss);
1176 YYSTACK_RELOCATE (yyvs_alloc, yyvs);
1177 # undef YYSTACK_RELOCATE
1178 if (yyss1 != yyssa)
1179 YYSTACK_FREE (yyss1);
1180 }
1181 # endif
1182 #endif /* no yyoverflow */
1183
1184 yyssp = yyss + yysize - 1;
1185 yyvsp = yyvs + yysize - 1;
1186
1187 YYDPRINTF ((stderr, "Stack size increased to %lu\n",
1188 (unsigned long int) yystacksize));
1189
1190 if (yyss + yystacksize - 1 <= yyssp)
1191 YYABORT;
1192 }
1193
1194 YYDPRINTF ((stderr, "Entering state %d\n", yystate));
1195
1196 if (yystate == YYFINAL)
1197 YYACCEPT;
1198
1199 goto yybackup;
1200
1201 /*-----------.
1202 | yybackup. |
1203 `-----------*/
1204 yybackup:
1205
1206 /* Do appropriate processing given the current state. Read a
1207 lookahead token if we need one and don't already have one. */
1208
1209 /* First try to decide what to do without reference to lookahead token. */
1210 yyn = yypact[yystate];
1211 if (yypact_value_is_default (yyn))
1212 goto yydefault;
1213
1214 /* Not known => get a lookahead token if don't already have one. */
1215
1216 /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
1217 if (yychar == YYEMPTY)
1218 {
1219 YYDPRINTF ((stderr, "Reading a token: "));
1220 yychar = yylex ();
1221 }
1222
1223 if (yychar <= YYEOF)
1224 {
1225 yychar = yytoken = YYEOF;
1226 YYDPRINTF ((stderr, "Now at end of input.\n"));
1227 }
1228 else
1229 {
1230 yytoken = YYTRANSLATE (yychar);
1231 YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
1232 }
1233
1234 /* If the proper action on seeing token YYTOKEN is to reduce or to
1235 detect an error, take that action. */
1236 yyn += yytoken;
1237 if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
1238 goto yydefault;
1239 yyn = yytable[yyn];
1240 if (yyn <= 0)
1241 {
1242 if (yytable_value_is_error (yyn))
1243 goto yyerrlab;
1244 yyn = -yyn;
1245 goto yyreduce;
1246 }
1247
1248 /* Count tokens shifted since error; after three, turn off error
1249 status. */
1250 if (yyerrstatus)
1251 yyerrstatus--;
1252
1253 /* Shift the lookahead token. */
1254 YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
1255
1256 /* Discard the shifted token. */
1257 yychar = YYEMPTY;
1258
1259 yystate = yyn;
1260 YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
1261 *++yyvsp = yylval;
1262 YY_IGNORE_MAYBE_UNINITIALIZED_END
1263
1264 goto yynewstate;
1265
1266
1267 /*-----------------------------------------------------------.
1268 | yydefault -- do the default action for the current state. |
1269 `-----------------------------------------------------------*/
1270 yydefault:
1271 yyn = yydefact[yystate];
1272 if (yyn == 0)
1273 goto yyerrlab;
1274 goto yyreduce;
1275
1276
1277 /*-----------------------------.
1278 | yyreduce -- Do a reduction. |
1279 `-----------------------------*/
1280 yyreduce:
1281 /* yyn is the number of a rule to reduce with. */
1282 yylen = yyr2[yyn];
1283
1284 /* If YYLEN is nonzero, implement the default value of the action:
1285 '$$ = $1'.
1286
1287 Otherwise, the following line sets YYVAL to garbage.
1288 This behavior is undocumented and Bison
1289 users should not rely upon it. Assigning to YYVAL
1290 unconditionally makes the parser a bit smaller, and it avoids a
1291 GCC warning that YYVAL may be used uninitialized. */
1292 yyval = yyvsp[1-yylen];
1293
1294
1295 YY_REDUCE_PRINT (yyn);
1296 switch (yyn)
1297 {
1298 case 2:
1299 #line 75 "msgset.y" /* yacc.c:1646 */
1300 {
1301 result = msgset_make_1 (get_cursor ());
1302 }
1303 #line 1304 "msgset.c" /* yacc.c:1646 */
1304 break;
1305
1306 case 3:
1307 #line 79 "msgset.y" /* yacc.c:1646 */
1308 {
1309 result = msgset_make_1 (get_cursor ());
1310 }
1311 #line 1312 "msgset.c" /* yacc.c:1646 */
1312 break;
1313
1314 case 4:
1315 #line 83 "msgset.y" /* yacc.c:1646 */
1316 {
1317 result = (yyvsp[0].mset);
1318 }
1319 #line 1320 "msgset.c" /* yacc.c:1646 */
1320 break;
1321
1322 case 5:
1323 #line 87 "msgset.y" /* yacc.c:1646 */
1324 {
1325 result = msgset_select (select_deleted, NULL, 0, 1);
1326 }
1327 #line 1328 "msgset.c" /* yacc.c:1646 */
1328 break;
1329
1330 case 6:
1331 #line 91 "msgset.y" /* yacc.c:1646 */
1332 {
1333 result = msgset_select (select_deleted, NULL, 1, 1);
1334 }
1335 #line 1336 "msgset.c" /* yacc.c:1646 */
1336 break;
1337
1338 case 7:
1339 #line 95 "msgset.y" /* yacc.c:1646 */
1340 {
1341 result = msgset_select (select_deleted, NULL, 0, total);
1342 }
1343 #line 1344 "msgset.c" /* yacc.c:1646 */
1344 break;
1345
1346 case 8:
1347 #line 99 "msgset.y" /* yacc.c:1646 */
1348 {
1349 result = msgset_select (select_deleted, NULL, 1, 1);
1350 }
1351 #line 1352 "msgset.c" /* yacc.c:1646 */
1352 break;
1353
1354 case 9:
1355 #line 103 "msgset.y" /* yacc.c:1646 */
1356 {
1357 result = msgset_select (select_deleted, NULL, 0, 1);
1358 }
1359 #line 1360 "msgset.c" /* yacc.c:1646 */
1360 break;
1361
1362 case 11:
1363 #line 110 "msgset.y" /* yacc.c:1646 */
1364 {
1365 (yyval.mset) = msgset_append ((yyvsp[-2].mset), (yyvsp[0].mset));
1366 }
1367 #line 1368 "msgset.c" /* yacc.c:1646 */
1368 break;
1369
1370 case 12:
1371 #line 114 "msgset.y" /* yacc.c:1646 */
1372 {
1373 (yyval.mset) = msgset_append ((yyvsp[-1].mset), (yyvsp[0].mset));
1374 }
1375 #line 1376 "msgset.c" /* yacc.c:1646 */
1376 break;
1377
1378 case 13:
1379 #line 120 "msgset.y" /* yacc.c:1646 */
1380 {
1381 (yyval.mset) = (yyvsp[0].mset);
1382 if (check_set (&(yyval.mset)))
1383 YYABORT;
1384 }
1385 #line 1386 "msgset.c" /* yacc.c:1646 */
1386 break;
1387
1388 case 14:
1389 #line 126 "msgset.y" /* yacc.c:1646 */
1390 {
1391 (yyval.mset) = (yyvsp[-1].mset);
1392 }
1393 #line 1394 "msgset.c" /* yacc.c:1646 */
1394 break;
1395
1396 case 15:
1397 #line 130 "msgset.y" /* yacc.c:1646 */
1398 {
1399 (yyval.mset) = msgset_negate ((yyvsp[0].mset));
1400 }
1401 #line 1402 "msgset.c" /* yacc.c:1646 */
1402 break;
1403
1404 case 17:
1405 #line 137 "msgset.y" /* yacc.c:1646 */
1406 {
1407 (yyval.mset) = msgset_expand ((yyvsp[-2].mset), (yyvsp[0].mset));
1408 msgset_free ((yyvsp[-2].mset));
1409 msgset_free ((yyvsp[0].mset));
1410 }
1411 #line 1412 "msgset.c" /* yacc.c:1646 */
1412 break;
1413
1414 case 18:
1415 #line 143 "msgset.y" /* yacc.c:1646 */
1416 {
1417 (yyval.mset) = msgset_expand ((yyvsp[-3].mset), (yyvsp[-1].mset));
1418 msgset_free ((yyvsp[-3].mset));
1419 msgset_free ((yyvsp[-1].mset));
1420 }
1421 #line 1422 "msgset.c" /* yacc.c:1646 */
1422 break;
1423
1424 case 20:
1425 #line 152 "msgset.y" /* yacc.c:1646 */
1426 {
1427 struct header_data hd;
1428 hd.header = (yyvsp[-1].string);
1429 hd.expr = (yyvsp[0].string);
1430 (yyval.mset) = msgset_select (select_header, &hd, 0, 0);
1431 if (!(yyval.mset))
1432 {
1433 if ((yyvsp[-1].string))
1434 mu_error (_("No applicable messages from {%s:/%s}"), (yyvsp[-1].string), (yyvsp[0].string));
1435 else
1436 mu_error (_("No applicable messages from {/%s}"), (yyvsp[0].string));
1437 YYERROR;
1438 }
1439 }
1440 #line 1441 "msgset.c" /* yacc.c:1646 */
1441 break;
1442
1443 case 21:
1444 #line 167 "msgset.y" /* yacc.c:1646 */
1445 {
1446 (yyval.mset) = msgset_select (select_body, (yyvsp[0].string), 0, 0);
1447 if (!(yyval.mset))
1448 {
1449 mu_error (_("No applicable messages from {:/%s}"), (yyvsp[0].string));
1450 YYERROR;
1451 }
1452 }
1453 #line 1454 "msgset.c" /* yacc.c:1646 */
1454 break;
1455
1456 case 22:
1457 #line 176 "msgset.y" /* yacc.c:1646 */
1458 {
1459 message_selector_t sel = find_type_selector ((yyvsp[0].type));
1460 if (!sel)
1461 {
1462 yyerror (_("unknown message type"));
1463 YYERROR;
1464 }
1465 (yyval.mset) = msgset_select (sel, NULL, 0, 0);
1466 if (!(yyval.mset))
1467 {
1468 mu_error (_("No messages satisfy :%c"), (yyvsp[0].type));
1469 YYERROR;
1470 }
1471 }
1472 #line 1473 "msgset.c" /* yacc.c:1646 */
1473 break;
1474
1475 case 23:
1476 #line 191 "msgset.y" /* yacc.c:1646 */
1477 {
1478 (yyval.mset) = msgset_select (select_sender, (void *)(yyvsp[0].string), 0, 0);
1479 if (!(yyval.mset))
1480 {
1481 mu_error (_("No applicable messages from {%s}"), (yyvsp[0].string));
1482 YYERROR;
1483 }
1484 }
1485 #line 1486 "msgset.c" /* yacc.c:1646 */
1486 break;
1487
1488 case 24:
1489 #line 202 "msgset.y" /* yacc.c:1646 */
1490 {
1491 (yyval.string) = NULL;
1492 }
1493 #line 1494 "msgset.c" /* yacc.c:1646 */
1494 break;
1495
1496 case 25:
1497 #line 206 "msgset.y" /* yacc.c:1646 */
1498 {
1499 (yyval.string) = (yyvsp[0].string);
1500 }
1501 #line 1502 "msgset.c" /* yacc.c:1646 */
1502 break;
1503
1504 case 27:
1505 #line 213 "msgset.y" /* yacc.c:1646 */
1506 {
1507 (yyval.mset) = msgset_append ((yyvsp[-2].mset), (yyvsp[0].mset));
1508 }
1509 #line 1510 "msgset.c" /* yacc.c:1646 */
1510 break;
1511
1512 case 28:
1513 #line 217 "msgset.y" /* yacc.c:1646 */
1514 {
1515 (yyval.mset) = msgset_append ((yyvsp[-1].mset), (yyvsp[0].mset));
1516 }
1517 #line 1518 "msgset.c" /* yacc.c:1646 */
1518 break;
1519
1520 case 30:
1521 #line 224 "msgset.y" /* yacc.c:1646 */
1522 {
1523 if (msgset_length ((yyvsp[0].mset)) == 1)
1524 {
1525 (yyval.mset) = msgset_range ((yyvsp[-2].number), msgset_msgno ((yyvsp[0].mset)));
1526 }
1527 else
1528 {
1529 (yyval.mset) = msgset_range ((yyvsp[-2].number), msgset_msgno ((yyvsp[0].mset)) - 1);
1530 if (!(yyval.mset))
1531 YYERROR;
1532 msgset_append ((yyval.mset), (yyvsp[0].mset));
1533 }
1534 }
1535 #line 1536 "msgset.c" /* yacc.c:1646 */
1536 break;
1537
1538 case 31:
1539 #line 238 "msgset.y" /* yacc.c:1646 */
1540 {
1541 (yyval.mset) = msgset_range ((yyvsp[-2].number), total);
1542 }
1543 #line 1544 "msgset.c" /* yacc.c:1646 */
1544 break;
1545
1546 case 32:
1547 #line 244 "msgset.y" /* yacc.c:1646 */
1548 {
1549 }
1550 #line 1551 "msgset.c" /* yacc.c:1646 */
1551 break;
1552
1553 case 33:
1554 #line 247 "msgset.y" /* yacc.c:1646 */
1555 {
1556 (yyval.mset) = msgset_expand ((yyvsp[-2].mset), (yyvsp[0].mset));
1557 msgset_free ((yyvsp[-2].mset));
1558 msgset_free ((yyvsp[0].mset));
1559 }
1560 #line 1561 "msgset.c" /* yacc.c:1646 */
1561 break;
1562
1563 case 34:
1564 #line 253 "msgset.y" /* yacc.c:1646 */
1565 {
1566 (yyval.mset) = msgset_expand ((yyvsp[-3].mset), (yyvsp[-1].mset));
1567 msgset_free ((yyvsp[-3].mset));
1568 msgset_free ((yyvsp[-1].mset));
1569 }
1570 #line 1571 "msgset.c" /* yacc.c:1646 */
1571 break;
1572
1573 case 35:
1574 #line 261 "msgset.y" /* yacc.c:1646 */
1575 {
1576 (yyval.mset) = msgset_make_1 ((yyvsp[0].number));
1577 }
1578 #line 1579 "msgset.c" /* yacc.c:1646 */
1579 break;
1580
1581 case 36:
1582 #line 265 "msgset.y" /* yacc.c:1646 */
1583 {
1584 (yyval.mset) = (yyvsp[-1].mset);
1585 }
1586 #line 1587 "msgset.c" /* yacc.c:1646 */
1587 break;
1588
1589
1590 #line 1591 "msgset.c" /* yacc.c:1646 */
1591 default: break;
1592 }
1593 /* User semantic actions sometimes alter yychar, and that requires
1594 that yytoken be updated with the new translation. We take the
1595 approach of translating immediately before every use of yytoken.
1596 One alternative is translating here after every semantic action,
1597 but that translation would be missed if the semantic action invokes
1598 YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
1599 if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an
1600 incorrect destructor might then be invoked immediately. In the
1601 case of YYERROR or YYBACKUP, subsequent parser actions might lead
1602 to an incorrect destructor call or verbose syntax error message
1603 before the lookahead is translated. */
1604 YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
1605
1606 YYPOPSTACK (yylen);
1607 yylen = 0;
1608 YY_STACK_PRINT (yyss, yyssp);
1609
1610 *++yyvsp = yyval;
1611
1612 /* Now 'shift' the result of the reduction. Determine what state
1613 that goes to, based on the state we popped back to and the rule
1614 number reduced by. */
1615
1616 yyn = yyr1[yyn];
1617
1618 yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
1619 if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
1620 yystate = yytable[yystate];
1621 else
1622 yystate = yydefgoto[yyn - YYNTOKENS];
1623
1624 goto yynewstate;
1625
1626
1627 /*--------------------------------------.
1628 | yyerrlab -- here on detecting error. |
1629 `--------------------------------------*/
1630 yyerrlab:
1631 /* Make sure we have latest lookahead translation. See comments at
1632 user semantic actions for why this is necessary. */
1633 yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
1634
1635 /* If not already recovering from an error, report this error. */
1636 if (!yyerrstatus)
1637 {
1638 ++yynerrs;
1639 #if ! YYERROR_VERBOSE
1640 yyerror (YY_("syntax error"));
1641 #else
1642 # define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
1643 yyssp, yytoken)
1644 {
1645 char const *yymsgp = YY_("syntax error");
1646 int yysyntax_error_status;
1647 yysyntax_error_status = YYSYNTAX_ERROR;
1648 if (yysyntax_error_status == 0)
1649 yymsgp = yymsg;
1650 else if (yysyntax_error_status == 1)
1651 {
1652 if (yymsg != yymsgbuf)
1653 YYSTACK_FREE (yymsg);
1654 yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
1655 if (!yymsg)
1656 {
1657 yymsg = yymsgbuf;
1658 yymsg_alloc = sizeof yymsgbuf;
1659 yysyntax_error_status = 2;
1660 }
1661 else
1662 {
1663 yysyntax_error_status = YYSYNTAX_ERROR;
1664 yymsgp = yymsg;
1665 }
1666 }
1667 yyerror (yymsgp);
1668 if (yysyntax_error_status == 2)
1669 goto yyexhaustedlab;
1670 }
1671 # undef YYSYNTAX_ERROR
1672 #endif
1673 }
1674
1675
1676
1677 if (yyerrstatus == 3)
1678 {
1679 /* If just tried and failed to reuse lookahead token after an
1680 error, discard it. */
1681
1682 if (yychar <= YYEOF)
1683 {
1684 /* Return failure if at end of input. */
1685 if (yychar == YYEOF)
1686 YYABORT;
1687 }
1688 else
1689 {
1690 yydestruct ("Error: discarding",
1691 yytoken, &yylval);
1692 yychar = YYEMPTY;
1693 }
1694 }
1695
1696 /* Else will try to reuse lookahead token after shifting the error
1697 token. */
1698 goto yyerrlab1;
1699
1700
1701 /*---------------------------------------------------.
1702 | yyerrorlab -- error raised explicitly by YYERROR. |
1703 `---------------------------------------------------*/
1704 yyerrorlab:
1705
1706 /* Pacify compilers like GCC when the user code never invokes
1707 YYERROR and the label yyerrorlab therefore never appears in user
1708 code. */
1709 if (/*CONSTCOND*/ 0)
1710 goto yyerrorlab;
1711
1712 /* Do not reclaim the symbols of the rule whose action triggered
1713 this YYERROR. */
1714 YYPOPSTACK (yylen);
1715 yylen = 0;
1716 YY_STACK_PRINT (yyss, yyssp);
1717 yystate = *yyssp;
1718 goto yyerrlab1;
1719
1720
1721 /*-------------------------------------------------------------.
1722 | yyerrlab1 -- common code for both syntax error and YYERROR. |
1723 `-------------------------------------------------------------*/
1724 yyerrlab1:
1725 yyerrstatus = 3; /* Each real token shifted decrements this. */
1726
1727 for (;;)
1728 {
1729 yyn = yypact[yystate];
1730 if (!yypact_value_is_default (yyn))
1731 {
1732 yyn += YYTERROR;
1733 if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
1734 {
1735 yyn = yytable[yyn];
1736 if (0 < yyn)
1737 break;
1738 }
1739 }
1740
1741 /* Pop the current state because it cannot handle the error token. */
1742 if (yyssp == yyss)
1743 YYABORT;
1744
1745
1746 yydestruct ("Error: popping",
1747 yystos[yystate], yyvsp);
1748 YYPOPSTACK (1);
1749 yystate = *yyssp;
1750 YY_STACK_PRINT (yyss, yyssp);
1751 }
1752
1753 YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
1754 *++yyvsp = yylval;
1755 YY_IGNORE_MAYBE_UNINITIALIZED_END
1756
1757
1758 /* Shift the error token. */
1759 YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
1760
1761 yystate = yyn;
1762 goto yynewstate;
1763
1764
1765 /*-------------------------------------.
1766 | yyacceptlab -- YYACCEPT comes here. |
1767 `-------------------------------------*/
1768 yyacceptlab:
1769 yyresult = 0;
1770 goto yyreturn;
1771
1772 /*-----------------------------------.
1773 | yyabortlab -- YYABORT comes here. |
1774 `-----------------------------------*/
1775 yyabortlab:
1776 yyresult = 1;
1777 goto yyreturn;
1778
1779 #if !defined yyoverflow || YYERROR_VERBOSE
1780 /*-------------------------------------------------.
1781 | yyexhaustedlab -- memory exhaustion comes here. |
1782 `-------------------------------------------------*/
1783 yyexhaustedlab:
1784 yyerror (YY_("memory exhausted"));
1785 yyresult = 2;
1786 /* Fall through. */
1787 #endif
1788
1789 yyreturn:
1790 if (yychar != YYEMPTY)
1791 {
1792 /* Make sure we have latest lookahead translation. See comments at
1793 user semantic actions for why this is necessary. */
1794 yytoken = YYTRANSLATE (yychar);
1795 yydestruct ("Cleanup: discarding lookahead",
1796 yytoken, &yylval);
1797 }
1798 /* Do not reclaim the symbols of the rule whose action triggered
1799 this YYABORT or YYACCEPT. */
1800 YYPOPSTACK (yylen);
1801 YY_STACK_PRINT (yyss, yyssp);
1802 while (yyssp != yyss)
1803 {
1804 yydestruct ("Cleanup: popping",
1805 yystos[*yyssp], yyvsp);
1806 YYPOPSTACK (1);
1807 }
1808 #ifndef yyoverflow
1809 if (yyss != yyssa)
1810 YYSTACK_FREE (yyss);
1811 #endif
1812 #if YYERROR_VERBOSE
1813 if (yymsg != yymsgbuf)
1814 YYSTACK_FREE (yymsg);
1815 #endif
1816 return yyresult;
1817 }
1818 #line 269 "msgset.y" /* yacc.c:1906 */
1819
1820
1821 static int xargc;
1822 static char **xargv;
1823 static int cur_ind;
1824 static char *cur_p;
1825
1826 int
yyerror(const char * s)1827 yyerror (const char *s)
1828 {
1829 mu_stream_printf (mu_strerr, "%s: ", xargv[0]);
1830 mu_stream_printf (mu_strerr, "%s", s);
1831 if (!cur_p)
1832 mu_stream_printf (mu_strerr, _(" near end"));
1833 else if (*cur_p == 0)
1834 {
1835 int i = (*cur_p == 0) ? cur_ind + 1 : cur_ind;
1836 if (i == xargc)
1837 mu_stream_printf (mu_strerr, _(" near end"));
1838 else
1839 mu_stream_printf (mu_strerr, _(" near %s"), xargv[i]);
1840 }
1841 else
1842 mu_stream_printf (mu_strerr, _(" near %s"), cur_p);
1843 mu_stream_printf (mu_strerr, "\n");
1844 return 0;
1845 }
1846
1847 int
yylex(void)1848 yylex (void)
1849 {
1850 if (cur_ind == xargc)
1851 return 0;
1852 if (!cur_p)
1853 cur_p = xargv[cur_ind];
1854 if (*cur_p == 0)
1855 {
1856 cur_ind++;
1857 cur_p = NULL;
1858 return yylex ();
1859 }
1860
1861 if (mu_isdigit (*cur_p))
1862 {
1863 yylval.number = strtoul (cur_p, &cur_p, 10);
1864 return NUMBER;
1865 }
1866
1867 if (mu_isalpha (*cur_p))
1868 {
1869 char *p = cur_p;
1870
1871 while (*cur_p && *cur_p != ',' && *cur_p != ':')
1872 cur_p++;
1873 mu_opool_append (tokpool, p, cur_p - p);
1874 mu_opool_append_char (tokpool, 0);
1875 yylval.string = mu_opool_finish (tokpool, NULL);
1876 if (*cur_p == ':')
1877 {
1878 ++cur_p;
1879 return HEADER;
1880 }
1881 return IDENT;
1882 }
1883
1884 if (*cur_p == '/')
1885 {
1886 char *p = ++cur_p;
1887
1888 while (*cur_p && *cur_p != '/')
1889 cur_p++;
1890
1891 mu_opool_append (tokpool, p, cur_p - p);
1892 mu_opool_append_char (tokpool, 0);
1893 yylval.string = mu_opool_finish (tokpool, NULL);
1894
1895 if (*cur_p)
1896 cur_p++;
1897
1898 return REGEXP;
1899 }
1900
1901 if (*cur_p == ':')
1902 {
1903 cur_p++;
1904 if (*cur_p == '/')
1905 {
1906 char *p = ++cur_p;
1907
1908 while (*cur_p && *cur_p != '/')
1909 cur_p++;
1910
1911 mu_opool_append (tokpool, p, cur_p - p);
1912 mu_opool_append_char (tokpool, 0);
1913 yylval.string = mu_opool_finish (tokpool, NULL);
1914
1915 if (*cur_p)
1916 cur_p++;
1917
1918 return BODY;
1919 }
1920 if (*cur_p == 0)
1921 return 0;
1922 yylval.type = *cur_p++;
1923 return TYPE;
1924 }
1925
1926 return *cur_p++;
1927 }
1928
1929 int
msgset_parse(const int argc,char ** argv,int flags,msgset_t ** mset)1930 msgset_parse (const int argc, char **argv, int flags, msgset_t **mset)
1931 {
1932 int rc;
1933 xargc = argc;
1934 xargv = argv;
1935 msgset_flags = flags;
1936 cur_ind = 1;
1937 cur_p = NULL;
1938 result = NULL;
1939
1940 mu_opool_create (&tokpool, MU_OPOOL_ENOMEMABRT);
1941 mu_mailbox_messages_count (mbox, &message_count);
1942 rc = yyparse ();
1943 if (rc == 0)
1944 {
1945 if (!result)
1946 {
1947 util_noapp ();
1948 rc = 1;
1949 }
1950 else
1951 {
1952 if (result->crd[1] > message_count)
1953 {
1954 util_error_range (result->crd[1]);
1955 msgset_free (result);
1956 return 1;
1957 }
1958 *mset = result;
1959 }
1960 }
1961 mu_opool_destroy (&tokpool);
1962 return rc;
1963 }
1964
1965 void
msgset_free(msgset_t * msg_set)1966 msgset_free (msgset_t *msg_set)
1967 {
1968 msgset_t *next;
1969
1970 while (msg_set)
1971 {
1972 next = msg_set->next;
1973 free (msg_set->crd);
1974 free (msg_set);
1975 msg_set = next;
1976 }
1977 }
1978
1979 size_t
msgset_count(msgset_t * set)1980 msgset_count (msgset_t *set)
1981 {
1982 size_t count = 0;
1983 for (; set; set = set->next)
1984 count++;
1985 return count;
1986 }
1987
1988 /* Create a message set consisting of a single msg_num and no subparts */
1989 msgset_t *
msgset_make_1(size_t number)1990 msgset_make_1 (size_t number)
1991 {
1992 msgset_t *mp;
1993
1994 if (number == 0)
1995 return NULL;
1996 mp = mu_alloc (sizeof (*mp));
1997 mp->next = NULL;
1998 if (mu_coord_alloc (&mp->crd, 1))
1999 mu_alloc_die ();
2000 mp->crd[1] = number;
2001 return mp;
2002 }
2003
2004 msgset_t *
msgset_dup(const msgset_t * set)2005 msgset_dup (const msgset_t *set)
2006 {
2007 msgset_t *mp;
2008 mp = mu_alloc (sizeof (*mp));
2009 mp->next = NULL;
2010 if (mu_coord_dup (set->crd, &mp->crd))
2011 mu_alloc_die ();
2012 return mp;
2013 }
2014
2015 /* Append message set TWO to the end of message set ONE. Take care to
2016 eliminate duplicates. Preserve the ordering of both lists. Return
2017 the resulting set.
2018
2019 The function is destructive: the set TWO is attached to ONE and
2020 eventually modified to avoid duplicates.
2021 */
2022 msgset_t *
msgset_append(msgset_t * one,msgset_t * two)2023 msgset_append (msgset_t *one, msgset_t *two)
2024 {
2025 msgset_t *last;
2026
2027 if (!one)
2028 return two;
2029 for (last = one; last->next; last = last->next)
2030 {
2031 msgset_remove (&two, msgset_msgno (last));
2032 }
2033 last->next = two;
2034 return one;
2035 }
2036
2037 int
msgset_member(msgset_t * set,size_t n)2038 msgset_member (msgset_t *set, size_t n)
2039 {
2040 for (; set; set = set->next)
2041 if (msgset_msgno (set) == n)
2042 return 1;
2043 return 0;
2044 }
2045
2046 void
msgset_remove(msgset_t ** pset,size_t n)2047 msgset_remove (msgset_t **pset, size_t n)
2048 {
2049 msgset_t *cur = *pset, **pnext = pset;
2050
2051 while (1)
2052 {
2053 if (cur == NULL)
2054 return;
2055 if (msgset_msgno (cur) == n)
2056 break;
2057 pnext = &cur->next;
2058 cur = cur->next;
2059 }
2060 *pnext = cur->next;
2061 cur->next = NULL;
2062 msgset_free (cur);
2063 }
2064
2065 msgset_t *
msgset_negate(msgset_t * set)2066 msgset_negate (msgset_t *set)
2067 {
2068 size_t i;
2069 msgset_t *first = NULL, *last = NULL;
2070
2071 for (i = 1; i <= total; i++)
2072 {
2073 if (!msgset_member (set, i))
2074 {
2075 msgset_t *mp = msgset_make_1 (i);
2076 if (!first)
2077 first = mp;
2078 else
2079 last->next = mp;
2080 last = mp;
2081 }
2082 }
2083 return first;
2084 }
2085
2086 msgset_t *
msgset_range(int low,int high)2087 msgset_range (int low, int high)
2088 {
2089 int i;
2090 msgset_t *mp, *first = NULL, *last = NULL;
2091
2092 if (low == high)
2093 return msgset_make_1 (low);
2094
2095 if (low >= high)
2096 {
2097 yyerror (_("range error"));
2098 return NULL;
2099 }
2100
2101 for (i = 0; low <= high; i++, low++)
2102 {
2103 mp = msgset_make_1 (low);
2104 if (!first)
2105 first = mp;
2106 else
2107 last->next = mp;
2108 last = mp;
2109 }
2110 return first;
2111 }
2112
2113 msgset_t *
msgset_expand(msgset_t * set,msgset_t * expand_by)2114 msgset_expand (msgset_t *set, msgset_t *expand_by)
2115 {
2116 msgset_t *i, *j;
2117 msgset_t *first = NULL, *last = NULL, *mp;
2118
2119 for (i = set; i; i = i->next)
2120 for (j = expand_by; j; j = j->next)
2121 {
2122 mp = mu_alloc (sizeof *mp);
2123 mp->next = NULL;
2124 if (mu_coord_alloc (&mp->crd,
2125 mu_coord_length (i->crd) + mu_coord_length (j->crd)))
2126 mu_alloc_die ();
2127 memcpy (&mp->crd[1], &i->crd[1],
2128 mu_coord_length (i->crd) * sizeof i->crd[0]);
2129 memcpy (&mp->crd[1] + mu_coord_length (i->crd), &j->crd[1],
2130 mu_coord_length (j->crd) * sizeof j->crd[0]);
2131
2132 if (!first)
2133 first = mp;
2134 else
2135 last->next = mp;
2136 last = mp;
2137 }
2138 return first;
2139 }
2140
2141 msgset_t *
msgset_select(message_selector_t sel,void * closure,int rev,unsigned int max_matches)2142 msgset_select (message_selector_t sel, void *closure, int rev,
2143 unsigned int max_matches)
2144 {
2145 size_t i, match_count = 0;
2146 msgset_t *first = NULL, *last = NULL, *mp;
2147 mu_message_t msg = NULL;
2148
2149 if (max_matches == 0)
2150 max_matches = total;
2151
2152 if (rev)
2153 {
2154 for (i = total; i > 0; i--)
2155 {
2156 mu_mailbox_get_message (mbox, i, &msg);
2157 if ((*sel) (msg, closure))
2158 {
2159 mp = msgset_make_1 (i);
2160 if (!first)
2161 first = mp;
2162 else
2163 last->next = mp;
2164 last = mp;
2165 if (++match_count == max_matches)
2166 break;
2167 }
2168 }
2169 }
2170 else
2171 {
2172 for (i = 1; i <= total; i++)
2173 {
2174 mu_mailbox_get_message (mbox, i, &msg);
2175 if ((*sel) (msg, closure))
2176 {
2177 mp = msgset_make_1 (i);
2178 if (!first)
2179 first = mp;
2180 else
2181 last->next = mp;
2182 last = mp;
2183 if (++match_count == max_matches)
2184 break;
2185 }
2186 }
2187 }
2188 return first;
2189 }
2190
2191 int
select_header(mu_message_t msg,void * closure)2192 select_header (mu_message_t msg, void *closure)
2193 {
2194 struct header_data *hd = (struct header_data *)closure;
2195 mu_header_t hdr;
2196 char *contents;
2197 const char *header = hd->header ? hd->header : MU_HEADER_SUBJECT;
2198
2199 mu_message_get_header (msg, &hdr);
2200 if (mu_header_aget_value (hdr, header, &contents) == 0)
2201 {
2202 if (mailvar_get (NULL, "regex", mailvar_type_boolean, 0) == 0)
2203 {
2204 /* Match string against the extended regular expression(ignoring
2205 case) in pattern, treating errors as no match.
2206 Return 1 for match, 0 for no match.
2207 */
2208 regex_t re;
2209 int status;
2210 int flags = REG_EXTENDED;
2211
2212 if (mu_islower (header[0]))
2213 flags |= REG_ICASE;
2214 if (regcomp (&re, hd->expr, flags) != 0)
2215 {
2216 free (contents);
2217 return 0;
2218 }
2219 status = regexec (&re, contents, 0, NULL, 0);
2220 free (contents);
2221 regfree (&re);
2222 return status == 0;
2223 }
2224 else
2225 {
2226 int rc;
2227 mu_strupper (contents);
2228 rc = strstr (contents, hd->expr) != NULL;
2229 free (contents);
2230 return rc;
2231 }
2232 }
2233 return 0;
2234 }
2235
2236 int
select_body(mu_message_t msg,void * closure)2237 select_body (mu_message_t msg, void *closure)
2238 {
2239 char *expr = closure;
2240 int noregex = mailvar_get (NULL, "regex", mailvar_type_boolean, 0);
2241 regex_t re;
2242 int status = 0;
2243 mu_body_t body = NULL;
2244 mu_stream_t stream = NULL;
2245 int rc;
2246
2247 if (noregex)
2248 mu_strupper (expr);
2249 else if (regcomp (&re, expr, REG_EXTENDED | REG_ICASE) != 0)
2250 return 0;
2251
2252 mu_message_get_body (msg, &body);
2253 rc = mu_body_get_streamref (body, &stream);
2254 if (rc == 0)
2255 {
2256 char *buffer = NULL;
2257 size_t size = 0;
2258 size_t n = 0;
2259
2260 while (status == 0
2261 && (rc = mu_stream_getline (stream, &buffer, &size, &n)) == 0
2262 && n > 0)
2263 {
2264 if (noregex)
2265 {
2266 /* FIXME: charset */
2267 mu_strupper (buffer);
2268 status = strstr (buffer, expr) != NULL;
2269 }
2270 else
2271 status = regexec (&re, buffer, 0, NULL, 0) == 0;
2272 }
2273 mu_stream_destroy (&stream);
2274 free (buffer);
2275 if (rc)
2276 mu_diag_funcall (MU_DIAG_ERROR, "mu_stream_getline", NULL, rc);
2277 }
2278 else
2279 mu_diag_funcall (MU_DIAG_ERROR, "mu_body_get_streamref", NULL, rc);
2280
2281 if (!noregex)
2282 regfree (&re);
2283
2284 return status;
2285 }
2286
2287 int
select_sender(mu_message_t msg,void * closure)2288 select_sender (mu_message_t msg, void *closure)
2289 {
2290 char *needle = (char*) closure;
2291 char *sender = sender_string (msg);
2292 int status = strcmp (sender, needle) == 0;
2293 free (sender);
2294 return status;
2295 }
2296
2297 static int
select_type_d(mu_message_t msg,void * unused MU_ARG_UNUSED)2298 select_type_d (mu_message_t msg, void *unused MU_ARG_UNUSED)
2299 {
2300 mu_attribute_t attr;
2301
2302 if (mu_message_get_attribute (msg, &attr) == 0)
2303 return mu_attribute_is_deleted (attr);
2304 return 0;
2305 }
2306
2307 static int
select_type_n(mu_message_t msg,void * unused MU_ARG_UNUSED)2308 select_type_n (mu_message_t msg, void *unused MU_ARG_UNUSED)
2309 {
2310 mu_attribute_t attr;
2311
2312 if (mu_message_get_attribute (msg, &attr) == 0)
2313 return mu_attribute_is_recent (attr);
2314 return 0;
2315 }
2316
2317 static int
select_type_o(mu_message_t msg,void * unused MU_ARG_UNUSED)2318 select_type_o (mu_message_t msg, void *unused MU_ARG_UNUSED)
2319 {
2320 mu_attribute_t attr;
2321
2322 if (mu_message_get_attribute (msg, &attr) == 0)
2323 return mu_attribute_is_seen (attr);
2324 return 0;
2325 }
2326
2327 static int
select_type_r(mu_message_t msg,void * unused MU_ARG_UNUSED)2328 select_type_r (mu_message_t msg, void *unused MU_ARG_UNUSED)
2329 {
2330 mu_attribute_t attr;
2331
2332 if (mu_message_get_attribute (msg, &attr) == 0)
2333 return mu_attribute_is_read (attr);
2334 return 0;
2335 }
2336
2337 static int
select_type_s(mu_message_t msg,void * unused MU_ARG_UNUSED)2338 select_type_s (mu_message_t msg, void *unused MU_ARG_UNUSED)
2339 {
2340 mu_attribute_t attr;
2341
2342 if (mu_message_get_attribute (msg, &attr) == 0)
2343 return mu_attribute_is_userflag (attr, MAIL_ATTRIBUTE_SAVED);
2344 return 0;
2345 }
2346
2347 static int
select_type_t(mu_message_t msg,void * unused MU_ARG_UNUSED)2348 select_type_t (mu_message_t msg, void *unused MU_ARG_UNUSED)
2349 {
2350 mu_attribute_t attr;
2351
2352 if (mu_message_get_attribute (msg, &attr) == 0)
2353 return mu_attribute_is_userflag (attr, MAIL_ATTRIBUTE_TAGGED);
2354 return 0;
2355 }
2356
2357 static int
select_type_T(mu_message_t msg,void * unused MU_ARG_UNUSED)2358 select_type_T (mu_message_t msg, void *unused MU_ARG_UNUSED)
2359 {
2360 mu_attribute_t attr;
2361
2362 if (mu_message_get_attribute (msg, &attr) == 0)
2363 return !mu_attribute_is_userflag (attr, MAIL_ATTRIBUTE_TAGGED);
2364 return 0;
2365 }
2366
2367 static int
select_type_u(mu_message_t msg,void * unused MU_ARG_UNUSED)2368 select_type_u (mu_message_t msg, void *unused MU_ARG_UNUSED)
2369 {
2370 mu_attribute_t attr;
2371
2372 if (mu_message_get_attribute (msg, &attr) == 0)
2373 return !mu_attribute_is_read (attr);
2374 return 0;
2375 }
2376
2377 struct type_selector
2378 {
2379 int letter;
2380 message_selector_t func;
2381 };
2382
2383 static struct type_selector type_selector[] = {
2384 { 'd', select_type_d },
2385 { 'n', select_type_n },
2386 { 'o', select_type_o },
2387 { 'r', select_type_r },
2388 { 's', select_type_s },
2389 { 't', select_type_t },
2390 { 'T', select_type_T },
2391 { 'u', select_type_u },
2392 { '/', NULL }, /* A pseudo-entry needed for msgtype_generator only */
2393 { 0 }
2394 };
2395
2396 static message_selector_t
find_type_selector(int type)2397 find_type_selector (int type)
2398 {
2399 struct type_selector *p;
2400 for (p = type_selector; p->func; p++)
2401 {
2402 if (p->letter == type)
2403 return p->func;
2404 }
2405 return NULL;
2406 }
2407
2408 #ifdef WITH_READLINE
2409 char *
msgtype_generator(const char * text,int state)2410 msgtype_generator (const char *text, int state)
2411 {
2412 /* Allowed message types, plus '/'. The latter can folow a colon,
2413 meaning body lookup */
2414 static int i;
2415 char c;
2416
2417 if (!state)
2418 {
2419 i = 0;
2420 }
2421 while ((c = type_selector[i].letter))
2422 {
2423 i++;
2424 if (!text[1] || text[1] == c)
2425 {
2426 char *s = mu_alloc (3);
2427 s[0] = ':';
2428 s[1] = c;
2429 s[2] = 0;
2430 return s;
2431 }
2432 }
2433 return NULL;
2434 }
2435 #endif
2436
2437 int
select_deleted(mu_message_t msg,void * closure MU_ARG_UNUSED)2438 select_deleted (mu_message_t msg, void *closure MU_ARG_UNUSED)
2439 {
2440 mu_attribute_t attr= NULL;
2441 int rc;
2442
2443 mu_message_get_attribute (msg, &attr);
2444 rc = mu_attribute_is_deleted (attr);
2445 return strcmp (xargv[0], "undelete") == 0 ? rc : !rc;
2446 }
2447
2448 int
check_set(msgset_t ** pset)2449 check_set (msgset_t **pset)
2450 {
2451 int flags = msgset_flags;
2452 int rc = 0;
2453
2454 if (!*pset)
2455 {
2456 util_noapp ();
2457 return 1;
2458 }
2459 if (msgset_count (*pset) == 1)
2460 flags ^= MSG_SILENT;
2461 if (flags & MSG_NODELETED)
2462 {
2463 msgset_t *p = *pset, *prev = NULL;
2464 msgset_t *delset = NULL;
2465
2466 while (p)
2467 {
2468 msgset_t *next = p->next;
2469 if (util_isdeleted (msgset_msgno (p)))
2470 {
2471 if ((flags & MSG_SILENT) && (prev || next))
2472 {
2473 /* Mark subset as deleted */
2474 p->next = delset;
2475 delset = p;
2476 /* Remove it from the set */
2477 if (prev)
2478 prev->next = next;
2479 else
2480 *pset = next;
2481 }
2482 else
2483 {
2484 mu_error (_("%lu: Inappropriate message (has been deleted)"),
2485 (unsigned long) msgset_msgno (p));
2486 /* Delete entire set */
2487 delset = *pset;
2488 *pset = NULL;
2489 rc = 1;
2490 break;
2491 }
2492 }
2493 else
2494 prev = p;
2495 p = next;
2496 }
2497
2498 if (delset)
2499 msgset_free (delset);
2500
2501 if (!*pset)
2502 rc = 1;
2503 }
2504
2505 return rc;
2506 }
2507
2508
2509 #if 0
2510 void
2511 msgset_print (msgset_t *mset)
2512 {
2513 int i;
2514 mu_printf ("(");
2515 mu_printf ("%d .", mset->msg_part[0]);
2516 for (i = 1; i < mset->npart; i++)
2517 {
2518 mu_printf (" %d", mset->msg_part[i]);
2519 }
2520 mu_printf (")\n");
2521 }
2522
2523 int
2524 main(int argc, char **argv)
2525 {
2526 msgset_t *mset = NULL;
2527 int rc = msgset_parse (argc, argv, &mset);
2528
2529 for (; mset; mset = mset->next)
2530 msgset_print (mset);
2531 return 0;
2532 }
2533 #endif
2534