xref: /netbsd-src/crypto/external/bsd/heimdal/dist/lib/sl/slc-gram.c (revision afab4e300d3a9fb07dd8c80daf53d0feb3345706)
1 /*	$NetBSD: slc-gram.c,v 1.3 2023/06/19 21:41:45 christos Exp $	*/
2 
3 /* A Bison parser, made by GNU Bison 3.8.2.  */
4 
5 /* Bison implementation for Yacc-like parsers in C
6 
7    Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation,
8    Inc.
9 
10    This program is free software: you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation, either version 3 of the License, or
13    (at your option) any later version.
14 
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19 
20    You should have received a copy of the GNU General Public License
21    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
22 
23 /* As a special exception, you may create a larger work that contains
24    part or all of the Bison parser skeleton and distribute that work
25    under terms of your choice, so long as that work isn't itself a
26    parser generator using the skeleton or a modified version thereof
27    as a parser skeleton.  Alternatively, if you modify or redistribute
28    the parser skeleton itself, you may (at your option) remove this
29    special exception, which will cause the skeleton and the resulting
30    Bison output files to be licensed under the GNU General Public
31    License without this special exception.
32 
33    This special exception was added by the Free Software Foundation in
34    version 2.2 of Bison.  */
35 
36 /* C LALR(1) parser skeleton written by Richard Stallman, by
37    simplifying the original so-called "semantic" parser.  */
38 
39 /* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual,
40    especially those whose name start with YY_ or yy_.  They are
41    private implementation details that can be changed or removed.  */
42 
43 /* All symbols defined below should begin with yy or YY, to avoid
44    infringing on user name space.  This should be done even for local
45    variables, as they might otherwise be expanded by user macros.
46    There are some unavoidable exceptions within include files to
47    define necessary library symbols; they are noted "INFRINGES ON
48    USER NAME SPACE" below.  */
49 
50 /* Identify Bison output, and Bison version.  */
51 #define YYBISON 30802
52 
53 /* Bison version string.  */
54 #define YYBISON_VERSION "3.8.2"
55 
56 /* Skeleton name.  */
57 #define YYSKELETON_NAME "yacc.c"
58 
59 /* Pure parsers.  */
60 #define YYPURE 0
61 
62 /* Push parsers.  */
63 #define YYPUSH 0
64 
65 /* Pull parsers.  */
66 #define YYPULL 1
67 
68 
69 
70 
71 /* First part of user prologue.  */
72 #line 1 "slc-gram.y"
73 
74 /*
75  * Copyright (c) 2004-2006 Kungliga Tekniska Högskolan
76  * (Royal Institute of Technology, Stockholm, Sweden).
77  * All rights reserved.
78  *
79  * Redistribution and use in source and binary forms, with or without
80  * modification, are permitted provided that the following conditions
81  * are met:
82  *
83  * 1. Redistributions of source code must retain the above copyright
84  *    notice, this list of conditions and the following disclaimer.
85  *
86  * 2. Redistributions in binary form must reproduce the above copyright
87  *    notice, this list of conditions and the following disclaimer in the
88  *    documentation and/or other materials provided with the distribution.
89  *
90  * 3. Neither the name of the Institute nor the names of its contributors
91  *    may be used to endorse or promote products derived from this software
92  *    without specific prior written permission.
93  *
94  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
95  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
96  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
97  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
98  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
99  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
100  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
101  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
102  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
103  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
104  * SUCH DAMAGE.
105  */
106 
107 #include <config.h>
108 
109 #include <stdio.h>
110 #include <stdlib.h>
111 #include <err.h>
112 #include <ctype.h>
113 #include <limits.h>
114 #include <krb5/getarg.h>
115 #include <vers.h>
116 #include <krb5/roken.h>
117 
118 #include "slc.h"
119 extern FILE *yyin;
120 extern struct assignment *assignment;
121 
122 /* Declarations for Bison:
123  */
124 #define YYMALLOC        malloc
125 #define YYFREE          free
126 
127 
128 #line 127 "slc-gram.c"
129 
130 # ifndef YY_CAST
131 #  ifdef __cplusplus
132 #   define YY_CAST(Type, Val) static_cast<Type> (Val)
133 #   define YY_REINTERPRET_CAST(Type, Val) reinterpret_cast<Type> (Val)
134 #  else
135 #   define YY_CAST(Type, Val) ((Type) (Val))
136 #   define YY_REINTERPRET_CAST(Type, Val) ((Type) (Val))
137 #  endif
138 # endif
139 # ifndef YY_NULLPTR
140 #  if defined __cplusplus
141 #   if 201103L <= __cplusplus
142 #    define YY_NULLPTR nullptr
143 #   else
144 #    define YY_NULLPTR 0
145 #   endif
146 #  else
147 #   define YY_NULLPTR ((void*)0)
148 #  endif
149 # endif
150 
151 /* Use api.header.include to #include this header
152    instead of duplicating it here.  */
153 #ifndef YY_YY_SLC_GRAM_H_INCLUDED
154 # define YY_YY_SLC_GRAM_H_INCLUDED
155 /* Debug traces.  */
156 #ifndef YYDEBUG
157 # define YYDEBUG 0
158 #endif
159 #if YYDEBUG
160 extern int yydebug;
161 #endif
162 
163 /* Token kinds.  */
164 #ifndef YYTOKENTYPE
165 # define YYTOKENTYPE
166   enum yytokentype
167   {
168     YYEMPTY = -2,
169     YYEOF = 0,                     /* "end of file"  */
170     YYerror = 256,                 /* error  */
171     YYUNDEF = 257,                 /* "invalid token"  */
172     LITERAL = 258,                 /* LITERAL  */
173     STRING = 259                   /* STRING  */
174   };
175   typedef enum yytokentype yytoken_kind_t;
176 #endif
177 /* Token kinds.  */
178 #define YYEMPTY -2
179 #define YYEOF 0
180 #define YYerror 256
181 #define YYUNDEF 257
182 #define LITERAL 258
183 #define STRING 259
184 
185 /* Value type.  */
186 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
187 union YYSTYPE
188 {
189 #line 57 "slc-gram.y"
190 
191 	char *string;
192 	struct assignment *assignment;
193 
194 #line 193 "slc-gram.c"
195 
196 };
197 typedef union YYSTYPE YYSTYPE;
198 # define YYSTYPE_IS_TRIVIAL 1
199 # define YYSTYPE_IS_DECLARED 1
200 #endif
201 
202 
203 extern YYSTYPE yylval;
204 
205 
206 int yyparse (void);
207 
208 
209 #endif /* !YY_YY_SLC_GRAM_H_INCLUDED  */
210 /* Symbol kind.  */
211 enum yysymbol_kind_t
212 {
213   YYSYMBOL_YYEMPTY = -2,
214   YYSYMBOL_YYEOF = 0,                      /* "end of file"  */
215   YYSYMBOL_YYerror = 1,                    /* error  */
216   YYSYMBOL_YYUNDEF = 2,                    /* "invalid token"  */
217   YYSYMBOL_LITERAL = 3,                    /* LITERAL  */
218   YYSYMBOL_STRING = 4,                     /* STRING  */
219   YYSYMBOL_5_ = 5,                         /* '='  */
220   YYSYMBOL_6_ = 6,                         /* '{'  */
221   YYSYMBOL_7_ = 7,                         /* '}'  */
222   YYSYMBOL_YYACCEPT = 8,                   /* $accept  */
223   YYSYMBOL_start = 9,                      /* start  */
224   YYSYMBOL_assignments = 10,               /* assignments  */
225   YYSYMBOL_assignment = 11                 /* assignment  */
226 };
227 typedef enum yysymbol_kind_t yysymbol_kind_t;
228 
229 
230 
231 
232 #ifdef short
233 # undef short
234 #endif
235 
236 /* On compilers that do not define __PTRDIFF_MAX__ etc., make sure
237    <limits.h> and (if available) <stdint.h> are included
238    so that the code can choose integer types of a good width.  */
239 
240 #ifndef __PTRDIFF_MAX__
241 # include <limits.h> /* INFRINGES ON USER NAME SPACE */
242 # if defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__
243 #  include <stdint.h> /* INFRINGES ON USER NAME SPACE */
244 #  define YY_STDINT_H
245 # endif
246 #endif
247 
248 /* Narrow types that promote to a signed type and that can represent a
249    signed or unsigned integer of at least N bits.  In tables they can
250    save space and decrease cache pressure.  Promoting to a signed type
251    helps avoid bugs in integer arithmetic.  */
252 
253 #ifdef __INT_LEAST8_MAX__
254 typedef __INT_LEAST8_TYPE__ yytype_int8;
255 #elif defined YY_STDINT_H
256 typedef int_least8_t yytype_int8;
257 #else
258 typedef signed char yytype_int8;
259 #endif
260 
261 #ifdef __INT_LEAST16_MAX__
262 typedef __INT_LEAST16_TYPE__ yytype_int16;
263 #elif defined YY_STDINT_H
264 typedef int_least16_t yytype_int16;
265 #else
266 typedef short yytype_int16;
267 #endif
268 
269 /* Work around bug in HP-UX 11.23, which defines these macros
270    incorrectly for preprocessor constants.  This workaround can likely
271    be removed in 2023, as HPE has promised support for HP-UX 11.23
272    (aka HP-UX 11i v2) only through the end of 2022; see Table 2 of
273    <https://h20195.www2.hpe.com/V2/getpdf.aspx/4AA4-7673ENW.pdf>.  */
274 #ifdef __hpux
275 # undef UINT_LEAST8_MAX
276 # undef UINT_LEAST16_MAX
277 # define UINT_LEAST8_MAX 255
278 # define UINT_LEAST16_MAX 65535
279 #endif
280 
281 #if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__
282 typedef __UINT_LEAST8_TYPE__ yytype_uint8;
283 #elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \
284        && UINT_LEAST8_MAX <= INT_MAX)
285 typedef uint_least8_t yytype_uint8;
286 #elif !defined __UINT_LEAST8_MAX__ && UCHAR_MAX <= INT_MAX
287 typedef unsigned char yytype_uint8;
288 #else
289 typedef short yytype_uint8;
290 #endif
291 
292 #if defined __UINT_LEAST16_MAX__ && __UINT_LEAST16_MAX__ <= __INT_MAX__
293 typedef __UINT_LEAST16_TYPE__ yytype_uint16;
294 #elif (!defined __UINT_LEAST16_MAX__ && defined YY_STDINT_H \
295        && UINT_LEAST16_MAX <= INT_MAX)
296 typedef uint_least16_t yytype_uint16;
297 #elif !defined __UINT_LEAST16_MAX__ && USHRT_MAX <= INT_MAX
298 typedef unsigned short yytype_uint16;
299 #else
300 typedef int yytype_uint16;
301 #endif
302 
303 #ifndef YYPTRDIFF_T
304 # if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__
305 #  define YYPTRDIFF_T __PTRDIFF_TYPE__
306 #  define YYPTRDIFF_MAXIMUM __PTRDIFF_MAX__
307 # elif defined PTRDIFF_MAX
308 #  ifndef ptrdiff_t
309 #   include <stddef.h> /* INFRINGES ON USER NAME SPACE */
310 #  endif
311 #  define YYPTRDIFF_T ptrdiff_t
312 #  define YYPTRDIFF_MAXIMUM PTRDIFF_MAX
313 # else
314 #  define YYPTRDIFF_T long
315 #  define YYPTRDIFF_MAXIMUM LONG_MAX
316 # endif
317 #endif
318 
319 #ifndef YYSIZE_T
320 # ifdef __SIZE_TYPE__
321 #  define YYSIZE_T __SIZE_TYPE__
322 # elif defined size_t
323 #  define YYSIZE_T size_t
324 # elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__
325 #  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
326 #  define YYSIZE_T size_t
327 # else
328 #  define YYSIZE_T unsigned
329 # endif
330 #endif
331 
332 #define YYSIZE_MAXIMUM                                  \
333   YY_CAST (YYPTRDIFF_T,                                 \
334            (YYPTRDIFF_MAXIMUM < YY_CAST (YYSIZE_T, -1)  \
335             ? YYPTRDIFF_MAXIMUM                         \
336             : YY_CAST (YYSIZE_T, -1)))
337 
338 #define YYSIZEOF(X) YY_CAST (YYPTRDIFF_T, sizeof (X))
339 
340 
341 /* Stored state numbers (used for stacks). */
342 typedef yytype_int8 yy_state_t;
343 
344 /* State numbers in computations.  */
345 typedef int yy_state_fast_t;
346 
347 #ifndef YY_
348 # if defined YYENABLE_NLS && YYENABLE_NLS
349 #  if ENABLE_NLS
350 #   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
351 #   define YY_(Msgid) dgettext ("bison-runtime", Msgid)
352 #  endif
353 # endif
354 # ifndef YY_
355 #  define YY_(Msgid) Msgid
356 # endif
357 #endif
358 
359 
360 #ifndef YY_ATTRIBUTE_PURE
361 # if defined __GNUC__ && 2 < __GNUC__ + (96 <= __GNUC_MINOR__)
362 #  define YY_ATTRIBUTE_PURE __attribute__ ((__pure__))
363 # else
364 #  define YY_ATTRIBUTE_PURE
365 # endif
366 #endif
367 
368 #ifndef YY_ATTRIBUTE_UNUSED
369 # if defined __GNUC__ && 2 < __GNUC__ + (7 <= __GNUC_MINOR__)
370 #  define YY_ATTRIBUTE_UNUSED __attribute__ ((__unused__))
371 # else
372 #  define YY_ATTRIBUTE_UNUSED
373 # endif
374 #endif
375 
376 /* Suppress unused-variable warnings by "using" E.  */
377 #if ! defined lint || defined __GNUC__
378 # define YY_USE(E) ((void) (E))
379 #else
380 # define YY_USE(E) /* empty */
381 #endif
382 
383 /* Suppress an incorrect diagnostic about yylval being uninitialized.  */
384 #if defined __GNUC__ && ! defined __ICC && 406 <= __GNUC__ * 100 + __GNUC_MINOR__
385 # if __GNUC__ * 100 + __GNUC_MINOR__ < 407
386 #  define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN                           \
387     _Pragma ("GCC diagnostic push")                                     \
388     _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")
389 # else
390 #  define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN                           \
391     _Pragma ("GCC diagnostic push")                                     \
392     _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")              \
393     _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
394 # endif
395 # define YY_IGNORE_MAYBE_UNINITIALIZED_END      \
396     _Pragma ("GCC diagnostic pop")
397 #else
398 # define YY_INITIAL_VALUE(Value) Value
399 #endif
400 #ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
401 # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
402 # define YY_IGNORE_MAYBE_UNINITIALIZED_END
403 #endif
404 #ifndef YY_INITIAL_VALUE
405 # define YY_INITIAL_VALUE(Value) /* Nothing. */
406 #endif
407 
408 #if defined __cplusplus && defined __GNUC__ && ! defined __ICC && 6 <= __GNUC__
409 # define YY_IGNORE_USELESS_CAST_BEGIN                          \
410     _Pragma ("GCC diagnostic push")                            \
411     _Pragma ("GCC diagnostic ignored \"-Wuseless-cast\"")
412 # define YY_IGNORE_USELESS_CAST_END            \
413     _Pragma ("GCC diagnostic pop")
414 #endif
415 #ifndef YY_IGNORE_USELESS_CAST_BEGIN
416 # define YY_IGNORE_USELESS_CAST_BEGIN
417 # define YY_IGNORE_USELESS_CAST_END
418 #endif
419 
420 
421 #define YY_ASSERT(E) ((void) (0 && (E)))
422 
423 #if !defined yyoverflow
424 
425 /* The parser invokes alloca or malloc; define the necessary symbols.  */
426 
427 # ifdef YYSTACK_USE_ALLOCA
428 #  if YYSTACK_USE_ALLOCA
429 #   ifdef __GNUC__
430 #    define YYSTACK_ALLOC __builtin_alloca
431 #   elif defined __BUILTIN_VA_ARG_INCR
432 #    include <alloca.h> /* INFRINGES ON USER NAME SPACE */
433 #   elif defined _AIX
434 #    define YYSTACK_ALLOC __alloca
435 #   elif defined _MSC_VER
436 #    include <malloc.h> /* INFRINGES ON USER NAME SPACE */
437 #    define alloca _alloca
438 #   else
439 #    define YYSTACK_ALLOC alloca
440 #    if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS
441 #     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
442       /* Use EXIT_SUCCESS as a witness for stdlib.h.  */
443 #     ifndef EXIT_SUCCESS
444 #      define EXIT_SUCCESS 0
445 #     endif
446 #    endif
447 #   endif
448 #  endif
449 # endif
450 
451 # ifdef YYSTACK_ALLOC
452    /* Pacify GCC's 'empty if-body' warning.  */
453 #  define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
454 #  ifndef YYSTACK_ALLOC_MAXIMUM
455     /* The OS might guarantee only one guard page at the bottom of the stack,
456        and a page size can be as small as 4096 bytes.  So we cannot safely
457        invoke alloca (N) if N exceeds 4096.  Use a slightly smaller number
458        to allow for a few compiler-allocated temporary stack slots.  */
459 #   define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
460 #  endif
461 # else
462 #  define YYSTACK_ALLOC YYMALLOC
463 #  define YYSTACK_FREE YYFREE
464 #  ifndef YYSTACK_ALLOC_MAXIMUM
465 #   define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
466 #  endif
467 #  if (defined __cplusplus && ! defined EXIT_SUCCESS \
468        && ! ((defined YYMALLOC || defined malloc) \
469              && (defined YYFREE || defined free)))
470 #   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
471 #   ifndef EXIT_SUCCESS
472 #    define EXIT_SUCCESS 0
473 #   endif
474 #  endif
475 #  ifndef YYMALLOC
476 #   define YYMALLOC malloc
477 #   if ! defined malloc && ! defined EXIT_SUCCESS
478 void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
479 #   endif
480 #  endif
481 #  ifndef YYFREE
482 #   define YYFREE free
483 #   if ! defined free && ! defined EXIT_SUCCESS
484 void free (void *); /* INFRINGES ON USER NAME SPACE */
485 #   endif
486 #  endif
487 # endif
488 #endif /* !defined yyoverflow */
489 
490 #if (! defined yyoverflow \
491      && (! defined __cplusplus \
492          || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
493 
494 /* A type that is properly aligned for any stack member.  */
495 union yyalloc
496 {
497   yy_state_t yyss_alloc;
498   YYSTYPE yyvs_alloc;
499 };
500 
501 /* The size of the maximum gap between one aligned stack and the next.  */
502 # define YYSTACK_GAP_MAXIMUM (YYSIZEOF (union yyalloc) - 1)
503 
504 /* The size of an array large to enough to hold all stacks, each with
505    N elements.  */
506 # define YYSTACK_BYTES(N) \
507      ((N) * (YYSIZEOF (yy_state_t) + YYSIZEOF (YYSTYPE)) \
508       + YYSTACK_GAP_MAXIMUM)
509 
510 # define YYCOPY_NEEDED 1
511 
512 /* Relocate STACK from its old location to the new one.  The
513    local variables YYSIZE and YYSTACKSIZE give the old and new number of
514    elements in the stack, and YYPTR gives the new location of the
515    stack.  Advance YYPTR to a properly aligned location for the next
516    stack.  */
517 # define YYSTACK_RELOCATE(Stack_alloc, Stack)                           \
518     do                                                                  \
519       {                                                                 \
520         YYPTRDIFF_T yynewbytes;                                         \
521         YYCOPY (&yyptr->Stack_alloc, Stack, yysize);                    \
522         Stack = &yyptr->Stack_alloc;                                    \
523         yynewbytes = yystacksize * YYSIZEOF (*Stack) + YYSTACK_GAP_MAXIMUM; \
524         yyptr += yynewbytes / YYSIZEOF (*yyptr);                        \
525       }                                                                 \
526     while (0)
527 
528 #endif
529 
530 #if defined YYCOPY_NEEDED && YYCOPY_NEEDED
531 /* Copy COUNT objects from SRC to DST.  The source and destination do
532    not overlap.  */
533 # ifndef YYCOPY
534 #  if defined __GNUC__ && 1 < __GNUC__
535 #   define YYCOPY(Dst, Src, Count) \
536       __builtin_memcpy (Dst, Src, YY_CAST (YYSIZE_T, (Count)) * sizeof (*(Src)))
537 #  else
538 #   define YYCOPY(Dst, Src, Count)              \
539       do                                        \
540         {                                       \
541           YYPTRDIFF_T yyi;                      \
542           for (yyi = 0; yyi < (Count); yyi++)   \
543             (Dst)[yyi] = (Src)[yyi];            \
544         }                                       \
545       while (0)
546 #  endif
547 # endif
548 #endif /* !YYCOPY_NEEDED */
549 
550 /* YYFINAL -- State number of the termination state.  */
551 #define YYFINAL  6
552 /* YYLAST -- Last index in YYTABLE.  */
553 #define YYLAST   7
554 
555 /* YYNTOKENS -- Number of terminals.  */
556 #define YYNTOKENS  8
557 /* YYNNTS -- Number of nonterminals.  */
558 #define YYNNTS  4
559 /* YYNRULES -- Number of rules.  */
560 #define YYNRULES  6
561 /* YYNSTATES -- Number of states.  */
562 #define YYNSTATES  12
563 
564 /* YYMAXUTOK -- Last valid token kind.  */
565 #define YYMAXUTOK   259
566 
567 
568 /* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM
569    as returned by yylex, with out-of-bounds checking.  */
570 #define YYTRANSLATE(YYX)                                \
571   (0 <= (YYX) && (YYX) <= YYMAXUTOK                     \
572    ? YY_CAST (yysymbol_kind_t, yytranslate[YYX])        \
573    : YYSYMBOL_YYUNDEF)
574 
575 /* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
576    as returned by yylex.  */
577 static const yytype_int8 yytranslate[] =
578 {
579        0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
580        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
581        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
582        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
583        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
584        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
585        2,     5,     2,     2,     2,     2,     2,     2,     2,     2,
586        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
587        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
588        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
589        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
590        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
591        2,     2,     2,     6,     2,     7,     2,     2,     2,     2,
592        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
593        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
594        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
595        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
596        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
597        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
598        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
599        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
600        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
601        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
602        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
603        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
604        2,     2,     2,     2,     2,     2,     1,     2,     3,     4
605 };
606 
607 #if YYDEBUG
608 /* YYRLINE[YYN] -- Source line where rule number YYN was defined.  */
609 static const yytype_int8 yyrline[] =
610 {
611        0,    70,    70,    76,    81,    84,    93
612 };
613 #endif
614 
615 /** Accessing symbol of state STATE.  */
616 #define YY_ACCESSING_SYMBOL(State) YY_CAST (yysymbol_kind_t, yystos[State])
617 
618 #if YYDEBUG || 0
619 /* The user-facing name of the symbol whose (internal) number is
620    YYSYMBOL.  No bounds checking.  */
621 static const char *yysymbol_name (yysymbol_kind_t yysymbol) YY_ATTRIBUTE_UNUSED;
622 
623 /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
624    First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
625 static const char *const yytname[] =
626 {
627   "\"end of file\"", "error", "\"invalid token\"", "LITERAL", "STRING",
628   "'='", "'{'", "'}'", "$accept", "start", "assignments", "assignment", YY_NULLPTR
629 };
630 
631 static const char *
yysymbol_name(yysymbol_kind_t yysymbol)632 yysymbol_name (yysymbol_kind_t yysymbol)
633 {
634   return yytname[yysymbol];
635 }
636 #endif
637 
638 #define YYPACT_NINF (-5)
639 
640 #define yypact_value_is_default(Yyn) \
641   ((Yyn) == YYPACT_NINF)
642 
643 #define YYTABLE_NINF (-1)
644 
645 #define yytable_value_is_error(Yyn) \
646   0
647 
648 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
649    STATE-NUM.  */
650 static const yytype_int8 yypact[] =
651 {
652       -1,     1,     4,    -5,    -1,    -3,    -5,    -5,    -5,    -1,
653        0,    -5
654 };
655 
656 /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
657    Performed when YYTABLE does not specify something else to do.  Zero
658    means the default is an error.  */
659 static const yytype_int8 yydefact[] =
660 {
661        0,     0,     0,     2,     4,     0,     1,     3,     5,     0,
662        0,     6
663 };
664 
665 /* YYPGOTO[NTERM-NUM].  */
666 static const yytype_int8 yypgoto[] =
667 {
668       -5,    -5,    -4,    -5
669 };
670 
671 /* YYDEFGOTO[NTERM-NUM].  */
672 static const yytype_int8 yydefgoto[] =
673 {
674        0,     2,     3,     4
675 };
676 
677 /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM.  If
678    positive, shift that token.  If negative, reduce the rule whose
679    number is the opposite.  If YYTABLE_NINF, syntax error.  */
680 static const yytype_int8 yytable[] =
681 {
682        7,     8,     1,     9,     6,    10,     5,    11
683 };
684 
685 static const yytype_int8 yycheck[] =
686 {
687        4,     4,     3,     6,     0,     9,     5,     7
688 };
689 
690 /* YYSTOS[STATE-NUM] -- The symbol kind of the accessing symbol of
691    state STATE-NUM.  */
692 static const yytype_int8 yystos[] =
693 {
694        0,     3,     9,    10,    11,     5,     0,    10,     4,     6,
695       10,     7
696 };
697 
698 /* YYR1[RULE-NUM] -- Symbol kind of the left-hand side of rule RULE-NUM.  */
699 static const yytype_int8 yyr1[] =
700 {
701        0,     8,     9,    10,    10,    11,    11
702 };
703 
704 /* YYR2[RULE-NUM] -- Number of symbols on the right-hand side of rule RULE-NUM.  */
705 static const yytype_int8 yyr2[] =
706 {
707        0,     2,     1,     2,     1,     3,     5
708 };
709 
710 
711 enum { YYENOMEM = -2 };
712 
713 #define yyerrok         (yyerrstatus = 0)
714 #define yyclearin       (yychar = YYEMPTY)
715 
716 #define YYACCEPT        goto yyacceptlab
717 #define YYABORT         goto yyabortlab
718 #define YYERROR         goto yyerrorlab
719 #define YYNOMEM         goto yyexhaustedlab
720 
721 
722 #define YYRECOVERING()  (!!yyerrstatus)
723 
724 #define YYBACKUP(Token, Value)                                    \
725   do                                                              \
726     if (yychar == YYEMPTY)                                        \
727       {                                                           \
728         yychar = (Token);                                         \
729         yylval = (Value);                                         \
730         YYPOPSTACK (yylen);                                       \
731         yystate = *yyssp;                                         \
732         goto yybackup;                                            \
733       }                                                           \
734     else                                                          \
735       {                                                           \
736         yyerror (YY_("syntax error: cannot back up")); \
737         YYERROR;                                                  \
738       }                                                           \
739   while (0)
740 
741 /* Backward compatibility with an undocumented macro.
742    Use YYerror or YYUNDEF. */
743 #define YYERRCODE YYUNDEF
744 
745 
746 /* Enable debugging if requested.  */
747 #if YYDEBUG
748 
749 # ifndef YYFPRINTF
750 #  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
751 #  define YYFPRINTF fprintf
752 # endif
753 
754 # define YYDPRINTF(Args)                        \
755 do {                                            \
756   if (yydebug)                                  \
757     YYFPRINTF Args;                             \
758 } while (0)
759 
760 
761 
762 
763 # define YY_SYMBOL_PRINT(Title, Kind, Value, Location)                    \
764 do {                                                                      \
765   if (yydebug)                                                            \
766     {                                                                     \
767       YYFPRINTF (stderr, "%s ", Title);                                   \
768       yy_symbol_print (stderr,                                            \
769                   Kind, Value); \
770       YYFPRINTF (stderr, "\n");                                           \
771     }                                                                     \
772 } while (0)
773 
774 
775 /*-----------------------------------.
776 | Print this symbol's value on YYO.  |
777 `-----------------------------------*/
778 
779 static void
yy_symbol_value_print(FILE * yyo,yysymbol_kind_t yykind,YYSTYPE const * const yyvaluep)780 yy_symbol_value_print (FILE *yyo,
781                        yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep)
782 {
783   FILE *yyoutput = yyo;
784   YY_USE (yyoutput);
785   if (!yyvaluep)
786     return;
787   YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
788   YY_USE (yykind);
789   YY_IGNORE_MAYBE_UNINITIALIZED_END
790 }
791 
792 
793 /*---------------------------.
794 | Print this symbol on YYO.  |
795 `---------------------------*/
796 
797 static void
yy_symbol_print(FILE * yyo,yysymbol_kind_t yykind,YYSTYPE const * const yyvaluep)798 yy_symbol_print (FILE *yyo,
799                  yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep)
800 {
801   YYFPRINTF (yyo, "%s %s (",
802              yykind < YYNTOKENS ? "token" : "nterm", yysymbol_name (yykind));
803 
804   yy_symbol_value_print (yyo, yykind, yyvaluep);
805   YYFPRINTF (yyo, ")");
806 }
807 
808 /*------------------------------------------------------------------.
809 | yy_stack_print -- Print the state stack from its BOTTOM up to its |
810 | TOP (included).                                                   |
811 `------------------------------------------------------------------*/
812 
813 static void
yy_stack_print(yy_state_t * yybottom,yy_state_t * yytop)814 yy_stack_print (yy_state_t *yybottom, yy_state_t *yytop)
815 {
816   YYFPRINTF (stderr, "Stack now");
817   for (; yybottom <= yytop; yybottom++)
818     {
819       int yybot = *yybottom;
820       YYFPRINTF (stderr, " %d", yybot);
821     }
822   YYFPRINTF (stderr, "\n");
823 }
824 
825 # define YY_STACK_PRINT(Bottom, Top)                            \
826 do {                                                            \
827   if (yydebug)                                                  \
828     yy_stack_print ((Bottom), (Top));                           \
829 } while (0)
830 
831 
832 /*------------------------------------------------.
833 | Report that the YYRULE is going to be reduced.  |
834 `------------------------------------------------*/
835 
836 static void
yy_reduce_print(yy_state_t * yyssp,YYSTYPE * yyvsp,int yyrule)837 yy_reduce_print (yy_state_t *yyssp, YYSTYPE *yyvsp,
838                  int yyrule)
839 {
840   int yylno = yyrline[yyrule];
841   int yynrhs = yyr2[yyrule];
842   int yyi;
843   YYFPRINTF (stderr, "Reducing stack by rule %d (line %d):\n",
844              yyrule - 1, yylno);
845   /* The symbols being reduced.  */
846   for (yyi = 0; yyi < yynrhs; yyi++)
847     {
848       YYFPRINTF (stderr, "   $%d = ", yyi + 1);
849       yy_symbol_print (stderr,
850                        YY_ACCESSING_SYMBOL (+yyssp[yyi + 1 - yynrhs]),
851                        &yyvsp[(yyi + 1) - (yynrhs)]);
852       YYFPRINTF (stderr, "\n");
853     }
854 }
855 
856 # define YY_REDUCE_PRINT(Rule)          \
857 do {                                    \
858   if (yydebug)                          \
859     yy_reduce_print (yyssp, yyvsp, Rule); \
860 } while (0)
861 
862 /* Nonzero means print parse trace.  It is left uninitialized so that
863    multiple parsers can coexist.  */
864 int yydebug;
865 #else /* !YYDEBUG */
866 # define YYDPRINTF(Args) ((void) 0)
867 # define YY_SYMBOL_PRINT(Title, Kind, Value, Location)
868 # define YY_STACK_PRINT(Bottom, Top)
869 # define YY_REDUCE_PRINT(Rule)
870 #endif /* !YYDEBUG */
871 
872 
873 /* YYINITDEPTH -- initial size of the parser's stacks.  */
874 #ifndef YYINITDEPTH
875 # define YYINITDEPTH 200
876 #endif
877 
878 /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
879    if the built-in stack extension method is used).
880 
881    Do not make this value too large; the results are undefined if
882    YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
883    evaluated with infinite-precision integer arithmetic.  */
884 
885 #ifndef YYMAXDEPTH
886 # define YYMAXDEPTH 10000
887 #endif
888 
889 
890 
891 
892 
893 
894 /*-----------------------------------------------.
895 | Release the memory associated to this symbol.  |
896 `-----------------------------------------------*/
897 
898 static void
yydestruct(const char * yymsg,yysymbol_kind_t yykind,YYSTYPE * yyvaluep)899 yydestruct (const char *yymsg,
900             yysymbol_kind_t yykind, YYSTYPE *yyvaluep)
901 {
902   YY_USE (yyvaluep);
903   if (!yymsg)
904     yymsg = "Deleting";
905   YY_SYMBOL_PRINT (yymsg, yykind, yyvaluep, yylocationp);
906 
907   YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
908   YY_USE (yykind);
909   YY_IGNORE_MAYBE_UNINITIALIZED_END
910 }
911 
912 
913 /* Lookahead token kind.  */
914 int yychar;
915 
916 /* The semantic value of the lookahead symbol.  */
917 YYSTYPE yylval;
918 /* Number of syntax errors so far.  */
919 int yynerrs;
920 
921 
922 
923 
924 /*----------.
925 | yyparse.  |
926 `----------*/
927 
928 int
yyparse(void)929 yyparse (void)
930 {
931     yy_state_fast_t yystate = 0;
932     /* Number of tokens to shift before error messages enabled.  */
933     int yyerrstatus = 0;
934 
935     /* Refer to the stacks through separate pointers, to allow yyoverflow
936        to reallocate them elsewhere.  */
937 
938     /* Their size.  */
939     YYPTRDIFF_T yystacksize = YYINITDEPTH;
940 
941     /* The state stack: array, bottom, top.  */
942     yy_state_t yyssa[YYINITDEPTH];
943     yy_state_t *yyss = yyssa;
944     yy_state_t *yyssp = yyss;
945 
946     /* The semantic value stack: array, bottom, top.  */
947     YYSTYPE yyvsa[YYINITDEPTH];
948     YYSTYPE *yyvs = yyvsa;
949     YYSTYPE *yyvsp = yyvs;
950 
951   int yyn;
952   /* The return value of yyparse.  */
953   int yyresult;
954   /* Lookahead symbol kind.  */
955   yysymbol_kind_t yytoken = YYSYMBOL_YYEMPTY;
956   /* The variables used to return semantic value and location from the
957      action routines.  */
958   YYSTYPE yyval;
959 
960 
961 
962 #define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N))
963 
964   /* The number of symbols on the RHS of the reduced rule.
965      Keep to zero when no symbol should be popped.  */
966   int yylen = 0;
967 
968   YYDPRINTF ((stderr, "Starting parse\n"));
969 
970   yychar = YYEMPTY; /* Cause a token to be read.  */
971 
972   goto yysetstate;
973 
974 
975 /*------------------------------------------------------------.
976 | yynewstate -- push a new state, which is found in yystate.  |
977 `------------------------------------------------------------*/
978 yynewstate:
979   /* In all cases, when you get here, the value and location stacks
980      have just been pushed.  So pushing a state here evens the stacks.  */
981   yyssp++;
982 
983 
984 /*--------------------------------------------------------------------.
985 | yysetstate -- set current state (the top of the stack) to yystate.  |
986 `--------------------------------------------------------------------*/
987 yysetstate:
988   YYDPRINTF ((stderr, "Entering state %d\n", yystate));
989   YY_ASSERT (0 <= yystate && yystate < YYNSTATES);
990   YY_IGNORE_USELESS_CAST_BEGIN
991   *yyssp = YY_CAST (yy_state_t, yystate);
992   YY_IGNORE_USELESS_CAST_END
993   YY_STACK_PRINT (yyss, yyssp);
994 
995   if (yyss + yystacksize - 1 <= yyssp)
996 #if !defined yyoverflow && !defined YYSTACK_RELOCATE
997     YYNOMEM;
998 #else
999     {
1000       /* Get the current used size of the three stacks, in elements.  */
1001       YYPTRDIFF_T yysize = yyssp - yyss + 1;
1002 
1003 # if defined yyoverflow
1004       {
1005         /* Give user a chance to reallocate the stack.  Use copies of
1006            these so that the &'s don't force the real ones into
1007            memory.  */
1008         yy_state_t *yyss1 = yyss;
1009         YYSTYPE *yyvs1 = yyvs;
1010 
1011         /* Each stack pointer address is followed by the size of the
1012            data in use in that stack, in bytes.  This used to be a
1013            conditional around just the two extra args, but that might
1014            be undefined if yyoverflow is a macro.  */
1015         yyoverflow (YY_("memory exhausted"),
1016                     &yyss1, yysize * YYSIZEOF (*yyssp),
1017                     &yyvs1, yysize * YYSIZEOF (*yyvsp),
1018                     &yystacksize);
1019         yyss = yyss1;
1020         yyvs = yyvs1;
1021       }
1022 # else /* defined YYSTACK_RELOCATE */
1023       /* Extend the stack our own way.  */
1024       if (YYMAXDEPTH <= yystacksize)
1025         YYNOMEM;
1026       yystacksize *= 2;
1027       if (YYMAXDEPTH < yystacksize)
1028         yystacksize = YYMAXDEPTH;
1029 
1030       {
1031         yy_state_t *yyss1 = yyss;
1032         union yyalloc *yyptr =
1033           YY_CAST (union yyalloc *,
1034                    YYSTACK_ALLOC (YY_CAST (YYSIZE_T, YYSTACK_BYTES (yystacksize))));
1035         if (! yyptr)
1036           YYNOMEM;
1037         YYSTACK_RELOCATE (yyss_alloc, yyss);
1038         YYSTACK_RELOCATE (yyvs_alloc, yyvs);
1039 #  undef YYSTACK_RELOCATE
1040         if (yyss1 != yyssa)
1041           YYSTACK_FREE (yyss1);
1042       }
1043 # endif
1044 
1045       yyssp = yyss + yysize - 1;
1046       yyvsp = yyvs + yysize - 1;
1047 
1048       YY_IGNORE_USELESS_CAST_BEGIN
1049       YYDPRINTF ((stderr, "Stack size increased to %ld\n",
1050                   YY_CAST (long, yystacksize)));
1051       YY_IGNORE_USELESS_CAST_END
1052 
1053       if (yyss + yystacksize - 1 <= yyssp)
1054         YYABORT;
1055     }
1056 #endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */
1057 
1058 
1059   if (yystate == YYFINAL)
1060     YYACCEPT;
1061 
1062   goto yybackup;
1063 
1064 
1065 /*-----------.
1066 | yybackup.  |
1067 `-----------*/
1068 yybackup:
1069   /* Do appropriate processing given the current state.  Read a
1070      lookahead token if we need one and don't already have one.  */
1071 
1072   /* First try to decide what to do without reference to lookahead token.  */
1073   yyn = yypact[yystate];
1074   if (yypact_value_is_default (yyn))
1075     goto yydefault;
1076 
1077   /* Not known => get a lookahead token if don't already have one.  */
1078 
1079   /* YYCHAR is either empty, or end-of-input, or a valid lookahead.  */
1080   if (yychar == YYEMPTY)
1081     {
1082       YYDPRINTF ((stderr, "Reading a token\n"));
1083       yychar = yylex ();
1084     }
1085 
1086   if (yychar <= YYEOF)
1087     {
1088       yychar = YYEOF;
1089       yytoken = YYSYMBOL_YYEOF;
1090       YYDPRINTF ((stderr, "Now at end of input.\n"));
1091     }
1092   else if (yychar == YYerror)
1093     {
1094       /* The scanner already issued an error message, process directly
1095          to error recovery.  But do not keep the error token as
1096          lookahead, it is too special and may lead us to an endless
1097          loop in error recovery. */
1098       yychar = YYUNDEF;
1099       yytoken = YYSYMBOL_YYerror;
1100       goto yyerrlab1;
1101     }
1102   else
1103     {
1104       yytoken = YYTRANSLATE (yychar);
1105       YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
1106     }
1107 
1108   /* If the proper action on seeing token YYTOKEN is to reduce or to
1109      detect an error, take that action.  */
1110   yyn += yytoken;
1111   if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
1112     goto yydefault;
1113   yyn = yytable[yyn];
1114   if (yyn <= 0)
1115     {
1116       if (yytable_value_is_error (yyn))
1117         goto yyerrlab;
1118       yyn = -yyn;
1119       goto yyreduce;
1120     }
1121 
1122   /* Count tokens shifted since error; after three, turn off error
1123      status.  */
1124   if (yyerrstatus)
1125     yyerrstatus--;
1126 
1127   /* Shift the lookahead token.  */
1128   YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
1129   yystate = yyn;
1130   YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
1131   *++yyvsp = yylval;
1132   YY_IGNORE_MAYBE_UNINITIALIZED_END
1133 
1134   /* Discard the shifted token.  */
1135   yychar = YYEMPTY;
1136   goto yynewstate;
1137 
1138 
1139 /*-----------------------------------------------------------.
1140 | yydefault -- do the default action for the current state.  |
1141 `-----------------------------------------------------------*/
1142 yydefault:
1143   yyn = yydefact[yystate];
1144   if (yyn == 0)
1145     goto yyerrlab;
1146   goto yyreduce;
1147 
1148 
1149 /*-----------------------------.
1150 | yyreduce -- do a reduction.  |
1151 `-----------------------------*/
1152 yyreduce:
1153   /* yyn is the number of a rule to reduce with.  */
1154   yylen = yyr2[yyn];
1155 
1156   /* If YYLEN is nonzero, implement the default value of the action:
1157      '$$ = $1'.
1158 
1159      Otherwise, the following line sets YYVAL to garbage.
1160      This behavior is undocumented and Bison
1161      users should not rely upon it.  Assigning to YYVAL
1162      unconditionally makes the parser a bit smaller, and it avoids a
1163      GCC warning that YYVAL may be used uninitialized.  */
1164   yyval = yyvsp[1-yylen];
1165 
1166 
1167   YY_REDUCE_PRINT (yyn);
1168   switch (yyn)
1169     {
1170   case 2: /* start: assignments  */
1171 #line 71 "slc-gram.y"
1172                 {
1173 			assignment = (yyvsp[0].assignment);
1174 		}
1175 #line 1174 "slc-gram.c"
1176     break;
1177 
1178   case 3: /* assignments: assignment assignments  */
1179 #line 77 "slc-gram.y"
1180                 {
1181 			(yyvsp[-1].assignment)->next = (yyvsp[0].assignment);
1182 			(yyval.assignment) = (yyvsp[-1].assignment);
1183 		}
1184 #line 1183 "slc-gram.c"
1185     break;
1186 
1187   case 5: /* assignment: LITERAL '=' STRING  */
1188 #line 85 "slc-gram.y"
1189                 {
1190 			(yyval.assignment) = malloc(sizeof(*(yyval.assignment)));
1191 			(yyval.assignment)->name = (yyvsp[-2].string);
1192 			(yyval.assignment)->type = a_value;
1193 			(yyval.assignment)->lineno = lineno;
1194 			(yyval.assignment)->u.value = (yyvsp[0].string);
1195 			(yyval.assignment)->next = NULL;
1196 		}
1197 #line 1196 "slc-gram.c"
1198     break;
1199 
1200   case 6: /* assignment: LITERAL '=' '{' assignments '}'  */
1201 #line 94 "slc-gram.y"
1202                 {
1203 			(yyval.assignment) = malloc(sizeof(*(yyval.assignment)));
1204 			(yyval.assignment)->name = (yyvsp[-4].string);
1205 			(yyval.assignment)->type = a_assignment;
1206 			(yyval.assignment)->lineno = lineno;
1207 			(yyval.assignment)->u.assignment = (yyvsp[-1].assignment);
1208 			(yyval.assignment)->next = NULL;
1209 		}
1210 #line 1209 "slc-gram.c"
1211     break;
1212 
1213 
1214 #line 1213 "slc-gram.c"
1215 
1216       default: break;
1217     }
1218   /* User semantic actions sometimes alter yychar, and that requires
1219      that yytoken be updated with the new translation.  We take the
1220      approach of translating immediately before every use of yytoken.
1221      One alternative is translating here after every semantic action,
1222      but that translation would be missed if the semantic action invokes
1223      YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
1224      if it invokes YYBACKUP.  In the case of YYABORT or YYACCEPT, an
1225      incorrect destructor might then be invoked immediately.  In the
1226      case of YYERROR or YYBACKUP, subsequent parser actions might lead
1227      to an incorrect destructor call or verbose syntax error message
1228      before the lookahead is translated.  */
1229   YY_SYMBOL_PRINT ("-> $$ =", YY_CAST (yysymbol_kind_t, yyr1[yyn]), &yyval, &yyloc);
1230 
1231   YYPOPSTACK (yylen);
1232   yylen = 0;
1233 
1234   *++yyvsp = yyval;
1235 
1236   /* Now 'shift' the result of the reduction.  Determine what state
1237      that goes to, based on the state we popped back to and the rule
1238      number reduced by.  */
1239   {
1240     const int yylhs = yyr1[yyn] - YYNTOKENS;
1241     const int yyi = yypgoto[yylhs] + *yyssp;
1242     yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp
1243                ? yytable[yyi]
1244                : yydefgoto[yylhs]);
1245   }
1246 
1247   goto yynewstate;
1248 
1249 
1250 /*--------------------------------------.
1251 | yyerrlab -- here on detecting error.  |
1252 `--------------------------------------*/
1253 yyerrlab:
1254   /* Make sure we have latest lookahead translation.  See comments at
1255      user semantic actions for why this is necessary.  */
1256   yytoken = yychar == YYEMPTY ? YYSYMBOL_YYEMPTY : YYTRANSLATE (yychar);
1257   /* If not already recovering from an error, report this error.  */
1258   if (!yyerrstatus)
1259     {
1260       ++yynerrs;
1261       yyerror (YY_("syntax error"));
1262     }
1263 
1264   if (yyerrstatus == 3)
1265     {
1266       /* If just tried and failed to reuse lookahead token after an
1267          error, discard it.  */
1268 
1269       if (yychar <= YYEOF)
1270         {
1271           /* Return failure if at end of input.  */
1272           if (yychar == YYEOF)
1273             YYABORT;
1274         }
1275       else
1276         {
1277           yydestruct ("Error: discarding",
1278                       yytoken, &yylval);
1279           yychar = YYEMPTY;
1280         }
1281     }
1282 
1283   /* Else will try to reuse lookahead token after shifting the error
1284      token.  */
1285   goto yyerrlab1;
1286 
1287 
1288 /*---------------------------------------------------.
1289 | yyerrorlab -- error raised explicitly by YYERROR.  |
1290 `---------------------------------------------------*/
1291 yyerrorlab:
1292   /* Pacify compilers when the user code never invokes YYERROR and the
1293      label yyerrorlab therefore never appears in user code.  */
1294   if (0)
1295     YYERROR;
1296   ++yynerrs;
1297 
1298   /* Do not reclaim the symbols of the rule whose action triggered
1299      this YYERROR.  */
1300   YYPOPSTACK (yylen);
1301   yylen = 0;
1302   YY_STACK_PRINT (yyss, yyssp);
1303   yystate = *yyssp;
1304   goto yyerrlab1;
1305 
1306 
1307 /*-------------------------------------------------------------.
1308 | yyerrlab1 -- common code for both syntax error and YYERROR.  |
1309 `-------------------------------------------------------------*/
1310 yyerrlab1:
1311   yyerrstatus = 3;      /* Each real token shifted decrements this.  */
1312 
1313   /* Pop stack until we find a state that shifts the error token.  */
1314   for (;;)
1315     {
1316       yyn = yypact[yystate];
1317       if (!yypact_value_is_default (yyn))
1318         {
1319           yyn += YYSYMBOL_YYerror;
1320           if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYSYMBOL_YYerror)
1321             {
1322               yyn = yytable[yyn];
1323               if (0 < yyn)
1324                 break;
1325             }
1326         }
1327 
1328       /* Pop the current state because it cannot handle the error token.  */
1329       if (yyssp == yyss)
1330         YYABORT;
1331 
1332 
1333       yydestruct ("Error: popping",
1334                   YY_ACCESSING_SYMBOL (yystate), yyvsp);
1335       YYPOPSTACK (1);
1336       yystate = *yyssp;
1337       YY_STACK_PRINT (yyss, yyssp);
1338     }
1339 
1340   YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
1341   *++yyvsp = yylval;
1342   YY_IGNORE_MAYBE_UNINITIALIZED_END
1343 
1344 
1345   /* Shift the error token.  */
1346   YY_SYMBOL_PRINT ("Shifting", YY_ACCESSING_SYMBOL (yyn), yyvsp, yylsp);
1347 
1348   yystate = yyn;
1349   goto yynewstate;
1350 
1351 
1352 /*-------------------------------------.
1353 | yyacceptlab -- YYACCEPT comes here.  |
1354 `-------------------------------------*/
1355 yyacceptlab:
1356   yyresult = 0;
1357   goto yyreturnlab;
1358 
1359 
1360 /*-----------------------------------.
1361 | yyabortlab -- YYABORT comes here.  |
1362 `-----------------------------------*/
1363 yyabortlab:
1364   yyresult = 1;
1365   goto yyreturnlab;
1366 
1367 
1368 /*-----------------------------------------------------------.
1369 | yyexhaustedlab -- YYNOMEM (memory exhaustion) comes here.  |
1370 `-----------------------------------------------------------*/
1371 yyexhaustedlab:
1372   yyerror (YY_("memory exhausted"));
1373   yyresult = 2;
1374   goto yyreturnlab;
1375 
1376 
1377 /*----------------------------------------------------------.
1378 | yyreturnlab -- parsing is finished, clean up and return.  |
1379 `----------------------------------------------------------*/
1380 yyreturnlab:
1381   if (yychar != YYEMPTY)
1382     {
1383       /* Make sure we have latest lookahead translation.  See comments at
1384          user semantic actions for why this is necessary.  */
1385       yytoken = YYTRANSLATE (yychar);
1386       yydestruct ("Cleanup: discarding lookahead",
1387                   yytoken, &yylval);
1388     }
1389   /* Do not reclaim the symbols of the rule whose action triggered
1390      this YYABORT or YYACCEPT.  */
1391   YYPOPSTACK (yylen);
1392   YY_STACK_PRINT (yyss, yyssp);
1393   while (yyssp != yyss)
1394     {
1395       yydestruct ("Cleanup: popping",
1396                   YY_ACCESSING_SYMBOL (+*yyssp), yyvsp);
1397       YYPOPSTACK (1);
1398     }
1399 #ifndef yyoverflow
1400   if (yyss != yyssa)
1401     YYSTACK_FREE (yyss);
1402 #endif
1403 
1404   return yyresult;
1405 }
1406 
1407 #line 104 "slc-gram.y"
1408 
1409 char *filename;
1410 FILE *cfile, *hfile;
1411 int error_flag;
1412 struct assignment *assignment;
1413 
1414 
1415 static void
ex(struct assignment * a,const char * fmt,...)1416 ex(struct assignment *a, const char *fmt, ...)
1417 {
1418     va_list ap;
1419     fprintf(stderr, "%s:%d: ", a->name, a->lineno);
1420     va_start(ap, fmt);
1421     vfprintf(stderr, fmt, ap);
1422     va_end(ap);
1423     fprintf(stderr, "\n");
1424 }
1425 
1426 
1427 
1428 static int
check_option(struct assignment * as)1429 check_option(struct assignment *as)
1430 {
1431     struct assignment *a;
1432     int seen_long = 0;
1433     int seen_name = 0;
1434     int seen_short = 0;
1435     int seen_type = 0;
1436     int seen_argument = 0;
1437     int seen_help = 0;
1438     int seen_default = 0;
1439     int ret = 0;
1440 
1441     for(a = as; a != NULL; a = a->next) {
1442 	if(strcmp(a->name, "long") == 0)
1443 	    seen_long++;
1444 	else if(strcmp(a->name, "short") == 0)
1445 	    seen_short++;
1446 	else if(strcmp(a->name, "name") == 0)
1447 	    seen_name++;
1448 	else if(strcmp(a->name, "type") == 0)
1449 	    seen_type++;
1450 	else if(strcmp(a->name, "argument") == 0)
1451 	    seen_argument++;
1452 	else if(strcmp(a->name, "help") == 0)
1453 	    seen_help++;
1454 	else if(strcmp(a->name, "default") == 0)
1455 	    seen_default++;
1456 	else {
1457 	    ex(a, "unknown name %s", a->name);
1458 	    ret++;
1459 	}
1460     }
1461     if(seen_long == 0 && seen_short == 0) {
1462 	ex(as, "neither long nor short option");
1463 	ret++;
1464     }
1465     if (seen_long == 0 && seen_name == 0) {
1466 	ex(as, "either of long or name option must be used");
1467 	ret++;
1468     }
1469     if(seen_long > 1) {
1470 	ex(as, "multiple long options");
1471 	ret++;
1472     }
1473     if(seen_short > 1) {
1474 	ex(as, "multiple short options");
1475 	ret++;
1476     }
1477     if(seen_type > 1) {
1478 	ex(as, "multiple types");
1479 	ret++;
1480     }
1481     if(seen_argument > 1) {
1482 	ex(as, "multiple arguments");
1483 	ret++;
1484     }
1485     if(seen_help > 1) {
1486 	ex(as, "multiple help strings");
1487 	ret++;
1488     }
1489     if(seen_default > 1) {
1490 	ex(as, "multiple default values");
1491 	ret++;
1492     }
1493     return ret;
1494 }
1495 
1496 static int
check_command(struct assignment * as)1497 check_command(struct assignment *as)
1498 {
1499 	struct assignment *a;
1500 	int seen_name = 0;
1501 	int seen_function = 0;
1502 	int seen_help = 0;
1503 	int seen_argument = 0;
1504 	int seen_minargs = 0;
1505 	int seen_maxargs = 0;
1506 	int ret = 0;
1507 	for(a = as; a != NULL; a = a->next) {
1508 		if(strcmp(a->name, "name") == 0)
1509 			seen_name++;
1510 		else if(strcmp(a->name, "function") == 0) {
1511 			seen_function++;
1512 		} else if(strcmp(a->name, "option") == 0)
1513 			ret += check_option(a->u.assignment);
1514 		else if(strcmp(a->name, "help") == 0) {
1515 			seen_help++;
1516 		} else if(strcmp(a->name, "argument") == 0) {
1517 			seen_argument++;
1518 		} else if(strcmp(a->name, "min_args") == 0) {
1519 			seen_minargs++;
1520 		} else if(strcmp(a->name, "max_args") == 0) {
1521 			seen_maxargs++;
1522 		} else {
1523 			ex(a, "unknown name: %s", a->name);
1524 			ret++;
1525 		}
1526 	}
1527 	if(seen_name == 0) {
1528 		ex(as, "no command name");
1529 		ret++;
1530 	}
1531 	if(seen_function > 1) {
1532 		ex(as, "multiple function names");
1533 		ret++;
1534 	}
1535 	if(seen_help > 1) {
1536 		ex(as, "multiple help strings");
1537 		ret++;
1538 	}
1539 	if(seen_argument > 1) {
1540 		ex(as, "multiple argument strings");
1541 		ret++;
1542 	}
1543 	if(seen_minargs > 1) {
1544 		ex(as, "multiple min_args strings");
1545 		ret++;
1546 	}
1547 	if(seen_maxargs > 1) {
1548 		ex(as, "multiple max_args strings");
1549 		ret++;
1550 	}
1551 
1552 	return ret;
1553 }
1554 
1555 static int
check(struct assignment * as)1556 check(struct assignment *as)
1557 {
1558     struct assignment *a;
1559     int ret = 0;
1560     for(a = as; a != NULL; a = a->next) {
1561 	if(strcmp(a->name, "command")) {
1562 	    fprintf(stderr, "unknown type %s line %d\n", a->name, a->lineno);
1563 	    ret++;
1564 	    continue;
1565 	}
1566 	if(a->type != a_assignment) {
1567 	    fprintf(stderr, "bad command definition %s line %d\n", a->name, a->lineno);
1568 	    ret++;
1569 	    continue;
1570 	}
1571 	ret += check_command(a->u.assignment);
1572     }
1573     return ret;
1574 }
1575 
1576 static struct assignment *
find_next(struct assignment * as,const char * name)1577 find_next(struct assignment *as, const char *name)
1578 {
1579     for(as = as->next; as != NULL; as = as->next) {
1580 	if(strcmp(as->name, name) == 0)
1581 	    return as;
1582     }
1583     return NULL;
1584 }
1585 
1586 static struct assignment *
find(struct assignment * as,const char * name)1587 find(struct assignment *as, const char *name)
1588 {
1589     for(; as != NULL; as = as->next) {
1590 	if(strcmp(as->name, name) == 0)
1591 	    return as;
1592     }
1593     return NULL;
1594 }
1595 
1596 static void
space(FILE * f,int level)1597 space(FILE *f, int level)
1598 {
1599     fprintf(f, "%*.*s", level * 4, level * 4, " ");
1600 }
1601 
1602 static void
cprint(int level,const char * fmt,...)1603 cprint(int level, const char *fmt, ...)
1604 {
1605     va_list ap;
1606     va_start(ap, fmt);
1607     space(cfile, level);
1608     vfprintf(cfile, fmt, ap);
1609     va_end(ap);
1610 }
1611 
1612 static void
hprint(int level,const char * fmt,...)1613 hprint(int level, const char *fmt, ...)
1614 {
1615     va_list ap;
1616     va_start(ap, fmt);
1617     space(hfile, level);
1618     vfprintf(hfile, fmt, ap);
1619     va_end(ap);
1620 }
1621 
1622 static void gen_name(char *str);
1623 
1624 static void
gen_command(struct assignment * as)1625 gen_command(struct assignment *as)
1626 {
1627     struct assignment *a, *b;
1628     char *f;
1629     a = find(as, "name");
1630     f = strdup(a->u.value);
1631     gen_name(f);
1632     cprint(1, "    { ");
1633     fprintf(cfile, "\"%s\", ", a->u.value);
1634     fprintf(cfile, "%s_wrap, ", f);
1635     free(f);
1636     b = find(as, "argument");
1637     if(b)
1638 	fprintf(cfile, "\"%s %s\", ", a->u.value, b->u.value);
1639     else
1640 	fprintf(cfile, "\"%s\", ", a->u.value);
1641     b = find(as, "help");
1642     if(b)
1643 	fprintf(cfile, "\"%s\"", b->u.value);
1644     else
1645 	fprintf(cfile, "NULL");
1646     fprintf(cfile, " },\n");
1647     for(a = a->next; a != NULL; a = a->next)
1648 	if(strcmp(a->name, "name") == 0)
1649 	    cprint(1, "    { \"%s\", NULL, NULL, NULL },\n", a->u.value);
1650     cprint(0, "\n");
1651 }
1652 
1653 static void
gen_name(char * str)1654 gen_name(char *str)
1655 {
1656     char *p;
1657     for(p = str; *p != '\0'; p++)
1658 	if(!isalnum((unsigned char)*p))
1659 	    *p = '_';
1660 }
1661 
1662 static char *
make_name(struct assignment * as)1663 make_name(struct assignment *as)
1664 {
1665     struct assignment *lopt;
1666     struct assignment *type;
1667     char *s;
1668     int ret;
1669 
1670     lopt = find(as, "long");
1671     if(lopt == NULL)
1672 	lopt = find(as, "name");
1673     if(lopt == NULL)
1674 	return NULL;
1675 
1676     type = find(as, "type");
1677     if(strcmp(type->u.value, "-flag") == 0)
1678 	ret = asprintf(&s, "%s_flag", lopt->u.value);
1679     else
1680 	ret = asprintf(&s, "%s_%s", lopt->u.value, type->u.value);
1681     if (ret == -1)
1682 	return NULL;
1683     gen_name(s);
1684     return s;
1685 }
1686 
1687 
defval_int(const char * name,struct assignment * defval)1688 static void defval_int(const char *name, struct assignment *defval)
1689 {
1690     if(defval != NULL)
1691 	cprint(1, "opt.%s = %s;\n", name, defval->u.value);
1692     else
1693 	cprint(1, "opt.%s = 0;\n", name);
1694 }
defval_neg_flag(const char * name,struct assignment * defval)1695 static void defval_neg_flag(const char *name, struct assignment *defval)
1696 {
1697     if(defval != NULL)
1698 	cprint(1, "opt.%s = %s;\n", name, defval->u.value);
1699     else
1700 	cprint(1, "opt.%s = 1;\n", name);
1701 }
defval_string(const char * name,struct assignment * defval)1702 static void defval_string(const char *name, struct assignment *defval)
1703 {
1704     if(defval != NULL)
1705 	cprint(1, "opt.%s = (char *)(unsigned long)\"%s\";\n", name, defval->u.value);
1706     else
1707 	cprint(1, "opt.%s = NULL;\n", name);
1708 }
defval_strings(const char * name,struct assignment * defval)1709 static void defval_strings(const char *name, struct assignment *defval)
1710 {
1711     cprint(1, "opt.%s.num_strings = 0;\n", name);
1712     cprint(1, "opt.%s.strings = NULL;\n", name);
1713 }
1714 
free_strings(const char * name)1715 static void free_strings(const char *name)
1716 {
1717     cprint(1, "free_getarg_strings (&opt.%s);\n", name);
1718 }
1719 
1720 struct type_handler {
1721     const char *typename;
1722     const char *c_type;
1723     const char *getarg_type;
1724     void (*defval)(const char*, struct assignment*);
1725     void (*free)(const char*);
1726 } type_handlers[] = {
1727 	{ "integer",
1728 	  "int",
1729 	  "arg_integer",
1730 	  defval_int,
1731 	  NULL
1732 	},
1733 	{ "string",
1734 	  "char*",
1735 	  "arg_string",
1736 	  defval_string,
1737 	  NULL
1738 	},
1739 	{ "strings",
1740 	  "struct getarg_strings",
1741 	  "arg_strings",
1742 	  defval_strings,
1743 	  free_strings
1744 	},
1745 	{ "flag",
1746 	  "int",
1747 	  "arg_flag",
1748 	  defval_int,
1749 	  NULL
1750 	},
1751 	{ "-flag",
1752 	  "int",
1753 	  "arg_negative_flag",
1754 	  defval_neg_flag,
1755 	  NULL
1756 	},
1757 	{ NULL, NULL, NULL, NULL, NULL }
1758 };
1759 
find_handler(struct assignment * type)1760 static struct type_handler *find_handler(struct assignment *type)
1761 {
1762     struct type_handler *th;
1763     for(th = type_handlers; th->typename != NULL; th++)
1764 	if(strcmp(type->u.value, th->typename) == 0)
1765 	    return th;
1766     ex(type, "unknown type \"%s\"", type->u.value);
1767     exit(1);
1768 }
1769 
1770 static void
gen_options(struct assignment * opt1,const char * name)1771 gen_options(struct assignment *opt1, const char *name)
1772 {
1773     struct assignment *tmp;
1774 
1775     hprint(0, "struct %s_options {\n", name);
1776 
1777     for(tmp = opt1;
1778 	tmp != NULL;
1779 	tmp = find_next(tmp, "option")) {
1780 	struct assignment *type;
1781 	struct type_handler *th;
1782 	char *s;
1783 
1784 	s = make_name(tmp->u.assignment);
1785 	type = find(tmp->u.assignment, "type");
1786 	th = find_handler(type);
1787 	hprint(1, "%s %s;\n", th->c_type, s);
1788 	free(s);
1789     }
1790     hprint(0, "};\n");
1791 }
1792 
1793 static void
gen_wrapper(struct assignment * as)1794 gen_wrapper(struct assignment *as)
1795 {
1796     struct assignment *name;
1797     struct assignment *arg;
1798     struct assignment *opt1;
1799     struct assignment *function;
1800     struct assignment *tmp;
1801     char *n, *f;
1802     int nargs = 0;
1803     int narguments = 0;
1804 
1805     name = find(as, "name");
1806     n = strdup(name->u.value);
1807     gen_name(n);
1808     arg = find(as, "argument");
1809     if (arg)
1810         narguments++;
1811     opt1 = find(as, "option");
1812     function = find(as, "function");
1813     if(function)
1814 	f = function->u.value;
1815     else
1816 	f = n;
1817 
1818 
1819     if(opt1 != NULL) {
1820 	gen_options(opt1, n);
1821 	hprint(0, "int %s(struct %s_options*, int, char **);\n", f, n);
1822     } else {
1823 	hprint(0, "int %s(void*, int, char **);\n", f);
1824     }
1825 
1826     fprintf(cfile, "static int\n");
1827     fprintf(cfile, "%s_wrap(int argc, char **argv)\n", n);
1828     fprintf(cfile, "{\n");
1829     if(opt1 != NULL)
1830 	cprint(1, "struct %s_options opt;\n", n);
1831     cprint(1, "int ret;\n");
1832     cprint(1, "int optidx = 0;\n");
1833     cprint(1, "struct getargs args[] = {\n");
1834     for(tmp = find(as, "option");
1835 	tmp != NULL;
1836 	tmp = find_next(tmp, "option")) {
1837 	struct assignment *type = find(tmp->u.assignment, "type");
1838 	struct assignment *lopt = find(tmp->u.assignment, "long");
1839 	struct assignment *sopt = find(tmp->u.assignment, "short");
1840 	struct assignment *aarg = find(tmp->u.assignment, "argument");
1841 	struct assignment *help = find(tmp->u.assignment, "help");
1842 
1843 	struct type_handler *th;
1844 
1845 	cprint(2, "{ ");
1846 	if(lopt)
1847 	    fprintf(cfile, "\"%s\", ", lopt->u.value);
1848 	else
1849 	    fprintf(cfile, "NULL, ");
1850 	if(sopt)
1851 	    fprintf(cfile, "'%c', ", *sopt->u.value);
1852 	else
1853 	    fprintf(cfile, "0, ");
1854 	th = find_handler(type);
1855 	fprintf(cfile, "%s, ", th->getarg_type);
1856 	fprintf(cfile, "NULL, ");
1857 	if(help)
1858 	    fprintf(cfile, "\"%s\", ", help->u.value);
1859 	else
1860 	    fprintf(cfile, "NULL, ");
1861 	if(aarg) {
1862 	    fprintf(cfile, "\"%s\"", aarg->u.value);
1863             narguments++;
1864 	} else
1865 	    fprintf(cfile, "NULL");
1866 	fprintf(cfile, " },\n");
1867     }
1868     cprint(2, "{ \"help\", 'h', arg_flag, NULL, NULL, NULL }\n");
1869     cprint(1, "};\n");
1870     cprint(1, "int help_flag = 0;\n");
1871 
1872     for(tmp = find(as, "option");
1873 	tmp != NULL;
1874 	tmp = find_next(tmp, "option")) {
1875 	char *s;
1876 	struct assignment *type = find(tmp->u.assignment, "type");
1877 
1878 	struct assignment *defval = find(tmp->u.assignment, "default");
1879 
1880 	struct type_handler *th;
1881 
1882 	s = make_name(tmp->u.assignment);
1883 	th = find_handler(type);
1884 	(*th->defval)(s, defval);
1885 	free(s);
1886     }
1887 
1888     for(tmp = find(as, "option");
1889 	tmp != NULL;
1890 	tmp = find_next(tmp, "option")) {
1891 	char *s;
1892 	s = make_name(tmp->u.assignment);
1893 	cprint(1, "args[%d].value = &opt.%s;\n", nargs++, s);
1894 	free(s);
1895     }
1896     cprint(1, "args[%d].value = &help_flag;\n", nargs++);
1897     cprint(1, "if(getarg(args, %d, argc, argv, &optidx))\n", nargs);
1898     cprint(2, "goto usage;\n");
1899 
1900     {
1901 	int min_args = -1;
1902 	int max_args = -1;
1903 	char *end;
1904 	if(narguments == 0) {
1905 	    max_args = 0;
1906 	} else {
1907 	    if((tmp = find(as, "min_args")) != NULL) {
1908 		min_args = strtol(tmp->u.value, &end, 0);
1909 		if(*end != '\0') {
1910 		    ex(tmp, "min_args is not numeric");
1911 		    exit(1);
1912 		}
1913 		if(min_args < 0) {
1914 		    ex(tmp, "min_args must be non-negative");
1915 		    exit(1);
1916 		}
1917 	    }
1918 	    if((tmp = find(as, "max_args")) != NULL) {
1919 		max_args = strtol(tmp->u.value, &end, 0);
1920 		if(*end != '\0') {
1921 		    ex(tmp, "max_args is not numeric");
1922 		    exit(1);
1923 		}
1924 		if(max_args < 0) {
1925 		    ex(tmp, "max_args must be non-negative");
1926 		    exit(1);
1927 		}
1928 	    }
1929 	}
1930 	if(min_args != -1 || max_args != -1) {
1931 	    if(min_args == max_args) {
1932 		cprint(1, "if(argc - optidx != %d) {\n",
1933 		       min_args);
1934 		cprint(2, "fprintf(stderr, \"Need exactly %u parameters (%%u given).\\n\\n\", argc - optidx);\n", min_args);
1935 		cprint(2, "goto usage;\n");
1936 		cprint(1, "}\n");
1937 	    } else {
1938 		if(max_args != -1) {
1939 		    cprint(1, "if(argc - optidx > %d) {\n", max_args);
1940 		    cprint(2, "fprintf(stderr, \"Arguments given (%%u) are more than expected (%u).\\n\\n\", argc - optidx);\n", max_args);
1941 		    cprint(2, "goto usage;\n");
1942 		    cprint(1, "}\n");
1943 		}
1944 		if(min_args != -1) {
1945 		    cprint(1, "if(argc - optidx < %d) {\n", min_args);
1946 		    cprint(2, "fprintf(stderr, \"Arguments given (%%u) are less than expected (%u).\\n\\n\", argc - optidx);\n", min_args);
1947 		    cprint(2, "goto usage;\n");
1948 		    cprint(1, "}\n");
1949 		}
1950 	    }
1951 	}
1952     }
1953 
1954     cprint(1, "if(help_flag)\n");
1955     cprint(2, "goto usage;\n");
1956 
1957     cprint(1, "ret = %s(%s, argc - optidx, argv + optidx);\n",
1958 	   f, opt1 ? "&opt": "NULL");
1959 
1960     /* free allocated data */
1961     for(tmp = find(as, "option");
1962 	tmp != NULL;
1963 	tmp = find_next(tmp, "option")) {
1964 	char *s;
1965 	struct assignment *type = find(tmp->u.assignment, "type");
1966 	struct type_handler *th;
1967 	th = find_handler(type);
1968 	if(th->free == NULL)
1969 	    continue;
1970 	s = make_name(tmp->u.assignment);
1971 	(*th->free)(s);
1972 	free(s);
1973     }
1974     cprint(1, "return ret;\n");
1975 
1976     cprint(0, "usage:\n");
1977     cprint(1, "arg_printusage (args, %d, \"%s\", \"%s\");\n", nargs,
1978 	   name->u.value, arg ? arg->u.value : "");
1979     /* free allocated data */
1980     for(tmp = find(as, "option");
1981 	tmp != NULL;
1982 	tmp = find_next(tmp, "option")) {
1983 	char *s;
1984 	struct assignment *type = find(tmp->u.assignment, "type");
1985 	struct type_handler *th;
1986 	th = find_handler(type);
1987 	if(th->free == NULL)
1988 	    continue;
1989 	s = make_name(tmp->u.assignment);
1990 	(*th->free)(s);
1991 	free(s);
1992     }
1993     cprint(1, "return 0;\n");
1994     cprint(0, "}\n");
1995     cprint(0, "\n");
1996 }
1997 
1998 char cname[PATH_MAX];
1999 char hname[PATH_MAX];
2000 
2001 static void
gen(struct assignment * as)2002 gen(struct assignment *as)
2003 {
2004     struct assignment *a;
2005     cprint(0, "#include <stdio.h>\n");
2006     cprint(0, "#include <krb5/getarg.h>\n");
2007     cprint(0, "#include <krb5/sl.h>\n");
2008     cprint(0, "#include \"%s\"\n\n", hname);
2009 
2010     hprint(0, "#include <stdio.h>\n");
2011     hprint(0, "#include <krb5/sl.h>\n");
2012     hprint(0, "\n");
2013 
2014 
2015     for(a = as; a != NULL; a = a->next)
2016 	gen_wrapper(a->u.assignment);
2017 
2018     cprint(0, "SL_cmd commands[] = {\n");
2019     for(a = as; a != NULL; a = a->next)
2020 	gen_command(a->u.assignment);
2021     cprint(1, "{ NULL, NULL, NULL, NULL }\n");
2022     cprint(0, "};\n");
2023 
2024     hprint(0, "extern SL_cmd commands[];\n");
2025 }
2026 
2027 int version_flag;
2028 int help_flag;
2029 struct getargs args[] = {
2030     { "version", 0, arg_flag, &version_flag, NULL, NULL },
2031     { "help", 0, arg_flag, &help_flag, NULL, NULL }
2032 };
2033 int num_args = sizeof(args) / sizeof(args[0]);
2034 
2035 static void
usage(int code)2036 usage(int code)
2037 {
2038     arg_printusage(args, num_args, NULL, "command-table");
2039     exit(code);
2040 }
2041 
2042 int
main(int argc,char ** argv)2043 main(int argc, char **argv)
2044 {
2045     char *p;
2046 
2047     int optidx = 0;
2048 
2049     setprogname(argv[0]);
2050     if(getarg(args, num_args, argc, argv, &optidx))
2051 	usage(1);
2052     if(help_flag)
2053 	usage(0);
2054     if(version_flag) {
2055 	print_version(NULL);
2056 	exit(0);
2057     }
2058 
2059     if(argc == optidx)
2060 	usage(1);
2061 
2062     filename = argv[optidx];
2063     yyin = fopen(filename, "r");
2064     if(yyin == NULL)
2065 	err(1, "%s", filename);
2066     p = strrchr(filename, '/');
2067     if(p)
2068 	strlcpy(cname, p + 1, sizeof(cname));
2069     else
2070 	strlcpy(cname, filename, sizeof(cname));
2071     p = strrchr(cname, '.');
2072     if(p)
2073 	*p = '\0';
2074     strlcpy(hname, cname, sizeof(hname));
2075     strlcat(cname, ".c", sizeof(cname));
2076     strlcat(hname, ".h", sizeof(hname));
2077     yyparse();
2078     if(error_flag)
2079 	exit(1);
2080     if(check(assignment) == 0) {
2081 	cfile = fopen(cname, "w");
2082 	if(cfile == NULL)
2083 	  err(1, "%s", cname);
2084 	hfile = fopen(hname, "w");
2085 	if(hfile == NULL)
2086 	  err(1, "%s", hname);
2087 	gen(assignment);
2088 	fclose(cfile);
2089 	fclose(hfile);
2090     }
2091     fclose(yyin);
2092     return 0;
2093 }
2094