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 1 "mh_fmtgram.y" /* yacc.c:339 */
66
67 /* GNU Mailutils -- a suite of utilities for electronic mail
68 Copyright (C) 1999-2021 Free Software Foundation, Inc.
69
70 GNU Mailutils is free software; you can redistribute it and/or modify
71 it under the terms of the GNU General Public License as published by
72 the Free Software Foundation; either version 3, or (at your option)
73 any later version.
74
75 GNU Mailutils is distributed in the hope that it will be useful,
76 but WITHOUT ANY WARRANTY; without even the implied warranty of
77 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
78 GNU General Public License for more details.
79
80 You should have received a copy of the GNU General Public License
81 along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
82
83 #include <mh.h>
84 #include <mh_format.h>
85 #include <sys/stat.h>
86
87 int fmt_yyerror (const char *s);
88 int fmt_yylex (void);
89
90 static mu_opool_t tokpool; /* Temporary token storage */
91
92
93 /* Lexical context */
94 enum context
95 {
96 ctx_init, /* Normal text */
97 ctx_if, /* After %< or %? */
98 ctx_expr, /* Expression within cond */
99 ctx_func, /* after (func */
100 };
101
102 static enum context *ctx_stack;
103 size_t ctx_tos;
104 size_t ctx_max;
105
106 static inline void
ctx_push(enum context ctx)107 ctx_push (enum context ctx)
108 {
109 if (ctx_tos == ctx_max)
110 ctx_stack = mu_2nrealloc (ctx_stack, &ctx_max, sizeof (ctx_stack[0]));
111 ctx_stack[ctx_tos++] = ctx;
112 }
113
114 static inline void
ctx_pop(void)115 ctx_pop (void)
116 {
117 if (ctx_tos == 0)
118 {
119 fmt_yyerror ("out of context");
120 abort ();
121 }
122 ctx_tos--;
123 }
124
125 static inline enum context
ctx_get(void)126 ctx_get (void)
127 {
128 return ctx_stack[ctx_tos-1];
129 }
130
131 enum node_type
132 {
133 fmtnode_print,
134 fmtnode_literal,
135 fmtnode_number,
136 fmtnode_body,
137 fmtnode_comp,
138 fmtnode_funcall,
139 fmtnode_cntl,
140 fmtnode_typecast,
141 };
142
143 struct node
144 {
145 enum node_type nodetype;
146 enum mh_type datatype;
147 int printflag;
148 struct node *prev, *next;
149 union
150 {
151 char *str;
152 long num;
153 struct node *arg;
154 struct
155 {
156 int fmtspec;
157 struct node *arg;
158 } prt;
159 struct
160 {
161 mh_builtin_t *builtin;
162 struct node *arg;
163 } funcall;
164 struct
165 {
166 struct node *cond;
167 struct node *iftrue;
168 struct node *iffalse;
169 } cntl;
170 } v;
171 };
172
173 static struct node *parse_tree;
174 static struct node *new_node (enum node_type nodetype, enum mh_type datatype);
175
176 static struct node *printelim (struct node *root);
177 static void codegen (mh_format_t *fmt, int tree);
178 static struct node *typecast (struct node *node, enum mh_type type);
179
180
181 #line 182 "mh_fmtgram.c" /* yacc.c:339 */
182
183 # ifndef YY_NULLPTR
184 # if defined __cplusplus && 201103L <= __cplusplus
185 # define YY_NULLPTR nullptr
186 # else
187 # define YY_NULLPTR 0
188 # endif
189 # endif
190
191 /* Enabling verbose error messages. */
192 #ifdef YYERROR_VERBOSE
193 # undef YYERROR_VERBOSE
194 # define YYERROR_VERBOSE 1
195 #else
196 # define YYERROR_VERBOSE 1
197 #endif
198
199
200 /* Debug traces. */
201 #ifndef YYDEBUG
202 # define YYDEBUG 1
203 #endif
204 #if YYDEBUG
205 extern int fmt_yydebug;
206 #endif
207
208 /* Token type. */
209 #ifndef YYTOKENTYPE
210 # define YYTOKENTYPE
211 enum yytokentype
212 {
213 NUMBER = 258,
214 STRING = 259,
215 COMPONENT = 260,
216 ARGUMENT = 261,
217 FUNCTION = 262,
218 IF = 263,
219 ELIF = 264,
220 ELSE = 265,
221 FI = 266,
222 FMTSPEC = 267,
223 BOGUS = 268,
224 EOFN = 269
225 };
226 #endif
227 /* Tokens. */
228 #define NUMBER 258
229 #define STRING 259
230 #define COMPONENT 260
231 #define ARGUMENT 261
232 #define FUNCTION 262
233 #define IF 263
234 #define ELIF 264
235 #define ELSE 265
236 #define FI 266
237 #define FMTSPEC 267
238 #define BOGUS 268
239 #define EOFN 269
240
241 /* Value type. */
242 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
243
244 union YYSTYPE
245 {
246 #line 117 "mh_fmtgram.y" /* yacc.c:355 */
247
248 char *str;
249 char const *mesg;
250 long num;
251 struct {
252 struct node *head, *tail;
253 } nodelist;
254 struct node *nodeptr;
255 mh_builtin_t *builtin;
256 int fmtspec;
257 struct {
258 enum mh_type type;
259 union
260 {
261 char *str;
262 long num;
263 } v;
264 } arg;
265
266 #line 267 "mh_fmtgram.c" /* yacc.c:355 */
267 };
268
269 typedef union YYSTYPE YYSTYPE;
270 # define YYSTYPE_IS_TRIVIAL 1
271 # define YYSTYPE_IS_DECLARED 1
272 #endif
273
274
275 extern YYSTYPE fmt_yylval;
276
277 int fmt_yyparse (void);
278
279
280
281 /* Copy the second part of user declarations. */
282
283 #line 284 "mh_fmtgram.c" /* yacc.c:358 */
284
285 #ifdef short
286 # undef short
287 #endif
288
289 #ifdef YYTYPE_UINT8
290 typedef YYTYPE_UINT8 yytype_uint8;
291 #else
292 typedef unsigned char yytype_uint8;
293 #endif
294
295 #ifdef YYTYPE_INT8
296 typedef YYTYPE_INT8 yytype_int8;
297 #else
298 typedef signed char yytype_int8;
299 #endif
300
301 #ifdef YYTYPE_UINT16
302 typedef YYTYPE_UINT16 yytype_uint16;
303 #else
304 typedef unsigned short int yytype_uint16;
305 #endif
306
307 #ifdef YYTYPE_INT16
308 typedef YYTYPE_INT16 yytype_int16;
309 #else
310 typedef short int yytype_int16;
311 #endif
312
313 #ifndef YYSIZE_T
314 # ifdef __SIZE_TYPE__
315 # define YYSIZE_T __SIZE_TYPE__
316 # elif defined size_t
317 # define YYSIZE_T size_t
318 # elif ! defined YYSIZE_T
319 # include <stddef.h> /* INFRINGES ON USER NAME SPACE */
320 # define YYSIZE_T size_t
321 # else
322 # define YYSIZE_T unsigned int
323 # endif
324 #endif
325
326 #define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
327
328 #ifndef YY_
329 # if defined YYENABLE_NLS && YYENABLE_NLS
330 # if ENABLE_NLS
331 # include <libintl.h> /* INFRINGES ON USER NAME SPACE */
332 # define YY_(Msgid) dgettext ("bison-runtime", Msgid)
333 # endif
334 # endif
335 # ifndef YY_
336 # define YY_(Msgid) Msgid
337 # endif
338 #endif
339
340 #ifndef YY_ATTRIBUTE
341 # if (defined __GNUC__ \
342 && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \
343 || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C
344 # define YY_ATTRIBUTE(Spec) __attribute__(Spec)
345 # else
346 # define YY_ATTRIBUTE(Spec) /* empty */
347 # endif
348 #endif
349
350 #ifndef YY_ATTRIBUTE_PURE
351 # define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__))
352 #endif
353
354 #ifndef YY_ATTRIBUTE_UNUSED
355 # define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__))
356 #endif
357
358 #if !defined _Noreturn \
359 && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112)
360 # if defined _MSC_VER && 1200 <= _MSC_VER
361 # define _Noreturn __declspec (noreturn)
362 # else
363 # define _Noreturn YY_ATTRIBUTE ((__noreturn__))
364 # endif
365 #endif
366
367 /* Suppress unused-variable warnings by "using" E. */
368 #if ! defined lint || defined __GNUC__
369 # define YYUSE(E) ((void) (E))
370 #else
371 # define YYUSE(E) /* empty */
372 #endif
373
374 #if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
375 /* Suppress an incorrect diagnostic about fmt_yylval being uninitialized. */
376 # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
377 _Pragma ("GCC diagnostic push") \
378 _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\
379 _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
380 # define YY_IGNORE_MAYBE_UNINITIALIZED_END \
381 _Pragma ("GCC diagnostic pop")
382 #else
383 # define YY_INITIAL_VALUE(Value) Value
384 #endif
385 #ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
386 # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
387 # define YY_IGNORE_MAYBE_UNINITIALIZED_END
388 #endif
389 #ifndef YY_INITIAL_VALUE
390 # define YY_INITIAL_VALUE(Value) /* Nothing. */
391 #endif
392
393
394 #if ! defined yyoverflow || YYERROR_VERBOSE
395
396 /* The parser invokes alloca or malloc; define the necessary symbols. */
397
398 # ifdef YYSTACK_USE_ALLOCA
399 # if YYSTACK_USE_ALLOCA
400 # ifdef __GNUC__
401 # define YYSTACK_ALLOC __builtin_alloca
402 # elif defined __BUILTIN_VA_ARG_INCR
403 # include <alloca.h> /* INFRINGES ON USER NAME SPACE */
404 # elif defined _AIX
405 # define YYSTACK_ALLOC __alloca
406 # elif defined _MSC_VER
407 # include <malloc.h> /* INFRINGES ON USER NAME SPACE */
408 # define alloca _alloca
409 # else
410 # define YYSTACK_ALLOC alloca
411 # if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS
412 # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
413 /* Use EXIT_SUCCESS as a witness for stdlib.h. */
414 # ifndef EXIT_SUCCESS
415 # define EXIT_SUCCESS 0
416 # endif
417 # endif
418 # endif
419 # endif
420 # endif
421
422 # ifdef YYSTACK_ALLOC
423 /* Pacify GCC's 'empty if-body' warning. */
424 # define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
425 # ifndef YYSTACK_ALLOC_MAXIMUM
426 /* The OS might guarantee only one guard page at the bottom of the stack,
427 and a page size can be as small as 4096 bytes. So we cannot safely
428 invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
429 to allow for a few compiler-allocated temporary stack slots. */
430 # define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
431 # endif
432 # else
433 # define YYSTACK_ALLOC YYMALLOC
434 # define YYSTACK_FREE YYFREE
435 # ifndef YYSTACK_ALLOC_MAXIMUM
436 # define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
437 # endif
438 # if (defined __cplusplus && ! defined EXIT_SUCCESS \
439 && ! ((defined YYMALLOC || defined malloc) \
440 && (defined YYFREE || defined free)))
441 # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
442 # ifndef EXIT_SUCCESS
443 # define EXIT_SUCCESS 0
444 # endif
445 # endif
446 # ifndef YYMALLOC
447 # define YYMALLOC malloc
448 # if ! defined malloc && ! defined EXIT_SUCCESS
449 void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
450 # endif
451 # endif
452 # ifndef YYFREE
453 # define YYFREE free
454 # if ! defined free && ! defined EXIT_SUCCESS
455 void free (void *); /* INFRINGES ON USER NAME SPACE */
456 # endif
457 # endif
458 # endif
459 #endif /* ! defined yyoverflow || YYERROR_VERBOSE */
460
461
462 #if (! defined yyoverflow \
463 && (! defined __cplusplus \
464 || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
465
466 /* A type that is properly aligned for any stack member. */
467 union fmt_yyalloc
468 {
469 yytype_int16 yyss_alloc;
470 YYSTYPE yyvs_alloc;
471 };
472
473 /* The size of the maximum gap between one aligned stack and the next. */
474 # define YYSTACK_GAP_MAXIMUM (sizeof (union fmt_yyalloc) - 1)
475
476 /* The size of an array large to enough to hold all stacks, each with
477 N elements. */
478 # define YYSTACK_BYTES(N) \
479 ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
480 + YYSTACK_GAP_MAXIMUM)
481
482 # define YYCOPY_NEEDED 1
483
484 /* Relocate STACK from its old location to the new one. The
485 local variables YYSIZE and YYSTACKSIZE give the old and new number of
486 elements in the stack, and YYPTR gives the new location of the
487 stack. Advance YYPTR to a properly aligned location for the next
488 stack. */
489 # define YYSTACK_RELOCATE(Stack_alloc, Stack) \
490 do \
491 { \
492 YYSIZE_T yynewbytes; \
493 YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \
494 Stack = &yyptr->Stack_alloc; \
495 yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
496 yyptr += yynewbytes / sizeof (*yyptr); \
497 } \
498 while (0)
499
500 #endif
501
502 #if defined YYCOPY_NEEDED && YYCOPY_NEEDED
503 /* Copy COUNT objects from SRC to DST. The source and destination do
504 not overlap. */
505 # ifndef YYCOPY
506 # if defined __GNUC__ && 1 < __GNUC__
507 # define YYCOPY(Dst, Src, Count) \
508 __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src)))
509 # else
510 # define YYCOPY(Dst, Src, Count) \
511 do \
512 { \
513 YYSIZE_T yyi; \
514 for (yyi = 0; yyi < (Count); yyi++) \
515 (Dst)[yyi] = (Src)[yyi]; \
516 } \
517 while (0)
518 # endif
519 # endif
520 #endif /* !YYCOPY_NEEDED */
521
522 /* YYFINAL -- State number of the termination state. */
523 #define YYFINAL 11
524 /* YYLAST -- Last index in YYTABLE. */
525 #define YYLAST 36
526
527 /* YYNTOKENS -- Number of terminals. */
528 #define YYNTOKENS 15
529 /* YYNNTS -- Number of nonterminals. */
530 #define YYNNTS 21
531 /* YYNRULES -- Number of rules. */
532 #define YYNRULES 34
533 /* YYNSTATES -- Number of states. */
534 #define YYNSTATES 44
535
536 /* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
537 by fmt_yylex, with out-of-bounds checking. */
538 #define YYUNDEFTOK 2
539 #define YYMAXUTOK 269
540
541 #define YYTRANSLATE(YYX) \
542 ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
543
544 /* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
545 as returned by fmt_yylex, without out-of-bounds checking. */
546 static const yytype_uint8 yytranslate[] =
547 {
548 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
549 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
550 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
551 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
552 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
553 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
554 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
555 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
556 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
557 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
558 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
559 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
560 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
561 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
562 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
563 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
564 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
565 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
566 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
567 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
568 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
569 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
570 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
571 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
572 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
573 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
574 5, 6, 7, 8, 9, 10, 11, 12, 13, 14
575 };
576
577 #if YYDEBUG
578 /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
579 static const yytype_uint16 yyrline[] =
580 {
581 0, 156, 156, 162, 166, 175, 182, 185, 186, 199,
582 200, 203, 215, 315, 318, 321, 328, 331, 349, 356,
583 366, 369, 372, 378, 384, 391, 399, 400, 404, 407,
584 408, 414, 422, 434, 442
585 };
586 #endif
587
588 #if YYDEBUG || YYERROR_VERBOSE || 1
589 /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
590 First, the terminals, then, starting at YYNTOKENS, nonterminals. */
591 static const char *const yytname[] =
592 {
593 "$end", "error", "$undefined", "\"number\"", "\"string\"",
594 "\"component\"", "\"argument\"", "\"function name\"", "\"%<\"", "\"%?\"",
595 "\"%|\"", "\"%>\"", "\"format specifier\"", "BOGUS", "\")\"", "$accept",
596 "input", "list", "item", "escape", "printable", "component", "funcall",
597 "fmtspec", "function", "argument", "cntl", "zlist", "if", "fi", "elif",
598 "cond", "cond_expr", "elif_part", "elif_list", "else_part", YY_NULLPTR
599 };
600 #endif
601
602 # ifdef YYPRINT
603 /* YYTOKNUM[NUM] -- (External) token number corresponding to the
604 (internal) symbol number NUM (which must be that of a token). */
605 static const yytype_uint16 yytoknum[] =
606 {
607 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
608 265, 266, 267, 268, 269
609 };
610 # endif
611
612 #define YYPACT_NINF -29
613
614 #define yypact_value_is_default(Yystate) \
615 (!!((Yystate) == (-29)))
616
617 #define YYTABLE_NINF -17
618
619 #define yytable_value_is_error(Yytable_value) \
620 0
621
622 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
623 STATE-NUM. */
624 static const yytype_int8 fmt_yypact[] =
625 {
626 11, -29, -29, -29, 24, 1, -29, -29, 15, -29,
627 15, -29, -29, -29, -29, -29, -29, -29, 4, -29,
628 -29, -1, -29, -29, -29, 14, -1, 17, -29, -29,
629 -1, 15, 18, 17, -29, -29, -1, -29, -29, 15,
630 -29, -29, -1, -29
631 };
632
633 /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
634 Performed when YYTABLE does not specify something else to do. Zero
635 means the default is an error. */
636 static const yytype_uint8 yydefact[] =
637 {
638 13, 5, 22, 14, 0, 13, 3, 6, 0, 7,
639 0, 1, 4, 11, 15, 8, 9, 10, 13, 26,
640 27, 20, 25, 17, 18, 0, 21, 28, 12, 24,
641 20, 0, 0, 30, 29, 34, 20, 23, 19, 0,
642 33, 31, 20, 32
643 };
644
645 /* YYPGOTO[NTERM-NUM]. */
646 static const yytype_int8 yypgoto[] =
647 {
648 -29, -29, 30, -5, 13, -29, 25, 26, -29, -29,
649 -29, -29, -28, -29, -29, 2, -14, -29, -29, -29,
650 3
651 };
652
653 /* YYDEFGOTO[NTERM-NUM]. */
654 static const yytype_int8 yydefgoto[] =
655 {
656 -1, 4, 26, 6, 7, 15, 19, 20, 8, 18,
657 25, 9, 27, 10, 38, 31, 21, 22, 32, 33,
658 34
659 };
660
661 /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If
662 positive, shift that token. If negative, reduce the rule whose
663 number is the opposite. If YYTABLE_NINF, syntax error. */
664 static const yytype_int8 fmt_yytable[] =
665 {
666 12, -2, 35, 1, -13, 1, -13, 2, 41, 2,
667 23, 3, 2, 3, 43, 1, 3, 36, -16, 2,
668 13, 12, 14, 3, 11, 42, 29, 30, 28, 37,
669 5, 24, 0, 16, 17, 39, 40
670 };
671
672 static const yytype_int8 fmt_yycheck[] =
673 {
674 5, 0, 30, 4, 5, 4, 7, 8, 36, 8,
675 6, 12, 8, 12, 42, 4, 12, 31, 14, 8,
676 5, 26, 7, 12, 0, 39, 9, 10, 14, 11,
677 0, 18, -1, 8, 8, 33, 33
678 };
679
680 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
681 symbol of state STATE-NUM. */
682 static const yytype_uint8 yystos[] =
683 {
684 0, 4, 8, 12, 16, 17, 18, 19, 23, 26,
685 28, 0, 18, 5, 7, 20, 21, 22, 24, 21,
686 22, 31, 32, 6, 19, 25, 17, 27, 14, 9,
687 10, 30, 33, 34, 35, 27, 31, 11, 29, 30,
688 35, 27, 31, 27
689 };
690
691 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
692 static const yytype_uint8 fmt_yyr1[] =
693 {
694 0, 15, 16, 17, 17, 18, 18, 19, 19, 20,
695 20, 21, 22, 23, 23, 24, 25, 25, 25, 26,
696 27, 27, 28, 29, 30, 31, 32, 32, 33, 33,
697 33, 34, 34, 34, 35
698 };
699
700 /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */
701 static const yytype_uint8 fmt_yyr2[] =
702 {
703 0, 2, 1, 1, 2, 1, 1, 1, 2, 1,
704 1, 1, 3, 0, 1, 1, 0, 1, 1, 5,
705 0, 1, 1, 1, 1, 1, 1, 1, 0, 1,
706 1, 3, 4, 2, 2
707 };
708
709
710 #define yyerrok (yyerrstatus = 0)
711 #define yyclearin (fmt_yychar = YYEMPTY)
712 #define YYEMPTY (-2)
713 #define YYEOF 0
714
715 #define YYACCEPT goto yyacceptlab
716 #define YYABORT goto yyabortlab
717 #define YYERROR goto yyerrorlab
718
719
720 #define YYRECOVERING() (!!yyerrstatus)
721
722 #define YYBACKUP(Token, Value) \
723 do \
724 if (fmt_yychar == YYEMPTY) \
725 { \
726 fmt_yychar = (Token); \
727 fmt_yylval = (Value); \
728 YYPOPSTACK (fmt_yylen); \
729 fmt_yystate = *yyssp; \
730 goto yybackup; \
731 } \
732 else \
733 { \
734 fmt_yyerror (YY_("syntax error: cannot back up")); \
735 YYERROR; \
736 } \
737 while (0)
738
739 /* Error token number */
740 #define YYTERROR 1
741 #define YYERRCODE 256
742
743
744
745 /* Enable debugging if requested. */
746 #if YYDEBUG
747
748 # ifndef YYFPRINTF
749 # include <stdio.h> /* INFRINGES ON USER NAME SPACE */
750 # define YYFPRINTF fprintf
751 # endif
752
753 # define YYDPRINTF(Args) \
754 do { \
755 if (fmt_yydebug) \
756 YYFPRINTF Args; \
757 } while (0)
758
759 /* This macro is provided for backward compatibility. */
760 #ifndef YY_LOCATION_PRINT
761 # define YY_LOCATION_PRINT(File, Loc) ((void) 0)
762 #endif
763
764
765 # define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
766 do { \
767 if (fmt_yydebug) \
768 { \
769 YYFPRINTF (stderr, "%s ", Title); \
770 yy_symbol_print (stderr, \
771 Type, Value); \
772 YYFPRINTF (stderr, "\n"); \
773 } \
774 } while (0)
775
776
777 /*----------------------------------------.
778 | Print this symbol's value on YYOUTPUT. |
779 `----------------------------------------*/
780
781 static void
yy_symbol_value_print(FILE * yyoutput,int yytype,YYSTYPE const * const yyvaluep)782 yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
783 {
784 FILE *yyo = yyoutput;
785 YYUSE (yyo);
786 if (!yyvaluep)
787 return;
788 # ifdef YYPRINT
789 if (yytype < YYNTOKENS)
790 YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
791 # endif
792 YYUSE (yytype);
793 }
794
795
796 /*--------------------------------.
797 | Print this symbol on YYOUTPUT. |
798 `--------------------------------*/
799
800 static void
yy_symbol_print(FILE * yyoutput,int yytype,YYSTYPE const * const yyvaluep)801 yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
802 {
803 YYFPRINTF (yyoutput, "%s %s (",
804 yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]);
805
806 yy_symbol_value_print (yyoutput, yytype, yyvaluep);
807 YYFPRINTF (yyoutput, ")");
808 }
809
810 /*------------------------------------------------------------------.
811 | yy_stack_print -- Print the state stack from its BOTTOM up to its |
812 | TOP (included). |
813 `------------------------------------------------------------------*/
814
815 static void
yy_stack_print(yytype_int16 * yybottom,yytype_int16 * yytop)816 yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
817 {
818 YYFPRINTF (stderr, "Stack now");
819 for (; yybottom <= yytop; yybottom++)
820 {
821 int yybot = *yybottom;
822 YYFPRINTF (stderr, " %d", yybot);
823 }
824 YYFPRINTF (stderr, "\n");
825 }
826
827 # define YY_STACK_PRINT(Bottom, Top) \
828 do { \
829 if (fmt_yydebug) \
830 yy_stack_print ((Bottom), (Top)); \
831 } while (0)
832
833
834 /*------------------------------------------------.
835 | Report that the YYRULE is going to be reduced. |
836 `------------------------------------------------*/
837
838 static void
yy_reduce_print(yytype_int16 * yyssp,YYSTYPE * yyvsp,int fmt_yyrule)839 yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int fmt_yyrule)
840 {
841 unsigned long int yylno = yyrline[fmt_yyrule];
842 int yynrhs = fmt_yyr2[fmt_yyrule];
843 int yyi;
844 YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
845 fmt_yyrule - 1, yylno);
846 /* The symbols being reduced. */
847 for (yyi = 0; yyi < yynrhs; yyi++)
848 {
849 YYFPRINTF (stderr, " $%d = ", yyi + 1);
850 yy_symbol_print (stderr,
851 yystos[yyssp[yyi + 1 - yynrhs]],
852 &(yyvsp[(yyi + 1) - (yynrhs)])
853 );
854 YYFPRINTF (stderr, "\n");
855 }
856 }
857
858 # define YY_REDUCE_PRINT(Rule) \
859 do { \
860 if (fmt_yydebug) \
861 yy_reduce_print (yyssp, yyvsp, Rule); \
862 } while (0)
863
864 /* Nonzero means print parse trace. It is left uninitialized so that
865 multiple parsers can coexist. */
866 int fmt_yydebug;
867 #else /* !YYDEBUG */
868 # define YYDPRINTF(Args)
869 # define YY_SYMBOL_PRINT(Title, Type, Value, Location)
870 # define YY_STACK_PRINT(Bottom, Top)
871 # define YY_REDUCE_PRINT(Rule)
872 #endif /* !YYDEBUG */
873
874
875 /* YYINITDEPTH -- initial size of the parser's stacks. */
876 #ifndef YYINITDEPTH
877 # define YYINITDEPTH 200
878 #endif
879
880 /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
881 if the built-in stack extension method is used).
882
883 Do not make this value too large; the results are undefined if
884 YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
885 evaluated with infinite-precision integer arithmetic. */
886
887 #ifndef YYMAXDEPTH
888 # define YYMAXDEPTH 10000
889 #endif
890
891
892 #if YYERROR_VERBOSE
893
894 # ifndef yystrlen
895 # if defined __GLIBC__ && defined _STRING_H
896 # define yystrlen strlen
897 # else
898 /* Return the length of YYSTR. */
899 static YYSIZE_T
yystrlen(const char * yystr)900 yystrlen (const char *yystr)
901 {
902 YYSIZE_T fmt_yylen;
903 for (fmt_yylen = 0; yystr[fmt_yylen]; fmt_yylen++)
904 continue;
905 return fmt_yylen;
906 }
907 # endif
908 # endif
909
910 # ifndef yystpcpy
911 # if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
912 # define yystpcpy stpcpy
913 # else
914 /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
915 YYDEST. */
916 static char *
yystpcpy(char * yydest,const char * yysrc)917 yystpcpy (char *yydest, const char *yysrc)
918 {
919 char *yyd = yydest;
920 const char *fmt_yys = yysrc;
921
922 while ((*yyd++ = *fmt_yys++) != '\0')
923 continue;
924
925 return yyd - 1;
926 }
927 # endif
928 # endif
929
930 # ifndef yytnamerr
931 /* Copy to YYRES the contents of YYSTR after stripping away unnecessary
932 quotes and backslashes, so that it's suitable for fmt_yyerror. The
933 heuristic is that double-quoting is unnecessary unless the string
934 contains an apostrophe, a comma, or backslash (other than
935 backslash-backslash). YYSTR is taken from yytname. If YYRES is
936 null, do not copy; instead, return the length of what the result
937 would have been. */
938 static YYSIZE_T
yytnamerr(char * yyres,const char * yystr)939 yytnamerr (char *yyres, const char *yystr)
940 {
941 if (*yystr == '"')
942 {
943 YYSIZE_T yyn = 0;
944 char const *yyp = yystr;
945
946 for (;;)
947 switch (*++yyp)
948 {
949 case '\'':
950 case ',':
951 goto do_not_strip_quotes;
952
953 case '\\':
954 if (*++yyp != '\\')
955 goto do_not_strip_quotes;
956 /* Fall through. */
957 default:
958 if (yyres)
959 yyres[yyn] = *yyp;
960 yyn++;
961 break;
962
963 case '"':
964 if (yyres)
965 yyres[yyn] = '\0';
966 return yyn;
967 }
968 do_not_strip_quotes: ;
969 }
970
971 if (! yyres)
972 return yystrlen (yystr);
973
974 return yystpcpy (yyres, yystr) - yyres;
975 }
976 # endif
977
978 /* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
979 about the unexpected token YYTOKEN for the state stack whose top is
980 YYSSP.
981
982 Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is
983 not large enough to hold the message. In that case, also set
984 *YYMSG_ALLOC to the required number of bytes. Return 2 if the
985 required number of bytes is too large to store. */
986 static int
yysyntax_error(YYSIZE_T * yymsg_alloc,char ** yymsg,yytype_int16 * yyssp,int yytoken)987 yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
988 yytype_int16 *yyssp, int yytoken)
989 {
990 YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]);
991 YYSIZE_T yysize = yysize0;
992 enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
993 /* Internationalized format string. */
994 const char *yyformat = YY_NULLPTR;
995 /* Arguments of yyformat. */
996 char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
997 /* Number of reported tokens (one for the "unexpected", one per
998 "expected"). */
999 int yycount = 0;
1000
1001 /* There are many possibilities here to consider:
1002 - If this state is a consistent state with a default action, then
1003 the only way this function was invoked is if the default action
1004 is an error action. In that case, don't check for expected
1005 tokens because there are none.
1006 - The only way there can be no lookahead present (in fmt_yychar) is if
1007 this state is a consistent state with a default action. Thus,
1008 detecting the absence of a lookahead is sufficient to determine
1009 that there is no unexpected or expected token to report. In that
1010 case, just report a simple "syntax error".
1011 - Don't assume there isn't a lookahead just because this state is a
1012 consistent state with a default action. There might have been a
1013 previous inconsistent state, consistent state with a non-default
1014 action, or user semantic action that manipulated fmt_yychar.
1015 - Of course, the expected token list depends on states to have
1016 correct lookahead information, and it depends on the parser not
1017 to perform extra reductions after fetching a lookahead from the
1018 scanner and before detecting a syntax error. Thus, state merging
1019 (from LALR or IELR) and default reductions corrupt the expected
1020 token list. However, the list is correct for canonical LR with
1021 one exception: it will still contain any token that will not be
1022 accepted due to an error action in a later state.
1023 */
1024 if (yytoken != YYEMPTY)
1025 {
1026 int yyn = fmt_yypact[*yyssp];
1027 yyarg[yycount++] = yytname[yytoken];
1028 if (!yypact_value_is_default (yyn))
1029 {
1030 /* Start YYX at -YYN if negative to avoid negative indexes in
1031 YYCHECK. In other words, skip the first -YYN actions for
1032 this state because they are default actions. */
1033 int yyxbegin = yyn < 0 ? -yyn : 0;
1034 /* Stay within bounds of both fmt_yycheck and yytname. */
1035 int yychecklim = YYLAST - yyn + 1;
1036 int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
1037 int yyx;
1038
1039 for (yyx = yyxbegin; yyx < yyxend; ++yyx)
1040 if (fmt_yycheck[yyx + yyn] == yyx && yyx != YYTERROR
1041 && !yytable_value_is_error (fmt_yytable[yyx + yyn]))
1042 {
1043 if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
1044 {
1045 yycount = 1;
1046 yysize = yysize0;
1047 break;
1048 }
1049 yyarg[yycount++] = yytname[yyx];
1050 {
1051 YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]);
1052 if (! (yysize <= yysize1
1053 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
1054 return 2;
1055 yysize = yysize1;
1056 }
1057 }
1058 }
1059 }
1060
1061 switch (yycount)
1062 {
1063 # define YYCASE_(N, S) \
1064 case N: \
1065 yyformat = S; \
1066 break
1067 YYCASE_(0, YY_("syntax error"));
1068 YYCASE_(1, YY_("syntax error, unexpected %s"));
1069 YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
1070 YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
1071 YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
1072 YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
1073 # undef YYCASE_
1074 }
1075
1076 {
1077 YYSIZE_T yysize1 = yysize + yystrlen (yyformat);
1078 if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
1079 return 2;
1080 yysize = yysize1;
1081 }
1082
1083 if (*yymsg_alloc < yysize)
1084 {
1085 *yymsg_alloc = 2 * yysize;
1086 if (! (yysize <= *yymsg_alloc
1087 && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
1088 *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
1089 return 1;
1090 }
1091
1092 /* Avoid sprintf, as that infringes on the user's name space.
1093 Don't have undefined behavior even if the translation
1094 produced a string with the wrong number of "%s"s. */
1095 {
1096 char *yyp = *yymsg;
1097 int yyi = 0;
1098 while ((*yyp = *yyformat) != '\0')
1099 if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
1100 {
1101 yyp += yytnamerr (yyp, yyarg[yyi++]);
1102 yyformat += 2;
1103 }
1104 else
1105 {
1106 yyp++;
1107 yyformat++;
1108 }
1109 }
1110 return 0;
1111 }
1112 #endif /* YYERROR_VERBOSE */
1113
1114 /*-----------------------------------------------.
1115 | Release the memory associated to this symbol. |
1116 `-----------------------------------------------*/
1117
1118 static void
yydestruct(const char * yymsg,int yytype,YYSTYPE * yyvaluep)1119 yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
1120 {
1121 YYUSE (yyvaluep);
1122 if (!yymsg)
1123 yymsg = "Deleting";
1124 YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
1125
1126 YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
1127 YYUSE (yytype);
1128 YY_IGNORE_MAYBE_UNINITIALIZED_END
1129 }
1130
1131
1132
1133
1134 /* The lookahead symbol. */
1135 int fmt_yychar;
1136
1137 /* The semantic value of the lookahead symbol. */
1138 YYSTYPE fmt_yylval;
1139 /* Number of syntax errors so far. */
1140 int fmt_yynerrs;
1141
1142
1143 /*----------.
1144 | fmt_yyparse. |
1145 `----------*/
1146
1147 int
fmt_yyparse(void)1148 fmt_yyparse (void)
1149 {
1150 int fmt_yystate;
1151 /* Number of tokens to shift before error messages enabled. */
1152 int yyerrstatus;
1153
1154 /* The stacks and their tools:
1155 'yyss': related to states.
1156 'yyvs': related to semantic values.
1157
1158 Refer to the stacks through separate pointers, to allow yyoverflow
1159 to reallocate them elsewhere. */
1160
1161 /* The state stack. */
1162 yytype_int16 yyssa[YYINITDEPTH];
1163 yytype_int16 *yyss;
1164 yytype_int16 *yyssp;
1165
1166 /* The semantic value stack. */
1167 YYSTYPE yyvsa[YYINITDEPTH];
1168 YYSTYPE *yyvs;
1169 YYSTYPE *yyvsp;
1170
1171 YYSIZE_T yystacksize;
1172
1173 int yyn;
1174 int yyresult;
1175 /* Lookahead token as an internal (translated) token number. */
1176 int yytoken = 0;
1177 /* The variables used to return semantic value and location from the
1178 action routines. */
1179 YYSTYPE fmt_yyval;
1180
1181 #if YYERROR_VERBOSE
1182 /* Buffer for error messages, and its allocated size. */
1183 char yymsgbuf[128];
1184 char *yymsg = yymsgbuf;
1185 YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
1186 #endif
1187
1188 #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N))
1189
1190 /* The number of symbols on the RHS of the reduced rule.
1191 Keep to zero when no symbol should be popped. */
1192 int fmt_yylen = 0;
1193
1194 yyssp = yyss = yyssa;
1195 yyvsp = yyvs = yyvsa;
1196 yystacksize = YYINITDEPTH;
1197
1198 YYDPRINTF ((stderr, "Starting parse\n"));
1199
1200 fmt_yystate = 0;
1201 yyerrstatus = 0;
1202 fmt_yynerrs = 0;
1203 fmt_yychar = YYEMPTY; /* Cause a token to be read. */
1204 goto yysetstate;
1205
1206 /*------------------------------------------------------------.
1207 | yynewstate -- Push a new state, which is found in fmt_yystate. |
1208 `------------------------------------------------------------*/
1209 yynewstate:
1210 /* In all cases, when you get here, the value and location stacks
1211 have just been pushed. So pushing a state here evens the stacks. */
1212 yyssp++;
1213
1214 yysetstate:
1215 *yyssp = fmt_yystate;
1216
1217 if (yyss + yystacksize - 1 <= yyssp)
1218 {
1219 /* Get the current used size of the three stacks, in elements. */
1220 YYSIZE_T yysize = yyssp - yyss + 1;
1221
1222 #ifdef yyoverflow
1223 {
1224 /* Give user a chance to reallocate the stack. Use copies of
1225 these so that the &'s don't force the real ones into
1226 memory. */
1227 YYSTYPE *yyvs1 = yyvs;
1228 yytype_int16 *yyss1 = yyss;
1229
1230 /* Each stack pointer address is followed by the size of the
1231 data in use in that stack, in bytes. This used to be a
1232 conditional around just the two extra args, but that might
1233 be undefined if yyoverflow is a macro. */
1234 yyoverflow (YY_("memory exhausted"),
1235 &yyss1, yysize * sizeof (*yyssp),
1236 &yyvs1, yysize * sizeof (*yyvsp),
1237 &yystacksize);
1238
1239 yyss = yyss1;
1240 yyvs = yyvs1;
1241 }
1242 #else /* no yyoverflow */
1243 # ifndef YYSTACK_RELOCATE
1244 goto yyexhaustedlab;
1245 # else
1246 /* Extend the stack our own way. */
1247 if (YYMAXDEPTH <= yystacksize)
1248 goto yyexhaustedlab;
1249 yystacksize *= 2;
1250 if (YYMAXDEPTH < yystacksize)
1251 yystacksize = YYMAXDEPTH;
1252
1253 {
1254 yytype_int16 *yyss1 = yyss;
1255 union fmt_yyalloc *yyptr =
1256 (union fmt_yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
1257 if (! yyptr)
1258 goto yyexhaustedlab;
1259 YYSTACK_RELOCATE (yyss_alloc, yyss);
1260 YYSTACK_RELOCATE (yyvs_alloc, yyvs);
1261 # undef YYSTACK_RELOCATE
1262 if (yyss1 != yyssa)
1263 YYSTACK_FREE (yyss1);
1264 }
1265 # endif
1266 #endif /* no yyoverflow */
1267
1268 yyssp = yyss + yysize - 1;
1269 yyvsp = yyvs + yysize - 1;
1270
1271 YYDPRINTF ((stderr, "Stack size increased to %lu\n",
1272 (unsigned long int) yystacksize));
1273
1274 if (yyss + yystacksize - 1 <= yyssp)
1275 YYABORT;
1276 }
1277
1278 YYDPRINTF ((stderr, "Entering state %d\n", fmt_yystate));
1279
1280 if (fmt_yystate == YYFINAL)
1281 YYACCEPT;
1282
1283 goto yybackup;
1284
1285 /*-----------.
1286 | yybackup. |
1287 `-----------*/
1288 yybackup:
1289
1290 /* Do appropriate processing given the current state. Read a
1291 lookahead token if we need one and don't already have one. */
1292
1293 /* First try to decide what to do without reference to lookahead token. */
1294 yyn = fmt_yypact[fmt_yystate];
1295 if (yypact_value_is_default (yyn))
1296 goto yydefault;
1297
1298 /* Not known => get a lookahead token if don't already have one. */
1299
1300 /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
1301 if (fmt_yychar == YYEMPTY)
1302 {
1303 YYDPRINTF ((stderr, "Reading a token: "));
1304 fmt_yychar = fmt_yylex ();
1305 }
1306
1307 if (fmt_yychar <= YYEOF)
1308 {
1309 fmt_yychar = yytoken = YYEOF;
1310 YYDPRINTF ((stderr, "Now at end of input.\n"));
1311 }
1312 else
1313 {
1314 yytoken = YYTRANSLATE (fmt_yychar);
1315 YY_SYMBOL_PRINT ("Next token is", yytoken, &fmt_yylval, &fmt_yylloc);
1316 }
1317
1318 /* If the proper action on seeing token YYTOKEN is to reduce or to
1319 detect an error, take that action. */
1320 yyn += yytoken;
1321 if (yyn < 0 || YYLAST < yyn || fmt_yycheck[yyn] != yytoken)
1322 goto yydefault;
1323 yyn = fmt_yytable[yyn];
1324 if (yyn <= 0)
1325 {
1326 if (yytable_value_is_error (yyn))
1327 goto yyerrlab;
1328 yyn = -yyn;
1329 goto yyreduce;
1330 }
1331
1332 /* Count tokens shifted since error; after three, turn off error
1333 status. */
1334 if (yyerrstatus)
1335 yyerrstatus--;
1336
1337 /* Shift the lookahead token. */
1338 YY_SYMBOL_PRINT ("Shifting", yytoken, &fmt_yylval, &fmt_yylloc);
1339
1340 /* Discard the shifted token. */
1341 fmt_yychar = YYEMPTY;
1342
1343 fmt_yystate = yyn;
1344 YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
1345 *++yyvsp = fmt_yylval;
1346 YY_IGNORE_MAYBE_UNINITIALIZED_END
1347
1348 goto yynewstate;
1349
1350
1351 /*-----------------------------------------------------------.
1352 | yydefault -- do the default action for the current state. |
1353 `-----------------------------------------------------------*/
1354 yydefault:
1355 yyn = yydefact[fmt_yystate];
1356 if (yyn == 0)
1357 goto yyerrlab;
1358 goto yyreduce;
1359
1360
1361 /*-----------------------------.
1362 | yyreduce -- Do a reduction. |
1363 `-----------------------------*/
1364 yyreduce:
1365 /* yyn is the number of a rule to reduce with. */
1366 fmt_yylen = fmt_yyr2[yyn];
1367
1368 /* If YYLEN is nonzero, implement the default value of the action:
1369 '$$ = $1'.
1370
1371 Otherwise, the following line sets YYVAL to garbage.
1372 This behavior is undocumented and Bison
1373 users should not rely upon it. Assigning to YYVAL
1374 unconditionally makes the parser a bit smaller, and it avoids a
1375 GCC warning that YYVAL may be used uninitialized. */
1376 fmt_yyval = yyvsp[1-fmt_yylen];
1377
1378
1379 YY_REDUCE_PRINT (yyn);
1380 switch (yyn)
1381 {
1382 case 2:
1383 #line 157 "mh_fmtgram.y" /* yacc.c:1646 */
1384 {
1385 parse_tree = (yyvsp[0].nodelist).head;
1386 }
1387 #line 1388 "mh_fmtgram.c" /* yacc.c:1646 */
1388 break;
1389
1390 case 3:
1391 #line 163 "mh_fmtgram.y" /* yacc.c:1646 */
1392 {
1393 (fmt_yyval.nodelist).head = (fmt_yyval.nodelist).tail = (yyvsp[0].nodeptr);
1394 }
1395 #line 1396 "mh_fmtgram.c" /* yacc.c:1646 */
1396 break;
1397
1398 case 4:
1399 #line 167 "mh_fmtgram.y" /* yacc.c:1646 */
1400 {
1401 (yyvsp[0].nodeptr)->prev = (yyvsp[-1].nodelist).tail;
1402 (yyvsp[-1].nodelist).tail->next = (yyvsp[0].nodeptr);
1403 (yyvsp[-1].nodelist).tail = (yyvsp[0].nodeptr);
1404 (fmt_yyval.nodelist) = (yyvsp[-1].nodelist);
1405 }
1406 #line 1407 "mh_fmtgram.c" /* yacc.c:1646 */
1407 break;
1408
1409 case 5:
1410 #line 176 "mh_fmtgram.y" /* yacc.c:1646 */
1411 {
1412 struct node *n = new_node (fmtnode_literal, mhtype_str);
1413 n->v.str = (yyvsp[0].str);
1414 (fmt_yyval.nodeptr) = new_node (fmtnode_print, mhtype_str);
1415 (fmt_yyval.nodeptr)->v.prt.arg = n;
1416 }
1417 #line 1418 "mh_fmtgram.c" /* yacc.c:1646 */
1418 break;
1419
1420 case 8:
1421 #line 187 "mh_fmtgram.y" /* yacc.c:1646 */
1422 {
1423 if ((yyvsp[0].nodeptr)->printflag & MHA_NOPRINT)
1424 (fmt_yyval.nodeptr) = (yyvsp[0].nodeptr);
1425 else
1426 {
1427 (fmt_yyval.nodeptr) = new_node (fmtnode_print, (yyvsp[0].nodeptr)->datatype);
1428 (fmt_yyval.nodeptr)->v.prt.fmtspec = ((yyvsp[0].nodeptr)->printflag & MHA_IGNOREFMT) ? 0 : (yyvsp[-1].fmtspec);
1429 (fmt_yyval.nodeptr)->v.prt.arg = (yyvsp[0].nodeptr);
1430 }
1431 }
1432 #line 1433 "mh_fmtgram.c" /* yacc.c:1646 */
1433 break;
1434
1435 case 11:
1436 #line 204 "mh_fmtgram.y" /* yacc.c:1646 */
1437 {
1438 if (mu_c_strcasecmp ((yyvsp[0].str), "body") == 0)
1439 (fmt_yyval.nodeptr) = new_node (fmtnode_body, mhtype_str);
1440 else
1441 {
1442 (fmt_yyval.nodeptr) = new_node (fmtnode_comp, mhtype_str);
1443 (fmt_yyval.nodeptr)->v.str = (yyvsp[0].str);
1444 }
1445 }
1446 #line 1447 "mh_fmtgram.c" /* yacc.c:1646 */
1447 break;
1448
1449 case 12:
1450 #line 216 "mh_fmtgram.y" /* yacc.c:1646 */
1451 {
1452 struct node *arg;
1453
1454 ctx_pop ();
1455
1456 arg = (yyvsp[-1].nodeptr);
1457 if ((yyvsp[-2].builtin)->argtype == mhtype_none)
1458 {
1459 if (arg)
1460 {
1461 fmt_yyerror ("function doesn't take arguments");
1462 YYABORT;
1463 }
1464 }
1465 else if (arg == NULL)
1466 {
1467 if ((yyvsp[-2].builtin)->flags & MHA_OPTARG_NIL)
1468 {
1469 switch ((yyvsp[-2].builtin)->argtype)
1470 {
1471 case mhtype_str:
1472 arg = new_node (fmtnode_literal, mhtype_str);
1473 arg->v.str = "";
1474 break;
1475
1476 case mhtype_num:
1477 arg = new_node (fmtnode_number, mhtype_num);
1478 arg->v.num = 0;
1479 break;
1480
1481 default:
1482 abort ();
1483 }
1484 }
1485 else if ((yyvsp[-2].builtin)->flags & MHA_OPTARG)
1486 {
1487 /* ok - ignore */;
1488 }
1489 else
1490 {
1491 fmt_yyerror ("required argument missing");
1492 YYABORT;
1493 }
1494 }
1495 else if ((yyvsp[-2].builtin)->flags & MHA_LITERAL)
1496 {
1497 switch ((yyvsp[-2].builtin)->argtype)
1498 {
1499 case mhtype_num:
1500 if (arg->nodetype == fmtnode_number)
1501 /* ok */;
1502 else
1503 {
1504 fmt_yyerror ("argument must be a number");
1505 YYABORT;
1506 }
1507 break;
1508
1509 case mhtype_str:
1510 if (arg->nodetype == fmtnode_literal)
1511 /* ok */;
1512 else if (arg->nodetype == fmtnode_number)
1513 {
1514 char *s;
1515 mu_asprintf (&s, "%ld", arg->v.num);
1516 arg->nodetype = fmtnode_literal;
1517 arg->datatype = mhtype_str;
1518 arg->v.str = s;
1519 }
1520 else
1521 {
1522 fmt_yyerror ("argument must be literal");
1523 YYABORT;
1524 }
1525 break;
1526
1527 default:
1528 break;
1529 }
1530 }
1531
1532 if ((yyvsp[-2].builtin)->flags & MHA_VOID)
1533 {
1534 (yyvsp[-1].nodeptr)->printflag = MHA_NOPRINT;
1535 (fmt_yyval.nodeptr) = (yyvsp[-1].nodeptr);
1536 }
1537 else
1538 {
1539 (fmt_yyval.nodeptr) = new_node (fmtnode_funcall, (yyvsp[-2].builtin)->type);
1540 (fmt_yyval.nodeptr)->v.funcall.builtin = (yyvsp[-2].builtin);
1541 (fmt_yyval.nodeptr)->v.funcall.arg = typecast (arg, (yyvsp[-2].builtin)->argtype);
1542 (fmt_yyval.nodeptr)->printflag = (yyvsp[-2].builtin)->flags & MHA_PRINT_MASK;
1543 if ((yyvsp[-2].builtin)->type == mhtype_none)
1544 (fmt_yyval.nodeptr)->printflag = MHA_NOPRINT;
1545 }
1546 }
1547 #line 1548 "mh_fmtgram.c" /* yacc.c:1646 */
1548 break;
1549
1550 case 13:
1551 #line 315 "mh_fmtgram.y" /* yacc.c:1646 */
1552 {
1553 (fmt_yyval.fmtspec) = 0;
1554 }
1555 #line 1556 "mh_fmtgram.c" /* yacc.c:1646 */
1556 break;
1557
1558 case 15:
1559 #line 322 "mh_fmtgram.y" /* yacc.c:1646 */
1560 {
1561 ctx_push (ctx_func);
1562 }
1563 #line 1564 "mh_fmtgram.c" /* yacc.c:1646 */
1564 break;
1565
1566 case 16:
1567 #line 328 "mh_fmtgram.y" /* yacc.c:1646 */
1568 {
1569 (fmt_yyval.nodeptr) = NULL;
1570 }
1571 #line 1572 "mh_fmtgram.c" /* yacc.c:1646 */
1572 break;
1573
1574 case 17:
1575 #line 332 "mh_fmtgram.y" /* yacc.c:1646 */
1576 {
1577 switch ((yyvsp[0].arg).type)
1578 {
1579 case mhtype_none:
1580 (fmt_yyval.nodeptr) = NULL;
1581 break;
1582
1583 case mhtype_str:
1584 (fmt_yyval.nodeptr) = new_node (fmtnode_literal, mhtype_str);
1585 (fmt_yyval.nodeptr)->v.str = (yyvsp[0].arg).v.str;
1586 break;
1587
1588 case mhtype_num:
1589 (fmt_yyval.nodeptr) = new_node (fmtnode_number, mhtype_num);
1590 (fmt_yyval.nodeptr)->v.num = (yyvsp[0].arg).v.num;
1591 }
1592 }
1593 #line 1594 "mh_fmtgram.c" /* yacc.c:1646 */
1594 break;
1595
1596 case 18:
1597 #line 350 "mh_fmtgram.y" /* yacc.c:1646 */
1598 {
1599 (fmt_yyval.nodeptr) = printelim ((yyvsp[0].nodeptr));
1600 }
1601 #line 1602 "mh_fmtgram.c" /* yacc.c:1646 */
1602 break;
1603
1604 case 19:
1605 #line 357 "mh_fmtgram.y" /* yacc.c:1646 */
1606 {
1607 (fmt_yyval.nodeptr) = new_node(fmtnode_cntl, mhtype_num);
1608 (fmt_yyval.nodeptr)->v.cntl.cond = (yyvsp[-3].nodeptr);
1609 (fmt_yyval.nodeptr)->v.cntl.iftrue = (yyvsp[-2].nodelist).head;
1610 (fmt_yyval.nodeptr)->v.cntl.iffalse = (yyvsp[-1].nodeptr);
1611 }
1612 #line 1613 "mh_fmtgram.c" /* yacc.c:1646 */
1613 break;
1614
1615 case 20:
1616 #line 366 "mh_fmtgram.y" /* yacc.c:1646 */
1617 {
1618 (fmt_yyval.nodelist).head = (fmt_yyval.nodelist).tail = NULL;
1619 }
1620 #line 1621 "mh_fmtgram.c" /* yacc.c:1646 */
1621 break;
1622
1623 case 22:
1624 #line 373 "mh_fmtgram.y" /* yacc.c:1646 */
1625 {
1626 ctx_push (ctx_if);
1627 }
1628 #line 1629 "mh_fmtgram.c" /* yacc.c:1646 */
1629 break;
1630
1631 case 23:
1632 #line 379 "mh_fmtgram.y" /* yacc.c:1646 */
1633 {
1634 ctx_pop ();
1635 }
1636 #line 1637 "mh_fmtgram.c" /* yacc.c:1646 */
1637 break;
1638
1639 case 24:
1640 #line 385 "mh_fmtgram.y" /* yacc.c:1646 */
1641 {
1642 ctx_pop ();
1643 ctx_push (ctx_if);
1644 }
1645 #line 1646 "mh_fmtgram.c" /* yacc.c:1646 */
1646 break;
1647
1648 case 25:
1649 #line 392 "mh_fmtgram.y" /* yacc.c:1646 */
1650 {
1651 ctx_pop ();
1652 ctx_push (ctx_expr);
1653 (fmt_yyval.nodeptr) = printelim ((yyvsp[0].nodeptr));
1654 }
1655 #line 1656 "mh_fmtgram.c" /* yacc.c:1646 */
1656 break;
1657
1658 case 28:
1659 #line 404 "mh_fmtgram.y" /* yacc.c:1646 */
1660 {
1661 (fmt_yyval.nodeptr) = NULL;
1662 }
1663 #line 1664 "mh_fmtgram.c" /* yacc.c:1646 */
1664 break;
1665
1666 case 30:
1667 #line 409 "mh_fmtgram.y" /* yacc.c:1646 */
1668 {
1669 (fmt_yyval.nodeptr) = (yyvsp[0].nodelist).head;
1670 }
1671 #line 1672 "mh_fmtgram.c" /* yacc.c:1646 */
1672 break;
1673
1674 case 31:
1675 #line 415 "mh_fmtgram.y" /* yacc.c:1646 */
1676 {
1677 struct node *np = new_node (fmtnode_cntl, mhtype_num);
1678 np->v.cntl.cond = (yyvsp[-1].nodeptr);
1679 np->v.cntl.iftrue = (yyvsp[0].nodelist).head;
1680 np->v.cntl.iffalse = NULL;
1681 (fmt_yyval.nodelist).head = (fmt_yyval.nodelist).tail = np;
1682 }
1683 #line 1684 "mh_fmtgram.c" /* yacc.c:1646 */
1684 break;
1685
1686 case 32:
1687 #line 423 "mh_fmtgram.y" /* yacc.c:1646 */
1688 {
1689 struct node *np = new_node(fmtnode_cntl, mhtype_num);
1690 np->v.cntl.cond = (yyvsp[-1].nodeptr);
1691 np->v.cntl.iftrue = (yyvsp[0].nodelist).head;
1692 np->v.cntl.iffalse = NULL;
1693
1694 (yyvsp[-3].nodelist).tail->v.cntl.iffalse = np;
1695 (yyvsp[-3].nodelist).tail = np;
1696
1697 (fmt_yyval.nodelist) = (yyvsp[-3].nodelist);
1698 }
1699 #line 1700 "mh_fmtgram.c" /* yacc.c:1646 */
1700 break;
1701
1702 case 33:
1703 #line 435 "mh_fmtgram.y" /* yacc.c:1646 */
1704 {
1705 (yyvsp[-1].nodelist).tail->v.cntl.iffalse = (yyvsp[0].nodeptr);
1706 (yyvsp[-1].nodelist).tail = (yyvsp[0].nodeptr);
1707 (fmt_yyval.nodelist) = (yyvsp[-1].nodelist);
1708 }
1709 #line 1710 "mh_fmtgram.c" /* yacc.c:1646 */
1710 break;
1711
1712 case 34:
1713 #line 443 "mh_fmtgram.y" /* yacc.c:1646 */
1714 {
1715 (fmt_yyval.nodeptr) = (yyvsp[0].nodelist).head;
1716 }
1717 #line 1718 "mh_fmtgram.c" /* yacc.c:1646 */
1718 break;
1719
1720
1721 #line 1722 "mh_fmtgram.c" /* yacc.c:1646 */
1722 default: break;
1723 }
1724 /* User semantic actions sometimes alter fmt_yychar, and that requires
1725 that yytoken be updated with the new translation. We take the
1726 approach of translating immediately before every use of yytoken.
1727 One alternative is translating here after every semantic action,
1728 but that translation would be missed if the semantic action invokes
1729 YYABORT, YYACCEPT, or YYERROR immediately after altering fmt_yychar or
1730 if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an
1731 incorrect destructor might then be invoked immediately. In the
1732 case of YYERROR or YYBACKUP, subsequent parser actions might lead
1733 to an incorrect destructor call or verbose syntax error message
1734 before the lookahead is translated. */
1735 YY_SYMBOL_PRINT ("-> $$ =", fmt_yyr1[yyn], &fmt_yyval, &yyloc);
1736
1737 YYPOPSTACK (fmt_yylen);
1738 fmt_yylen = 0;
1739 YY_STACK_PRINT (yyss, yyssp);
1740
1741 *++yyvsp = fmt_yyval;
1742
1743 /* Now 'shift' the result of the reduction. Determine what state
1744 that goes to, based on the state we popped back to and the rule
1745 number reduced by. */
1746
1747 yyn = fmt_yyr1[yyn];
1748
1749 fmt_yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
1750 if (0 <= fmt_yystate && fmt_yystate <= YYLAST && fmt_yycheck[fmt_yystate] == *yyssp)
1751 fmt_yystate = fmt_yytable[fmt_yystate];
1752 else
1753 fmt_yystate = yydefgoto[yyn - YYNTOKENS];
1754
1755 goto yynewstate;
1756
1757
1758 /*--------------------------------------.
1759 | yyerrlab -- here on detecting error. |
1760 `--------------------------------------*/
1761 yyerrlab:
1762 /* Make sure we have latest lookahead translation. See comments at
1763 user semantic actions for why this is necessary. */
1764 yytoken = fmt_yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (fmt_yychar);
1765
1766 /* If not already recovering from an error, report this error. */
1767 if (!yyerrstatus)
1768 {
1769 ++fmt_yynerrs;
1770 #if ! YYERROR_VERBOSE
1771 fmt_yyerror (YY_("syntax error"));
1772 #else
1773 # define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
1774 yyssp, yytoken)
1775 {
1776 char const *yymsgp = YY_("syntax error");
1777 int yysyntax_error_status;
1778 yysyntax_error_status = YYSYNTAX_ERROR;
1779 if (yysyntax_error_status == 0)
1780 yymsgp = yymsg;
1781 else if (yysyntax_error_status == 1)
1782 {
1783 if (yymsg != yymsgbuf)
1784 YYSTACK_FREE (yymsg);
1785 yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
1786 if (!yymsg)
1787 {
1788 yymsg = yymsgbuf;
1789 yymsg_alloc = sizeof yymsgbuf;
1790 yysyntax_error_status = 2;
1791 }
1792 else
1793 {
1794 yysyntax_error_status = YYSYNTAX_ERROR;
1795 yymsgp = yymsg;
1796 }
1797 }
1798 fmt_yyerror (yymsgp);
1799 if (yysyntax_error_status == 2)
1800 goto yyexhaustedlab;
1801 }
1802 # undef YYSYNTAX_ERROR
1803 #endif
1804 }
1805
1806
1807
1808 if (yyerrstatus == 3)
1809 {
1810 /* If just tried and failed to reuse lookahead token after an
1811 error, discard it. */
1812
1813 if (fmt_yychar <= YYEOF)
1814 {
1815 /* Return failure if at end of input. */
1816 if (fmt_yychar == YYEOF)
1817 YYABORT;
1818 }
1819 else
1820 {
1821 yydestruct ("Error: discarding",
1822 yytoken, &fmt_yylval);
1823 fmt_yychar = YYEMPTY;
1824 }
1825 }
1826
1827 /* Else will try to reuse lookahead token after shifting the error
1828 token. */
1829 goto yyerrlab1;
1830
1831
1832 /*---------------------------------------------------.
1833 | yyerrorlab -- error raised explicitly by YYERROR. |
1834 `---------------------------------------------------*/
1835 yyerrorlab:
1836
1837 /* Pacify compilers like GCC when the user code never invokes
1838 YYERROR and the label yyerrorlab therefore never appears in user
1839 code. */
1840 if (/*CONSTCOND*/ 0)
1841 goto yyerrorlab;
1842
1843 /* Do not reclaim the symbols of the rule whose action triggered
1844 this YYERROR. */
1845 YYPOPSTACK (fmt_yylen);
1846 fmt_yylen = 0;
1847 YY_STACK_PRINT (yyss, yyssp);
1848 fmt_yystate = *yyssp;
1849 goto yyerrlab1;
1850
1851
1852 /*-------------------------------------------------------------.
1853 | yyerrlab1 -- common code for both syntax error and YYERROR. |
1854 `-------------------------------------------------------------*/
1855 yyerrlab1:
1856 yyerrstatus = 3; /* Each real token shifted decrements this. */
1857
1858 for (;;)
1859 {
1860 yyn = fmt_yypact[fmt_yystate];
1861 if (!yypact_value_is_default (yyn))
1862 {
1863 yyn += YYTERROR;
1864 if (0 <= yyn && yyn <= YYLAST && fmt_yycheck[yyn] == YYTERROR)
1865 {
1866 yyn = fmt_yytable[yyn];
1867 if (0 < yyn)
1868 break;
1869 }
1870 }
1871
1872 /* Pop the current state because it cannot handle the error token. */
1873 if (yyssp == yyss)
1874 YYABORT;
1875
1876
1877 yydestruct ("Error: popping",
1878 yystos[fmt_yystate], yyvsp);
1879 YYPOPSTACK (1);
1880 fmt_yystate = *yyssp;
1881 YY_STACK_PRINT (yyss, yyssp);
1882 }
1883
1884 YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
1885 *++yyvsp = fmt_yylval;
1886 YY_IGNORE_MAYBE_UNINITIALIZED_END
1887
1888
1889 /* Shift the error token. */
1890 YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
1891
1892 fmt_yystate = yyn;
1893 goto yynewstate;
1894
1895
1896 /*-------------------------------------.
1897 | yyacceptlab -- YYACCEPT comes here. |
1898 `-------------------------------------*/
1899 yyacceptlab:
1900 yyresult = 0;
1901 goto yyreturn;
1902
1903 /*-----------------------------------.
1904 | yyabortlab -- YYABORT comes here. |
1905 `-----------------------------------*/
1906 yyabortlab:
1907 yyresult = 1;
1908 goto yyreturn;
1909
1910 #if !defined yyoverflow || YYERROR_VERBOSE
1911 /*-------------------------------------------------.
1912 | yyexhaustedlab -- memory exhaustion comes here. |
1913 `-------------------------------------------------*/
1914 yyexhaustedlab:
1915 fmt_yyerror (YY_("memory exhausted"));
1916 yyresult = 2;
1917 /* Fall through. */
1918 #endif
1919
1920 yyreturn:
1921 if (fmt_yychar != YYEMPTY)
1922 {
1923 /* Make sure we have latest lookahead translation. See comments at
1924 user semantic actions for why this is necessary. */
1925 yytoken = YYTRANSLATE (fmt_yychar);
1926 yydestruct ("Cleanup: discarding lookahead",
1927 yytoken, &fmt_yylval);
1928 }
1929 /* Do not reclaim the symbols of the rule whose action triggered
1930 this YYABORT or YYACCEPT. */
1931 YYPOPSTACK (fmt_yylen);
1932 YY_STACK_PRINT (yyss, yyssp);
1933 while (yyssp != yyss)
1934 {
1935 yydestruct ("Cleanup: popping",
1936 yystos[*yyssp], yyvsp);
1937 YYPOPSTACK (1);
1938 }
1939 #ifndef yyoverflow
1940 if (yyss != yyssa)
1941 YYSTACK_FREE (yyss);
1942 #endif
1943 #if YYERROR_VERBOSE
1944 if (yymsg != yymsgbuf)
1945 YYSTACK_FREE (yymsg);
1946 #endif
1947 return yyresult;
1948 }
1949 #line 448 "mh_fmtgram.y" /* yacc.c:1906 */
1950
1951
1952 static char *start;
1953 static char *tok_start;
1954 static char *curp;
1955 static mu_linetrack_t trk;
1956 static struct mu_locus_range fmt_yylloc;
1957
1958 static inline size_t
token_leng(void)1959 token_leng (void)
1960 {
1961 return curp - tok_start;
1962 }
1963
1964 static inline void
mark(void)1965 mark (void)
1966 {
1967 if (curp > tok_start)
1968 mu_linetrack_advance (trk, &fmt_yylloc, tok_start, token_leng ());
1969 tok_start = curp;
1970 }
1971
1972 static inline int
input(void)1973 input (void)
1974 {
1975 if (*curp == 0)
1976 return 0;
1977 return *curp++;
1978 }
1979
1980 static inline void
eatinput(size_t n)1981 eatinput (size_t n)
1982 {
1983 mark ();
1984 while (n--)
1985 input ();
1986 mark ();
1987 }
1988
1989 static inline int
peek(void)1990 peek (void)
1991 {
1992 return *curp;
1993 }
1994
1995 static inline int
unput(int c)1996 unput (int c)
1997 {
1998 if (curp == start)
1999 {
2000 mu_error (_("%s:%d: INTERNAL ERROR: out of unput space: please report"),
2001 __FILE__, __LINE__);
2002 abort ();
2003 }
2004 return *--curp = c;
2005 }
2006
2007 static int
skip(int class)2008 skip (int class)
2009 {
2010 curp = mu_str_skip_class (curp, class);
2011 return *curp;
2012 }
2013
2014 static int
skipeol(void)2015 skipeol (void)
2016 {
2017 int c;
2018
2019 do
2020 {
2021 c = input ();
2022 if (c == '\\' && (c = input ()) == '\n')
2023 c = input ();
2024 }
2025 while (c && c != '\n');
2026 return *curp;
2027 }
2028
2029
2030 static inline int
bogus(const char * mesg)2031 bogus (const char *mesg)
2032 {
2033 fmt_yylval.mesg = mesg;
2034 return BOGUS;
2035 }
2036
2037 static char *
find_bol(unsigned line)2038 find_bol (unsigned line)
2039 {
2040 char *p = start;
2041
2042 while (--line)
2043 {
2044 while (*p != '\n')
2045 {
2046 if (*p == 0)
2047 return p;
2048 p++;
2049 }
2050 p++;
2051 }
2052 return p;
2053 }
2054
2055 int
fmt_yyerror(const char * s)2056 fmt_yyerror (const char *s)
2057 {
2058 if (fmt_yychar != BOGUS)
2059 {
2060 char *bol;
2061 size_t len;
2062 static char tab[] = " ";
2063 size_t b = 0, e = 0;
2064 size_t i;
2065
2066 bol = find_bol (fmt_yylloc.beg.mu_line);
2067 len = strcspn (bol, "\n");
2068
2069 mu_diag_at_locus_range (MU_DIAG_ERROR, &fmt_yylloc, "%s", s);
2070 for (i = 0; i < len; i++)
2071 /* How ... tribal! */
2072 {
2073 if (bol[i] == '\t')
2074 {
2075 mu_stream_write (mu_strerr, tab, strlen (tab), NULL);
2076 if (fmt_yylloc.beg.mu_col > i)
2077 b += strlen (tab) - 1;
2078 if (fmt_yylloc.end.mu_col > i)
2079 e += strlen (tab) - 1;
2080 }
2081 else
2082 mu_stream_write (mu_strerr, bol + i, 1, NULL);
2083 }
2084 mu_stream_write (mu_strerr, "\n", 1, NULL);
2085 if (mu_locus_point_eq (&fmt_yylloc.beg, &fmt_yylloc.end))
2086 mu_error ("%*.*s^",
2087 (int) (b + fmt_yylloc.beg.mu_col - 1),
2088 (int) (b + fmt_yylloc.beg.mu_col - 1), "");
2089 else
2090 mu_error ("%*.*s^%*.*s^",
2091 (int)(b + fmt_yylloc.beg.mu_col - 1),
2092 (int)(b + fmt_yylloc.beg.mu_col - 1), "",
2093 (int)(e + fmt_yylloc.end.mu_col - fmt_yylloc.beg.mu_col - b - 1),
2094 (int)(e + fmt_yylloc.end.mu_col - fmt_yylloc.beg.mu_col - b - 1),
2095 "");
2096 }
2097 return 0;
2098 }
2099
2100 static int backslash(int c);
2101
2102 struct lexer_tab
2103 {
2104 char *ctx_name;
2105 int (*lexer) (void);
2106 };
2107
2108 static int yylex_initial (void);
2109 static int yylex_cond (void);
2110 static int yylex_expr (void);
2111 static int yylex_func (void);
2112
2113 static struct lexer_tab lexer_tab[] = {
2114 [ctx_init] = { "initial", yylex_initial },
2115 [ctx_if] = { "condition", yylex_cond },
2116 [ctx_expr] = { "expression", yylex_expr },
2117 [ctx_func] = { "function", yylex_func }
2118 };
2119
2120 int
fmt_yylex(void)2121 fmt_yylex (void)
2122 {
2123 int tok;
2124
2125 do
2126 {
2127 mark ();
2128 if (fmt_yydebug)
2129 fprintf (stderr, "lex: [%s] at %-10.10s...]\n",
2130 lexer_tab[ctx_get ()].ctx_name, curp);
2131 tok = lexer_tab[ctx_get ()].lexer ();
2132 }
2133 while (tok == STRING && fmt_yylval.str[0] == 0);
2134
2135 mark ();
2136 if (tok == BOGUS)
2137 fmt_yyerror (fmt_yylval.mesg);
2138 return tok;
2139 }
2140
2141 static int
token_fmtspec(int flags)2142 token_fmtspec (int flags)
2143 {
2144 int num = 0;
2145
2146 if (peek () == '0')
2147 {
2148 flags |= MH_FMT_ZEROPAD;
2149 input ();
2150 }
2151 else if (!mu_isdigit (peek ()))
2152 {
2153 return bogus ("expected digit");
2154 }
2155 mark ();
2156 while (*curp && mu_isdigit (peek ()))
2157 num = num * 10 + input () - '0';
2158 fmt_yylval.fmtspec = flags | num;
2159 unput ('%');
2160 return FMTSPEC;
2161 }
2162
2163 static int
token_function(void)2164 token_function (void)
2165 {
2166 eatinput (1);
2167 skip (MU_CTYPE_IDENT);
2168 if (token_leng () == 0 || !strchr (" \t(){%", peek ()))
2169 {
2170 return bogus ("expected function name");
2171 }
2172
2173 fmt_yylval.builtin = mh_lookup_builtin (tok_start, token_leng ());
2174
2175 if (!fmt_yylval.builtin)
2176 {
2177 return bogus ("unknown function");
2178 }
2179 if (!fmt_yylval.builtin->fun
2180 && !(fmt_yylval.builtin->flags & (MHA_SPECIAL|MHA_VOID)))
2181 {
2182 mu_error ("INTERNAL ERROR at %s:%d: \"%s\" has no associated function"
2183 " and is not marked as MHA_SPECIAL",
2184 __FILE__, __LINE__, fmt_yylval.builtin->name);
2185 abort ();
2186 }
2187
2188 return FUNCTION;
2189 }
2190
2191 static int
token_component(void)2192 token_component (void)
2193 {
2194 eatinput (1);
2195 if (!mu_isalpha (peek ()))
2196 {
2197 return bogus ("component name expected");
2198 }
2199 mark ();
2200 if (skip (MU_CTYPE_HEADR) != '}')
2201 {
2202 return bogus ("component name expected");
2203 }
2204 mu_opool_append (tokpool, tok_start, token_leng ());
2205 mu_opool_append_char (tokpool, 0);
2206 fmt_yylval.str = mu_opool_finish (tokpool, NULL);
2207 eatinput (1);
2208 return COMPONENT;
2209 }
2210
2211 int
yylex_initial(void)2212 yylex_initial (void)
2213 {
2214 int c;
2215
2216 again:
2217 mark ();
2218 if (peek () == '%')
2219 {
2220 input ();
2221
2222 switch (c = input ())
2223 {
2224 case ';':
2225 skipeol ();
2226 goto again;
2227 case '<':
2228 return IF;
2229 case '%':
2230 unput (c);
2231 unput (c);
2232 break;
2233 case '(':
2234 unput (c);
2235 return token_function ();
2236 case '{':
2237 unput (c);
2238 return token_component ();
2239 case '-':
2240 return token_fmtspec (MH_FMT_RALIGN);
2241 case '0': case '1': case '2': case '3': case '4':
2242 case '5': case '6': case '7': case '8': case '9':
2243 unput (c);
2244 return token_fmtspec (MH_FMT_DEFAULT);
2245 default:
2246 return bogus ("component or function name expected");
2247 }
2248 }
2249
2250 c = peek ();
2251
2252 if (c == 0)
2253 return 0;
2254
2255 while ((c = input ()) != 0)
2256 {
2257 if (c == '%')
2258 {
2259 if (peek () == '%')
2260 mu_opool_append_char (tokpool, input ());
2261 else
2262 {
2263 unput (c);
2264 break;
2265 }
2266 }
2267 else if (c == '\\')
2268 {
2269 if ((c = input ()) == 0)
2270 {
2271 return bogus ("unexpected end of file");
2272 }
2273 if (c != '\n')
2274 mu_opool_append_char (tokpool, backslash (c));
2275 }
2276 else
2277 mu_opool_append_char (tokpool, c);
2278 }
2279
2280 mu_opool_append_char (tokpool, 0);
2281 fmt_yylval.str = mu_opool_finish (tokpool, NULL);
2282 return STRING;
2283 }
2284
2285 int
yylex_cond(void)2286 yylex_cond (void)
2287 {
2288 while (1)
2289 {
2290 switch (peek ())
2291 {
2292 case '(':
2293 return token_function ();
2294 case '{':
2295 return token_component ();
2296 case '\\':
2297 input ();
2298 if (input () == '\n')
2299 continue;
2300 default:
2301 return bogus ("'(' or '{' expected");
2302 }
2303 }
2304 }
2305
2306 int
yylex_expr(void)2307 yylex_expr (void)
2308 {
2309 int c;
2310
2311 if ((c = input ()) == '%')
2312 {
2313 switch (c = input ())
2314 {
2315 case '?':
2316 return ELIF;
2317 case '|':
2318 return ELSE;
2319 case '>':
2320 return FI;
2321 }
2322 unput (c);
2323 unput ('%');
2324 }
2325 else
2326 unput (c);
2327 return yylex_initial ();
2328 }
2329
2330 int
yylex_func(void)2331 yylex_func (void)
2332 {
2333 int c;
2334
2335 /* Expected argument or closing parenthesis */
2336 again:
2337 mark ();
2338 switch (peek ())
2339 {
2340 case '(':
2341 return token_function ();
2342
2343 case ')':
2344 eatinput (1);
2345 return EOFN;
2346
2347 case '{':
2348 return token_component ();
2349
2350 case '%':
2351 input ();
2352 switch (peek ())
2353 {
2354 case '<':
2355 input ();
2356 return IF;
2357
2358 case '%':
2359 break;
2360
2361 default:
2362 return bogus ("expected '%' or '<'");
2363 }
2364 break;
2365
2366 case ' ':
2367 case '\t':
2368 skip (MU_CTYPE_SPACE);
2369 if (peek () == '%')
2370 goto again;
2371 break;
2372
2373 default:
2374 return input ();
2375 }
2376
2377 mark ();
2378
2379 while ((c = input ()) != ')')
2380 {
2381 if (c == 0)
2382 {
2383 return bogus ("expected ')'");
2384 }
2385
2386 if (c == '\\')
2387 {
2388 if ((c = input ()) == 0)
2389 {
2390 return bogus ("unexpected end of file");
2391 }
2392 mu_opool_append_char (tokpool, backslash (c));
2393 }
2394 else
2395 mu_opool_append_char (tokpool, c);
2396 }
2397 mu_opool_append_char (tokpool, 0);
2398
2399 fmt_yylval.arg.v.str = mu_opool_finish (tokpool, NULL);
2400 fmt_yylval.arg.type = mhtype_str;
2401 unput (c);
2402
2403 if (mu_isdigit (fmt_yylval.arg.v.str[0])
2404 || (fmt_yylval.arg.v.str[0] == '-' && mu_isdigit (fmt_yylval.arg.v.str[1])))
2405 {
2406 long n;
2407 char *p;
2408 errno = 0;
2409 n = strtol (fmt_yylval.arg.v.str, &p, 0);
2410 if (errno == 0 && *p == 0)
2411 {
2412 fmt_yylval.arg.type = mhtype_num;
2413 fmt_yylval.arg.v.num = n;
2414 }
2415 }
2416
2417 if (peek () != ')')
2418 {
2419 return bogus ("expected ')'");
2420 }
2421
2422 return ARGUMENT;
2423 }
2424
2425 static int
format_parse(mh_format_t * fmtptr,char * format_str,struct mu_locus_point const * locus,int flags)2426 format_parse (mh_format_t *fmtptr, char *format_str,
2427 struct mu_locus_point const *locus,
2428 int flags)
2429 {
2430 int rc;
2431 char *p = getenv ("MHFORMAT_DEBUG");
2432
2433 if (p || (flags & MH_FMT_PARSE_DEBUG))
2434 fmt_yydebug = 1;
2435 start = tok_start = curp = format_str;
2436 mu_opool_create (&tokpool, MU_OPOOL_ENOMEMABRT);
2437
2438 ctx_tos = ctx_max = 0;
2439 ctx_stack = NULL;
2440 ctx_push (ctx_init);
2441 mu_linetrack_create (&trk, "input", 2);
2442 if (locus && locus->mu_file)
2443 mu_linetrack_rebase (trk, locus);
2444 mu_locus_range_init (&fmt_yylloc);
2445
2446 rc = fmt_yyparse ();
2447 if (rc == 0)
2448 codegen (fmtptr, flags & MH_FMT_PARSE_TREE);
2449 else
2450 mu_opool_destroy (&tokpool);
2451
2452 mu_locus_range_deinit (&fmt_yylloc);
2453 mu_linetrack_destroy (&trk);
2454 free (ctx_stack);
2455
2456 parse_tree = NULL;
2457 tokpool = NULL;
2458 return rc;
2459 }
2460
2461 int
mh_format_string_parse(mh_format_t * retfmt,char const * format_str,struct mu_locus_point const * locus,int flags)2462 mh_format_string_parse (mh_format_t *retfmt, char const *format_str,
2463 struct mu_locus_point const *locus,
2464 int flags)
2465 {
2466 char *fmts = mu_strdup (format_str);
2467 int rc = format_parse (retfmt, fmts, locus, flags);
2468 free (fmts);
2469 return rc;
2470 }
2471
2472 int
mh_read_formfile(char const * name,char ** pformat)2473 mh_read_formfile (char const *name, char **pformat)
2474 {
2475 FILE *fp;
2476 struct stat st;
2477 char *format_str;
2478 char *file_name;
2479 int rc;
2480
2481 rc = mh_find_file (name, &file_name);
2482 if (rc)
2483 {
2484 mu_error (_("cannot access format file %s: %s"), name, strerror (rc));
2485 return -1;
2486 }
2487
2488 if (stat (file_name, &st))
2489 {
2490 mu_error (_("cannot stat format file %s: %s"), file_name,
2491 strerror (errno));
2492 free (file_name);
2493 return -1;
2494 }
2495
2496 fp = fopen (file_name, "r");
2497 if (!fp)
2498 {
2499 mu_error (_("cannot open format file %s: %s"), file_name,
2500 strerror (errno));
2501 free (file_name);
2502 return -1;
2503 }
2504
2505 format_str = mu_alloc (st.st_size + 1);
2506 if (fread (format_str, st.st_size, 1, fp) != 1)
2507 {
2508 mu_error (_("error reading format file %s: %s"), file_name,
2509 strerror (errno));
2510 free (file_name);
2511 return -1;
2512 }
2513 free (file_name);
2514
2515 format_str[st.st_size] = 0;
2516 if (format_str[st.st_size-1] == '\n')
2517 format_str[st.st_size-1] = 0;
2518 fclose (fp);
2519 *pformat = format_str;
2520 return 0;
2521 }
2522
2523 int
mh_format_file_parse(mh_format_t * retfmt,char const * formfile,int flags)2524 mh_format_file_parse (mh_format_t *retfmt, char const *formfile, int flags)
2525 {
2526 char *fmts;
2527 int rc;
2528
2529 rc = mh_read_formfile (formfile, &fmts);
2530 if (rc == 0)
2531 {
2532 struct mu_locus_point loc;
2533 loc.mu_file = formfile;
2534 loc.mu_line = 1;
2535 loc.mu_col = 0;
2536 rc = format_parse (retfmt, fmts, &loc, flags);
2537 free (fmts);
2538 }
2539 return rc;
2540 }
2541
2542 int
backslash(int c)2543 backslash (int c)
2544 {
2545 static char transtab[] = "b\bf\fn\nr\rt\t";
2546 char *p;
2547
2548 for (p = transtab; *p; p += 2)
2549 {
2550 if (*p == c)
2551 return p[1];
2552 }
2553 return c;
2554 }
2555
2556 static struct node *
new_node(enum node_type nodetype,enum mh_type datatype)2557 new_node (enum node_type nodetype, enum mh_type datatype)
2558 {
2559 struct node *np = mu_zalloc (sizeof *np);
2560 np->nodetype = nodetype;
2561 np->datatype = datatype;
2562 return np;
2563 }
2564
2565 static void node_list_free (struct node *node);
2566
2567 static void
node_free(struct node * node)2568 node_free (struct node *node)
2569 {
2570 if (!node)
2571 return;
2572 switch (node->nodetype)
2573 {
2574 case fmtnode_print:
2575 node_free (node->v.prt.arg);
2576 break;
2577
2578 case fmtnode_literal:
2579 break;
2580
2581 case fmtnode_number:
2582 break;
2583
2584 case fmtnode_body:
2585 break;
2586
2587 case fmtnode_comp:
2588 break;
2589
2590 case fmtnode_funcall:
2591 node_free (node->v.funcall.arg);
2592 break;
2593
2594 case fmtnode_cntl:
2595 node_list_free (node->v.cntl.cond);
2596 node_list_free (node->v.cntl.iftrue);
2597 node_list_free (node->v.cntl.iffalse);
2598 break;
2599
2600 default:
2601 abort ();
2602 }
2603 free (node);
2604 }
2605
2606 static void
node_list_free(struct node * node)2607 node_list_free (struct node *node)
2608 {
2609 while (node)
2610 {
2611 struct node *next = node->next;
2612 node_free (node);
2613 node = next;
2614 }
2615 }
2616
2617 static struct node *
typecast(struct node * node,enum mh_type type)2618 typecast (struct node *node, enum mh_type type)
2619 {
2620 if (!node)
2621 /* FIXME: when passing optional argument, the caller must know the
2622 type of value returned by the previous expression */
2623 return node;
2624
2625 if (node->datatype == type)
2626 return node;
2627 switch (node->nodetype)
2628 {
2629 case fmtnode_cntl:
2630 node->v.cntl.iftrue = typecast (node->v.cntl.iftrue, type);
2631 node->v.cntl.iffalse = typecast (node->v.cntl.iffalse, type);
2632 node->datatype = type;
2633 break;
2634
2635 default:
2636 {
2637 struct node *arg = new_node (fmtnode_typecast, type);
2638 arg->v.arg = node;
2639 node = arg;
2640 }
2641 }
2642 return node;
2643 }
2644
2645 #define INLINE -1
2646
2647 static inline void
indent(int level)2648 indent (int level)
2649 {
2650 printf ("%*.*s", 2*level, 2*level, "");
2651 }
2652
2653 static inline void
delim(int level,char const * dstr)2654 delim (int level, char const *dstr)
2655 {
2656 if (level == INLINE)
2657 printf ("%s", dstr);
2658 else
2659 {
2660 printf ("\n");
2661 indent (level);
2662 }
2663 }
2664
2665 static void dump_statement (struct node *node, int level);
2666
2667 void
mh_print_fmtspec(int fmtspec)2668 mh_print_fmtspec (int fmtspec)
2669 {
2670 if (!(fmtspec & (MH_FMT_RALIGN|MH_FMT_ZEROPAD|MH_FMT_COMPWS)))
2671 printf ("NONE");
2672 else
2673 {
2674 if (!(fmtspec & MH_FMT_RALIGN))
2675 printf ("NO");
2676 printf ("RALIGN|");
2677 if (!(fmtspec & MH_FMT_ZEROPAD))
2678 printf ("NO");
2679 printf ("ZEROPAD|");
2680 if (!(fmtspec & MH_FMT_COMPWS))
2681 printf ("NO");
2682 printf ("COMPWS");
2683 }
2684 }
2685
2686 static char *typename[] = { "NONE", "NUM", "STR" };
2687
2688 static void
dump_node_pretty(struct node * node,int level)2689 dump_node_pretty (struct node *node, int level)
2690 {
2691 if (!node)
2692 return;
2693 switch (node->nodetype)
2694 {
2695 case fmtnode_print:
2696 if (node->v.prt.fmtspec)
2697 {
2698 printf ("FORMAT(");
2699 mh_print_fmtspec (node->v.prt.fmtspec);
2700 printf(", %d, ", node->v.prt.fmtspec & MH_WIDTH_MASK);
2701 }
2702 else
2703 printf ("PRINT(");
2704 dump_statement (node->v.prt.arg, INLINE);
2705 printf (")");
2706 break;
2707
2708 case fmtnode_literal:
2709 {
2710 char const *p = node->v.str;
2711 putchar ('"');
2712 while (*p)
2713 {
2714 if (*p == '\\' || *p == '"')
2715 {
2716 putchar ('\\');
2717 putchar (*p);
2718 }
2719 else if (*p == '\n')
2720 {
2721 putchar ('\\');
2722 putchar ('n');
2723 }
2724 else
2725 putchar (*p);
2726 p++;
2727 }
2728 putchar ('"');
2729 }
2730 break;
2731
2732 case fmtnode_number:
2733 printf ("%ld", node->v.num);
2734 break;
2735
2736 case fmtnode_body:
2737 printf ("BODY");
2738 break;
2739
2740 case fmtnode_comp:
2741 printf ("COMPONENT.%s", node->v.str);
2742 break;
2743
2744 case fmtnode_funcall:
2745 printf ("%s(", node->v.funcall.builtin->name);
2746 dump_statement (node->v.funcall.arg, INLINE);
2747 printf (")");
2748 break;
2749
2750 case fmtnode_cntl:
2751 printf ("IF (");
2752 dump_node_pretty (node->v.cntl.cond, INLINE);
2753 printf (") THEN");
2754
2755 if (level != INLINE)
2756 level++;
2757
2758 delim (level, "; ");
2759
2760 dump_statement (node->v.cntl.iftrue, level);
2761
2762 if (node->v.cntl.iffalse)
2763 {
2764 delim (level == INLINE ? level : level - 1, "; ");
2765 printf ("ELSE");
2766 delim (level, " ");
2767 dump_statement (node->v.cntl.iffalse, level);
2768 }
2769
2770 if (level != INLINE)
2771 level--;
2772 delim (level, "; ");
2773 printf ("FI");
2774 break;
2775
2776 case fmtnode_typecast:
2777 printf ("%s(", typename[node->datatype]);
2778 dump_node_pretty (node->v.arg, INLINE);
2779 printf (")");
2780 break;
2781
2782 default:
2783 abort ();
2784 }
2785 }
2786
2787 static void
dump_statement(struct node * node,int level)2788 dump_statement (struct node *node, int level)
2789 {
2790 while (node)
2791 {
2792 dump_node_pretty (node, level);
2793 node = node->next;
2794 if (node)
2795 delim (level, "; ");
2796 }
2797 }
2798
2799 void
mh_format_dump_code(mh_format_t fmt)2800 mh_format_dump_code (mh_format_t fmt)
2801 {
2802 dump_statement (fmt->tree, 0);
2803 printf ("\n");
2804 }
2805
2806 void
mh_format_free_tree(mh_format_t fmt)2807 mh_format_free_tree (mh_format_t fmt)
2808 {
2809 if (fmt)
2810 {
2811 node_list_free (fmt->tree);
2812 fmt->tree = NULL;
2813 mu_opool_destroy (&fmt->pool);
2814 }
2815 }
2816
2817 void
mh_format_free(mh_format_t fmt)2818 mh_format_free (mh_format_t fmt)
2819 {
2820 if (!fmt)
2821 return;
2822
2823 mh_format_free_tree (fmt);
2824
2825 if (fmt->prog)
2826 free (fmt->prog);
2827 fmt->progmax = fmt->progcnt = 0;
2828 fmt->prog = NULL;
2829 }
2830
2831 void
mh_format_destroy(mh_format_t * fmt)2832 mh_format_destroy (mh_format_t *fmt)
2833 {
2834 if (fmt)
2835 {
2836 mh_format_free (*fmt);
2837 *fmt = NULL;
2838 }
2839 }
2840
2841 static struct node *
printelim(struct node * node)2842 printelim (struct node *node)
2843 {
2844 if (node->nodetype == fmtnode_print)
2845 {
2846 struct node *arg = node->v.prt.arg;
2847 arg->next = node->next;
2848 free (node);
2849 node = arg;
2850 }
2851 return node;
2852 }
2853
2854 #define PROG_MIN_ALLOC 8
2855
2856 static inline void
ensure_space(struct mh_format * fmt,size_t n)2857 ensure_space (struct mh_format *fmt, size_t n)
2858 {
2859 while (fmt->progcnt + n >= fmt->progmax)
2860 {
2861 if (fmt->progmax == 0)
2862 fmt->progmax = n < PROG_MIN_ALLOC ? PROG_MIN_ALLOC : n;
2863 fmt->prog = mu_2nrealloc (fmt->prog, &fmt->progmax, sizeof fmt->prog[0]);
2864 }
2865 }
2866
2867 static void
emit_instr(struct mh_format * fmt,mh_instr_t instr)2868 emit_instr (struct mh_format *fmt, mh_instr_t instr)
2869 {
2870 ensure_space (fmt, 1);
2871 fmt->prog[fmt->progcnt++] = instr;
2872 }
2873
2874 static inline void
emit_opcode(struct mh_format * fmt,mh_opcode_t op)2875 emit_opcode (struct mh_format *fmt, mh_opcode_t op)
2876 {
2877 emit_instr (fmt, (mh_instr_t) op);
2878 }
2879
2880 static void
emit_string(struct mh_format * fmt,char const * str)2881 emit_string (struct mh_format *fmt, char const *str)
2882 {
2883 size_t length = strlen (str) + 1;
2884 size_t count = (length + sizeof (mh_instr_t)) / sizeof (mh_instr_t) + 1;
2885
2886 ensure_space (fmt, count);
2887 emit_instr (fmt, (mh_instr_t) count);
2888 memcpy (MHI_STR (fmt->prog[fmt->progcnt]), str, length);
2889 fmt->progcnt += count;
2890 }
2891
2892 static void codegen_node (struct mh_format *fmt, struct node *node);
2893 static void codegen_nodelist (struct mh_format *fmt, struct node *node);
2894
2895 static void
emit_opcode_typed(struct mh_format * fmt,enum mh_type type,enum mh_opcode opnum,enum mh_opcode opstr)2896 emit_opcode_typed (struct mh_format *fmt, enum mh_type type,
2897 enum mh_opcode opnum, enum mh_opcode opstr)
2898 {
2899 switch (type)
2900 {
2901 case mhtype_num:
2902 emit_opcode (fmt, opnum);
2903 break;
2904
2905 case mhtype_str:
2906 emit_opcode (fmt, opstr);
2907 break;
2908
2909 default:
2910 abort ();
2911 }
2912 }
2913
2914 static void
emit_special(struct mh_format * fmt,mh_builtin_t * builtin,struct node * arg)2915 emit_special (struct mh_format *fmt, mh_builtin_t *builtin, struct node *arg)
2916 {
2917 if (arg)
2918 {
2919 if (builtin->flags & MHA_LITERAL)
2920 {
2921 switch (arg->nodetype)
2922 {
2923 case fmtnode_literal:
2924 emit_opcode (fmt, mhop_sets);
2925 emit_instr (fmt, (mh_instr_t) (long) R_REG);
2926 emit_string (fmt, arg->v.str);
2927 break;
2928
2929 case fmtnode_number:
2930 emit_opcode (fmt, mhop_setn);
2931 emit_instr (fmt, (mh_instr_t) (long) R_REG);
2932 emit_instr (fmt, (mh_instr_t) (long) arg->v.num);
2933 break;
2934
2935 default:
2936 abort ();
2937 }
2938 }
2939 else
2940 codegen_node (fmt, arg);
2941 }
2942 }
2943
2944 static void
emit_funcall(struct mh_format * fmt,mh_builtin_t * builtin,struct node * arg)2945 emit_funcall (struct mh_format *fmt, mh_builtin_t *builtin, struct node *arg)
2946 {
2947 if (builtin->flags & MHA_ACC)
2948 {
2949 emit_opcode (fmt, mhop_movs);
2950 emit_instr (fmt, (mh_instr_t) (long) R_ACC);
2951 emit_instr (fmt, (mh_instr_t) (long) R_REG);
2952 }
2953
2954 if (builtin->flags & MHA_SPECIAL)
2955 {
2956 emit_special (fmt, builtin, arg);
2957 return;
2958 }
2959
2960 if (arg)
2961 {
2962 if (builtin->flags & MHA_LITERAL)
2963 {
2964 switch (arg->nodetype)
2965 {
2966 case fmtnode_literal:
2967 emit_opcode (fmt, mhop_sets);
2968 emit_instr (fmt, (mh_instr_t) (long) R_ARG);
2969 emit_string (fmt, arg->v.str);
2970 break;
2971
2972 case fmtnode_number:
2973 emit_opcode (fmt, mhop_setn);
2974 emit_instr (fmt, (mh_instr_t) (long) R_ARG);
2975 emit_instr (fmt, (mh_instr_t) (long) arg->v.num);
2976 break;
2977
2978 default:
2979 abort ();
2980 }
2981 }
2982 else
2983 {
2984 codegen_node (fmt, arg);
2985 emit_opcode_typed (fmt, arg->datatype, mhop_movn, mhop_movs);
2986 emit_instr (fmt, (mh_instr_t) (long) R_ARG);
2987 emit_instr (fmt, (mh_instr_t) (long) R_REG);
2988 }
2989 }
2990 else if (builtin->argtype != mhtype_none)
2991 {
2992 emit_opcode_typed (fmt, builtin->argtype, mhop_movn, mhop_movs);
2993 emit_instr (fmt, (mh_instr_t) (long) R_ARG);
2994 emit_instr (fmt, (mh_instr_t) (long) R_REG);
2995 }
2996
2997 emit_opcode (fmt, mhop_call);
2998 emit_instr (fmt, (mh_instr_t) builtin->fun);
2999 }
3000
3001 static void
codegen_node(struct mh_format * fmt,struct node * node)3002 codegen_node (struct mh_format *fmt, struct node *node)
3003 {
3004 if (!node)
3005 return;
3006 switch (node->nodetype)
3007 {
3008 case fmtnode_print:
3009 if (node->v.prt.arg->nodetype == fmtnode_literal)
3010 {
3011 emit_opcode (fmt, mhop_printlit);
3012 emit_string (fmt, node->v.prt.arg->v.str);
3013 }
3014 else if (node->v.prt.arg->nodetype == fmtnode_number)
3015 {
3016 char *s;
3017 emit_opcode (fmt, mhop_printlit);
3018 mu_asprintf (&s, "%ld", node->v.prt.arg->v.num);
3019 emit_string (fmt, s);
3020 free (s);
3021 }
3022 else
3023 {
3024 codegen_node (fmt, node->v.prt.arg);
3025 if (node->v.prt.fmtspec)
3026 {
3027 emit_opcode (fmt, mhop_fmtspec);
3028 emit_instr (fmt, (mh_instr_t) (long) node->v.prt.fmtspec);
3029 }
3030
3031 if (node->v.prt.arg->datatype != mhtype_none)
3032 emit_opcode_typed (fmt, node->v.prt.arg->datatype,
3033 mhop_printn, mhop_prints);
3034 }
3035 break;
3036
3037 case fmtnode_literal:
3038 emit_opcode (fmt, mhop_sets);
3039 emit_instr (fmt, (mh_instr_t) (long) R_REG);
3040 emit_string (fmt, node->v.str);
3041 break;
3042
3043 case fmtnode_number:
3044 emit_opcode (fmt, mhop_setn);
3045 emit_instr (fmt, (mh_instr_t) (long) R_REG);
3046 emit_instr (fmt, (mh_instr_t) (long) node->v.num);
3047 break;
3048
3049 case fmtnode_body:
3050 emit_opcode (fmt, mhop_ldbody);
3051 emit_instr (fmt, (mh_instr_t) (long) R_REG);
3052 break;
3053
3054 case fmtnode_comp:
3055 emit_opcode (fmt, mhop_ldcomp);
3056 emit_instr (fmt, (mh_instr_t) (long) R_REG);
3057 emit_string (fmt, node->v.str);
3058 break;
3059
3060 case fmtnode_funcall:
3061 emit_funcall (fmt, node->v.funcall.builtin, node->v.funcall.arg);
3062 break;
3063
3064 case fmtnode_cntl:
3065 {
3066 long pc[2];
3067
3068 /* Implementation of control escapes is a bit tricky. According to
3069 the spec:
3070
3071 "[f]unction escapes write their return value in 'num' for
3072 functions returning integer or boolean values"
3073
3074 That means that after "%<(gt 1024)" the value of 'num' would be
3075 1 or 0, depending on its value prior to entering the conditional.
3076 However this would defeat the purpose of the conditional itself,
3077 because then the following construct would be meaningless:
3078
3079 %<(gt 1024)...%?(gt 512)...%|...%>
3080
3081 Indeed, in MH implementation the value of 'num' propagates into
3082 the conditional expression, because any function escape serving
3083 as condition is evaluated in a separate context.
3084
3085 To ensure this behavior, the virtual machine of GNU MH holds the
3086 value of the 'num' register on stack while evaluating the condition
3087 and restores it afterward.
3088
3089 On the other hand, the spec says that:
3090
3091 "[c]ontrol escapes return a boolean value, setting num to 1
3092 if the last explicit condition evaluated by a `%<' or `%?'
3093 control succeeded, and 0 otherwise."
3094
3095 To ensure this, the value on top of stack is exchanged with the
3096 value of the 'num' register upon entering the 'if' branch, and
3097 the tos value is popped into the 'num' upon leaving it. Any
3098 'else if' branches are handled the same way.
3099
3100 Before leaving the 'else' branch, the 'num' is set to 0 explicitly.
3101 */
3102 emit_opcode (fmt, mhop_pushn);
3103 codegen_node (fmt, node->v.cntl.cond);
3104 emit_opcode_typed (fmt, node->v.cntl.cond->datatype,
3105 mhop_brzn, mhop_brzs);
3106 pc[0] = fmt->progcnt;
3107 emit_instr (fmt, (mh_instr_t) NULL);
3108 if (node->v.cntl.iftrue)
3109 {
3110 emit_opcode (fmt, mhop_xchgn);
3111 codegen_nodelist (fmt, node->v.cntl.iftrue);
3112 }
3113 emit_opcode (fmt, mhop_popn);
3114
3115 if (node->v.cntl.iffalse)
3116 {
3117 emit_opcode (fmt, mhop_branch);
3118 pc[1] = fmt->progcnt;
3119 emit_instr (fmt, (mh_instr_t) NULL);
3120
3121 fmt->prog[pc[0]].num = fmt->progcnt - pc[0];
3122 emit_opcode (fmt, mhop_popn);
3123 codegen_nodelist (fmt, node->v.cntl.iffalse);
3124 if (node->v.cntl.iffalse->nodetype != fmtnode_cntl)
3125 {
3126 emit_opcode (fmt, mhop_setn);
3127 emit_instr (fmt, (mh_instr_t) (long) R_REG);
3128 emit_instr (fmt, (mh_instr_t) (long) 0);
3129 }
3130 fmt->prog[pc[1]].num = fmt->progcnt - pc[1];
3131 }
3132 else
3133 fmt->prog[pc[0]].num = fmt->progcnt - pc[0];
3134 }
3135 break;
3136
3137 case fmtnode_typecast:
3138 codegen_node (fmt, node->v.arg);
3139 switch (node->datatype)
3140 {
3141 case mhtype_num:
3142 emit_opcode (fmt, mhop_atoi);
3143 break;
3144
3145 case mhtype_str:
3146 emit_opcode (fmt, mhop_itoa);
3147 break;
3148
3149 default:
3150 abort ();
3151 }
3152 break;
3153
3154 default:
3155 abort ();
3156 }
3157 }
3158
3159 static void
codegen_nodelist(struct mh_format * fmt,struct node * node)3160 codegen_nodelist (struct mh_format *fmt, struct node *node)
3161 {
3162 while (node)
3163 {
3164 codegen_node (fmt, node);
3165 node = node->next;
3166 }
3167 }
3168
3169 static void
codegen(mh_format_t * fmtptr,int tree)3170 codegen (mh_format_t *fmtptr, int tree)
3171 {
3172 struct mh_format *fmt;
3173
3174 fmt = mu_zalloc (sizeof *fmt);
3175
3176 *fmtptr = fmt;
3177 emit_opcode (fmt, mhop_stop);
3178 codegen_nodelist (fmt, parse_tree);
3179 emit_opcode (fmt, mhop_stop);
3180
3181 if (tree)
3182 {
3183 fmt->tree = parse_tree;
3184 fmt->pool = tokpool;
3185 }
3186 else
3187 {
3188 node_list_free (parse_tree);
3189 mu_opool_destroy (&tokpool);
3190 }
3191 }
3192
3193
3194