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