1 /* A Bison parser, made by GNU Bison 2.5. */
3 /* Bison implementation for Yacc-like parsers in C
5 Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
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.
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.
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/>. */
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.
30 This special exception was added by the Free Software Foundation in
31 version 2.2 of Bison. */
33 /* C LALR(1) parser skeleton written by Richard Stallman, by
34 simplifying the original so-called "semantic" parser. */
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. */
43 /* Identify Bison output. */
47 #define YYBISON_VERSION "2.5"
50 #define YYSKELETON_NAME "yacc.c"
61 /* Using locations. */
62 #define YYLSP_NEEDED 0
66 /* Copy the first part of user declarations. */
68 /* Line 268 of yacc.c */
77 #if defined(__STDC__) && __STDC__ < 1 /* VMS weirdness, maybe elsewhere */
81 static void yyerror(const char *m, ...) ATTRIBUTE_PRINTF_1;
82 static void error_ln(int line, const char *m, ...) ATTRIBUTE_PRINTF_2;
83 static void lintwarn_ln(int line, const char *m, ...) ATTRIBUTE_PRINTF_2;
84 static void warning_ln(int line, const char *m, ...) ATTRIBUTE_PRINTF_2;
85 static char *get_src_buf(void);
86 static int yylex(void);
88 static INSTRUCTION *snode(INSTRUCTION *subn, INSTRUCTION *op);
89 static int func_install(INSTRUCTION *fp, INSTRUCTION *def);
90 static void pop_params(NODE *params);
91 static NODE *make_param(char *pname);
92 static NODE *mk_rexp(INSTRUCTION *exp);
93 static void append_param(char *pname);
94 static int dup_parms(INSTRUCTION *fp, NODE *func);
95 static void param_sanity(INSTRUCTION *arglist);
96 static int parms_shadow(INSTRUCTION *pc, int *shadow);
97 static int isnoeffect(OPCODE type);
98 static INSTRUCTION *make_assignable(INSTRUCTION *ip);
99 static void dumpintlstr(const char *str, size_t len);
100 static void dumpintlstr2(const char *str1, size_t len1, const char *str2, size_t len2);
101 static int isarray(NODE *n);
102 static int include_source(INSTRUCTION *file);
103 static void next_sourcefile(void);
104 static char *tokexpand(void);
106 #define instruction(t) bcalloc(t, 1, 0)
108 static INSTRUCTION *mk_program(void);
109 static INSTRUCTION *append_rule(INSTRUCTION *pattern, INSTRUCTION *action);
110 static INSTRUCTION *mk_condition(INSTRUCTION *cond, INSTRUCTION *ifp, INSTRUCTION *true_branch,
111 INSTRUCTION *elsep, INSTRUCTION *false_branch);
112 static INSTRUCTION *mk_expression_list(INSTRUCTION *list, INSTRUCTION *s1);
113 static INSTRUCTION *mk_for_loop(INSTRUCTION *forp, INSTRUCTION *init, INSTRUCTION *cond,
114 INSTRUCTION *incr, INSTRUCTION *body);
115 static void fix_break_continue(INSTRUCTION *list, INSTRUCTION *b_target, INSTRUCTION *c_target);
116 static INSTRUCTION *mk_binary(INSTRUCTION *s1, INSTRUCTION *s2, INSTRUCTION *op);
117 static INSTRUCTION *mk_boolean(INSTRUCTION *left, INSTRUCTION *right, INSTRUCTION *op);
118 static INSTRUCTION *mk_assignment(INSTRUCTION *lhs, INSTRUCTION *rhs, INSTRUCTION *op);
119 static INSTRUCTION *mk_getline(INSTRUCTION *op, INSTRUCTION *opt_var, INSTRUCTION *redir, int redirtype);
120 static NODE *make_regnode(int type, NODE *exp);
121 static int count_expressions(INSTRUCTION **list, int isarg);
122 static INSTRUCTION *optimize_assignment(INSTRUCTION *exp);
123 static void add_lint(INSTRUCTION *list, LINTTYPE linttype);
125 enum defref { FUNC_DEFINE, FUNC_USE };
126 static void func_use(const char *name, enum defref how);
127 static void check_funcs(void);
128 static void free_bcpool(INSTRUCTION *pl);
130 static ssize_t read_one_line(int fd, void *buffer, size_t count);
131 static int one_line_close(int fd);
133 static void (*install_func)(char *) = NULL;
135 static int want_source = FALSE;
136 static int want_regexp; /* lexical scanning kludge */
137 static int can_return; /* parsing kludge */
140 const char *const ruletab[] = {
149 static int in_print = FALSE; /* lexical scanning kludge for print */
150 static int in_parens = 0; /* lexical scanning kludge for print */
151 static int sub_counter = 0; /* array dimension counter for use in delete */
152 static char *lexptr = NULL; /* pointer to next char during parsing */
154 static char *lexptr_begin; /* keep track of where we were for error msgs */
155 static char *lexeme; /* beginning of lexeme for debugging */
156 static int lexeof; /* seen EOF for current source? */
157 static char *thisline = NULL;
158 static int in_braces = 0; /* count braces for firstline, lastline in an 'action' */
159 static int lastline = 0;
160 static int firstline = 0;
161 static SRCFILE *sourcefile = NULL; /* current program source */
162 static int lasttok = 0;
163 static int eof_warned = FALSE; /* GLOBAL: want warning for each file */
164 static int break_allowed; /* kludge for break */
165 static int continue_allowed; /* kludge for continue */
168 #define END_FILE -1000
169 #define END_SRC -2000
171 #define YYDEBUG_LEXER_TEXT (lexeme)
172 static int param_counter;
173 static NODE *func_params; /* list of parameters for the current function */
174 static char *tokstart = NULL;
175 static char *tok = NULL;
177 static int errcount = 0;
179 static NODE *symbol_list;
180 extern void destroy_symbol(char *name);
182 static long func_count; /* total number of functions */
184 #define HASHSIZE 1021 /* this constant only used here */
185 NODE *variables[HASHSIZE];
186 static int var_count; /* total number of global variables */
189 extern int sourceline;
190 extern SRCFILE *srcfiles;
191 extern INSTRUCTION *rule_list;
194 static INSTRUCTION *rule_block[sizeof(ruletab)];
196 static INSTRUCTION *ip_rec;
197 static INSTRUCTION *ip_newfile;
198 static INSTRUCTION *ip_atexit = NULL;
199 static INSTRUCTION *ip_end;
200 static INSTRUCTION *ip_endfile;
201 static INSTRUCTION *ip_beginfile;
203 static inline INSTRUCTION *list_create(INSTRUCTION *x);
204 static inline INSTRUCTION *list_append(INSTRUCTION *l, INSTRUCTION *x);
205 static inline INSTRUCTION *list_prepend(INSTRUCTION *l, INSTRUCTION *x);
206 static inline INSTRUCTION *list_merge(INSTRUCTION *l1, INSTRUCTION *l2);
208 extern double fmod(double x, double y);
210 * This string cannot occur as a real awk identifier.
211 * Use it as a special token to make function parsing
212 * uniform, but if it's seen, don't install the function.
214 * function split(x) { return x }
215 * function x(a) { return a }
216 * should only produce one error message, and not core dump.
218 static char builtin_func[] = "@builtin";
220 #define YYSTYPE INSTRUCTION *
223 /* Line 268 of yacc.c */
224 #line 225 "awkgram.c"
226 /* Enabling traces. */
231 /* Enabling verbose error messages. */
232 #ifdef YYERROR_VERBOSE
233 # undef YYERROR_VERBOSE
234 # define YYERROR_VERBOSE 1
236 # define YYERROR_VERBOSE 0
239 /* Enabling the token table. */
240 #ifndef YYTOKEN_TABLE
241 # define YYTOKEN_TABLE 0
248 /* Put the tokens into the symbol table, so that GDB and other debuggers
299 SLASH_BEFORE_EQUAL = 306,
304 #define FUNC_CALL 258
316 #define CONCAT_OP 270
317 #define SUBSCRIPT 271
318 #define LEX_BEGIN 272
322 #define LEX_RETURN 276
323 #define LEX_DELETE 277
324 #define LEX_SWITCH 278
326 #define LEX_DEFAULT 280
327 #define LEX_WHILE 281
330 #define LEX_BREAK 284
331 #define LEX_CONTINUE 285
332 #define LEX_PRINT 286
333 #define LEX_PRINTF 287
336 #define LEX_FUNCTION 290
337 #define LEX_BEGINFILE 291
338 #define LEX_ENDFILE 292
339 #define LEX_GETLINE 293
340 #define LEX_NEXTFILE 294
344 #define INCREMENT 298
345 #define DECREMENT 299
346 #define LEX_BUILTIN 300
347 #define LEX_LENGTH 301
349 #define LEX_INCLUDE 303
352 #define SLASH_BEFORE_EQUAL 306
358 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
360 # define YYSTYPE_IS_TRIVIAL 1
361 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
362 # define YYSTYPE_IS_DECLARED 1
366 /* Copy the second part of user declarations. */
369 /* Line 343 of yacc.c */
370 #line 371 "awkgram.c"
377 typedef YYTYPE_UINT8 yytype_uint8;
379 typedef unsigned char yytype_uint8;
383 typedef YYTYPE_INT8 yytype_int8;
384 #elif (defined __STDC__ || defined __C99__FUNC__ \
385 || defined __cplusplus || defined _MSC_VER)
386 typedef signed char yytype_int8;
388 typedef short int yytype_int8;
392 typedef YYTYPE_UINT16 yytype_uint16;
394 typedef unsigned short int yytype_uint16;
398 typedef YYTYPE_INT16 yytype_int16;
400 typedef short int yytype_int16;
404 # ifdef __SIZE_TYPE__
405 # define YYSIZE_T __SIZE_TYPE__
406 # elif defined size_t
407 # define YYSIZE_T size_t
408 # elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
409 || defined __cplusplus || defined _MSC_VER)
410 # include <stddef.h> /* INFRINGES ON USER NAME SPACE */
411 # define YYSIZE_T size_t
413 # define YYSIZE_T unsigned int
417 #define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
420 # if defined YYENABLE_NLS && YYENABLE_NLS
422 # include <libintl.h> /* INFRINGES ON USER NAME SPACE */
423 # define YY_(msgid) dgettext ("bison-runtime", msgid)
427 # define YY_(msgid) msgid
431 /* Suppress unused-variable warnings by "using" E. */
432 #if ! defined lint || defined __GNUC__
433 # define YYUSE(e) ((void) (e))
435 # define YYUSE(e) /* empty */
438 /* Identity function, used to suppress warnings about constant conditions. */
442 #if (defined __STDC__ || defined __C99__FUNC__ || defined __cplusplus || defined _MSC_VER)
455 #if ! defined yyoverflow || YYERROR_VERBOSE
457 /* The parser invokes alloca or malloc; define the necessary symbols. */
459 # ifdef YYSTACK_USE_ALLOCA
460 # if YYSTACK_USE_ALLOCA
462 # define YYSTACK_ALLOC __builtin_alloca
463 # elif defined __BUILTIN_VA_ARG_INCR
464 # include <alloca.h> /* INFRINGES ON USER NAME SPACE */
466 # define YYSTACK_ALLOC __alloca
467 # elif defined _MSC_VER
468 # include <malloc.h> /* INFRINGES ON USER NAME SPACE */
469 # define alloca _alloca
471 # define YYSTACK_ALLOC alloca
472 # if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
473 || defined __cplusplus || defined _MSC_VER)
474 # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
475 # ifndef EXIT_SUCCESS
476 # define EXIT_SUCCESS 0
483 # ifdef YYSTACK_ALLOC
484 /* Pacify GCC's `empty if-body' warning. */
485 # define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
486 # ifndef YYSTACK_ALLOC_MAXIMUM
487 /* The OS might guarantee only one guard page at the bottom of the stack,
488 and a page size can be as small as 4096 bytes. So we cannot safely
489 invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
490 to allow for a few compiler-allocated temporary stack slots. */
491 # define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
494 # define YYSTACK_ALLOC YYMALLOC
495 # define YYSTACK_FREE YYFREE
496 # ifndef YYSTACK_ALLOC_MAXIMUM
497 # define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
499 # if (defined __cplusplus && ! defined EXIT_SUCCESS \
500 && ! ((defined YYMALLOC || defined malloc) \
501 && (defined YYFREE || defined free)))
502 # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
503 # ifndef EXIT_SUCCESS
504 # define EXIT_SUCCESS 0
508 # define YYMALLOC malloc
509 # if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
510 || defined __cplusplus || defined _MSC_VER)
511 void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
516 # if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
517 || defined __cplusplus || defined _MSC_VER)
518 void free (void *); /* INFRINGES ON USER NAME SPACE */
522 #endif /* ! defined yyoverflow || YYERROR_VERBOSE */
525 #if (! defined yyoverflow && (! defined __cplusplus || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
527 /* A type that is properly aligned for any stack member. */
530 yytype_int16 yyss_alloc;
534 /* The size of the maximum gap between one aligned stack and the next. */
535 # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
537 /* The size of an array large to enough to hold all stacks, each with
539 # define YYSTACK_BYTES(N) \
540 ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
541 + YYSTACK_GAP_MAXIMUM)
543 # define YYCOPY_NEEDED 1
545 /* Relocate STACK from its old location to the new one. The
546 local variables YYSIZE and YYSTACKSIZE give the old and new number of
547 elements in the stack, and YYPTR gives the new location of the
548 stack. Advance YYPTR to a properly aligned location for the next
550 # define YYSTACK_RELOCATE(Stack_alloc, Stack) \
553 YYSIZE_T yynewbytes; \
554 YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \
555 Stack = &yyptr->Stack_alloc; \
556 yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
557 yyptr += yynewbytes / sizeof (*yyptr); \
563 #if defined YYCOPY_NEEDED && YYCOPY_NEEDED
564 /* Copy COUNT objects from FROM to TO. The source and destination do
567 # if defined __GNUC__ && 1 < __GNUC__
568 # define YYCOPY(To, From, Count) \
569 __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
571 # define YYCOPY(To, From, Count) \
575 for (yyi = 0; yyi < (Count); yyi++) \
576 (To)[yyi] = (From)[yyi]; \
581 #endif /* !YYCOPY_NEEDED */
583 /* YYFINAL -- State number of the termination state. */
585 /* YYLAST -- Last index in YYTABLE. */
588 /* YYNTOKENS -- Number of terminals. */
590 /* YYNNTS -- Number of nonterminals. */
592 /* YYNRULES -- Number of rules. */
594 /* YYNRULES -- Number of states. */
595 #define YYNSTATES 330
597 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
599 #define YYMAXUTOK 307
601 #define YYTRANSLATE(YYX) \
602 ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
604 /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
605 static const yytype_uint8 yytranslate[] =
607 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
608 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
609 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
610 2, 2, 2, 62, 2, 2, 65, 61, 2, 2,
611 66, 67, 59, 57, 54, 58, 2, 60, 2, 2,
612 2, 2, 2, 2, 2, 2, 2, 2, 53, 73,
613 55, 2, 56, 52, 68, 2, 2, 2, 2, 2,
614 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
615 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
616 2, 69, 2, 70, 64, 2, 2, 2, 2, 2,
617 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
618 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
619 2, 2, 2, 71, 2, 72, 2, 2, 2, 2,
620 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
621 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
622 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
623 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
624 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
625 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
626 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
627 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
628 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
629 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
630 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
631 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
632 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
633 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
634 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
635 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
636 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
637 45, 46, 47, 48, 49, 50, 51, 63
641 /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
643 static const yytype_uint16 yyprhs[] =
645 0, 0, 3, 4, 7, 10, 13, 16, 19, 22,
646 25, 30, 32, 35, 37, 38, 40, 45, 47, 49,
647 51, 53, 59, 61, 63, 65, 68, 70, 72, 73,
648 81, 82, 86, 88, 90, 91, 94, 97, 99, 102,
649 105, 109, 111, 121, 128, 137, 146, 159, 171, 173,
650 176, 179, 182, 185, 189, 190, 195, 198, 199, 204,
651 205, 210, 215, 217, 218, 220, 221, 224, 227, 233,
652 238, 240, 243, 246, 248, 250, 252, 254, 256, 260,
653 261, 262, 266, 273, 283, 285, 288, 289, 291, 292,
654 295, 296, 298, 300, 304, 306, 309, 313, 314, 316,
655 317, 319, 321, 325, 327, 330, 334, 338, 342, 346,
656 350, 354, 358, 362, 368, 370, 372, 374, 377, 379,
657 381, 383, 385, 387, 389, 392, 394, 398, 402, 406,
658 410, 414, 418, 422, 425, 428, 434, 439, 443, 447,
659 451, 455, 459, 463, 465, 468, 472, 477, 482, 484,
660 486, 488, 491, 494, 496, 498, 501, 504, 506, 509,
661 514, 515, 517, 518, 521, 523, 526, 528, 532, 534,
662 537, 540, 542, 545, 547, 551, 553, 555, 556, 559,
663 562, 564, 565, 567, 569, 571
666 /* YYRHS -- A `-1'-separated list of the rules' RHS. */
667 static const yytype_int16 yyrhs[] =
669 75, 0, -1, -1, 75, 76, -1, 75, 104, -1,
670 75, 47, -1, 75, 1, -1, 78, 79, -1, 78,
671 88, -1, 82, 79, -1, 68, 48, 77, 88, -1,
672 6, -1, 6, 1, -1, 1, -1, -1, 112, -1,
673 112, 54, 105, 112, -1, 17, -1, 18, -1, 36,
674 -1, 37, -1, 132, 87, 133, 135, 105, -1, 4,
675 -1, 3, -1, 81, -1, 68, 49, -1, 45, -1,
676 46, -1, -1, 35, 83, 80, 66, 107, 134, 105,
677 -1, -1, 86, 85, 5, -1, 60, -1, 51, -1,
678 -1, 87, 89, -1, 87, 1, -1, 104, -1, 136,
679 105, -1, 136, 105, -1, 132, 87, 133, -1, 103,
680 -1, 23, 66, 112, 134, 105, 132, 96, 105, 133,
681 -1, 26, 66, 112, 134, 105, 89, -1, 27, 105,
682 89, 26, 66, 112, 134, 105, -1, 28, 66, 4,
683 40, 129, 134, 105, 89, -1, 28, 66, 95, 136,
684 105, 112, 136, 105, 95, 134, 105, 89, -1, 28,
685 66, 95, 136, 105, 136, 105, 95, 134, 105, 89,
686 -1, 90, -1, 29, 88, -1, 30, 88, -1, 33,
687 88, -1, 39, 88, -1, 34, 109, 88, -1, -1,
688 21, 91, 109, 88, -1, 92, 88, -1, -1, 99,
689 93, 100, 101, -1, -1, 22, 4, 94, 123, -1,
690 22, 66, 4, 67, -1, 112, -1, -1, 92, -1,
691 -1, 96, 97, -1, 96, 1, -1, 24, 98, 137,
692 105, 87, -1, 25, 137, 105, 87, -1, 7, -1,
693 58, 7, -1, 57, 7, -1, 8, -1, 84, -1,
694 31, -1, 32, -1, 110, -1, 66, 111, 134, -1,
695 -1, -1, 10, 102, 116, -1, 19, 66, 112, 134,
696 105, 89, -1, 19, 66, 112, 134, 105, 89, 20,
697 105, 89, -1, 50, -1, 104, 50, -1, -1, 104,
698 -1, -1, 55, 117, -1, -1, 108, -1, 4, -1,
699 108, 138, 4, -1, 1, -1, 108, 1, -1, 108,
700 138, 1, -1, -1, 112, -1, -1, 111, -1, 112,
701 -1, 111, 138, 112, -1, 1, -1, 111, 1, -1,
702 111, 1, 112, -1, 111, 138, 1, -1, 130, 113,
703 112, -1, 112, 41, 112, -1, 112, 42, 112, -1,
704 112, 14, 112, -1, 112, 40, 129, -1, 112, 115,
705 112, -1, 112, 52, 112, 53, 112, -1, 116, -1,
706 13, -1, 12, -1, 51, 13, -1, 9, -1, 55,
707 -1, 114, -1, 56, -1, 117, -1, 118, -1, 116,
708 117, -1, 119, -1, 117, 64, 117, -1, 117, 59,
709 117, -1, 117, 60, 117, -1, 117, 61, 117, -1,
710 117, 57, 117, -1, 117, 58, 117, -1, 38, 122,
711 106, -1, 130, 43, -1, 130, 44, -1, 66, 111,
712 134, 40, 129, -1, 116, 11, 38, 122, -1, 118,
713 64, 117, -1, 118, 59, 117, -1, 118, 60, 117,
714 -1, 118, 61, 117, -1, 118, 57, 117, -1, 118,
715 58, 117, -1, 84, -1, 62, 117, -1, 66, 112,
716 134, -1, 45, 66, 110, 134, -1, 46, 66, 110,
717 134, -1, 46, -1, 120, -1, 130, -1, 43, 130,
718 -1, 44, 130, -1, 7, -1, 8, -1, 58, 117,
719 -1, 57, 117, -1, 121, -1, 68, 121, -1, 3,
720 66, 110, 134, -1, -1, 130, -1, -1, 124, 16,
721 -1, 125, -1, 124, 125, -1, 126, -1, 69, 111,
722 70, -1, 126, -1, 127, 126, -1, 127, 16, -1,
723 4, -1, 4, 128, -1, 129, -1, 65, 119, 131,
724 -1, 43, -1, 44, -1, -1, 71, 105, -1, 72,
725 105, -1, 67, -1, -1, 136, -1, 73, -1, 53,
729 /* YYRLINE[YYN] -- source line where rule number YYN was defined. */
730 static const yytype_uint16 yyrline[] =
732 0, 218, 218, 220, 225, 226, 230, 242, 246, 257,
733 265, 273, 281, 283, 289, 290, 292, 318, 329, 340,
734 346, 355, 365, 367, 369, 380, 385, 386, 391, 390,
735 420, 419, 452, 454, 459, 460, 473, 478, 479, 483,
736 485, 487, 494, 584, 626, 668, 781, 788, 795, 805,
737 814, 823, 832, 847, 863, 862, 874, 886, 886, 982,
738 982, 1007, 1030, 1036, 1037, 1043, 1044, 1051, 1056, 1068,
739 1082, 1084, 1090, 1095, 1097, 1105, 1107, 1116, 1117, 1125,
740 1130, 1130, 1141, 1145, 1153, 1154, 1157, 1159, 1164, 1165,
741 1172, 1174, 1178, 1184, 1191, 1193, 1195, 1202, 1203, 1209,
742 1210, 1215, 1217, 1222, 1224, 1226, 1228, 1234, 1241, 1243,
743 1245, 1261, 1271, 1278, 1280, 1285, 1287, 1289, 1297, 1299,
744 1304, 1306, 1311, 1313, 1315, 1368, 1370, 1372, 1374, 1376,
745 1378, 1380, 1382, 1405, 1410, 1415, 1440, 1446, 1448, 1450,
746 1452, 1454, 1456, 1461, 1465, 1496, 1498, 1504, 1510, 1523,
747 1524, 1525, 1530, 1535, 1539, 1543, 1555, 1568, 1573, 1609,
748 1627, 1628, 1634, 1635, 1640, 1642, 1649, 1666, 1683, 1685,
749 1692, 1697, 1705, 1719, 1731, 1740, 1744, 1748, 1752, 1756,
750 1760, 1763, 1765, 1769, 1773, 1777
754 #if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
755 /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
756 First, the terminals, then, starting at YYNTOKENS, nonterminals. */
757 static const char *const yytname[] =
759 "$end", "error", "$undefined", "FUNC_CALL", "NAME", "REGEXP",
760 "FILENAME", "YNUMBER", "YSTRING", "RELOP", "IO_OUT", "IO_IN", "ASSIGNOP",
761 "ASSIGN", "MATCHOP", "CONCAT_OP", "SUBSCRIPT", "LEX_BEGIN", "LEX_END",
762 "LEX_IF", "LEX_ELSE", "LEX_RETURN", "LEX_DELETE", "LEX_SWITCH",
763 "LEX_CASE", "LEX_DEFAULT", "LEX_WHILE", "LEX_DO", "LEX_FOR", "LEX_BREAK",
764 "LEX_CONTINUE", "LEX_PRINT", "LEX_PRINTF", "LEX_NEXT", "LEX_EXIT",
765 "LEX_FUNCTION", "LEX_BEGINFILE", "LEX_ENDFILE", "LEX_GETLINE",
766 "LEX_NEXTFILE", "LEX_IN", "LEX_AND", "LEX_OR", "INCREMENT", "DECREMENT",
767 "LEX_BUILTIN", "LEX_LENGTH", "LEX_EOF", "LEX_INCLUDE", "LEX_EVAL",
768 "NEWLINE", "SLASH_BEFORE_EQUAL", "'?'", "':'", "','", "'<'", "'>'",
769 "'+'", "'-'", "'*'", "'/'", "'%'", "'!'", "UNARY", "'^'", "'$'", "'('",
770 "')'", "'@'", "'['", "']'", "'{'", "'}'", "';'", "$accept", "program",
771 "rule", "source", "pattern", "action", "func_name", "lex_builtin",
772 "function_prologue", "$@1", "regexp", "$@2", "a_slash", "statements",
773 "statement_term", "statement", "non_compound_stmt", "$@3", "simple_stmt",
774 "$@4", "$@5", "opt_simple_stmt", "case_statements", "case_statement",
775 "case_value", "print", "print_expression_list", "output_redir", "$@6",
776 "if_statement", "nls", "opt_nls", "input_redir", "opt_param_list",
777 "param_list", "opt_exp", "opt_expression_list", "expression_list", "exp",
778 "assign_operator", "relop_or_less", "a_relop", "common_exp", "simp_exp",
779 "simp_exp_nc", "non_post_simp_exp", "func_call", "direct_func_call",
780 "opt_variable", "delete_subscript_list", "delete_subscript",
781 "delete_exp_list", "bracketed_exp_list", "subscript", "subscript_list",
782 "simple_variable", "variable", "opt_incdec", "l_brace", "r_brace",
783 "r_paren", "opt_semi", "semi", "colon", "comma", 0
788 /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
790 static const yytype_uint16 yytoknum[] =
792 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
793 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
794 275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
795 285, 286, 287, 288, 289, 290, 291, 292, 293, 294,
796 295, 296, 297, 298, 299, 300, 301, 302, 303, 304,
797 305, 306, 63, 58, 44, 60, 62, 43, 45, 42,
798 47, 37, 33, 307, 94, 36, 40, 41, 64, 91,
803 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
804 static const yytype_uint8 yyr1[] =
806 0, 74, 75, 75, 75, 75, 75, 76, 76, 76,
807 76, 77, 77, 77, 78, 78, 78, 78, 78, 78,
808 78, 79, 80, 80, 80, 80, 81, 81, 83, 82,
809 85, 84, 86, 86, 87, 87, 87, 88, 88, 89,
810 89, 89, 89, 89, 89, 89, 89, 89, 89, 90,
811 90, 90, 90, 90, 91, 90, 90, 93, 92, 94,
812 92, 92, 92, 95, 95, 96, 96, 96, 97, 97,
813 98, 98, 98, 98, 98, 99, 99, 100, 100, 101,
814 102, 101, 103, 103, 104, 104, 105, 105, 106, 106,
815 107, 107, 108, 108, 108, 108, 108, 109, 109, 110,
816 110, 111, 111, 111, 111, 111, 111, 112, 112, 112,
817 112, 112, 112, 112, 112, 113, 113, 113, 114, 114,
818 115, 115, 116, 116, 116, 117, 117, 117, 117, 117,
819 117, 117, 117, 117, 117, 117, 118, 118, 118, 118,
820 118, 118, 118, 119, 119, 119, 119, 119, 119, 119,
821 119, 119, 119, 119, 119, 119, 119, 120, 120, 121,
822 122, 122, 123, 123, 124, 124, 125, 126, 127, 127,
823 128, 129, 129, 130, 130, 131, 131, 131, 132, 133,
824 134, 135, 135, 136, 137, 138
827 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
828 static const yytype_uint8 yyr2[] =
830 0, 2, 0, 2, 2, 2, 2, 2, 2, 2,
831 4, 1, 2, 1, 0, 1, 4, 1, 1, 1,
832 1, 5, 1, 1, 1, 2, 1, 1, 0, 7,
833 0, 3, 1, 1, 0, 2, 2, 1, 2, 2,
834 3, 1, 9, 6, 8, 8, 12, 11, 1, 2,
835 2, 2, 2, 3, 0, 4, 2, 0, 4, 0,
836 4, 4, 1, 0, 1, 0, 2, 2, 5, 4,
837 1, 2, 2, 1, 1, 1, 1, 1, 3, 0,
838 0, 3, 6, 9, 1, 2, 0, 1, 0, 2,
839 0, 1, 1, 3, 1, 2, 3, 0, 1, 0,
840 1, 1, 3, 1, 2, 3, 3, 3, 3, 3,
841 3, 3, 3, 5, 1, 1, 1, 2, 1, 1,
842 1, 1, 1, 1, 2, 1, 3, 3, 3, 3,
843 3, 3, 3, 2, 2, 5, 4, 3, 3, 3,
844 3, 3, 3, 1, 2, 3, 4, 4, 1, 1,
845 1, 2, 2, 1, 1, 2, 2, 1, 2, 4,
846 0, 1, 0, 2, 1, 2, 1, 3, 1, 2,
847 2, 1, 2, 1, 3, 1, 1, 0, 2, 2,
851 /* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM.
852 Performed when YYTABLE doesn't specify something else to do. Zero
853 means the default is an error. */
854 static const yytype_uint8 yydefact[] =
856 2, 0, 1, 6, 0, 171, 153, 154, 17, 18,
857 28, 19, 20, 160, 0, 0, 0, 148, 5, 84,
858 33, 0, 0, 32, 0, 0, 0, 0, 3, 0,
859 0, 143, 30, 4, 15, 114, 122, 123, 125, 149,
860 157, 173, 150, 0, 0, 168, 0, 172, 0, 88,
861 161, 151, 152, 0, 0, 0, 156, 150, 155, 144,
862 0, 177, 150, 103, 0, 101, 0, 158, 86, 183,
863 7, 8, 37, 34, 86, 9, 0, 85, 118, 0,
864 0, 0, 0, 0, 86, 119, 121, 120, 0, 0,
865 124, 0, 0, 0, 0, 0, 0, 0, 0, 0,
866 0, 0, 0, 116, 115, 133, 134, 0, 0, 0,
867 0, 101, 0, 170, 169, 23, 22, 26, 27, 0,
868 0, 24, 0, 132, 0, 0, 0, 175, 176, 174,
869 104, 86, 180, 0, 0, 145, 13, 0, 0, 87,
870 178, 0, 38, 31, 110, 111, 108, 109, 0, 0,
871 112, 160, 130, 131, 127, 128, 129, 126, 141, 142,
872 138, 139, 140, 137, 117, 107, 159, 167, 25, 0,
873 89, 146, 147, 105, 185, 0, 106, 102, 12, 10,
874 36, 0, 54, 0, 0, 0, 86, 0, 0, 0,
875 75, 76, 0, 97, 0, 86, 35, 48, 0, 57,
876 41, 62, 34, 181, 86, 0, 16, 136, 94, 92,
877 0, 0, 135, 0, 97, 59, 0, 0, 0, 0,
878 63, 49, 50, 51, 0, 98, 52, 179, 56, 0,
879 0, 86, 182, 39, 113, 86, 95, 0, 0, 0,
880 162, 0, 0, 0, 0, 171, 64, 0, 53, 0,
881 79, 77, 40, 21, 29, 96, 93, 86, 55, 60,
882 0, 164, 166, 61, 86, 86, 0, 0, 86, 0,
883 80, 58, 0, 163, 165, 0, 0, 0, 0, 0,
884 78, 0, 82, 65, 43, 0, 86, 0, 86, 81,
885 86, 0, 86, 0, 86, 63, 0, 67, 0, 0,
886 66, 0, 44, 45, 63, 0, 83, 70, 73, 0,
887 0, 74, 0, 184, 86, 42, 0, 86, 72, 71,
888 86, 34, 86, 0, 34, 0, 0, 47, 0, 46
891 /* YYDEFGOTO[NTERM-NUM]. */
892 static const yytype_int16 yydefgoto[] =
894 -1, 1, 28, 138, 29, 70, 120, 121, 30, 48,
895 31, 76, 32, 141, 71, 196, 197, 214, 198, 229,
896 240, 247, 291, 300, 312, 199, 250, 271, 281, 200,
897 139, 140, 123, 210, 211, 224, 109, 110, 201, 108,
898 87, 88, 35, 36, 37, 38, 39, 40, 49, 259,
899 260, 261, 45, 46, 47, 41, 42, 129, 202, 203,
900 135, 231, 204, 314, 134
903 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
905 #define YYPACT_NINF -269
906 static const yytype_int16 yypact[] =
908 -269, 335, -269, -269, -31, -24, -269, -269, -269, -269,
909 -269, -269, -269, 12, 12, 12, -19, -12, -269, -269,
910 -269, 978, 978, -269, 978, 1023, 804, 21, -269, 115,
911 -21, -269, -269, 8, 1062, 952, -20, 330, -269, -269,
912 -269, -269, 246, 736, 804, -269, 2, -269, 205, 15,
913 -269, -269, -269, 736, 736, 70, 52, 80, 52, 52,
914 978, 147, -269, -269, 50, 308, 174, -269, 64, -269,
915 -269, -269, 8, -269, 64, -269, 129, -269, -269, 978,
916 143, 978, 978, 978, 64, -269, -269, -269, 978, 112,
917 -20, 978, 978, 978, 978, 978, 978, 978, 978, 978,
918 978, 978, 978, -269, -269, -269, -269, 141, 978, 90,
919 152, 1101, 48, -269, -269, -269, -269, -269, -269, 111,
920 105, -269, 978, -269, 90, 90, 308, -269, -269, -269,
921 978, 64, -269, 134, 830, -269, -269, 13, -16, 8,
922 -269, 552, -269, -269, 53, -269, 142, 300, 1081, 978,
923 103, 12, 185, 185, 52, 52, 52, 52, 185, 185,
924 52, 52, 52, 52, -269, 1101, -269, -269, -269, 63,
925 -20, -269, -269, 1101, -269, 143, -269, 1101, -269, -269,
926 -269, 121, -269, 6, 130, 137, 64, 139, -16, -16,
927 -269, -269, -16, 978, -16, 64, -269, -269, -16, -269,
928 -269, 1101, -269, 127, 64, 978, 1101, -269, -269, -269,
929 90, 118, -269, 978, 978, -269, 180, 978, 978, 665,
930 875, -269, -269, -269, -16, 1101, -269, -269, -269, 598,
931 552, 64, -269, -269, 1101, 64, -269, 28, 308, -16,
932 -24, 140, 308, 308, 189, -14, -269, 127, -269, 804,
933 201, -269, -269, -269, -269, -269, -269, 64, -269, -269,
934 14, -269, -269, -269, 64, 64, 158, 143, 64, 50,
935 -269, -269, 665, -269, -269, -21, 665, 978, 90, 710,
936 134, 978, 198, -269, -269, 308, 64, 1056, 64, 952,
937 64, 60, 64, 665, 64, 907, 665, -269, 119, 177,
938 -269, 155, -269, -269, 907, 90, -269, -269, -269, 224,
939 228, -269, 177, -269, 64, -269, 90, 64, -269, -269,
940 64, -269, 64, 665, -269, 406, 665, -269, 479, -269
943 /* YYPGOTO[NTERM-NUM]. */
944 static const yytype_int16 yypgoto[] =
946 -269, -269, -269, -269, -269, 208, -269, -269, -269, -269,
947 -58, -269, -269, -193, 72, -171, -269, -269, -189, -269,
948 -269, -268, -269, -269, -269, -269, -269, -269, -269, -269,
949 45, 37, -269, -269, -269, 38, -48, -23, -1, -269,
950 -269, -269, -26, 44, -269, 217, -269, 1, 102, -269,
951 -269, -3, -39, -269, -269, -72, -2, -269, -28, -213,
952 -49, -269, -25, -47, 66
955 /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
956 positive, shift that token. If negative, reduce the rule which
957 number is the opposite. If YYTABLE_NINF, syntax error. */
958 #define YYTABLE_NINF -101
959 static const yytype_int16 yytable[] =
961 34, 73, 73, 64, 74, 124, 125, 114, 145, 230,
962 215, 50, 51, 52, 178, 133, 5, 252, 113, 57,
963 57, 112, 57, 62, 4, 65, 267, 305, 67, 255,
964 273, 246, 256, 57, 19, 43, 316, 91, 92, 93,
965 94, 95, 111, 111, 96, 44, 33, 53, 244, 130,
966 68, 130, 111, 111, 54, 44, 67, 69, 77, 126,
967 166, 297, 78, -11, 208, 56, 58, 209, 59, 66,
968 122, 44, 216, 4, 72, 171, 172, 25, 144, 90,
969 146, 147, 148, 44, 298, 299, -11, 150, 315, 57,
970 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
971 57, 282, 131, 212, 131, 284, 246, 165, 85, 86,
972 19, 142, -101, 74, 19, 246, 96, 132, 167, 236,
973 57, 149, 303, 105, 106, 306, 307, 308, 325, 173,
974 -90, 328, -86, 177, 143, 152, 153, 154, 155, 156,
975 157, 158, 159, 160, 161, 162, 163, 5, 206, 50,
976 151, 78, 327, 130, 164, 329, 79, 132, -101, -101,
977 168, 235, -100, 74, 74, 19, 170, 74, 174, 74,
978 20, 169, 131, 74, 175, 136, 309, 310, 232, 23,
979 137, 251, 80, 72, 241, -91, 68, 213, 69, 257,
980 127, 128, 225, 264, 265, 278, 217, 85, 86, 74,
981 69, 262, -100, 218, 234, 220, 131, 263, 115, 116,
982 179, 270, 238, 225, 74, 266, 242, 243, 290, -100,
983 280, 262, 268, 219, 277, -100, 269, 195, 111, 286,
984 313, 318, 227, 72, 72, 319, 292, 72, 75, 72,
985 311, 233, 61, 72, 93, 94, 95, 283, 65, 96,
986 117, 118, 239, 207, 288, 289, 317, 274, 103, 104,
987 221, 222, 294, 0, 223, 320, 226, 322, 253, 72,
988 228, 0, 254, 119, 0, 0, 285, 237, 287, 57,
989 0, 0, 0, 0, 72, 0, 0, 57, 0, 105,
990 106, 0, 0, 0, 272, 0, 248, 107, 0, 0,
991 0, 275, 276, 0, 0, 279, 0, 0, 0, 78,
992 0, 258, 0, 0, 79, 0, 0, 78, 0, 0,
993 0, 0, 79, 293, 0, 295, 0, 296, 301, 302,
994 0, 304, 0, 90, 0, 2, 3, 0, 4, 5,
995 80, 81, 6, 7, 0, 0, 0, 0, 80, 81,
996 82, 321, 8, 9, 323, 85, 86, 324, 0, 326,
997 83, 0, 0, 85, 86, 0, 0, 0, 0, 0,
998 10, 11, 12, 13, 0, 132, 0, 0, 14, 15,
999 16, 17, 18, 0, 0, 19, 20, 97, 98, 99,
1000 100, 101, 21, 22, 102, 23, 0, 24, 0, 0,
1001 25, 26, 0, 27, 0, 0, -14, 180, -14, 4,
1002 5, 0, 0, 6, 7, 0, 0, 0, 0, 0,
1003 0, 0, 0, 0, 0, 181, 0, 182, 183, 184,
1004 -69, -69, 185, 186, 187, 188, 189, 190, 191, 192,
1005 193, 0, 0, 0, 13, 194, 0, 0, 0, 14,
1006 15, 16, 17, 0, 0, 0, -69, 20, 0, 0,
1007 0, 0, 0, 21, 22, 0, 23, 0, 24, 0,
1008 0, 25, 26, 0, 55, 0, 0, 68, -69, 69,
1009 180, 0, 4, 5, 0, 0, 6, 7, 0, 0,
1010 0, 0, 0, 0, 0, 0, 0, 0, 181, 0,
1011 182, 183, 184, -68, -68, 185, 186, 187, 188, 189,
1012 190, 191, 192, 193, 0, 0, 0, 13, 194, 0,
1013 0, 0, 14, 15, 16, 17, 0, 0, 0, -68,
1014 20, 0, 0, 0, 0, 0, 21, 22, 0, 23,
1015 0, 24, 0, 0, 25, 26, 0, 55, 0, 0,
1016 68, -68, 69, 180, 0, 4, 5, 0, 0, 6,
1017 7, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1018 0, 181, 0, 182, 183, 184, 0, 0, 185, 186,
1019 187, 188, 189, 190, 191, 192, 193, 0, 0, 0,
1020 13, 194, 0, 0, 0, 14, 15, 16, 17, 63,
1021 0, 4, 5, 20, 0, 6, 7, 0, -99, 21,
1022 22, 0, 23, 0, 24, 0, 0, 25, 26, 0,
1023 55, 0, 0, 68, 195, 69, 0, 0, 0, 0,
1024 0, 0, 0, 0, 0, 0, 13, 0, 0, 0,
1025 0, 14, 15, 16, 17, 0, 0, 0, -99, 20,
1026 0, 0, 0, 0, 0, 21, 22, 0, 23, 0,
1027 24, 0, 0, 25, 249, -99, 55, 0, 4, 5,
1028 0, -99, 6, 7, 0, 0, 0, 0, 0, 0,
1029 0, 0, 0, 0, 181, 0, 182, 183, 184, 0,
1030 0, 185, 186, 187, 188, 189, 190, 191, 192, 193,
1031 0, 0, 0, 13, 194, 0, 0, 0, 14, 15,
1032 16, 17, 0, 4, 5, 0, 20, 6, 7, 0,
1033 0, 0, 21, 22, 0, 23, 0, 24, 0, 0,
1034 25, 26, 0, 55, 0, 0, 68, 63, 69, 4,
1035 5, 0, 0, 6, 7, 0, 0, 0, 13, 0,
1036 0, 0, 0, 14, 15, 16, 17, 0, 0, 0,
1037 0, 20, 0, 0, 0, 0, 0, 21, 22, 0,
1038 23, 0, 24, 0, 13, 25, 26, 0, 55, 14,
1039 15, 16, 17, 69, 0, 0, 0, 20, 0, 0,
1040 0, 0, 0, 21, 22, 0, 23, 0, 24, 0,
1041 0, 25, 26, -99, 55, 63, 0, 4, 5, 0,
1042 0, 6, 7, 0, 0, 0, 0, 0, 0, 0,
1043 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1044 0, 176, 0, 4, 5, 0, 0, 6, 7, 0,
1045 0, 0, 13, 0, 0, 0, 0, 14, 15, 16,
1046 17, 0, 0, 0, 0, 20, 0, 0, 0, 0,
1047 0, 21, 22, 0, 23, 0, 24, 0, 13, 25,
1048 26, 0, 55, 14, 15, 16, 17, 0, 4, 245,
1049 0, 20, 6, 7, 0, 0, 0, 21, 22, 0,
1050 23, 0, 24, 0, 0, 25, 26, 183, 55, 0,
1051 0, 0, 0, 0, 0, 0, 190, 191, 0, 0,
1052 4, 5, 0, 13, 6, 7, 0, 0, 14, 15,
1053 16, 17, 0, 0, 0, 0, 20, 0, 0, 183,
1054 0, 0, 21, 22, 0, 23, 0, 24, 190, 191,
1055 25, 26, 0, 55, 0, 13, 0, 0, 0, 0,
1056 14, 15, 16, 17, 0, 4, 5, 0, 20, 6,
1057 7, 0, 0, 89, 21, 22, 0, 23, 0, 24,
1058 0, 0, 25, 26, 0, 55, 0, 0, 0, 0,
1059 0, 4, 5, 0, 0, 6, 7, 0, 0, 0,
1060 13, 0, 0, 0, 0, 14, 15, 16, 17, 0,
1061 0, 0, 0, 20, 0, 0, 0, 0, 0, 21,
1062 22, 0, 23, 0, 24, 0, 13, 25, 26, 0,
1063 55, 14, 15, 16, 17, 0, 4, 5, 0, 20,
1064 6, 7, 0, 0, 0, 21, 22, 0, 23, 0,
1065 24, 0, 0, 25, 26, 0, 55, 0, 0, 0,
1066 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1067 0, 0, 0, 0, 0, 78, 14, 15, 16, 17,
1068 79, 78, 0, 0, 20, 0, 79, 0, 0, 0,
1069 21, 22, 0, 23, 0, 24, 0, 0, 25, 60,
1070 78, 55, 0, 0, 0, 79, 80, 81, 82, 0,
1071 0, 0, 80, 81, 82, 0, 0, 0, 83, 0,
1072 78, 85, 86, 0, 83, 79, 84, 85, 86, 0,
1073 0, 80, 81, 82, 0, 0, 0, 0, 0, 69,
1074 0, 0, 0, 83, 205, 0, 85, 86, 0, 0,
1075 0, 80, 81, 82, 0, 0, 0, 0, 0, 0,
1076 0, 0, 0, 83, 0, 0, 85, 86
1079 #define yypact_value_is_default(yystate) \
1080 ((yystate) == (-269))
1082 #define yytable_value_is_error(yytable_value) \
1083 ((yytable_value) == (-101))
1085 static const yytype_int16 yycheck[] =
1087 1, 29, 30, 26, 29, 53, 54, 46, 80, 202,
1088 4, 13, 14, 15, 1, 64, 4, 230, 16, 21,
1089 22, 44, 24, 25, 3, 26, 40, 295, 27, 1,
1090 16, 220, 4, 35, 50, 66, 304, 57, 58, 59,
1091 60, 61, 43, 44, 64, 69, 1, 66, 219, 1,
1092 71, 1, 53, 54, 66, 69, 55, 73, 50, 60,
1093 109, 1, 9, 50, 1, 21, 22, 4, 24, 48,
1094 55, 69, 66, 3, 29, 124, 125, 65, 79, 35,
1095 81, 82, 83, 69, 24, 25, 73, 88, 301, 91,
1096 92, 93, 94, 95, 96, 97, 98, 99, 100, 101,
1097 102, 272, 54, 175, 54, 276, 295, 108, 55, 56,
1098 50, 74, 9, 138, 50, 304, 64, 67, 70, 1,
1099 122, 84, 293, 43, 44, 296, 7, 8, 321, 130,
1100 67, 324, 72, 134, 5, 91, 92, 93, 94, 95,
1101 96, 97, 98, 99, 100, 101, 102, 4, 149, 151,
1102 38, 9, 323, 1, 13, 326, 14, 67, 55, 56,
1103 49, 210, 10, 188, 189, 50, 122, 192, 131, 194,
1104 51, 66, 54, 198, 40, 1, 57, 58, 203, 60,
1105 6, 229, 40, 138, 4, 67, 71, 66, 73, 238,
1106 43, 44, 193, 242, 243, 267, 66, 55, 56, 224,
1107 73, 240, 50, 66, 205, 66, 54, 67, 3, 4,
1108 138, 10, 213, 214, 239, 26, 217, 218, 20, 67,
1109 269, 260, 247, 186, 66, 73, 249, 72, 229, 278,
1110 53, 7, 195, 188, 189, 7, 285, 192, 30, 194,
1111 298, 204, 25, 198, 59, 60, 61, 275, 249, 64,
1112 45, 46, 214, 151, 279, 281, 305, 260, 12, 13,
1113 188, 189, 287, -1, 192, 312, 194, 316, 231, 224,
1114 198, -1, 235, 68, -1, -1, 277, 211, 279, 281,
1115 -1, -1, -1, -1, 239, -1, -1, 289, -1, 43,
1116 44, -1, -1, -1, 257, -1, 224, 51, -1, -1,
1117 -1, 264, 265, -1, -1, 268, -1, -1, -1, 9,
1118 -1, 239, -1, -1, 14, -1, -1, 9, -1, -1,
1119 -1, -1, 14, 286, -1, 288, -1, 290, 291, 292,
1120 -1, 294, -1, 289, -1, 0, 1, -1, 3, 4,
1121 40, 41, 7, 8, -1, -1, -1, -1, 40, 41,
1122 42, 314, 17, 18, 317, 55, 56, 320, -1, 322,
1123 52, -1, -1, 55, 56, -1, -1, -1, -1, -1,
1124 35, 36, 37, 38, -1, 67, -1, -1, 43, 44,
1125 45, 46, 47, -1, -1, 50, 51, 57, 58, 59,
1126 60, 61, 57, 58, 64, 60, -1, 62, -1, -1,
1127 65, 66, -1, 68, -1, -1, 71, 1, 73, 3,
1128 4, -1, -1, 7, 8, -1, -1, -1, -1, -1,
1129 -1, -1, -1, -1, -1, 19, -1, 21, 22, 23,
1130 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
1131 34, -1, -1, -1, 38, 39, -1, -1, -1, 43,
1132 44, 45, 46, -1, -1, -1, 50, 51, -1, -1,
1133 -1, -1, -1, 57, 58, -1, 60, -1, 62, -1,
1134 -1, 65, 66, -1, 68, -1, -1, 71, 72, 73,
1135 1, -1, 3, 4, -1, -1, 7, 8, -1, -1,
1136 -1, -1, -1, -1, -1, -1, -1, -1, 19, -1,
1137 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
1138 31, 32, 33, 34, -1, -1, -1, 38, 39, -1,
1139 -1, -1, 43, 44, 45, 46, -1, -1, -1, 50,
1140 51, -1, -1, -1, -1, -1, 57, 58, -1, 60,
1141 -1, 62, -1, -1, 65, 66, -1, 68, -1, -1,
1142 71, 72, 73, 1, -1, 3, 4, -1, -1, 7,
1143 8, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1144 -1, 19, -1, 21, 22, 23, -1, -1, 26, 27,
1145 28, 29, 30, 31, 32, 33, 34, -1, -1, -1,
1146 38, 39, -1, -1, -1, 43, 44, 45, 46, 1,
1147 -1, 3, 4, 51, -1, 7, 8, -1, 10, 57,
1148 58, -1, 60, -1, 62, -1, -1, 65, 66, -1,
1149 68, -1, -1, 71, 72, 73, -1, -1, -1, -1,
1150 -1, -1, -1, -1, -1, -1, 38, -1, -1, -1,
1151 -1, 43, 44, 45, 46, -1, -1, -1, 50, 51,
1152 -1, -1, -1, -1, -1, 57, 58, -1, 60, -1,
1153 62, -1, -1, 65, 66, 67, 68, -1, 3, 4,
1154 -1, 73, 7, 8, -1, -1, -1, -1, -1, -1,
1155 -1, -1, -1, -1, 19, -1, 21, 22, 23, -1,
1156 -1, 26, 27, 28, 29, 30, 31, 32, 33, 34,
1157 -1, -1, -1, 38, 39, -1, -1, -1, 43, 44,
1158 45, 46, -1, 3, 4, -1, 51, 7, 8, -1,
1159 -1, -1, 57, 58, -1, 60, -1, 62, -1, -1,
1160 65, 66, -1, 68, -1, -1, 71, 1, 73, 3,
1161 4, -1, -1, 7, 8, -1, -1, -1, 38, -1,
1162 -1, -1, -1, 43, 44, 45, 46, -1, -1, -1,
1163 -1, 51, -1, -1, -1, -1, -1, 57, 58, -1,
1164 60, -1, 62, -1, 38, 65, 66, -1, 68, 43,
1165 44, 45, 46, 73, -1, -1, -1, 51, -1, -1,
1166 -1, -1, -1, 57, 58, -1, 60, -1, 62, -1,
1167 -1, 65, 66, 67, 68, 1, -1, 3, 4, -1,
1168 -1, 7, 8, -1, -1, -1, -1, -1, -1, -1,
1169 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1170 -1, 1, -1, 3, 4, -1, -1, 7, 8, -1,
1171 -1, -1, 38, -1, -1, -1, -1, 43, 44, 45,
1172 46, -1, -1, -1, -1, 51, -1, -1, -1, -1,
1173 -1, 57, 58, -1, 60, -1, 62, -1, 38, 65,
1174 66, -1, 68, 43, 44, 45, 46, -1, 3, 4,
1175 -1, 51, 7, 8, -1, -1, -1, 57, 58, -1,
1176 60, -1, 62, -1, -1, 65, 66, 22, 68, -1,
1177 -1, -1, -1, -1, -1, -1, 31, 32, -1, -1,
1178 3, 4, -1, 38, 7, 8, -1, -1, 43, 44,
1179 45, 46, -1, -1, -1, -1, 51, -1, -1, 22,
1180 -1, -1, 57, 58, -1, 60, -1, 62, 31, 32,
1181 65, 66, -1, 68, -1, 38, -1, -1, -1, -1,
1182 43, 44, 45, 46, -1, 3, 4, -1, 51, 7,
1183 8, -1, -1, 11, 57, 58, -1, 60, -1, 62,
1184 -1, -1, 65, 66, -1, 68, -1, -1, -1, -1,
1185 -1, 3, 4, -1, -1, 7, 8, -1, -1, -1,
1186 38, -1, -1, -1, -1, 43, 44, 45, 46, -1,
1187 -1, -1, -1, 51, -1, -1, -1, -1, -1, 57,
1188 58, -1, 60, -1, 62, -1, 38, 65, 66, -1,
1189 68, 43, 44, 45, 46, -1, 3, 4, -1, 51,
1190 7, 8, -1, -1, -1, 57, 58, -1, 60, -1,
1191 62, -1, -1, 65, 66, -1, 68, -1, -1, -1,
1192 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1193 -1, -1, -1, -1, -1, 9, 43, 44, 45, 46,
1194 14, 9, -1, -1, 51, -1, 14, -1, -1, -1,
1195 57, 58, -1, 60, -1, 62, -1, -1, 65, 66,
1196 9, 68, -1, -1, -1, 14, 40, 41, 42, -1,
1197 -1, -1, 40, 41, 42, -1, -1, -1, 52, -1,
1198 9, 55, 56, -1, 52, 14, 54, 55, 56, -1,
1199 -1, 40, 41, 42, -1, -1, -1, -1, -1, 73,
1200 -1, -1, -1, 52, 53, -1, 55, 56, -1, -1,
1201 -1, 40, 41, 42, -1, -1, -1, -1, -1, -1,
1202 -1, -1, -1, 52, -1, -1, 55, 56
1205 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
1206 symbol of state STATE-NUM. */
1207 static const yytype_uint8 yystos[] =
1209 0, 75, 0, 1, 3, 4, 7, 8, 17, 18,
1210 35, 36, 37, 38, 43, 44, 45, 46, 47, 50,
1211 51, 57, 58, 60, 62, 65, 66, 68, 76, 78,
1212 82, 84, 86, 104, 112, 116, 117, 118, 119, 120,
1213 121, 129, 130, 66, 69, 126, 127, 128, 83, 122,
1214 130, 130, 130, 66, 66, 68, 117, 130, 117, 117,
1215 66, 119, 130, 1, 111, 112, 48, 121, 71, 73,
1216 79, 88, 104, 132, 136, 79, 85, 50, 9, 14,
1217 40, 41, 42, 52, 54, 55, 56, 114, 115, 11,
1218 117, 57, 58, 59, 60, 61, 64, 57, 58, 59,
1219 60, 61, 64, 12, 13, 43, 44, 51, 113, 110,
1220 111, 112, 111, 16, 126, 3, 4, 45, 46, 68,
1221 80, 81, 55, 106, 110, 110, 112, 43, 44, 131,
1222 1, 54, 67, 134, 138, 134, 1, 6, 77, 104,
1223 105, 87, 105, 5, 112, 129, 112, 112, 112, 105,
1224 112, 38, 117, 117, 117, 117, 117, 117, 117, 117,
1225 117, 117, 117, 117, 13, 112, 134, 70, 49, 66,
1226 117, 134, 134, 112, 105, 40, 1, 112, 1, 88,
1227 1, 19, 21, 22, 23, 26, 27, 28, 29, 30,
1228 31, 32, 33, 34, 39, 72, 89, 90, 92, 99,
1229 103, 112, 132, 133, 136, 53, 112, 122, 1, 4,
1230 107, 108, 129, 66, 91, 4, 66, 66, 66, 105,
1231 66, 88, 88, 88, 109, 112, 88, 105, 88, 93,
1232 87, 135, 136, 105, 112, 134, 1, 138, 112, 109,
1233 94, 4, 112, 112, 89, 4, 92, 95, 88, 66,
1234 100, 110, 133, 105, 105, 1, 4, 134, 88, 123,
1235 124, 125, 126, 67, 134, 134, 26, 40, 136, 111,
1236 10, 101, 105, 16, 125, 105, 105, 66, 129, 105,
1237 134, 102, 89, 132, 89, 112, 134, 112, 136, 116,
1238 20, 96, 134, 105, 136, 105, 105, 1, 24, 25,
1239 97, 105, 105, 89, 105, 95, 89, 7, 8, 57,
1240 58, 84, 98, 53, 137, 133, 95, 134, 7, 7,
1241 137, 105, 134, 105, 105, 87, 105, 89, 87, 89
1244 #define yyerrok (yyerrstatus = 0)
1245 #define yyclearin (yychar = YYEMPTY)
1246 #define YYEMPTY (-2)
1249 #define YYACCEPT goto yyacceptlab
1250 #define YYABORT goto yyabortlab
1251 #define YYERROR goto yyerrorlab
1254 /* Like YYERROR except do call yyerror. This remains here temporarily
1255 to ease the transition to the new meaning of YYERROR, for GCC.
1256 Once GCC version 2 has supplanted version 1, this can go. However,
1257 YYFAIL appears to be in use. Nevertheless, it is formally deprecated
1258 in Bison 2.4.2's NEWS entry, where a plan to phase it out is
1261 #define YYFAIL goto yyerrlab
1263 /* This is here to suppress warnings from the GCC cpp's
1264 -Wunused-macros. Normally we don't worry about that warning, but
1265 some users do, and we want to make it easy for users to remove
1266 YYFAIL uses, which will produce warnings from Bison 2.5. */
1269 #define YYRECOVERING() (!!yyerrstatus)
1271 #define YYBACKUP(Token, Value) \
1273 if (yychar == YYEMPTY && yylen == 1) \
1282 yyerror (YY_("syntax error: cannot back up")); \
1289 #define YYERRCODE 256
1292 /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
1293 If N is 0, then set CURRENT to the empty location which ends
1294 the previous symbol: RHS[0] (always defined). */
1296 #define YYRHSLOC(Rhs, K) ((Rhs)[K])
1297 #ifndef YYLLOC_DEFAULT
1298 # define YYLLOC_DEFAULT(Current, Rhs, N) \
1302 (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
1303 (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
1304 (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
1305 (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
1309 (Current).first_line = (Current).last_line = \
1310 YYRHSLOC (Rhs, 0).last_line; \
1311 (Current).first_column = (Current).last_column = \
1312 YYRHSLOC (Rhs, 0).last_column; \
1318 /* This macro is provided for backward compatibility. */
1320 #ifndef YY_LOCATION_PRINT
1321 # define YY_LOCATION_PRINT(File, Loc) ((void) 0)
1325 /* YYLEX -- calling `yylex' with the right arguments. */
1328 # define YYLEX yylex (YYLEX_PARAM)
1330 # define YYLEX yylex ()
1333 /* Enable debugging if requested. */
1337 # include <stdio.h> /* INFRINGES ON USER NAME SPACE */
1338 # define YYFPRINTF fprintf
1341 # define YYDPRINTF(Args) \
1347 # define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
1351 YYFPRINTF (stderr, "%s ", Title); \
1352 yy_symbol_print (stderr, \
1354 YYFPRINTF (stderr, "\n"); \
1359 /*--------------------------------.
1360 | Print this symbol on YYOUTPUT. |
1361 `--------------------------------*/
1364 #if (defined __STDC__ || defined __C99__FUNC__ || defined __cplusplus || defined _MSC_VER)
1366 yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
1369 yy_symbol_value_print (yyoutput, yytype, yyvaluep)
1372 YYSTYPE const * const yyvaluep;
1378 if (yytype < YYNTOKENS)
1379 YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
1391 /*--------------------------------.
1392 | Print this symbol on YYOUTPUT. |
1393 `--------------------------------*/
1395 #if (defined __STDC__ || defined __C99__FUNC__ || defined __cplusplus || defined _MSC_VER)
1397 yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
1400 yy_symbol_print (yyoutput, yytype, yyvaluep)
1403 YYSTYPE const * const yyvaluep;
1406 if (yytype < YYNTOKENS)
1407 YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
1409 YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
1411 yy_symbol_value_print (yyoutput, yytype, yyvaluep);
1412 YYFPRINTF (yyoutput, ")");
1415 /*------------------------------------------------------------------.
1416 | yy_stack_print -- Print the state stack from its BOTTOM up to its |
1418 `------------------------------------------------------------------*/
1420 #if (defined __STDC__ || defined __C99__FUNC__ || defined __cplusplus || defined _MSC_VER)
1422 yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
1425 yy_stack_print (yybottom, yytop)
1426 yytype_int16 *yybottom;
1427 yytype_int16 *yytop;
1430 YYFPRINTF (stderr, "Stack now");
1431 for (; yybottom <= yytop; yybottom++)
1433 int yybot = *yybottom;
1434 YYFPRINTF (stderr, " %d", yybot);
1436 YYFPRINTF (stderr, "\n");
1439 # define YY_STACK_PRINT(Bottom, Top) \
1442 yy_stack_print ((Bottom), (Top)); \
1446 /*------------------------------------------------.
1447 | Report that the YYRULE is going to be reduced. |
1448 `------------------------------------------------*/
1450 #if (defined __STDC__ || defined __C99__FUNC__ || defined __cplusplus || defined _MSC_VER)
1452 yy_reduce_print (YYSTYPE *yyvsp, int yyrule)
1455 yy_reduce_print (yyvsp, yyrule)
1460 int yynrhs = yyr2[yyrule];
1462 unsigned long int yylno = yyrline[yyrule];
1463 YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
1465 /* The symbols being reduced. */
1466 for (yyi = 0; yyi < yynrhs; yyi++)
1468 YYFPRINTF (stderr, " $%d = ", yyi + 1);
1469 yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
1470 &(yyvsp[(yyi + 1) - (yynrhs)])
1472 YYFPRINTF (stderr, "\n");
1476 # define YY_REDUCE_PRINT(Rule) \
1479 yy_reduce_print (yyvsp, Rule); \
1482 /* Nonzero means print parse trace. It is left uninitialized so that
1483 multiple parsers can coexist. */
1485 #else /* !YYDEBUG */
1486 # define YYDPRINTF(Args)
1487 # define YY_SYMBOL_PRINT(Title, Type, Value, Location)
1488 # define YY_STACK_PRINT(Bottom, Top)
1489 # define YY_REDUCE_PRINT(Rule)
1490 #endif /* !YYDEBUG */
1493 /* YYINITDEPTH -- initial size of the parser's stacks. */
1495 # define YYINITDEPTH 200
1498 /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
1499 if the built-in stack extension method is used).
1501 Do not make this value too large; the results are undefined if
1502 YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
1503 evaluated with infinite-precision integer arithmetic. */
1506 # define YYMAXDEPTH 10000
1513 # if defined __GLIBC__ && defined _STRING_H
1514 # define yystrlen strlen
1516 /* Return the length of YYSTR. */
1517 #if (defined __STDC__ || defined __C99__FUNC__ || defined __cplusplus || defined _MSC_VER)
1519 yystrlen (const char *yystr)
1527 for (yylen = 0; yystr[yylen]; yylen++)
1535 # if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
1536 # define yystpcpy stpcpy
1538 /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
1540 #if (defined __STDC__ || defined __C99__FUNC__ || defined __cplusplus || defined _MSC_VER)
1542 yystpcpy (char *yydest, const char *yysrc)
1545 yystpcpy (yydest, yysrc)
1551 const char *yys = yysrc;
1553 while ((*yyd++ = *yys++) != '\0')
1562 /* Copy to YYRES the contents of YYSTR after stripping away unnecessary
1563 quotes and backslashes, so that it's suitable for yyerror. The
1564 heuristic is that double-quoting is unnecessary unless the string
1565 contains an apostrophe, a comma, or backslash (other than
1566 backslash-backslash). YYSTR is taken from yytname. If YYRES is
1567 null, do not copy; instead, return the length of what the result
1570 yytnamerr (char *yyres, const char *yystr)
1575 char const *yyp = yystr;
1582 goto do_not_strip_quotes;
1586 goto do_not_strip_quotes;
1599 do_not_strip_quotes: ;
1603 return yystrlen (yystr);
1605 return yystpcpy (yyres, yystr) - yyres;
1609 /* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
1610 about the unexpected token YYTOKEN for the state stack whose top is
1613 Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is
1614 not large enough to hold the message. In that case, also set
1615 *YYMSG_ALLOC to the required number of bytes. Return 2 if the
1616 required number of bytes is too large to store. */
1618 yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
1619 yytype_int16 *yyssp, int yytoken)
1621 YYSIZE_T yysize0 = yytnamerr (0, yytname[yytoken]);
1622 YYSIZE_T yysize = yysize0;
1624 enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
1625 /* Internationalized format string. */
1626 const char *yyformat = 0;
1627 /* Arguments of yyformat. */
1628 char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
1629 /* Number of reported tokens (one for the "unexpected", one per
1633 /* There are many possibilities here to consider:
1634 - Assume YYFAIL is not used. It's too flawed to consider. See
1635 <http://lists.gnu.org/archive/html/bison-patches/2009-12/msg00024.html>
1636 for details. YYERROR is fine as it does not invoke this
1638 - If this state is a consistent state with a default action, then
1639 the only way this function was invoked is if the default action
1640 is an error action. In that case, don't check for expected
1641 tokens because there are none.
1642 - The only way there can be no lookahead present (in yychar) is if
1643 this state is a consistent state with a default action. Thus,
1644 detecting the absence of a lookahead is sufficient to determine
1645 that there is no unexpected or expected token to report. In that
1646 case, just report a simple "syntax error".
1647 - Don't assume there isn't a lookahead just because this state is a
1648 consistent state with a default action. There might have been a
1649 previous inconsistent state, consistent state with a non-default
1650 action, or user semantic action that manipulated yychar.
1651 - Of course, the expected token list depends on states to have
1652 correct lookahead information, and it depends on the parser not
1653 to perform extra reductions after fetching a lookahead from the
1654 scanner and before detecting a syntax error. Thus, state merging
1655 (from LALR or IELR) and default reductions corrupt the expected
1656 token list. However, the list is correct for canonical LR with
1657 one exception: it will still contain any token that will not be
1658 accepted due to an error action in a later state.
1660 if (yytoken != YYEMPTY)
1662 int yyn = yypact[*yyssp];
1663 yyarg[yycount++] = yytname[yytoken];
1664 if (!yypact_value_is_default (yyn))
1666 /* Start YYX at -YYN if negative to avoid negative indexes in
1667 YYCHECK. In other words, skip the first -YYN actions for
1668 this state because they are default actions. */
1669 int yyxbegin = yyn < 0 ? -yyn : 0;
1670 /* Stay within bounds of both yycheck and yytname. */
1671 int yychecklim = YYLAST - yyn + 1;
1672 int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
1675 for (yyx = yyxbegin; yyx < yyxend; ++yyx)
1676 if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
1677 && !yytable_value_is_error (yytable[yyx + yyn]))
1679 if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
1685 yyarg[yycount++] = yytname[yyx];
1686 yysize1 = yysize + yytnamerr (0, yytname[yyx]);
1687 if (! (yysize <= yysize1
1688 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
1697 # define YYCASE_(N, S) \
1701 YYCASE_(0, YY_("syntax error"));
1702 YYCASE_(1, YY_("syntax error, unexpected %s"));
1703 YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
1704 YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
1705 YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
1706 YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
1710 yysize1 = yysize + yystrlen (yyformat);
1711 if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
1715 if (*yymsg_alloc < yysize)
1717 *yymsg_alloc = 2 * yysize;
1718 if (! (yysize <= *yymsg_alloc
1719 && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
1720 *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
1724 /* Avoid sprintf, as that infringes on the user's name space.
1725 Don't have undefined behavior even if the translation
1726 produced a string with the wrong number of "%s"s. */
1730 while ((*yyp = *yyformat) != '\0')
1731 if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
1733 yyp += yytnamerr (yyp, yyarg[yyi++]);
1744 #endif /* YYERROR_VERBOSE */
1746 /*-----------------------------------------------.
1747 | Release the memory associated to this symbol. |
1748 `-----------------------------------------------*/
1751 #if (defined __STDC__ || defined __C99__FUNC__ || defined __cplusplus || defined _MSC_VER)
1753 yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
1756 yydestruct (yymsg, yytype, yyvaluep)
1766 YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
1777 /* Prevent warnings from -Wmissing-prototypes. */
1778 #ifdef YYPARSE_PARAM
1779 #if defined __STDC__ || defined __cplusplus
1780 int yyparse (void *YYPARSE_PARAM);
1784 #else /* ! YYPARSE_PARAM */
1785 #if defined __STDC__ || defined __cplusplus
1790 #endif /* ! YYPARSE_PARAM */
1793 /* The lookahead symbol. */
1796 /* The semantic value of the lookahead symbol. */
1799 /* Number of syntax errors so far. */
1807 #ifdef YYPARSE_PARAM
1808 #if (defined __STDC__ || defined __C99__FUNC__ || defined __cplusplus || defined _MSC_VER)
1810 yyparse (void *YYPARSE_PARAM)
1813 yyparse (YYPARSE_PARAM)
1814 void *YYPARSE_PARAM;
1816 #else /* ! YYPARSE_PARAM */
1817 #if (defined __STDC__ || defined __C99__FUNC__ || defined __cplusplus || defined _MSC_VER)
1828 /* Number of tokens to shift before error messages enabled. */
1831 /* The stacks and their tools:
1832 `yyss': related to states.
1833 `yyvs': related to semantic values.
1835 Refer to the stacks thru separate pointers, to allow yyoverflow
1836 to reallocate them elsewhere. */
1838 /* The state stack. */
1839 yytype_int16 yyssa[YYINITDEPTH];
1841 yytype_int16 *yyssp;
1843 /* The semantic value stack. */
1844 YYSTYPE yyvsa[YYINITDEPTH];
1848 YYSIZE_T yystacksize;
1852 /* Lookahead token as an internal (translated) token number. */
1854 /* The variables used to return semantic value and location from the
1859 /* Buffer for error messages, and its allocated size. */
1861 char *yymsg = yymsgbuf;
1862 YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
1865 #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N))
1867 /* The number of symbols on the RHS of the reduced rule.
1868 Keep to zero when no symbol should be popped. */
1874 yystacksize = YYINITDEPTH;
1876 YYDPRINTF ((stderr, "Starting parse\n"));
1881 yychar = YYEMPTY; /* Cause a token to be read. */
1883 /* Initialize stack pointers.
1884 Waste one element of value and location stack
1885 so that they stay on the same level as the state stack.
1886 The wasted elements are never initialized. */
1892 /*------------------------------------------------------------.
1893 | yynewstate -- Push a new state, which is found in yystate. |
1894 `------------------------------------------------------------*/
1896 /* In all cases, when you get here, the value and location stacks
1897 have just been pushed. So pushing a state here evens the stacks. */
1903 if (yyss + yystacksize - 1 <= yyssp)
1905 /* Get the current used size of the three stacks, in elements. */
1906 YYSIZE_T yysize = yyssp - yyss + 1;
1910 /* Give user a chance to reallocate the stack. Use copies of
1911 these so that the &'s don't force the real ones into
1913 YYSTYPE *yyvs1 = yyvs;
1914 yytype_int16 *yyss1 = yyss;
1916 /* Each stack pointer address is followed by the size of the
1917 data in use in that stack, in bytes. This used to be a
1918 conditional around just the two extra args, but that might
1919 be undefined if yyoverflow is a macro. */
1920 yyoverflow (YY_("memory exhausted"),
1921 &yyss1, yysize * sizeof (*yyssp),
1922 &yyvs1, yysize * sizeof (*yyvsp),
1928 #else /* no yyoverflow */
1929 # ifndef YYSTACK_RELOCATE
1930 goto yyexhaustedlab;
1932 /* Extend the stack our own way. */
1933 if (YYMAXDEPTH <= yystacksize)
1934 goto yyexhaustedlab;
1936 if (YYMAXDEPTH < yystacksize)
1937 yystacksize = YYMAXDEPTH;
1940 yytype_int16 *yyss1 = yyss;
1941 union yyalloc *yyptr =
1942 (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
1944 goto yyexhaustedlab;
1945 YYSTACK_RELOCATE (yyss_alloc, yyss);
1946 YYSTACK_RELOCATE (yyvs_alloc, yyvs);
1947 # undef YYSTACK_RELOCATE
1949 YYSTACK_FREE (yyss1);
1952 #endif /* no yyoverflow */
1954 yyssp = yyss + yysize - 1;
1955 yyvsp = yyvs + yysize - 1;
1957 YYDPRINTF ((stderr, "Stack size increased to %lu\n",
1958 (unsigned long int) yystacksize));
1960 if (yyss + yystacksize - 1 <= yyssp)
1964 YYDPRINTF ((stderr, "Entering state %d\n", yystate));
1966 if (yystate == YYFINAL)
1976 /* Do appropriate processing given the current state. Read a
1977 lookahead token if we need one and don't already have one. */
1979 /* First try to decide what to do without reference to lookahead token. */
1980 yyn = yypact[yystate];
1981 if (yypact_value_is_default (yyn))
1984 /* Not known => get a lookahead token if don't already have one. */
1986 /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
1987 if (yychar == YYEMPTY)
1989 YYDPRINTF ((stderr, "Reading a token: "));
1993 if (yychar <= YYEOF)
1995 yychar = yytoken = YYEOF;
1996 YYDPRINTF ((stderr, "Now at end of input.\n"));
2000 yytoken = YYTRANSLATE (yychar);
2001 YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
2004 /* If the proper action on seeing token YYTOKEN is to reduce or to
2005 detect an error, take that action. */
2007 if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
2012 if (yytable_value_is_error (yyn))
2018 /* Count tokens shifted since error; after three, turn off error
2023 /* Shift the lookahead token. */
2024 YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
2026 /* Discard the shifted token. */
2035 /*-----------------------------------------------------------.
2036 | yydefault -- do the default action for the current state. |
2037 `-----------------------------------------------------------*/
2039 yyn = yydefact[yystate];
2045 /*-----------------------------.
2046 | yyreduce -- Do a reduction. |
2047 `-----------------------------*/
2049 /* yyn is the number of a rule to reduce with. */
2052 /* If YYLEN is nonzero, implement the default value of the action:
2055 Otherwise, the following line sets YYVAL to garbage.
2056 This behavior is undocumented and Bison
2057 users should not rely upon it. Assigning to YYVAL
2058 unconditionally makes the parser a bit smaller, and it avoids a
2059 GCC warning that YYVAL may be used uninitialized. */
2060 yyval = yyvsp[1-yylen];
2063 YY_REDUCE_PRINT (yyn);
2068 /* Line 1806 of yacc.c */
2069 #line 221 "awkgram.y"
2078 /* Line 1806 of yacc.c */
2079 #line 227 "awkgram.y"
2087 /* Line 1806 of yacc.c */
2088 #line 231 "awkgram.y"
2092 * If errors, give up, don't produce an infinite
2093 * stream of syntax error messages.
2101 /* Line 1806 of yacc.c */
2102 #line 243 "awkgram.y"
2104 (void) append_rule((yyvsp[(1) - (2)]), (yyvsp[(2) - (2)]));
2110 /* Line 1806 of yacc.c */
2111 #line 247 "awkgram.y"
2114 msg(_("%s blocks must have an action part"), ruletab[rule]);
2116 } else if ((yyvsp[(1) - (2)]) == NULL) {
2117 msg(_("each rule must have a pattern or an action part"));
2119 } else /* pattern rule with non-empty pattern */
2120 (void) append_rule((yyvsp[(1) - (2)]), NULL);
2126 /* Line 1806 of yacc.c */
2127 #line 258 "awkgram.y"
2130 if ((yyvsp[(1) - (2)]) && func_install((yyvsp[(1) - (2)]), (yyvsp[(2) - (2)])) < 0)
2139 /* Line 1806 of yacc.c */
2140 #line 266 "awkgram.y"
2142 want_source = FALSE;
2149 /* Line 1806 of yacc.c */
2150 #line 274 "awkgram.y"
2152 if (include_source((yyvsp[(1) - (1)])) < 0)
2154 efree((yyvsp[(1) - (1)])->lextok);
2155 bcfree((yyvsp[(1) - (1)]));
2162 /* Line 1806 of yacc.c */
2163 #line 282 "awkgram.y"
2169 /* Line 1806 of yacc.c */
2170 #line 284 "awkgram.y"
2176 /* Line 1806 of yacc.c */
2177 #line 289 "awkgram.y"
2178 { (yyval) = NULL; rule = Rule; }
2183 /* Line 1806 of yacc.c */
2184 #line 291 "awkgram.y"
2185 { (yyval) = (yyvsp[(1) - (1)]); rule = Rule; }
2190 /* Line 1806 of yacc.c */
2191 #line 293 "awkgram.y"
2195 add_lint((yyvsp[(1) - (4)]), LINT_assign_in_cond);
2196 add_lint((yyvsp[(4) - (4)]), LINT_assign_in_cond);
2198 tp = instruction(Op_no_op);
2199 list_prepend((yyvsp[(1) - (4)]), bcalloc(Op_line_range, !!do_profiling + 1, 0));
2200 (yyvsp[(1) - (4)])->nexti->triggered = FALSE;
2201 (yyvsp[(1) - (4)])->nexti->target_jmp = (yyvsp[(4) - (4)])->nexti;
2203 list_append((yyvsp[(1) - (4)]), instruction(Op_cond_pair));
2204 (yyvsp[(1) - (4)])->lasti->line_range = (yyvsp[(1) - (4)])->nexti;
2205 (yyvsp[(1) - (4)])->lasti->target_jmp = tp;
2207 list_append((yyvsp[(4) - (4)]), instruction(Op_cond_pair));
2208 (yyvsp[(4) - (4)])->lasti->line_range = (yyvsp[(1) - (4)])->nexti;
2209 (yyvsp[(4) - (4)])->lasti->target_jmp = tp;
2211 ((yyvsp[(1) - (4)])->nexti + 1)->condpair_left = (yyvsp[(1) - (4)])->lasti;
2212 ((yyvsp[(1) - (4)])->nexti + 1)->condpair_right = (yyvsp[(4) - (4)])->lasti;
2214 (yyval) = list_append(list_merge((yyvsp[(1) - (4)]), (yyvsp[(4) - (4)])), tp);
2221 /* Line 1806 of yacc.c */
2222 #line 319 "awkgram.y"
2224 static int begin_seen = 0;
2225 if (do_lint_old && ++begin_seen == 2)
2226 warning_ln((yyvsp[(1) - (1)])->source_line,
2227 _("old awk does not support multiple `BEGIN' or `END' rules"));
2229 (yyvsp[(1) - (1)])->in_rule = rule = BEGIN;
2230 (yyvsp[(1) - (1)])->source_file = source;
2231 (yyval) = (yyvsp[(1) - (1)]);
2237 /* Line 1806 of yacc.c */
2238 #line 330 "awkgram.y"
2240 static int end_seen = 0;
2241 if (do_lint_old && ++end_seen == 2)
2242 warning_ln((yyvsp[(1) - (1)])->source_line,
2243 _("old awk does not support multiple `BEGIN' or `END' rules"));
2245 (yyvsp[(1) - (1)])->in_rule = rule = END;
2246 (yyvsp[(1) - (1)])->source_file = source;
2247 (yyval) = (yyvsp[(1) - (1)]);
2253 /* Line 1806 of yacc.c */
2254 #line 341 "awkgram.y"
2256 (yyvsp[(1) - (1)])->in_rule = rule = BEGINFILE;
2257 (yyvsp[(1) - (1)])->source_file = source;
2258 (yyval) = (yyvsp[(1) - (1)]);
2264 /* Line 1806 of yacc.c */
2265 #line 347 "awkgram.y"
2267 (yyvsp[(1) - (1)])->in_rule = rule = ENDFILE;
2268 (yyvsp[(1) - (1)])->source_file = source;
2269 (yyval) = (yyvsp[(1) - (1)]);
2275 /* Line 1806 of yacc.c */
2276 #line 356 "awkgram.y"
2278 if ((yyvsp[(2) - (5)]) == NULL)
2279 (yyval) = list_create(instruction(Op_no_op));
2281 (yyval) = (yyvsp[(2) - (5)]);
2287 /* Line 1806 of yacc.c */
2288 #line 366 "awkgram.y"
2289 { (yyval) = (yyvsp[(1) - (1)]); }
2294 /* Line 1806 of yacc.c */
2295 #line 368 "awkgram.y"
2296 { (yyval) = (yyvsp[(1) - (1)]); }
2301 /* Line 1806 of yacc.c */
2302 #line 370 "awkgram.y"
2304 yyerror(_("`%s' is a built-in function, it cannot be redefined"),
2306 (yyvsp[(1) - (1)])->opcode = Op_symbol; /* Op_symbol instead of Op_token so that
2307 * free_bc_internal does not try to free it
2309 (yyvsp[(1) - (1)])->lextok = builtin_func;
2310 (yyval) = (yyvsp[(1) - (1)]);
2317 /* Line 1806 of yacc.c */
2318 #line 381 "awkgram.y"
2319 { (yyval) = (yyvsp[(2) - (2)]); }
2324 /* Line 1806 of yacc.c */
2325 #line 391 "awkgram.y"
2334 /* Line 1806 of yacc.c */
2335 #line 396 "awkgram.y"
2339 (yyvsp[(1) - (7)])->source_file = source;
2340 t = make_param((yyvsp[(3) - (7)])->lextok);
2341 (yyvsp[(3) - (7)])->lextok = NULL;
2342 bcfree((yyvsp[(3) - (7)]));
2344 t->rnode = func_params;
2346 (yyval) = (yyvsp[(1) - (7)]);
2348 /* check for duplicate parameter names */
2349 if (dup_parms((yyvsp[(1) - (7)]), t))
2356 /* Line 1806 of yacc.c */
2357 #line 420 "awkgram.y"
2363 /* Line 1806 of yacc.c */
2364 #line 422 "awkgram.y"
2370 re = (yyvsp[(3) - (3)])->lextok;
2374 lintwarn_ln((yyvsp[(3) - (3)])->source_line,
2375 _("regexp constant `//' looks like a C++ comment, but is not"));
2376 else if ((re)[0] == '*' && (re)[len-1] == '*')
2377 /* possible C comment */
2378 lintwarn_ln((yyvsp[(3) - (3)])->source_line,
2379 _("regexp constant `/%s/' looks like a C comment, but is not"), re);
2382 exp = make_str_node(re, len, ALREADY_MALLOCED);
2383 n = make_regnode(Node_regex, exp);
2388 (yyval) = (yyvsp[(3) - (3)]);
2389 (yyval)->opcode = Op_match_rec;
2390 (yyval)->memory = n;
2396 /* Line 1806 of yacc.c */
2397 #line 453 "awkgram.y"
2398 { bcfree((yyvsp[(1) - (1)])); }
2403 /* Line 1806 of yacc.c */
2404 #line 459 "awkgram.y"
2410 /* Line 1806 of yacc.c */
2411 #line 461 "awkgram.y"
2413 if ((yyvsp[(2) - (2)]) == NULL)
2414 (yyval) = (yyvsp[(1) - (2)]);
2416 add_lint((yyvsp[(2) - (2)]), LINT_no_effect);
2417 if ((yyvsp[(1) - (2)]) == NULL)
2418 (yyval) = (yyvsp[(2) - (2)]);
2420 (yyval) = list_merge((yyvsp[(1) - (2)]), (yyvsp[(2) - (2)]));
2428 /* Line 1806 of yacc.c */
2429 #line 474 "awkgram.y"
2435 /* Line 1806 of yacc.c */
2436 #line 484 "awkgram.y"
2442 /* Line 1806 of yacc.c */
2443 #line 486 "awkgram.y"
2444 { (yyval) = (yyvsp[(2) - (3)]); }
2449 /* Line 1806 of yacc.c */
2450 #line 488 "awkgram.y"
2453 (yyval) = list_prepend((yyvsp[(1) - (1)]), instruction(Op_exec_count));
2455 (yyval) = (yyvsp[(1) - (1)]);
2461 /* Line 1806 of yacc.c */
2462 #line 495 "awkgram.y"
2464 INSTRUCTION *dflt, *curr = NULL, *cexp, *cstmt;
2465 INSTRUCTION *ip, *nextc, *tbreak;
2466 const char **case_values = NULL;
2471 tbreak = instruction(Op_no_op);
2472 cstmt = list_create(tbreak);
2473 cexp = list_create(instruction(Op_pop));
2474 dflt = instruction(Op_jmp);
2475 dflt->target_jmp = tbreak; /* if no case match and no explicit default */
2477 if ((yyvsp[(7) - (9)]) != NULL) {
2478 curr = (yyvsp[(7) - (9)])->nexti;
2479 bcfree((yyvsp[(7) - (9)])); /* Op_list */
2483 for(; curr != NULL; curr = nextc) {
2484 INSTRUCTION *caseexp = curr->case_exp;
2485 INSTRUCTION *casestmt = curr->case_stmt;
2487 nextc = curr->nexti;
2488 if (curr->opcode == Op_K_case) {
2489 if (caseexp->opcode == Op_push_i) {
2490 /* a constant scalar */
2492 caseval = force_string(caseexp->memory)->stptr;
2493 for (i = 0; i < case_count; i++) {
2494 if (strcmp(caseval, case_values[i]) == 0)
2495 error_ln(curr->source_line,
2496 _("duplicate case values in switch body: %s"), caseval);
2499 if (case_values == NULL)
2500 emalloc(case_values, const char **, sizeof(char *) * maxcount, "statement");
2501 else if (case_count >= maxcount) {
2503 erealloc(case_values, const char **, sizeof(char*) * maxcount, "statement");
2505 case_values[case_count++] = caseval;
2507 /* match a constant regex against switch expression. */
2508 (curr + 1)->match_exp = TRUE;
2510 curr->stmt_start = casestmt->nexti;
2511 curr->stmt_end = casestmt->lasti;
2512 (void) list_prepend(cexp, curr);
2513 (void) list_prepend(cexp, caseexp);
2515 if (dflt->target_jmp != tbreak)
2516 error_ln(curr->source_line,
2517 _("duplicate `default' detected in switch body"));
2519 dflt->target_jmp = casestmt->nexti;
2522 curr->stmt_start = casestmt->nexti;
2523 curr->stmt_end = casestmt->lasti;
2524 (void) list_prepend(cexp, curr);
2529 cstmt = list_merge(casestmt, cstmt);
2532 if (case_values != NULL)
2535 ip = (yyvsp[(3) - (9)]);
2537 (void) list_prepend(ip, (yyvsp[(1) - (9)]));
2538 (void) list_prepend(ip, instruction(Op_exec_count));
2539 (yyvsp[(1) - (9)])->target_break = tbreak;
2540 ((yyvsp[(1) - (9)]) + 1)->switch_start = cexp->nexti;
2541 ((yyvsp[(1) - (9)]) + 1)->switch_end = cexp->lasti;
2545 (void) list_append(cexp, dflt);
2546 (void) list_merge(ip, cexp);
2547 (yyval) = list_merge(ip, cstmt);
2550 fix_break_continue(ip, tbreak, NULL);
2556 /* Line 1806 of yacc.c */
2557 #line 585 "awkgram.y"
2564 * [Op_jmp_false tb ]
2572 INSTRUCTION *ip, *tbreak, *tcont;
2574 tbreak = instruction(Op_no_op);
2575 add_lint((yyvsp[(3) - (6)]), LINT_assign_in_cond);
2576 tcont = (yyvsp[(3) - (6)])->nexti;
2577 ip = list_append((yyvsp[(3) - (6)]), instruction(Op_jmp_false));
2578 ip->lasti->target_jmp = tbreak;
2581 (void) list_append(ip, instruction(Op_exec_count));
2582 (yyvsp[(1) - (6)])->target_break = tbreak;
2583 (yyvsp[(1) - (6)])->target_continue = tcont;
2584 ((yyvsp[(1) - (6)]) + 1)->while_body = ip->lasti;
2585 (void) list_prepend(ip, (yyvsp[(1) - (6)]));
2589 if ((yyvsp[(6) - (6)]) != NULL)
2590 (void) list_merge(ip, (yyvsp[(6) - (6)]));
2591 (void) list_append(ip, instruction(Op_jmp));
2592 ip->lasti->target_jmp = tcont;
2593 (yyval) = list_append(ip, tbreak);
2597 fix_break_continue(ip, tbreak, tcont);
2603 /* Line 1806 of yacc.c */
2604 #line 627 "awkgram.y"
2614 * [Op_jmp_true | z ]
2618 INSTRUCTION *ip, *tbreak, *tcont;
2620 tbreak = instruction(Op_no_op);
2621 tcont = (yyvsp[(6) - (8)])->nexti;
2622 add_lint((yyvsp[(6) - (8)]), LINT_assign_in_cond);
2623 if ((yyvsp[(3) - (8)]) != NULL)
2624 ip = list_merge((yyvsp[(3) - (8)]), (yyvsp[(6) - (8)]));
2626 ip = list_prepend((yyvsp[(6) - (8)]), instruction(Op_no_op));
2628 (void) list_prepend(ip, instruction(Op_exec_count));
2629 (void) list_append(ip, instruction(Op_jmp_true));
2630 ip->lasti->target_jmp = ip->nexti;
2631 (yyval) = list_append(ip, tbreak);
2635 fix_break_continue(ip, tbreak, tcont);
2638 (yyvsp[(1) - (8)])->target_break = tbreak;
2639 (yyvsp[(1) - (8)])->target_continue = tcont;
2640 ((yyvsp[(1) - (8)]) + 1)->doloop_cond = tcont;
2641 (yyval) = list_prepend(ip, (yyvsp[(1) - (8)]));
2642 bcfree((yyvsp[(4) - (8)]));
2644 $1 and $4 are NULLs */
2650 /* Line 1806 of yacc.c */
2651 #line 669 "awkgram.y"
2654 char *var_name = (yyvsp[(3) - (8)])->lextok;
2656 if ((yyvsp[(8) - (8)]) != NULL
2657 && (yyvsp[(8) - (8)])->lasti->opcode == Op_K_delete
2658 && (yyvsp[(8) - (8)])->lasti->expr_count == 1
2659 && (yyvsp[(8) - (8)])->nexti->opcode == Op_push
2660 && ((yyvsp[(8) - (8)])->nexti->memory->type != Node_var || !((yyvsp[(8) - (8)])->nexti->memory->var_update))
2661 && strcmp((yyvsp[(8) - (8)])->nexti->memory->vname, var_name) == 0
2664 /* Efficiency hack. Recognize the special case of
2669 * and treat it as if it were
2673 * Check that the body is a `delete a[i]' statement,
2674 * and that both the loop var and array names match.
2678 ip = (yyvsp[(8) - (8)])->nexti->nexti;
2679 if ((yyvsp[(5) - (8)])->nexti->opcode == Op_push && (yyvsp[(5) - (8)])->lasti == (yyvsp[(5) - (8)])->nexti)
2680 arr = (yyvsp[(5) - (8)])->nexti->memory;
2682 && ip->opcode == Op_no_op
2683 && ip->nexti->opcode == Op_push_array
2684 && strcmp(ip->nexti->memory->vname, arr->vname) == 0
2685 && ip->nexti->nexti == (yyvsp[(8) - (8)])->lasti
2687 (void) make_assignable((yyvsp[(8) - (8)])->nexti);
2688 (yyvsp[(8) - (8)])->lasti->opcode = Op_K_delete_loop;
2689 (yyvsp[(8) - (8)])->lasti->expr_count = 0;
2690 if ((yyvsp[(1) - (8)]) != NULL)
2691 bcfree((yyvsp[(1) - (8)]));
2693 bcfree((yyvsp[(3) - (8)]));
2694 bcfree((yyvsp[(4) - (8)]));
2695 bcfree((yyvsp[(5) - (8)]));
2696 (yyval) = (yyvsp[(8) - (8)]);
2700 INSTRUCTION *tbreak, *tcont;
2702 /* [ Op_push_array a ]
2703 * [ Op_arrayfor_init | ib ]
2704 * ic:[ Op_arrayfor_incr | ib ]
2705 * [ Op_var_assign if any ]
2710 * ib:[Op_arrayfor_final ]
2713 ip = (yyvsp[(5) - (8)]);
2714 ip->nexti->opcode = Op_push_array;
2716 tbreak = instruction(Op_arrayfor_final);
2717 (yyvsp[(4) - (8)])->opcode = Op_arrayfor_incr;
2718 (yyvsp[(4) - (8)])->array_var = variable(var_name, Node_var);
2719 (yyvsp[(4) - (8)])->target_jmp = tbreak;
2720 tcont = (yyvsp[(4) - (8)]);
2721 (yyvsp[(3) - (8)])->opcode = Op_arrayfor_init;
2722 (yyvsp[(3) - (8)])->target_jmp = tbreak;
2723 (void) list_append(ip, (yyvsp[(3) - (8)]));
2726 (yyvsp[(1) - (8)])->opcode = Op_K_arrayfor;
2727 (yyvsp[(1) - (8)])->target_continue = tcont;
2728 (yyvsp[(1) - (8)])->target_break = tbreak;
2729 (void) list_append(ip, (yyvsp[(1) - (8)]));
2733 /* add update_FOO instruction if necessary */
2734 if ((yyvsp[(4) - (8)])->array_var->type == Node_var && (yyvsp[(4) - (8)])->array_var->var_update) {
2735 (void) list_append(ip, instruction(Op_var_update));
2736 ip->lasti->update_var = (yyvsp[(4) - (8)])->array_var->var_update;
2738 (void) list_append(ip, (yyvsp[(4) - (8)]));
2740 /* add set_FOO instruction if necessary */
2741 if ((yyvsp[(4) - (8)])->array_var->type == Node_var && (yyvsp[(4) - (8)])->array_var->var_assign) {
2742 (void) list_append(ip, instruction(Op_var_assign));
2743 ip->lasti->assign_var = (yyvsp[(4) - (8)])->array_var->var_assign;
2747 (void) list_append(ip, instruction(Op_exec_count));
2748 ((yyvsp[(1) - (8)]) + 1)->forloop_cond = (yyvsp[(4) - (8)]);
2749 ((yyvsp[(1) - (8)]) + 1)->forloop_body = ip->lasti;
2752 if ((yyvsp[(8) - (8)]) != NULL)
2753 (void) list_merge(ip, (yyvsp[(8) - (8)]));
2755 (void) list_append(ip, instruction(Op_jmp));
2756 ip->lasti->target_jmp = (yyvsp[(4) - (8)]);
2757 (yyval) = list_append(ip, tbreak);
2758 fix_break_continue(ip, tbreak, tcont);
2768 /* Line 1806 of yacc.c */
2769 #line 782 "awkgram.y"
2771 (yyval) = mk_for_loop((yyvsp[(1) - (12)]), (yyvsp[(3) - (12)]), (yyvsp[(6) - (12)]), (yyvsp[(9) - (12)]), (yyvsp[(12) - (12)]));
2780 /* Line 1806 of yacc.c */
2781 #line 789 "awkgram.y"
2783 (yyval) = mk_for_loop((yyvsp[(1) - (11)]), (yyvsp[(3) - (11)]), (INSTRUCTION *) NULL, (yyvsp[(8) - (11)]), (yyvsp[(11) - (11)]));
2792 /* Line 1806 of yacc.c */
2793 #line 796 "awkgram.y"
2796 (yyval) = list_prepend((yyvsp[(1) - (1)]), instruction(Op_exec_count));
2798 (yyval) = (yyvsp[(1) - (1)]);
2804 /* Line 1806 of yacc.c */
2805 #line 806 "awkgram.y"
2807 if (! break_allowed)
2808 error_ln((yyvsp[(1) - (2)])->source_line,
2809 _("`break' is not allowed outside a loop or switch"));
2810 (yyvsp[(1) - (2)])->target_jmp = NULL;
2811 (yyval) = list_create((yyvsp[(1) - (2)]));
2818 /* Line 1806 of yacc.c */
2819 #line 815 "awkgram.y"
2821 if (! continue_allowed)
2822 error_ln((yyvsp[(1) - (2)])->source_line,
2823 _("`continue' is not allowed outside a loop"));
2824 (yyvsp[(1) - (2)])->target_jmp = NULL;
2825 (yyval) = list_create((yyvsp[(1) - (2)]));
2832 /* Line 1806 of yacc.c */
2833 #line 824 "awkgram.y"
2835 /* if inside function (rule = 0), resolve context at run-time */
2836 if (rule && rule != Rule)
2837 error_ln((yyvsp[(1) - (2)])->source_line,
2838 _("`next' used in %s action"), ruletab[rule]);
2839 (yyvsp[(1) - (2)])->target_jmp = ip_rec;
2840 (yyval) = list_create((yyvsp[(1) - (2)]));
2846 /* Line 1806 of yacc.c */
2847 #line 833 "awkgram.y"
2850 error_ln((yyvsp[(1) - (2)])->source_line,
2851 _("`nextfile' is a gawk extension"));
2853 /* if inside function (rule = 0), resolve context at run-time */
2854 if (rule == BEGIN || rule == END || rule == ENDFILE)
2855 error_ln((yyvsp[(1) - (2)])->source_line,
2856 _("`nextfile' used in %s action"), ruletab[rule]);
2858 (yyvsp[(1) - (2)])->target_newfile = ip_newfile;
2859 (yyvsp[(1) - (2)])->target_endfile = ip_endfile;
2860 (yyval) = list_create((yyvsp[(1) - (2)]));
2866 /* Line 1806 of yacc.c */
2867 #line 848 "awkgram.y"
2869 /* Initialize the two possible jump targets, the actual target
2870 * is resolved at run-time.
2872 (yyvsp[(1) - (3)])->target_end = ip_end; /* first instruction in end_block */
2873 (yyvsp[(1) - (3)])->target_atexit = ip_atexit; /* cleanup and go home */
2875 if ((yyvsp[(2) - (3)]) == NULL) {
2876 (yyval) = list_create((yyvsp[(1) - (3)]));
2877 (void) list_prepend((yyval), instruction(Op_push_i));
2878 (yyval)->nexti->memory = Nnull_string;
2880 (yyval) = list_append((yyvsp[(2) - (3)]), (yyvsp[(1) - (3)]));
2886 /* Line 1806 of yacc.c */
2887 #line 863 "awkgram.y"
2890 yyerror(_("`return' used outside function context"));
2896 /* Line 1806 of yacc.c */
2897 #line 866 "awkgram.y"
2899 if ((yyvsp[(3) - (4)]) == NULL) {
2900 (yyval) = list_create((yyvsp[(1) - (4)]));
2901 (void) list_prepend((yyval), instruction(Op_push_i));
2902 (yyval)->nexti->memory = Nnull_string;
2904 (yyval) = list_append((yyvsp[(3) - (4)]), (yyvsp[(1) - (4)]));
2910 /* Line 1806 of yacc.c */
2911 #line 886 "awkgram.y"
2912 { in_print = TRUE; in_parens = 0; }
2917 /* Line 1806 of yacc.c */
2918 #line 887 "awkgram.y"
2921 * Optimization: plain `print' has no expression list, so $3 is null.
2922 * If $3 is NULL or is a bytecode list for $0 use Op_K_print_rec,
2923 * which is faster for these two cases.
2926 if ((yyvsp[(1) - (4)])->opcode == Op_K_print &&
2927 ((yyvsp[(3) - (4)]) == NULL
2928 || ((yyvsp[(3) - (4)])->lasti->opcode == Op_field_spec
2929 && (yyvsp[(3) - (4)])->nexti->nexti->nexti == (yyvsp[(3) - (4)])->lasti
2930 && (yyvsp[(3) - (4)])->nexti->nexti->opcode == Op_push_i
2931 && (yyvsp[(3) - (4)])->nexti->nexti->memory->type == Node_val
2932 && (yyvsp[(3) - (4)])->nexti->nexti->memory->numbr == 0.0)
2935 static short warned = FALSE;
2936 /* -----------------
2941 * ------------------
2942 * [Op_K_print_rec | NULL | redir_type | expr_count]
2945 if ((yyvsp[(3) - (4)]) != NULL) {
2946 bcfree((yyvsp[(3) - (4)])->lasti); /* Op_field_spec */
2947 (yyvsp[(3) - (4)])->nexti->nexti->memory->flags &= ~PERM;
2948 (yyvsp[(3) - (4)])->nexti->nexti->memory->flags |= MALLOC;
2949 unref((yyvsp[(3) - (4)])->nexti->nexti->memory); /* Node_val */
2950 bcfree((yyvsp[(3) - (4)])->nexti->nexti); /* Op_push_i */
2951 bcfree((yyvsp[(3) - (4)])->nexti); /* Op_list */
2952 bcfree((yyvsp[(3) - (4)])); /* Op_list */
2954 if (do_lint && (rule == BEGIN || rule == END) && ! warned) {
2956 lintwarn_ln((yyvsp[(1) - (4)])->source_line,
2957 _("plain `print' in BEGIN or END rule should probably be `print \"\"'"));
2961 (yyvsp[(1) - (4)])->expr_count = 0;
2962 (yyvsp[(1) - (4)])->opcode = Op_K_print_rec;
2963 if ((yyvsp[(4) - (4)]) == NULL) { /* no redircetion */
2964 (yyvsp[(1) - (4)])->redir_type = 0;
2965 (yyval) = list_create((yyvsp[(1) - (4)]));
2968 ip = (yyvsp[(4) - (4)])->nexti;
2969 (yyvsp[(1) - (4)])->redir_type = ip->redir_type;
2970 (yyvsp[(4) - (4)])->nexti = ip->nexti;
2972 (yyval) = list_append((yyvsp[(4) - (4)]), (yyvsp[(1) - (4)]));
2975 /* -----------------
2979 * [ expression_list ]
2980 * ------------------
2981 * [$1 | NULL | redir_type | expr_count]
2985 if ((yyvsp[(4) - (4)]) == NULL) { /* no redirection */
2986 if ((yyvsp[(3) - (4)]) == NULL) { /* printf without arg */
2987 (yyvsp[(1) - (4)])->expr_count = 0;
2988 (yyvsp[(1) - (4)])->redir_type = 0;
2989 (yyval) = list_create((yyvsp[(1) - (4)]));
2991 INSTRUCTION *t = (yyvsp[(3) - (4)]);
2992 (yyvsp[(1) - (4)])->expr_count = count_expressions(&t, FALSE);
2993 (yyvsp[(1) - (4)])->redir_type = 0;
2994 (yyval) = list_append(t, (yyvsp[(1) - (4)]));
2998 ip = (yyvsp[(4) - (4)])->nexti;
2999 (yyvsp[(1) - (4)])->redir_type = ip->redir_type;
3000 (yyvsp[(4) - (4)])->nexti = ip->nexti;
3002 if ((yyvsp[(3) - (4)]) == NULL) {
3003 (yyvsp[(1) - (4)])->expr_count = 0;
3004 (yyval) = list_append((yyvsp[(4) - (4)]), (yyvsp[(1) - (4)]));
3006 INSTRUCTION *t = (yyvsp[(3) - (4)]);
3007 (yyvsp[(1) - (4)])->expr_count = count_expressions(&t, FALSE);
3008 (yyval) = list_append(list_merge((yyvsp[(4) - (4)]), t), (yyvsp[(1) - (4)]));
3017 /* Line 1806 of yacc.c */
3018 #line 982 "awkgram.y"
3019 { sub_counter = 0; }
3024 /* Line 1806 of yacc.c */
3025 #line 983 "awkgram.y"
3027 char *arr = (yyvsp[(2) - (4)])->lextok;
3029 (yyvsp[(2) - (4)])->opcode = Op_push_array;
3030 (yyvsp[(2) - (4)])->memory = variable(arr, Node_var_new);
3032 if ((yyvsp[(4) - (4)]) == NULL) {
3033 static short warned = FALSE;
3035 if (do_lint && ! warned) {
3037 lintwarn_ln((yyvsp[(1) - (4)])->source_line,
3038 _("`delete array' is a gawk extension"));
3041 error_ln((yyvsp[(1) - (4)])->source_line,
3042 _("`delete array' is a gawk extension"));
3043 (yyvsp[(1) - (4)])->expr_count = 0;
3044 (yyval) = list_append(list_create((yyvsp[(2) - (4)])), (yyvsp[(1) - (4)]));
3046 (yyvsp[(1) - (4)])->expr_count = sub_counter;
3047 (yyval) = list_append(list_append((yyvsp[(4) - (4)]), (yyvsp[(2) - (4)])), (yyvsp[(1) - (4)]));
3054 /* Line 1806 of yacc.c */
3055 #line 1012 "awkgram.y"
3057 static short warned = FALSE;
3058 char *arr = (yyvsp[(3) - (4)])->lextok;
3060 if (do_lint && ! warned) {
3062 lintwarn_ln((yyvsp[(1) - (4)])->source_line,
3063 _("`delete(array)' is a non-portable tawk extension"));
3065 if (do_traditional) {
3066 error_ln((yyvsp[(1) - (4)])->source_line,
3067 _("`delete array' is a gawk extension"));
3069 (yyvsp[(3) - (4)])->memory = variable(arr, Node_var_new);
3070 (yyvsp[(3) - (4)])->opcode = Op_push_array;
3071 (yyvsp[(1) - (4)])->expr_count = 0;
3072 (yyval) = list_append(list_create((yyvsp[(3) - (4)])), (yyvsp[(1) - (4)]));
3078 /* Line 1806 of yacc.c */
3079 #line 1031 "awkgram.y"
3080 { (yyval) = optimize_assignment((yyvsp[(1) - (1)])); }
3085 /* Line 1806 of yacc.c */
3086 #line 1036 "awkgram.y"
3092 /* Line 1806 of yacc.c */
3093 #line 1038 "awkgram.y"
3094 { (yyval) = (yyvsp[(1) - (1)]); }
3099 /* Line 1806 of yacc.c */
3100 #line 1043 "awkgram.y"
3106 /* Line 1806 of yacc.c */
3107 #line 1045 "awkgram.y"
3109 if ((yyvsp[(1) - (2)]) == NULL)
3110 (yyval) = list_create((yyvsp[(2) - (2)]));
3112 (yyval) = list_prepend((yyvsp[(1) - (2)]), (yyvsp[(2) - (2)]));
3118 /* Line 1806 of yacc.c */
3119 #line 1052 "awkgram.y"
3125 /* Line 1806 of yacc.c */
3126 #line 1057 "awkgram.y"
3128 INSTRUCTION *casestmt = (yyvsp[(5) - (5)]);
3129 if ((yyvsp[(5) - (5)]) == NULL)
3130 casestmt = list_create(instruction(Op_no_op));
3132 (void) list_prepend(casestmt, instruction(Op_exec_count));
3133 (yyvsp[(1) - (5)])->case_exp = (yyvsp[(2) - (5)]);
3134 (yyvsp[(1) - (5)])->case_stmt = casestmt;
3135 bcfree((yyvsp[(3) - (5)]));
3136 (yyval) = (yyvsp[(1) - (5)]);
3142 /* Line 1806 of yacc.c */
3143 #line 1069 "awkgram.y"
3145 INSTRUCTION *casestmt = (yyvsp[(4) - (4)]);
3146 if ((yyvsp[(4) - (4)]) == NULL)
3147 casestmt = list_create(instruction(Op_no_op));
3149 (void) list_prepend(casestmt, instruction(Op_exec_count));
3150 bcfree((yyvsp[(2) - (4)]));
3151 (yyvsp[(1) - (4)])->case_stmt = casestmt;
3152 (yyval) = (yyvsp[(1) - (4)]);
3158 /* Line 1806 of yacc.c */
3159 #line 1083 "awkgram.y"
3160 { (yyval) = (yyvsp[(1) - (1)]); }
3165 /* Line 1806 of yacc.c */
3166 #line 1085 "awkgram.y"
3168 (yyvsp[(2) - (2)])->memory->numbr = -(force_number((yyvsp[(2) - (2)])->memory));
3169 bcfree((yyvsp[(1) - (2)]));
3170 (yyval) = (yyvsp[(2) - (2)]);
3176 /* Line 1806 of yacc.c */
3177 #line 1091 "awkgram.y"
3179 bcfree((yyvsp[(1) - (2)]));
3180 (yyval) = (yyvsp[(2) - (2)]);
3186 /* Line 1806 of yacc.c */
3187 #line 1096 "awkgram.y"
3188 { (yyval) = (yyvsp[(1) - (1)]); }
3193 /* Line 1806 of yacc.c */
3194 #line 1098 "awkgram.y"
3196 (yyvsp[(1) - (1)])->opcode = Op_push_re;
3197 (yyval) = (yyvsp[(1) - (1)]);
3203 /* Line 1806 of yacc.c */
3204 #line 1106 "awkgram.y"
3205 { (yyval) = (yyvsp[(1) - (1)]); }
3210 /* Line 1806 of yacc.c */
3211 #line 1108 "awkgram.y"
3212 { (yyval) = (yyvsp[(1) - (1)]); }
3217 /* Line 1806 of yacc.c */
3218 #line 1118 "awkgram.y"
3220 (yyval) = (yyvsp[(2) - (3)]);
3226 /* Line 1806 of yacc.c */
3227 #line 1125 "awkgram.y"
3237 /* Line 1806 of yacc.c */
3238 #line 1130 "awkgram.y"
3239 { in_print = FALSE; in_parens = 0; }
3244 /* Line 1806 of yacc.c */
3245 #line 1131 "awkgram.y"
3247 if ((yyvsp[(1) - (3)])->redir_type == redirect_twoway
3248 && (yyvsp[(3) - (3)])->lasti->opcode == Op_K_getline_redir
3249 && (yyvsp[(3) - (3)])->lasti->redir_type == redirect_twoway)
3250 yyerror(_("multistage two-way pipelines don't work"));
3251 (yyval) = list_prepend((yyvsp[(3) - (3)]), (yyvsp[(1) - (3)]));
3257 /* Line 1806 of yacc.c */
3258 #line 1142 "awkgram.y"
3260 (yyval) = mk_condition((yyvsp[(3) - (6)]), (yyvsp[(1) - (6)]), (yyvsp[(6) - (6)]), NULL, NULL);
3266 /* Line 1806 of yacc.c */
3267 #line 1147 "awkgram.y"
3269 (yyval) = mk_condition((yyvsp[(3) - (9)]), (yyvsp[(1) - (9)]), (yyvsp[(6) - (9)]), (yyvsp[(7) - (9)]), (yyvsp[(9) - (9)]));
3275 /* Line 1806 of yacc.c */
3276 #line 1164 "awkgram.y"
3282 /* Line 1806 of yacc.c */
3283 #line 1166 "awkgram.y"
3285 bcfree((yyvsp[(1) - (2)]));
3286 (yyval) = (yyvsp[(2) - (2)]);
3292 /* Line 1806 of yacc.c */
3293 #line 1179 "awkgram.y"
3295 append_param((yyvsp[(1) - (1)])->lextok);
3296 (yyvsp[(1) - (1)])->lextok = NULL;
3297 bcfree((yyvsp[(1) - (1)]));
3303 /* Line 1806 of yacc.c */
3304 #line 1185 "awkgram.y"
3306 append_param((yyvsp[(3) - (3)])->lextok);
3307 (yyvsp[(3) - (3)])->lextok = NULL;
3308 bcfree((yyvsp[(3) - (3)]));
3315 /* Line 1806 of yacc.c */
3316 #line 1192 "awkgram.y"
3317 { /* func_params = NULL; */ }
3322 /* Line 1806 of yacc.c */
3323 #line 1194 "awkgram.y"
3324 { /* func_params = NULL; */ }
3329 /* Line 1806 of yacc.c */
3330 #line 1196 "awkgram.y"
3331 { /* func_params = NULL; */ }
3336 /* Line 1806 of yacc.c */
3337 #line 1202 "awkgram.y"
3343 /* Line 1806 of yacc.c */
3344 #line 1204 "awkgram.y"
3345 { (yyval) = (yyvsp[(1) - (1)]); }
3350 /* Line 1806 of yacc.c */
3351 #line 1209 "awkgram.y"
3357 /* Line 1806 of yacc.c */
3358 #line 1211 "awkgram.y"
3359 { (yyval) = (yyvsp[(1) - (1)]); }
3364 /* Line 1806 of yacc.c */
3365 #line 1216 "awkgram.y"
3366 { (yyval) = mk_expression_list(NULL, (yyvsp[(1) - (1)])); }
3371 /* Line 1806 of yacc.c */
3372 #line 1218 "awkgram.y"
3374 (yyval) = mk_expression_list((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]));
3381 /* Line 1806 of yacc.c */
3382 #line 1223 "awkgram.y"
3388 /* Line 1806 of yacc.c */
3389 #line 1225 "awkgram.y"
3395 /* Line 1806 of yacc.c */
3396 #line 1227 "awkgram.y"
3402 /* Line 1806 of yacc.c */
3403 #line 1229 "awkgram.y"
3409 /* Line 1806 of yacc.c */
3410 #line 1235 "awkgram.y"
3412 if (do_lint && (yyvsp[(3) - (3)])->lasti->opcode == Op_match_rec)
3413 lintwarn_ln((yyvsp[(2) - (3)])->source_line,
3414 _("regular expression on right of assignment"));
3415 (yyval) = mk_assignment((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)]));
3421 /* Line 1806 of yacc.c */
3422 #line 1242 "awkgram.y"
3423 { (yyval) = mk_boolean((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); }
3428 /* Line 1806 of yacc.c */
3429 #line 1244 "awkgram.y"
3430 { (yyval) = mk_boolean((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); }
3435 /* Line 1806 of yacc.c */
3436 #line 1246 "awkgram.y"
3438 if ((yyvsp[(1) - (3)])->lasti->opcode == Op_match_rec)
3439 warning_ln((yyvsp[(2) - (3)])->source_line,
3440 _("regular expression on left of `~' or `!~' operator"));
3442 if ((yyvsp[(3) - (3)])->lasti == (yyvsp[(3) - (3)])->nexti && (yyvsp[(3) - (3)])->nexti->opcode == Op_match_rec) {
3443 (yyvsp[(2) - (3)])->memory = (yyvsp[(3) - (3)])->nexti->memory;
3444 bcfree((yyvsp[(3) - (3)])->nexti); /* Op_match_rec */
3445 bcfree((yyvsp[(3) - (3)])); /* Op_list */
3446 (yyval) = list_append((yyvsp[(1) - (3)]), (yyvsp[(2) - (3)]));
3448 (yyvsp[(2) - (3)])->memory = make_regnode(Node_dynregex, NULL);
3449 (yyval) = list_append(list_merge((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)])), (yyvsp[(2) - (3)]));
3456 /* Line 1806 of yacc.c */
3457 #line 1262 "awkgram.y"
3460 warning_ln((yyvsp[(2) - (3)])->source_line,
3461 _("old awk does not support the keyword `in' except after `for'"));
3462 (yyvsp[(3) - (3)])->nexti->opcode = Op_push_array;
3463 (yyvsp[(2) - (3)])->opcode = Op_in_array;
3464 (yyvsp[(2) - (3)])->expr_count = 1;
3465 (yyval) = list_append(list_merge((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)])), (yyvsp[(2) - (3)]));
3471 /* Line 1806 of yacc.c */
3472 #line 1272 "awkgram.y"
3474 if (do_lint && (yyvsp[(3) - (3)])->lasti->opcode == Op_match_rec)
3475 lintwarn_ln((yyvsp[(2) - (3)])->source_line,
3476 _("regular expression on right of comparison"));
3477 (yyval) = list_append(list_merge((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)])), (yyvsp[(2) - (3)]));
3483 /* Line 1806 of yacc.c */
3484 #line 1279 "awkgram.y"
3485 { (yyval) = mk_condition((yyvsp[(1) - (5)]), (yyvsp[(2) - (5)]), (yyvsp[(3) - (5)]), (yyvsp[(4) - (5)]), (yyvsp[(5) - (5)])); }
3490 /* Line 1806 of yacc.c */
3491 #line 1281 "awkgram.y"
3492 { (yyval) = (yyvsp[(1) - (1)]); }
3497 /* Line 1806 of yacc.c */
3498 #line 1286 "awkgram.y"
3499 { (yyval) = (yyvsp[(1) - (1)]); }
3504 /* Line 1806 of yacc.c */
3505 #line 1288 "awkgram.y"
3506 { (yyval) = (yyvsp[(1) - (1)]); }
3511 /* Line 1806 of yacc.c */
3512 #line 1290 "awkgram.y"
3514 (yyvsp[(2) - (2)])->opcode = Op_assign_quotient;
3515 (yyval) = (yyvsp[(2) - (2)]);
3521 /* Line 1806 of yacc.c */
3522 #line 1298 "awkgram.y"
3523 { (yyval) = (yyvsp[(1) - (1)]); }
3528 /* Line 1806 of yacc.c */
3529 #line 1300 "awkgram.y"
3530 { (yyval) = (yyvsp[(1) - (1)]); }
3535 /* Line 1806 of yacc.c */
3536 #line 1305 "awkgram.y"
3537 { (yyval) = (yyvsp[(1) - (1)]); }
3542 /* Line 1806 of yacc.c */
3543 #line 1307 "awkgram.y"
3544 { (yyval) = (yyvsp[(1) - (1)]); }
3549 /* Line 1806 of yacc.c */
3550 #line 1312 "awkgram.y"
3551 { (yyval) = (yyvsp[(1) - (1)]); }
3556 /* Line 1806 of yacc.c */
3557 #line 1314 "awkgram.y"
3558 { (yyval) = (yyvsp[(1) - (1)]); }
3563 /* Line 1806 of yacc.c */
3564 #line 1316 "awkgram.y"
3567 int is_simple_var = FALSE;
3569 if ((yyvsp[(1) - (2)])->lasti->opcode == Op_concat) {
3570 /* multiple (> 2) adjacent strings optimization */
3571 is_simple_var = ((yyvsp[(1) - (2)])->lasti->concat_flag & CSVAR);
3572 count = (yyvsp[(1) - (2)])->lasti->expr_count + 1;
3573 (yyvsp[(1) - (2)])->lasti->opcode = Op_no_op;
3575 is_simple_var = ((yyvsp[(1) - (2)])->nexti->opcode == Op_push
3576 && (yyvsp[(1) - (2)])->lasti == (yyvsp[(1) - (2)])->nexti); /* first exp. is a simple
3577 * variable?; kludge for use
3578 * in Op_assign_concat.
3583 && (yyvsp[(1) - (2)])->nexti == (yyvsp[(1) - (2)])->lasti && (yyvsp[(1) - (2)])->nexti->opcode == Op_push_i
3584 && (yyvsp[(2) - (2)])->nexti == (yyvsp[(2) - (2)])->lasti && (yyvsp[(2) - (2)])->nexti->opcode == Op_push_i
3586 NODE *n1 = (yyvsp[(1) - (2)])->nexti->memory;
3587 NODE *n2 = (yyvsp[(2) - (2)])->nexti->memory;
3590 (void) force_string(n1);
3591 (void) force_string(n2);
3592 nlen = n1->stlen + n2->stlen;
3593 erealloc(n1->stptr, char *, nlen + 2, "constant fold");
3594 memcpy(n1->stptr + n1->stlen, n2->stptr, n2->stlen);
3596 n1->stptr[nlen] = '\0';
3597 n1->flags &= ~(NUMCUR|NUMBER);
3598 n1->flags |= (STRING|STRCUR);
3601 n2->flags |= MALLOC;
3603 bcfree((yyvsp[(2) - (2)])->nexti);
3604 bcfree((yyvsp[(2) - (2)]));
3605 (yyval) = (yyvsp[(1) - (2)]);
3607 (yyval) = list_append(list_merge((yyvsp[(1) - (2)]), (yyvsp[(2) - (2)])), instruction(Op_concat));
3608 (yyval)->lasti->concat_flag = (is_simple_var ? CSVAR : 0);
3609 (yyval)->lasti->expr_count = count;
3610 if (count > max_args)
3618 /* Line 1806 of yacc.c */
3619 #line 1371 "awkgram.y"
3620 { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); }
3625 /* Line 1806 of yacc.c */
3626 #line 1373 "awkgram.y"
3627 { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); }
3632 /* Line 1806 of yacc.c */
3633 #line 1375 "awkgram.y"
3634 { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); }
3639 /* Line 1806 of yacc.c */
3640 #line 1377 "awkgram.y"
3641 { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); }
3646 /* Line 1806 of yacc.c */
3647 #line 1379 "awkgram.y"
3648 { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); }
3653 /* Line 1806 of yacc.c */
3654 #line 1381 "awkgram.y"
3655 { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); }
3660 /* Line 1806 of yacc.c */
3661 #line 1383 "awkgram.y"
3664 * In BEGINFILE/ENDFILE, allow `getline var < file'
3667 if (rule == BEGINFILE || rule == ENDFILE) {
3668 if ((yyvsp[(2) - (3)]) != NULL && (yyvsp[(3) - (3)]) != NULL)
3671 if ((yyvsp[(2) - (3)]) != NULL)
3672 error_ln((yyvsp[(1) - (3)])->source_line,
3673 _("`getline var' invalid inside `%s' rule"), ruletab[rule]);
3675 error_ln((yyvsp[(1) - (3)])->source_line,
3676 _("`getline' invalid inside `%s' rule"), ruletab[rule]);
3679 if (do_lint && rule == END && (yyvsp[(3) - (3)]) == NULL)
3680 lintwarn_ln((yyvsp[(1) - (3)])->source_line,
3681 _("non-redirected `getline' undefined inside END action"));
3682 (yyval) = mk_getline((yyvsp[(1) - (3)]), (yyvsp[(2) - (3)]), (yyvsp[(3) - (3)]), redirect_input);
3688 /* Line 1806 of yacc.c */
3689 #line 1406 "awkgram.y"
3691 (yyvsp[(2) - (2)])->opcode = Op_postincrement;
3692 (yyval) = mk_assignment((yyvsp[(1) - (2)]), NULL, (yyvsp[(2) - (2)]));
3698 /* Line 1806 of yacc.c */
3699 #line 1411 "awkgram.y"
3701 (yyvsp[(2) - (2)])->opcode = Op_postdecrement;
3702 (yyval) = mk_assignment((yyvsp[(1) - (2)]), NULL, (yyvsp[(2) - (2)]));
3708 /* Line 1806 of yacc.c */
3709 #line 1416 "awkgram.y"
3712 warning_ln((yyvsp[(4) - (5)])->source_line,
3713 _("old awk does not support the keyword `in' except after `for'"));
3714 warning_ln((yyvsp[(4) - (5)])->source_line,
3715 _("old awk does not support multidimensional arrays"));
3717 (yyvsp[(5) - (5)])->nexti->opcode = Op_push_array;
3718 (yyvsp[(4) - (5)])->opcode = Op_in_array;
3719 if ((yyvsp[(2) - (5)]) == NULL) { /* error */
3721 (yyvsp[(4) - (5)])->expr_count = 0;
3722 (yyval) = list_merge((yyvsp[(5) - (5)]), (yyvsp[(4) - (5)]));
3724 INSTRUCTION *t = (yyvsp[(2) - (5)]);
3725 (yyvsp[(4) - (5)])->expr_count = count_expressions(&t, FALSE);
3726 (yyval) = list_append(list_merge(t, (yyvsp[(5) - (5)])), (yyvsp[(4) - (5)]));
3733 /* Line 1806 of yacc.c */
3734 #line 1441 "awkgram.y"
3736 (yyval) = mk_getline((yyvsp[(3) - (4)]), (yyvsp[(4) - (4)]), (yyvsp[(1) - (4)]), (yyvsp[(2) - (4)])->redir_type);
3737 bcfree((yyvsp[(2) - (4)]));
3743 /* Line 1806 of yacc.c */
3744 #line 1447 "awkgram.y"
3745 { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); }
3750 /* Line 1806 of yacc.c */
3751 #line 1449 "awkgram.y"
3752 { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); }
3757 /* Line 1806 of yacc.c */
3758 #line 1451 "awkgram.y"
3759 { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); }
3764 /* Line 1806 of yacc.c */
3765 #line 1453 "awkgram.y"
3766 { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); }
3771 /* Line 1806 of yacc.c */
3772 #line 1455 "awkgram.y"
3773 { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); }
3778 /* Line 1806 of yacc.c */
3779 #line 1457 "awkgram.y"
3780 { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); }
3785 /* Line 1806 of yacc.c */
3786 #line 1462 "awkgram.y"
3788 (yyval) = list_create((yyvsp[(1) - (1)]));
3794 /* Line 1806 of yacc.c */
3795 #line 1466 "awkgram.y"
3797 if ((yyvsp[(2) - (2)])->opcode == Op_match_rec) {
3798 (yyvsp[(2) - (2)])->opcode = Op_nomatch;
3799 (yyvsp[(1) - (2)])->opcode = Op_push_i;
3800 (yyvsp[(1) - (2)])->memory = mk_number(0.0, (PERM|NUMCUR|NUMBER));
3801 (yyval) = list_append(list_append(list_create((yyvsp[(1) - (2)])),
3802 instruction(Op_field_spec)), (yyvsp[(2) - (2)]));
3804 if (do_optimize > 1 && (yyvsp[(2) - (2)])->nexti == (yyvsp[(2) - (2)])->lasti
3805 && (yyvsp[(2) - (2)])->nexti->opcode == Op_push_i
3807 NODE *n = (yyvsp[(2) - (2)])->nexti->memory;
3808 if ((n->flags & (STRCUR|STRING)) != 0) {
3809 n->numbr = (AWKNUM) (n->stlen == 0);
3810 n->flags &= ~(STRCUR|STRING);
3811 n->flags |= (NUMCUR|NUMBER);
3816 n->numbr = (AWKNUM) (n->numbr == 0.0);
3817 bcfree((yyvsp[(1) - (2)]));
3818 (yyval) = (yyvsp[(2) - (2)]);
3820 (yyvsp[(1) - (2)])->opcode = Op_not;
3821 add_lint((yyvsp[(2) - (2)]), LINT_assign_in_cond);
3822 (yyval) = list_append((yyvsp[(2) - (2)]), (yyvsp[(1) - (2)]));
3830 /* Line 1806 of yacc.c */
3831 #line 1497 "awkgram.y"
3832 { (yyval) = (yyvsp[(2) - (3)]); }
3837 /* Line 1806 of yacc.c */
3838 #line 1499 "awkgram.y"
3840 (yyval) = snode((yyvsp[(3) - (4)]), (yyvsp[(1) - (4)]));
3841 if ((yyval) == NULL)
3848 /* Line 1806 of yacc.c */
3849 #line 1505 "awkgram.y"
3851 (yyval) = snode((yyvsp[(3) - (4)]), (yyvsp[(1) - (4)]));
3852 if ((yyval) == NULL)
3859 /* Line 1806 of yacc.c */
3860 #line 1511 "awkgram.y"
3862 static short warned1 = FALSE;
3864 if (do_lint && ! warned1) {
3866 lintwarn_ln((yyvsp[(1) - (1)])->source_line,
3867 _("call of `length' without parentheses is not portable"));
3869 (yyval) = snode(NULL, (yyvsp[(1) - (1)]));
3870 if ((yyval) == NULL)
3877 /* Line 1806 of yacc.c */
3878 #line 1526 "awkgram.y"
3880 (yyvsp[(1) - (2)])->opcode = Op_preincrement;
3881 (yyval) = mk_assignment((yyvsp[(2) - (2)]), NULL, (yyvsp[(1) - (2)]));
3887 /* Line 1806 of yacc.c */
3888 #line 1531 "awkgram.y"
3890 (yyvsp[(1) - (2)])->opcode = Op_predecrement;
3891 (yyval) = mk_assignment((yyvsp[(2) - (2)]), NULL, (yyvsp[(1) - (2)]));
3897 /* Line 1806 of yacc.c */
3898 #line 1536 "awkgram.y"
3900 (yyval) = list_create((yyvsp[(1) - (1)]));
3906 /* Line 1806 of yacc.c */
3907 #line 1540 "awkgram.y"
3909 (yyval) = list_create((yyvsp[(1) - (1)]));
3915 /* Line 1806 of yacc.c */
3916 #line 1544 "awkgram.y"
3918 if ((yyvsp[(2) - (2)])->lasti->opcode == Op_push_i
3919 && ((yyvsp[(2) - (2)])->lasti->memory->flags & (STRCUR|STRING)) == 0) {
3920 (yyvsp[(2) - (2)])->lasti->memory->numbr = -(force_number((yyvsp[(2) - (2)])->lasti->memory));
3921 (yyval) = (yyvsp[(2) - (2)]);
3922 bcfree((yyvsp[(1) - (2)]));
3924 (yyvsp[(1) - (2)])->opcode = Op_unary_minus;
3925 (yyval) = list_append((yyvsp[(2) - (2)]), (yyvsp[(1) - (2)]));
3932 /* Line 1806 of yacc.c */
3933 #line 1556 "awkgram.y"
3937 * POSIX semantics: force a conversion to numeric type
3939 (yyvsp[(1) - (2)])->opcode = Op_plus_i;
3940 (yyvsp[(1) - (2)])->memory = mk_number((AWKNUM) 0.0, (PERM|NUMCUR|NUMBER));
3941 (yyval) = list_append((yyvsp[(2) - (2)]), (yyvsp[(1) - (2)]));
3947 /* Line 1806 of yacc.c */
3948 #line 1569 "awkgram.y"
3950 func_use((yyvsp[(1) - (1)])->lasti->func_name, FUNC_USE);
3951 (yyval) = (yyvsp[(1) - (1)]);
3957 /* Line 1806 of yacc.c */
3958 #line 1574 "awkgram.y"
3960 /* indirect function call */
3964 static short warned = FALSE;
3965 const char *msg = _("indirect function calls are a gawk extension");
3967 if (do_traditional || do_posix)
3969 else if (do_lint && ! warned) {
3971 lintwarn("%s", msg);
3974 f = (yyvsp[(2) - (2)])->lasti;
3975 f->opcode = Op_indirect_func_call;
3976 name = estrdup(f->func_name, strlen(f->func_name));
3977 if (is_std_var(name))
3978 yyerror(_("can not use special variable `%s' for indirect function call"), name);
3979 indirect_var = variable(name, Node_var_new);
3980 t = instruction(Op_push);
3981 t->memory = indirect_var;
3983 /* prepend indirect var instead of appending to arguments (opt_expression_list),
3984 * and pop it off in setup_frame (eval.c) (left to right evaluation order); Test case:
3989 (yyval) = list_prepend((yyvsp[(2) - (2)]), t);
3995 /* Line 1806 of yacc.c */
3996 #line 1610 "awkgram.y"
3998 param_sanity((yyvsp[(3) - (4)]));
3999 (yyvsp[(1) - (4)])->opcode = Op_func_call;
4000 (yyvsp[(1) - (4)])->func_body = NULL;
4001 if ((yyvsp[(3) - (4)]) == NULL) { /* no argument or error */
4002 ((yyvsp[(1) - (4)]) + 1)->expr_count = 0;
4003 (yyval) = list_create((yyvsp[(1) - (4)]));
4005 INSTRUCTION *t = (yyvsp[(3) - (4)]);
4006 ((yyvsp[(1) - (4)]) + 1)->expr_count = count_expressions(&t, TRUE);
4007 (yyval) = list_append(t, (yyvsp[(1) - (4)]));
4014 /* Line 1806 of yacc.c */
4015 #line 1627 "awkgram.y"
4021 /* Line 1806 of yacc.c */
4022 #line 1629 "awkgram.y"
4023 { (yyval) = (yyvsp[(1) - (1)]); }
4028 /* Line 1806 of yacc.c */
4029 #line 1634 "awkgram.y"
4035 /* Line 1806 of yacc.c */
4036 #line 1636 "awkgram.y"
4037 { (yyval) = (yyvsp[(1) - (2)]); }
4042 /* Line 1806 of yacc.c */
4043 #line 1641 "awkgram.y"
4044 { (yyval) = (yyvsp[(1) - (1)]); }
4049 /* Line 1806 of yacc.c */
4050 #line 1643 "awkgram.y"
4052 (yyval) = list_merge((yyvsp[(1) - (2)]), (yyvsp[(2) - (2)]));
4058 /* Line 1806 of yacc.c */
4059 #line 1650 "awkgram.y"
4061 INSTRUCTION *ip = (yyvsp[(1) - (1)])->lasti;
4062 int count = ip->sub_count; /* # of SUBSEP-seperated expressions */
4064 /* change Op_subscript or Op_sub_array to Op_concat */
4065 ip->opcode = Op_concat;
4066 ip->concat_flag = CSUBSEP;
4067 ip->expr_count = count;
4069 ip->opcode = Op_no_op;
4070 sub_counter++; /* count # of dimensions */
4071 (yyval) = (yyvsp[(1) - (1)]);
4077 /* Line 1806 of yacc.c */
4078 #line 1667 "awkgram.y"
4080 INSTRUCTION *t = (yyvsp[(2) - (3)]);
4081 if ((yyvsp[(2) - (3)]) == NULL) {
4082 error_ln((yyvsp[(3) - (3)])->source_line,
4083 _("invalid subscript expression"));
4084 /* install Null string as subscript. */
4085 t = list_create(instruction(Op_push_i));
4086 t->nexti->memory = Nnull_string;
4087 (yyvsp[(3) - (3)])->sub_count = 1;
4089 (yyvsp[(3) - (3)])->sub_count = count_expressions(&t, FALSE);
4090 (yyval) = list_append(t, (yyvsp[(3) - (3)]));
4096 /* Line 1806 of yacc.c */
4097 #line 1684 "awkgram.y"
4098 { (yyval) = (yyvsp[(1) - (1)]); }
4103 /* Line 1806 of yacc.c */
4104 #line 1686 "awkgram.y"
4106 (yyval) = list_merge((yyvsp[(1) - (2)]), (yyvsp[(2) - (2)]));
4112 /* Line 1806 of yacc.c */
4113 #line 1693 "awkgram.y"
4114 { (yyval) = (yyvsp[(1) - (2)]); }
4119 /* Line 1806 of yacc.c */
4120 #line 1698 "awkgram.y"
4122 char *var_name = (yyvsp[(1) - (1)])->lextok;
4124 (yyvsp[(1) - (1)])->opcode = Op_push;
4125 (yyvsp[(1) - (1)])->memory = variable(var_name, Node_var_new);
4126 (yyval) = list_create((yyvsp[(1) - (1)]));
4132 /* Line 1806 of yacc.c */
4133 #line 1706 "awkgram.y"
4137 char *arr = (yyvsp[(1) - (2)])->lextok;
4138 if ((n = lookup(arr)) != NULL && ! isarray(n))
4139 yyerror(_("use of non-array as array"));
4140 (yyvsp[(1) - (2)])->memory = variable(arr, Node_var_new);
4141 (yyvsp[(1) - (2)])->opcode = Op_push_array;
4142 (yyval) = list_prepend((yyvsp[(2) - (2)]), (yyvsp[(1) - (2)]));
4148 /* Line 1806 of yacc.c */
4149 #line 1720 "awkgram.y"
4151 INSTRUCTION *ip = (yyvsp[(1) - (1)])->nexti;
4152 if (ip->opcode == Op_push
4153 && ip->memory->type == Node_var
4154 && ip->memory->var_update
4156 (yyval) = list_prepend((yyvsp[(1) - (1)]), instruction(Op_var_update));
4157 (yyval)->nexti->update_var = ip->memory->var_update;
4159 (yyval) = (yyvsp[(1) - (1)]);
4165 /* Line 1806 of yacc.c */
4166 #line 1732 "awkgram.y"
4168 (yyval) = list_append((yyvsp[(2) - (3)]), (yyvsp[(1) - (3)]));
4169 if ((yyvsp[(3) - (3)]) != NULL)
4170 mk_assignment((yyvsp[(2) - (3)]), NULL, (yyvsp[(3) - (3)]));
4176 /* Line 1806 of yacc.c */
4177 #line 1741 "awkgram.y"
4179 (yyvsp[(1) - (1)])->opcode = Op_postincrement;
4185 /* Line 1806 of yacc.c */
4186 #line 1745 "awkgram.y"
4188 (yyvsp[(1) - (1)])->opcode = Op_postdecrement;
4194 /* Line 1806 of yacc.c */
4195 #line 1748 "awkgram.y"
4201 /* Line 1806 of yacc.c */
4202 #line 1756 "awkgram.y"
4208 /* Line 1806 of yacc.c */
4209 #line 1760 "awkgram.y"
4215 /* Line 1806 of yacc.c */
4216 #line 1769 "awkgram.y"
4222 /* Line 1806 of yacc.c */
4223 #line 1773 "awkgram.y"
4224 { (yyval) = (yyvsp[(1) - (1)]); yyerrok; }
4229 /* Line 1806 of yacc.c */
4230 #line 1777 "awkgram.y"
4236 /* Line 1806 of yacc.c */
4237 #line 4250 "awkgram.c"
4240 /* User semantic actions sometimes alter yychar, and that requires
4241 that yytoken be updated with the new translation. We take the
4242 approach of translating immediately before every use of yytoken.
4243 One alternative is translating here after every semantic action,
4244 but that translation would be missed if the semantic action invokes
4245 YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
4246 if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an
4247 incorrect destructor might then be invoked immediately. In the
4248 case of YYERROR or YYBACKUP, subsequent parser actions might lead
4249 to an incorrect destructor call or verbose syntax error message
4250 before the lookahead is translated. */
4251 YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
4255 YY_STACK_PRINT (yyss, yyssp);
4259 /* Now `shift' the result of the reduction. Determine what state
4260 that goes to, based on the state we popped back to and the rule
4261 number reduced by. */
4265 yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
4266 if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
4267 yystate = yytable[yystate];
4269 yystate = yydefgoto[yyn - YYNTOKENS];
4274 /*------------------------------------.
4275 | yyerrlab -- here on detecting error |
4276 `------------------------------------*/
4278 /* Make sure we have latest lookahead translation. See comments at
4279 user semantic actions for why this is necessary. */
4280 yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
4282 /* If not already recovering from an error, report this error. */
4286 #if ! YYERROR_VERBOSE
4287 yyerror (YY_("syntax error"));
4289 # define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
4292 char const *yymsgp = YY_("syntax error");
4293 int yysyntax_error_status;
4294 yysyntax_error_status = YYSYNTAX_ERROR;
4295 if (yysyntax_error_status == 0)
4297 else if (yysyntax_error_status == 1)
4299 if (yymsg != yymsgbuf)
4300 YYSTACK_FREE (yymsg);
4301 yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
4305 yymsg_alloc = sizeof yymsgbuf;
4306 yysyntax_error_status = 2;
4310 yysyntax_error_status = YYSYNTAX_ERROR;
4315 if (yysyntax_error_status == 2)
4316 goto yyexhaustedlab;
4318 # undef YYSYNTAX_ERROR
4324 if (yyerrstatus == 3)
4326 /* If just tried and failed to reuse lookahead token after an
4327 error, discard it. */
4329 if (yychar <= YYEOF)
4331 /* Return failure if at end of input. */
4332 if (yychar == YYEOF)
4337 yydestruct ("Error: discarding",
4343 /* Else will try to reuse lookahead token after shifting the error
4348 /*---------------------------------------------------.
4349 | yyerrorlab -- error raised explicitly by YYERROR. |
4350 `---------------------------------------------------*/
4353 /* Pacify compilers like GCC when the user code never invokes
4354 YYERROR and the label yyerrorlab therefore never appears in user
4356 if (/*CONSTCOND*/ 0)
4359 /* Do not reclaim the symbols of the rule which action triggered
4363 YY_STACK_PRINT (yyss, yyssp);
4368 /*-------------------------------------------------------------.
4369 | yyerrlab1 -- common code for both syntax error and YYERROR. |
4370 `-------------------------------------------------------------*/
4372 yyerrstatus = 3; /* Each real token shifted decrements this. */
4376 yyn = yypact[yystate];
4377 if (!yypact_value_is_default (yyn))
4380 if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
4388 /* Pop the current state because it cannot handle the error token. */
4393 yydestruct ("Error: popping",
4394 yystos[yystate], yyvsp);
4397 YY_STACK_PRINT (yyss, yyssp);
4403 /* Shift the error token. */
4404 YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
4410 /*-------------------------------------.
4411 | yyacceptlab -- YYACCEPT comes here. |
4412 `-------------------------------------*/
4417 /*-----------------------------------.
4418 | yyabortlab -- YYABORT comes here. |
4419 `-----------------------------------*/
4424 #if !defined(yyoverflow) || YYERROR_VERBOSE
4425 /*-------------------------------------------------.
4426 | yyexhaustedlab -- memory exhaustion comes here. |
4427 `-------------------------------------------------*/
4429 yyerror (YY_("memory exhausted"));
4435 if (yychar != YYEMPTY)
4437 /* Make sure we have latest lookahead translation. See comments at
4438 user semantic actions for why this is necessary. */
4439 yytoken = YYTRANSLATE (yychar);
4440 yydestruct ("Cleanup: discarding lookahead",
4443 /* Do not reclaim the symbols of the rule which action triggered
4444 this YYABORT or YYACCEPT. */
4446 YY_STACK_PRINT (yyss, yyssp);
4447 while (yyssp != yyss)
4449 yydestruct ("Cleanup: popping",
4450 yystos[*yyssp], yyvsp);
4455 YYSTACK_FREE (yyss);
4458 if (yymsg != yymsgbuf)
4459 YYSTACK_FREE (yymsg);
4461 /* Make sure YYID is used. */
4462 return YYID (yyresult);
4467 /* Line 2067 of yacc.c */
4468 #line 1779 "awkgram.y"
4472 const char *operator; /* text to match */
4473 OPCODE value; /* type */
4474 int class; /* lexical class */
4475 unsigned flags; /* # of args. allowed and compatability */
4476 # define ARGS 0xFF /* 0, 1, 2, 3 args allowed (any combination */
4477 # define A(n) (1<<(n))
4478 # define VERSION_MASK 0xFF00 /* old awk is zero */
4479 # define NOT_OLD 0x0100 /* feature not in old awk */
4480 # define NOT_POSIX 0x0200 /* feature not in POSIX */
4481 # define GAWKX 0x0400 /* gawk extension */
4482 # define RESX 0x0800 /* Bell Labs Research extension */
4483 # define BREAK 0x1000 /* break allowed inside */
4484 # define CONTINUE 0x2000 /* continue allowed inside */
4486 NODE *(*ptr)(int); /* function that implements this keyword */
4489 #if 'a' == 0x81 /* it's EBCDIC */
4490 /* tokcompare --- lexicographically compare token names for sorting */
4493 tokcompare(const void *l, const void *r)
4495 struct token *lhs, *rhs;
4497 lhs = (struct token *) l;
4498 rhs = (struct token *) r;
4500 return strcmp(lhs->operator, rhs->operator);
4505 * Tokentab is sorted ASCII ascending order, so it can be binary searched.
4506 * See check_special(), which sorts the table on EBCDIC systems.
4507 * Function pointers come from declarations in awk.h.
4510 static const struct token tokentab[] = {
4511 {"BEGIN", Op_rule, LEX_BEGIN, 0, 0},
4512 {"BEGINFILE", Op_rule, LEX_BEGINFILE, GAWKX, 0},
4513 {"END", Op_rule, LEX_END, 0, 0},
4514 {"ENDFILE", Op_rule, LEX_ENDFILE, GAWKX, 0},
4516 {"adump", Op_builtin, LEX_BUILTIN, GAWKX|A(1), do_adump},
4518 {"and", Op_builtin, LEX_BUILTIN, GAWKX|A(2), do_and},
4519 {"asort", Op_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2)|A(3), do_asort},
4520 {"asorti", Op_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2)|A(3), do_asorti},
4521 {"atan2", Op_builtin, LEX_BUILTIN, NOT_OLD|A(2), do_atan2},
4522 {"bindtextdomain", Op_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2), do_bindtextdomain},
4523 {"break", Op_K_break, LEX_BREAK, 0, 0},
4524 {"case", Op_K_case, LEX_CASE, GAWKX, 0},
4525 {"close", Op_builtin, LEX_BUILTIN, NOT_OLD|A(1)|A(2), do_close},
4526 {"compl", Op_builtin, LEX_BUILTIN, GAWKX|A(1), do_compl},
4527 {"continue", Op_K_continue, LEX_CONTINUE, 0, 0},
4528 {"cos", Op_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_cos},
4529 {"dcgettext", Op_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2)|A(3), do_dcgettext},
4530 {"dcngettext", Op_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2)|A(3)|A(4)|A(5), do_dcngettext},
4531 {"default", Op_K_default, LEX_DEFAULT, GAWKX, 0},
4532 {"delete", Op_K_delete, LEX_DELETE, NOT_OLD, 0},
4533 {"do", Op_K_do, LEX_DO, NOT_OLD|BREAK|CONTINUE, 0},
4534 {"else", Op_K_else, LEX_ELSE, 0, 0},
4535 {"eval", Op_symbol, LEX_EVAL, 0, 0},
4536 {"exit", Op_K_exit, LEX_EXIT, 0, 0},
4537 {"exp", Op_builtin, LEX_BUILTIN, A(1), do_exp},
4538 {"extension", Op_builtin, LEX_BUILTIN, GAWKX|A(2), do_ext},
4539 {"fflush", Op_builtin, LEX_BUILTIN, RESX|A(0)|A(1), do_fflush},
4540 {"for", Op_K_for, LEX_FOR, BREAK|CONTINUE, 0},
4541 {"func", Op_func, LEX_FUNCTION, NOT_POSIX|NOT_OLD, 0},
4542 {"function",Op_func, LEX_FUNCTION, NOT_OLD, 0},
4543 {"gensub", Op_sub_builtin, LEX_BUILTIN, GAWKX|A(3)|A(4), 0},
4544 {"getline", Op_K_getline_redir, LEX_GETLINE, NOT_OLD, 0},
4545 {"gsub", Op_sub_builtin, LEX_BUILTIN, NOT_OLD|A(2)|A(3), 0},
4546 {"if", Op_K_if, LEX_IF, 0, 0},
4547 {"in", Op_symbol, LEX_IN, 0, 0},
4548 {"include", Op_symbol, LEX_INCLUDE, GAWKX, 0},
4549 {"index", Op_builtin, LEX_BUILTIN, A(2), do_index},
4550 {"int", Op_builtin, LEX_BUILTIN, A(1), do_int},
4551 {"isarray", Op_builtin, LEX_BUILTIN, GAWKX|A(1), do_isarray},
4552 {"length", Op_builtin, LEX_LENGTH, A(0)|A(1), do_length},
4553 {"log", Op_builtin, LEX_BUILTIN, A(1), do_log},
4554 {"lshift", Op_builtin, LEX_BUILTIN, GAWKX|A(2), do_lshift},
4555 {"match", Op_builtin, LEX_BUILTIN, NOT_OLD|A(2)|A(3), do_match},
4556 {"mktime", Op_builtin, LEX_BUILTIN, GAWKX|A(1), do_mktime},
4557 {"next", Op_K_next, LEX_NEXT, 0, 0},
4558 {"nextfile", Op_K_nextfile, LEX_NEXTFILE, GAWKX, 0},
4559 {"or", Op_builtin, LEX_BUILTIN, GAWKX|A(2), do_or},
4560 {"patsplit", Op_builtin, LEX_BUILTIN, GAWKX|A(2)|A(3)|A(4), do_patsplit},
4561 {"print", Op_K_print, LEX_PRINT, 0, 0},
4562 {"printf", Op_K_printf, LEX_PRINTF, 0, 0},
4563 {"rand", Op_builtin, LEX_BUILTIN, NOT_OLD|A(0), do_rand},
4564 {"return", Op_K_return, LEX_RETURN, NOT_OLD, 0},
4565 {"rshift", Op_builtin, LEX_BUILTIN, GAWKX|A(2), do_rshift},
4566 {"sin", Op_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_sin},
4567 {"split", Op_builtin, LEX_BUILTIN, A(2)|A(3)|A(4), do_split},
4568 {"sprintf", Op_builtin, LEX_BUILTIN, 0, do_sprintf},
4569 {"sqrt", Op_builtin, LEX_BUILTIN, A(1), do_sqrt},
4570 {"srand", Op_builtin, LEX_BUILTIN, NOT_OLD|A(0)|A(1), do_srand},
4571 #if defined(GAWKDEBUG) || defined(ARRAYDEBUG) /* || ... */
4572 {"stopme", Op_builtin, LEX_BUILTIN, GAWKX|A(0), stopme},
4574 {"strftime", Op_builtin, LEX_BUILTIN, GAWKX|A(0)|A(1)|A(2)|A(3), do_strftime},
4575 {"strtonum", Op_builtin, LEX_BUILTIN, GAWKX|A(1), do_strtonum},
4576 {"sub", Op_sub_builtin, LEX_BUILTIN, NOT_OLD|A(2)|A(3), 0},
4577 {"substr", Op_builtin, LEX_BUILTIN, A(2)|A(3), do_substr},
4578 {"switch", Op_K_switch, LEX_SWITCH, GAWKX|BREAK, 0},
4579 {"system", Op_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_system},
4580 {"systime", Op_builtin, LEX_BUILTIN, GAWKX|A(0), do_systime},
4581 {"tolower", Op_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_tolower},
4582 {"toupper", Op_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_toupper},
4583 {"while", Op_K_while, LEX_WHILE, BREAK|CONTINUE, 0},
4584 {"xor", Op_builtin, LEX_BUILTIN, GAWKX|A(2), do_xor},
4588 /* Variable containing the current shift state. */
4589 static mbstate_t cur_mbstate;
4590 /* Ring buffer containing current characters. */
4591 #define MAX_CHAR_IN_RING_BUFFER 8
4592 #define RING_BUFFER_SIZE (MAX_CHAR_IN_RING_BUFFER * MB_LEN_MAX)
4593 static char cur_char_ring[RING_BUFFER_SIZE];
4594 /* Index for ring buffers. */
4595 static int cur_ring_idx;
4596 /* This macro means that last nextc() return a singlebyte character
4597 or 1st byte of a multibyte character. */
4598 #define nextc_is_1stbyte (cur_char_ring[cur_ring_idx] == 1)
4599 #else /* MBS_SUPPORT */
4601 #define nextc_is_1stbyte 1
4602 #endif /* MBS_SUPPORT */
4604 /* getfname --- return name of a builtin function (for pretty printing) */
4607 getfname(NODE *(*fptr)(int))
4611 j = sizeof(tokentab) / sizeof(tokentab[0]);
4612 /* linear search, no other way to do it */
4613 for (i = 0; i < j; i++)
4614 if (tokentab[i].ptr == fptr)
4615 return tokentab[i].operator;
4620 /* print_included_from --- print `Included from ..' file names and locations */
4623 print_included_from()
4628 /* suppress current file name, line # from `.. included from ..' msgs */
4629 saveline = sourceline;
4632 for (s = sourcefile; s != NULL && s->stype == SRC_INC; ) {
4634 if (s == NULL || s->fd <= INVALID_HANDLE)
4638 /* if last token is NEWLINE, line number is off by 1. */
4639 if (s->lasttok == NEWLINE)
4642 s->prev == sourcefile ? "In file included from"
4644 (s->stype == SRC_INC ||
4645 s->stype == SRC_FILE) ? s->src : "cmd. line",
4647 s->stype == SRC_INC ? ',' : ':'
4650 sourceline = saveline;
4653 /* warning_ln --- print a warning message with location */
4656 warning_ln(int line, const char *mesg, ...)
4661 saveline = sourceline;
4663 print_included_from();
4664 va_start(args, mesg);
4665 err(_("warning: "), mesg, args);
4667 sourceline = saveline;
4670 /* lintwarn_ln --- print a lint warning and location */
4673 lintwarn_ln(int line, const char *mesg, ...)
4678 saveline = sourceline;
4680 print_included_from();
4681 va_start(args, mesg);
4682 if (lintfunc == r_fatal)
4683 err(_("fatal: "), mesg, args);
4685 err(_("warning: "), mesg, args);
4687 sourceline = saveline;
4688 if (lintfunc == r_fatal)
4689 gawk_exit(EXIT_FATAL);
4692 /* error_ln --- print an error message and location */
4695 error_ln(int line, const char *m, ...)
4700 saveline = sourceline;
4702 print_included_from();
4705 err("error: ", m, args);
4707 sourceline = saveline;
4710 /* yyerror --- print a syntax error message, show where */
4713 yyerror(const char *m, ...)
4716 const char *mesg = NULL;
4721 static char end_of_file_line[] = "(END OF FILE)";
4724 print_included_from();
4727 /* Find the current line in the input file */
4728 if (lexptr && lexeme) {
4729 if (thisline == NULL) {
4733 mesg = _("unexpected newline or end of string");
4735 for (; cp != lexptr_begin && *cp != '\n'; --cp)
4741 /* NL isn't guaranteed */
4743 while (bp < lexend && *bp && *bp != '\n')
4746 thisline = end_of_file_line;
4747 bp = thisline + strlen(thisline);
4751 * Saving and restoring *bp keeps valgrind happy,
4752 * since the guts of glibc uses strlen, even though
4753 * we're passing an explict precision. Sigh.
4755 * 8/2003: We may not need this anymore.
4760 msg("%.*s", (int) (bp - thisline), thisline);
4767 count = (bp - thisline) + strlen(mesg) + 2 + 1;
4768 emalloc(buf, char *, count, "yyerror");
4772 if (lexptr != NULL) {
4774 while (scan < lexeme)
4775 if (*scan++ == '\t')
4788 /* mk_program --- create a single list of instructions */
4790 static INSTRUCTION *
4793 INSTRUCTION *cp, *tmp;
4795 #define begin_block rule_block[BEGIN]
4796 #define end_block rule_block[END]
4797 #define prog_block rule_block[Rule]
4798 #define beginfile_block rule_block[BEGINFILE]
4799 #define endfile_block rule_block[ENDFILE]
4801 if (end_block == NULL)
4802 end_block = list_create(ip_end);
4804 (void) list_prepend(end_block, ip_end);
4806 if (! in_main_context()) {
4807 if (begin_block != NULL && prog_block != NULL)
4808 cp = list_merge(begin_block, prog_block);
4810 cp = (begin_block != NULL) ? begin_block : prog_block;
4813 (void) list_merge(cp, end_block);
4817 (void) list_append(cp, instruction(Op_stop));
4821 if (endfile_block == NULL)
4822 endfile_block = list_create(ip_endfile);
4824 ip_rec->has_endfile = TRUE;
4825 (void) list_prepend(endfile_block, ip_endfile);
4828 if (beginfile_block == NULL)
4829 beginfile_block = list_create(ip_beginfile);
4831 (void) list_prepend(beginfile_block, ip_beginfile);
4833 if (prog_block == NULL) {
4834 if (end_block->nexti == end_block->lasti
4835 && beginfile_block->nexti == beginfile_block->lasti
4836 && endfile_block->nexti == endfile_block->lasti
4838 /* no pattern-action and (real) end, beginfile or endfile blocks */
4841 ip_rec = ip_newfile = NULL;
4843 list_append(beginfile_block, instruction(Op_after_beginfile));
4844 (void) list_append(endfile_block, instruction(Op_after_endfile));
4846 if (begin_block == NULL) /* no program at all */
4849 cp = list_merge(begin_block, end_block);
4850 (void) list_append(cp, ip_atexit);
4851 (void) list_append(cp, instruction(Op_stop));
4853 /* append beginfile_block and endfile_block for sole use
4854 * in getline without redirection (Op_K_getline).
4857 (void) list_merge(cp, beginfile_block);
4858 (void) list_merge(cp, endfile_block);
4863 /* install a do-nothing prog block */
4864 prog_block = list_create(instruction(Op_no_op));
4868 (void) list_append(endfile_block, instruction(Op_after_endfile));
4869 (void) list_prepend(prog_block, ip_rec);
4870 (void) list_append(prog_block, instruction(Op_jmp));
4871 prog_block->lasti->target_jmp = ip_rec;
4873 list_append(beginfile_block, instruction(Op_after_beginfile));
4875 cp = list_merge(beginfile_block, prog_block);
4876 (void) list_prepend(cp, ip_newfile);
4877 (void) list_merge(cp, endfile_block);
4878 (void) list_merge(cp, end_block);
4879 if (begin_block != NULL)
4880 cp = list_merge(begin_block, cp);
4882 (void) list_append(cp, ip_atexit);
4883 (void) list_append(cp, instruction(Op_stop));
4886 /* delete the Op_list, not needed */
4894 #undef beginfile_block
4895 #undef endfile_block
4898 /* parse_program --- read in the program and convert into a list of instructions */
4901 parse_program(INSTRUCTION **pcode)
4905 /* pre-create non-local jump targets
4906 * ip_end (Op_no_op) -- used as jump target for `exit'
4907 * outside an END block.
4909 ip_end = instruction(Op_no_op);
4911 if (! in_main_context())
4912 ip_newfile = ip_rec = ip_atexit = ip_beginfile = ip_endfile = NULL;
4914 ip_endfile = instruction(Op_no_op);
4915 ip_beginfile = instruction(Op_no_op);
4916 ip_rec = instruction(Op_get_record); /* target for `next', also ip_newfile */
4917 ip_newfile = bcalloc(Op_newfile, 2, 0); /* target for `nextfile' */
4918 ip_newfile->target_jmp = ip_end;
4919 ip_newfile->target_endfile = ip_endfile;
4920 (ip_newfile + 1)->target_get_record = ip_rec;
4921 ip_rec->target_newfile = ip_newfile;
4922 ip_atexit = instruction(Op_atexit); /* target for `exit' in END block */
4925 sourcefile = srcfiles->next;
4929 memset(rule_block, 0, sizeof(ruletab) * sizeof(INSTRUCTION *));
4931 tok = tokstart != NULL ? tokstart : tokexpand();
4934 *pcode = mk_program();
4936 /* avoid false source indications */
4939 if (ret == 0) /* avoid spurious warning if parser aborted with YYABORT */
4942 return (ret || errcount);
4945 /* do_add_srcfile --- add one item to srcfiles */
4948 do_add_srcfile(int stype, char *src, char *path, SRCFILE *thisfile)
4952 emalloc(s, SRCFILE *, sizeof(SRCFILE), "do_add_srcfile");
4953 memset(s, 0, sizeof(SRCFILE));
4954 s->src = estrdup(src, strlen(src));
4957 s->fd = INVALID_HANDLE;
4959 s->prev = thisfile->prev;
4960 thisfile->prev->next = s;
4965 /* add_srcfile --- add one item to srcfiles after checking if
4966 * a source file exists and not already in list.
4970 add_srcfile(int stype, char *src, SRCFILE *thisfile, int *already_included, int *errcode)
4977 if (already_included)
4978 *already_included = FALSE;
4981 if (stype == SRC_CMDLINE || stype == SRC_STDIN)
4982 return do_add_srcfile(stype, src, NULL, thisfile);
4984 path = find_source(src, &sbuf, &errno_val);
4987 *errcode = errno_val;
4990 fatal(_("can't open source file `%s' for reading (%s)"),
4991 src, errno_val ? strerror(errno_val) : _("reason unknown"));
4994 for (s = srcfiles->next; s != srcfiles; s = s->next) {
4995 if ((s->stype == SRC_FILE || s->stype == SRC_INC)
4996 && files_are_same(path, s)
4999 int line = sourceline;
5000 /* Kludge: the line number may be off for `@include file'.
5001 * Since, this function is also used for '-f file' in main.c,
5002 * sourceline > 1 check ensures that the call is at
5005 if (sourceline > 1 && lasttok == NEWLINE)
5007 lintwarn_ln(line, _("already included source file `%s'"), src);
5010 if (already_included)
5011 *already_included = TRUE;
5016 s = do_add_srcfile(stype, src, path, thisfile);
5018 s->mtime = sbuf.st_mtime;
5022 /* include_source --- read program from source included using `@include' */
5025 include_source(INSTRUCTION *file)
5028 char *src = file->lextok;
5030 int already_included;
5032 if (do_traditional || do_posix) {
5033 error_ln(file->source_line, _("@include is a gawk extension"));
5037 if (strlen(src) == 0) {
5039 lintwarn_ln(file->source_line, _("empty filename after @include"));
5043 s = add_srcfile(SRC_INC, src, sourcefile, &already_included, &errcode);
5045 if (already_included)
5047 error_ln(file->source_line,
5048 _("can't open source file `%s' for reading (%s)"),
5049 src, errcode ? strerror(errcode) : _("reason unknown"));
5053 /* save scanner state for the current sourcefile */
5054 sourcefile->srclines = sourceline;
5055 sourcefile->lexptr = lexptr;
5056 sourcefile->lexend = lexend;
5057 sourcefile->lexptr_begin = lexptr_begin;
5058 sourcefile->lexeme = lexeme;
5059 sourcefile->lasttok = lasttok;
5061 /* included file becomes the current source */
5072 /* next_sourcefile --- read program from the next source in srcfiles */
5077 static int (*closefunc)(int fd) = NULL;
5079 if (closefunc == NULL) {
5080 char *cp = getenv("AWKREADFUNC");
5082 /* If necessary, one day, test value for different functions. */
5086 closefunc = one_line_close;
5090 * This won't be true if there's an invalid character in
5091 * the source file or source string (e.g., user typo).
5092 * Previous versions of gawk did not core dump in such a
5095 * assert(lexeof == TRUE);
5099 sourcefile->srclines = sourceline; /* total no of lines in current file */
5100 if (sourcefile->fd > INVALID_HANDLE) {
5101 if (sourcefile->fd != fileno(stdin)) /* safety */
5102 (*closefunc)(sourcefile->fd);
5103 sourcefile->fd = INVALID_HANDLE;
5105 if (sourcefile->buf != NULL) {
5106 efree(sourcefile->buf);
5107 sourcefile->buf = NULL;
5108 sourcefile->lexptr_begin = NULL;
5111 sourcefile = sourcefile->next;
5112 if (sourcefile == srcfiles)
5115 if (sourcefile->lexptr_begin != NULL) {
5116 /* resume reading from already opened file (postponed to process '@include') */
5117 lexptr = sourcefile->lexptr;
5118 lexend = sourcefile->lexend;
5119 lasttok = sourcefile->lasttok;
5120 lexptr_begin = sourcefile->lexptr_begin;
5121 lexeme = sourcefile->lexeme;
5122 sourceline = sourcefile->srclines;
5123 source = sourcefile->src;
5132 /* get_src_buf --- read the next buffer of source program */
5144 * No argument prototype on readfunc on purpose,
5145 * avoids problems with some ancient systems where
5146 * the types of arguments to read() aren't up to date.
5148 static ssize_t (*readfunc)() = 0;
5150 if (readfunc == NULL) {
5151 char *cp = getenv("AWKREADFUNC");
5153 /* If necessary, one day, test value for different functions. */
5156 * cast is to remove warnings on systems with
5157 * different return types for read.
5159 readfunc = ( ssize_t(*)() ) read;
5161 readfunc = read_one_line;
5165 if (sourcefile == srcfiles)
5168 if (sourcefile->stype == SRC_CMDLINE) {
5169 if (sourcefile->bufsize == 0) {
5170 sourcefile->bufsize = strlen(sourcefile->src);
5171 lexptr = lexptr_begin = lexeme = sourcefile->src;
5172 lexend = lexptr + sourcefile->bufsize;
5174 if (sourcefile->bufsize == 0) {
5176 * Yet Another Special case:
5177 * gawk '' /path/name
5180 static short warned = FALSE;
5182 if (do_lint && ! warned) {
5184 lintwarn(_("empty program text on command line"));
5188 } else if (sourcefile->buf == NULL && *(lexptr-1) != '\n') {
5190 * The following goop is to ensure that the source
5191 * ends with a newline and that the entire current
5192 * line is available for error messages.
5197 offset = lexptr - lexeme;
5198 for (scan = lexeme; scan > lexptr_begin; scan--)
5199 if (*scan == '\n') {
5203 savelen = lexptr - scan;
5204 emalloc(buf, char *, savelen + 1, "get_src_buf");
5205 memcpy(buf, scan, savelen);
5207 lexptr = buf + savelen;
5209 lexeme = lexptr - offset;
5211 lexend = lexptr + 1;
5212 sourcefile->buf = buf;
5218 if (sourcefile->fd <= INVALID_HANDLE) {
5222 source = sourcefile->src;
5225 fd = srcopen(sourcefile);
5226 if (fd <= INVALID_HANDLE) {
5229 /* suppress file name and line no. in error mesg */
5232 error(_("can't open source file `%s' for reading (%s)"),
5233 in, strerror(errno));
5236 return sourcefile->src;
5239 sourcefile->fd = fd;
5240 l = optimal_bufsize(fd, &sbuf);
5242 * Make sure that something silly like
5243 * AWKBUFSIZE=8 make check
5246 #define A_DECENT_BUFFER_SIZE 128
5247 if (l < A_DECENT_BUFFER_SIZE)
5248 l = A_DECENT_BUFFER_SIZE;
5249 #undef A_DECENT_BUFFER_SIZE
5250 sourcefile->bufsize = l;
5252 emalloc(sourcefile->buf, char *, sourcefile->bufsize, "get_src_buf");
5253 lexptr = lexptr_begin = lexeme = sourcefile->buf;
5259 * Here, we retain the current source line in the beginning of the buffer.
5262 for (scan = lexeme; scan > lexptr_begin; scan--)
5263 if (*scan == '\n') {
5268 savelen = lexptr - scan;
5269 offset = lexptr - lexeme;
5273 * Need to make sure we have room left for reading new text;
5274 * grow the buffer (by doubling, an arbitrary choice), if the retained line
5275 * takes up more than a certain percentage (50%, again an arbitrary figure)
5276 * of the available space.
5279 if (savelen > sourcefile->bufsize / 2) { /* long line or token */
5280 sourcefile->bufsize *= 2;
5281 erealloc(sourcefile->buf, char *, sourcefile->bufsize, "get_src_buf");
5282 scan = sourcefile->buf + (scan - lexptr_begin);
5283 lexptr_begin = sourcefile->buf;
5286 thisline = lexptr_begin;
5287 memmove(thisline, scan, savelen);
5288 lexptr = thisline + savelen;
5289 lexeme = lexptr - offset;
5292 lexptr = lexeme = lexptr_begin;
5297 n = (*readfunc)(sourcefile->fd, lexptr, sourcefile->bufsize - savelen);
5299 error(_("can't read sourcefile `%s' (%s)"),
5300 source, strerror(errno));
5304 lexend = lexptr + n;
5306 static short warned = FALSE;
5307 if (do_lint && newfile && ! warned){
5310 lintwarn(_("source file `%s' is empty"), source);
5315 return sourcefile->buf;
5318 /* tokadd --- add a character to the token buffer */
5320 #define tokadd(x) (*tok++ = (x), tok == tokend ? tokexpand() : tok)
5322 /* tokexpand --- grow the token buffer */
5330 if (tokstart != NULL) {
5331 tokoffset = tok - tokstart;
5333 erealloc(tokstart, char *, toksize, "tokexpand");
5334 tok = tokstart + tokoffset;
5337 emalloc(tokstart, char *, toksize, "tokexpand");
5340 tokend = tokstart + toksize;
5344 /* nextc --- get the next input character */
5351 if (gawk_mb_cur_max > 1) {
5355 if (lexptr == NULL || lexptr >= lexend) {
5361 /* Update the buffer index. */
5362 cur_ring_idx = (cur_ring_idx == RING_BUFFER_SIZE - 1)? 0 :
5365 /* Did we already check the current character? */
5366 if (cur_char_ring[cur_ring_idx] == 0) {
5367 /* No, we need to check the next character on the buffer. */
5368 int idx, work_ring_idx = cur_ring_idx;
5369 mbstate_t tmp_state;
5372 for (idx = 0 ; lexptr + idx < lexend ; idx++) {
5373 tmp_state = cur_mbstate;
5374 mbclen = mbrlen(lexptr, idx + 1, &tmp_state);
5376 if (mbclen == 1 || mbclen == (size_t)-1 || mbclen == 0) {
5377 /* It is a singlebyte character, non-complete multibyte
5378 character or EOF. We treat it as a singlebyte
5380 cur_char_ring[work_ring_idx] = 1;
5382 } else if (mbclen == (size_t)-2) {
5383 /* It is not a complete multibyte character. */
5384 cur_char_ring[work_ring_idx] = idx + 1;
5387 cur_char_ring[work_ring_idx] = mbclen;
5390 work_ring_idx = (work_ring_idx == RING_BUFFER_SIZE - 1)?
5391 0 : work_ring_idx + 1;
5393 cur_mbstate = tmp_state;
5395 /* Put a mark on the position on which we write next character. */
5396 work_ring_idx = (work_ring_idx == RING_BUFFER_SIZE - 1)?
5397 0 : work_ring_idx + 1;
5398 cur_char_ring[work_ring_idx] = 0;
5401 return (int) (unsigned char) *lexptr++;
5406 if (lexptr && lexptr < lexend)
5407 return ((int) (unsigned char) *lexptr++);
5408 } while (get_src_buf());
5413 #else /* MBS_SUPPORT */
5421 if (lexptr && lexptr < lexend)
5422 return ((int) (unsigned char) *lexptr++);
5423 } while (get_src_buf());
5427 #endif /* MBS_SUPPORT */
5429 /* pushback --- push a character back on the input */
5435 if (gawk_mb_cur_max > 1)
5436 cur_ring_idx = (cur_ring_idx == 0)? RING_BUFFER_SIZE - 1 :
5439 (! lexeof && lexptr && lexptr > lexptr_begin ? lexptr-- : lexptr);
5443 /* allow_newline --- allow newline after &&, ||, ? and : */
5452 if (c == END_FILE) {
5457 while ((c = nextc()) != '\n' && c != END_FILE)
5459 if (c == END_FILE) {
5473 /* newline_eof --- return newline or EOF as needed and adjust variables */
5476 * This routine used to be a macro, however GCC 4.6.2 warned about
5477 * the result of a computation not being used. Converting to a function
5478 * removes the warnings.
5481 static int newline_eof()
5483 /* NB: a newline at end does not start a source line. */
5484 if (lasttok != NEWLINE) {
5486 if (do_lint && ! eof_warned) {
5487 lintwarn(_("source file does not end in newline"));
5499 /* yylex --- Read the input and turn it into tokens. */
5505 int seen_e = FALSE; /* These are for numbers */
5506 int seen_point = FALSE;
5507 int esc_seen; /* for literal strings */
5509 static int did_newline = FALSE;
5512 int intlstr = FALSE;
5514 #define GET_INSTRUCTION(op) bcalloc(op, 1, sourceline)
5516 #define NEWLINE_EOF newline_eof()
5518 yylval = (INSTRUCTION *) NULL;
5519 if (lasttok == SUBSCRIPT) {
5524 if (lasttok == LEX_EOF) /* error earlier in current source, must give up !! */
5531 return lasttok = NEWLINE_EOF;
5536 * added for OS/2's extproc feature of cmd.exe
5537 * (like #! in BSD sh)
5539 if (strncasecmp(lexptr, "extproc ", 8) == 0) {
5540 while (*lexptr && *lexptr != '\n')
5548 int in_brack = 0; /* count brackets, [[:alnum:]] allowed */
5550 * Counting brackets is non-trivial. [[] is ok,
5551 * and so is [\]], with a point being that /[/]/ as a regexp
5552 * constant has to work.
5554 * Do not count [ or ] if either one is preceded by a \.
5555 * A `[' should be counted if
5556 * a) it is the first one so far (in_brack == 0)
5557 * b) it is the `[' in `[:'
5558 * A ']' should be counted if not preceded by a \, since
5559 * it is either closing `:]' or just a plain list.
5560 * According to POSIX, []] is how you put a ] into a set.
5561 * Try to handle that too.
5563 * The code for \ handles \[ and \].
5566 want_regexp = FALSE;
5571 if (gawk_mb_cur_max == 1 || nextc_is_1stbyte) switch (c) {
5573 /* one day check for `.' and `=' too */
5574 if (nextc() == ':' || in_brack == 0)
5579 if (tokstart[0] == '['
5580 && (tok == tokstart + 1
5581 || (tok == tokstart + 2
5582 && tokstart[1] == '^')))
5588 if ((c = nextc()) == END_FILE) {
5590 yyerror(_("unterminated regexp ends with `\\' at end of file"));
5591 goto end_regexp; /* kludge */
5592 } else if (c == '\n') {
5601 case '/': /* end of the regexp */
5605 yylval = GET_INSTRUCTION(Op_token);
5606 yylval->lextok = estrdup(tokstart, tok - tokstart);
5611 if (peek == 'i' || peek == 's') {
5614 _("%s: %d: tawk regex modifier `/.../%c' doesn't work in gawk"),
5615 source, sourceline, peek);
5618 _("tawk regex modifier `/.../%c' doesn't work in gawk"),
5622 return lasttok = REGEXP;
5625 yyerror(_("unterminated regexp"));
5626 goto end_regexp; /* kludge */
5629 yyerror(_("unterminated regexp at end of file"));
5630 goto end_regexp; /* kludge */
5637 /* skipping \r is a hack, but windows is just too pervasive. sigh. */
5638 while ((c = nextc()) == ' ' || c == '\t' || c == '\r')
5641 lexeme = lexptr ? lexptr - 1 : lexptr;
5646 if (gawk_mb_cur_max == 1 || nextc_is_1stbyte)
5653 return lasttok = NEWLINE_EOF;
5657 return lasttok = NEWLINE;
5659 case '#': /* it's a comment */
5660 while ((c = nextc()) != '\n') {
5662 return lasttok = NEWLINE_EOF;
5665 return lasttok = NEWLINE;
5668 return lasttok = '@';
5671 #ifdef RELAXED_CONTINUATION
5673 * This code puports to allow comments and/or whitespace
5674 * after the `\' at the end of a line used for continuation.
5675 * Use it at your own risk. We think it's a bad idea, which
5676 * is why it's not on by default.
5678 if (! do_traditional) {
5679 /* strip trailing white-space and/or comment */
5680 while ((c = nextc()) == ' ' || c == '\t' || c == '\r')
5683 static short warned = FALSE;
5685 if (do_lint && ! warned) {
5688 _("use of `\\ #...' line continuation is not portable"));
5690 while ((c = nextc()) != '\n')
5696 #endif /* RELAXED_CONTINUATION */
5698 if (c == '\r') /* allow MS-DOS files. bleah */
5704 yyerror(_("backslash not last character on line"));
5705 return lasttok = LEX_EOF;
5711 yylval = GET_INSTRUCTION(Op_cond_exp);
5717 * in_parens is undefined unless we are parsing a print
5718 * statement (in_print), but why bother with a check?
5728 yylval = GET_INSTRUCTION(Op_field_spec);
5731 if (++in_braces == 1)
5732 firstline = sourceline;
5741 yylval = GET_INSTRUCTION(Op_sub_array);
5744 yylval = GET_INSTRUCTION(Op_subscript);
5745 lasttok = SUBSCRIPT; /* end of subscripts */
5750 if ((c = nextc()) == '=') {
5751 yylval = GET_INSTRUCTION(Op_assign_times);
5752 return lasttok = ASSIGNOP;
5753 } else if (do_posix) {
5755 yylval = GET_INSTRUCTION(Op_times);
5756 return lasttok = '*';
5757 } else if (c == '*') {
5758 /* make ** and **= aliases for ^ and ^= */
5759 static int did_warn_op = FALSE, did_warn_assgn = FALSE;
5761 if (nextc() == '=') {
5762 if (! did_warn_assgn) {
5763 did_warn_assgn = TRUE;
5765 lintwarn(_("POSIX does not allow operator `**='"));
5767 warning(_("old awk does not support operator `**='"));
5769 yylval = GET_INSTRUCTION(Op_assign_exp);
5773 if (! did_warn_op) {
5776 lintwarn(_("POSIX does not allow operator `**'"));
5778 warning(_("old awk does not support operator `**'"));
5780 yylval = GET_INSTRUCTION(Op_exp);
5781 return lasttok = '^';
5785 yylval = GET_INSTRUCTION(Op_times);
5786 return lasttok = '*';
5789 if (nextc() == '=') {
5791 return lasttok = SLASH_BEFORE_EQUAL;
5794 yylval = GET_INSTRUCTION(Op_quotient);
5795 return lasttok = '/';
5798 if (nextc() == '=') {
5799 yylval = GET_INSTRUCTION(Op_assign_mod);
5800 return lasttok = ASSIGNOP;
5803 yylval = GET_INSTRUCTION(Op_mod);
5804 return lasttok = '%';
5808 static int did_warn_op = FALSE, did_warn_assgn = FALSE;
5810 if (nextc() == '=') {
5811 if (do_lint_old && ! did_warn_assgn) {
5812 did_warn_assgn = TRUE;
5813 warning(_("operator `^=' is not supported in old awk"));
5815 yylval = GET_INSTRUCTION(Op_assign_exp);
5816 return lasttok = ASSIGNOP;
5819 if (do_lint_old && ! did_warn_op) {
5821 warning(_("operator `^' is not supported in old awk"));
5823 yylval = GET_INSTRUCTION(Op_exp);
5824 return lasttok = '^';
5828 if ((c = nextc()) == '=') {
5829 yylval = GET_INSTRUCTION(Op_assign_plus);
5830 return lasttok = ASSIGNOP;
5833 yylval = GET_INSTRUCTION(Op_symbol);
5834 return lasttok = INCREMENT;
5837 yylval = GET_INSTRUCTION(Op_plus);
5838 return lasttok = '+';
5841 if ((c = nextc()) == '=') {
5842 yylval = GET_INSTRUCTION(Op_notequal);
5843 return lasttok = RELOP;
5846 yylval = GET_INSTRUCTION(Op_nomatch);
5847 return lasttok = MATCHOP;
5850 yylval = GET_INSTRUCTION(Op_symbol);
5851 return lasttok = '!';
5854 if (nextc() == '=') {
5855 yylval = GET_INSTRUCTION(Op_leq);
5856 return lasttok = RELOP;
5858 yylval = GET_INSTRUCTION(Op_less);
5860 return lasttok = '<';
5863 if (nextc() == '=') {
5864 yylval = GET_INSTRUCTION(Op_equal);
5865 return lasttok = RELOP;
5867 yylval = GET_INSTRUCTION(Op_assign);
5869 return lasttok = ASSIGN;
5872 if ((c = nextc()) == '=') {
5873 yylval = GET_INSTRUCTION(Op_geq);
5874 return lasttok = RELOP;
5875 } else if (c == '>') {
5876 yylval = GET_INSTRUCTION(Op_symbol);
5877 yylval->redir_type = redirect_append;
5878 return lasttok = IO_OUT;
5881 if (in_print && in_parens == 0) {
5882 yylval = GET_INSTRUCTION(Op_symbol);
5883 yylval->redir_type = redirect_output;
5884 return lasttok = IO_OUT;
5886 yylval = GET_INSTRUCTION(Op_greater);
5887 return lasttok = '>';
5890 yylval = GET_INSTRUCTION(Op_match);
5891 return lasttok = MATCHOP;
5895 * Added did newline stuff. Easier than
5896 * hacking the grammar.
5899 did_newline = FALSE;
5900 if (--in_braces == 0)
5901 lastline = sourceline;
5905 --lexptr; /* pick up } next time */
5906 return lasttok = NEWLINE;
5911 while ((c = nextc()) != '"') {
5914 yyerror(_("unterminated string"));
5915 return lasttok = LEX_EOF;
5917 if ((gawk_mb_cur_max == 1 || nextc_is_1stbyte) &&
5925 if (! want_source || c != '"')
5928 if (c == END_FILE) {
5930 yyerror(_("unterminated string"));
5931 return lasttok = LEX_EOF;
5935 yylval = GET_INSTRUCTION(Op_token);
5937 yylval->lextok = estrdup(tokstart, tok - tokstart);
5938 return lasttok = FILENAME;
5941 yylval->opcode = Op_push_i;
5942 yylval->memory = make_str_node(tokstart,
5943 tok - tokstart, esc_seen ? SCAN : 0);
5944 yylval->memory->flags &= ~MALLOC;
5945 yylval->memory->flags |= PERM;
5947 yylval->memory->flags |= INTLSTR;
5950 dumpintlstr(yylval->memory->stptr, yylval->memory->stlen);
5952 return lasttok = YSTRING;
5955 if ((c = nextc()) == '=') {
5956 yylval = GET_INSTRUCTION(Op_assign_minus);
5957 return lasttok = ASSIGNOP;
5960 yylval = GET_INSTRUCTION(Op_symbol);
5961 return lasttok = DECREMENT;
5964 yylval = GET_INSTRUCTION(Op_minus);
5965 return lasttok = '-';
5971 return lasttok = '.';
5987 int gotnumber = FALSE;
5995 if (tok == tokstart + 2) {
5998 if (isxdigit(peek)) {
6000 pushback(); /* following digit */
6002 pushback(); /* x or X */
6008 /* period ends exponent part of floating point number */
6009 if (seen_point || seen_e) {
6024 if ((c = nextc()) == '-' || c == '+') {
6031 pushback(); /* non-digit after + or - */
6032 pushback(); /* + or - */
6033 pushback(); /* e or E */
6035 } else if (! isdigit(c)) {
6036 pushback(); /* character after e or E */
6037 pushback(); /* e or E */
6039 pushback(); /* digit */
6052 if (do_traditional || ! inhex)
6077 yylval = GET_INSTRUCTION(Op_push_i);
6078 if (! do_traditional && isnondecimal(tokstart, FALSE)) {
6080 if (isdigit((unsigned char) tokstart[1])) /* not an 'x' or 'X' */
6081 lintwarn("numeric constant `%.*s' treated as octal",
6082 (int) strlen(tokstart)-1, tokstart);
6083 else if (tokstart[1] == 'x' || tokstart[1] == 'X')
6084 lintwarn("numeric constant `%.*s' treated as hexadecimal",
6085 (int) strlen(tokstart)-1, tokstart);
6087 yylval->memory = mk_number(nondec2awknum(tokstart, strlen(tokstart)),
6088 PERM|NUMCUR|NUMBER);
6090 yylval->memory = mk_number(atof(tokstart), PERM|NUMCUR|NUMBER);
6091 return lasttok = YNUMBER;
6094 if ((c = nextc()) == '&') {
6095 yylval = GET_INSTRUCTION(Op_and);
6097 return lasttok = LEX_AND;
6100 yylval = GET_INSTRUCTION(Op_symbol);
6101 return lasttok = '&';
6104 if ((c = nextc()) == '|') {
6105 yylval = GET_INSTRUCTION(Op_or);
6107 return lasttok = LEX_OR;
6108 } else if (! do_traditional && c == '&') {
6109 yylval = GET_INSTRUCTION(Op_symbol);
6110 yylval->redir_type = redirect_twoway;
6111 return lasttok = (in_print && in_parens == 0 ? IO_OUT : IO_IN);
6114 if (in_print && in_parens == 0) {
6115 yylval = GET_INSTRUCTION(Op_symbol);
6116 yylval->redir_type = redirect_pipe;
6117 return lasttok = IO_OUT;
6119 yylval = GET_INSTRUCTION(Op_symbol);
6120 yylval->redir_type = redirect_pipein;
6121 return lasttok = IO_IN;
6125 if (c != '_' && ! isalpha(c)) {
6126 yyerror(_("invalid char '%c' in expression"), c);
6127 return lasttok = LEX_EOF;
6131 * Lots of fog here. Consider:
6133 * print "xyzzy"$_"foo"
6135 * Without the check for ` lasttok != '$' ', this is parsed as
6137 * print "xxyzz" $(_"foo")
6139 * With the check, it is "correctly" parsed as three
6140 * string concatenations. Sigh. This seems to be
6141 * "more correct", but this is definitely one of those
6142 * occasions where the interactions are funny.
6144 if (! do_traditional && c == '_' && lasttok != '$') {
6145 if ((c = nextc()) == '"') {
6153 /* it's some type of name-type-thing. Find its length. */
6155 while (c != END_FILE && is_identchar(c)) {
6162 /* See if it is a special token. */
6163 if ((mid = check_special(tokstart)) >= 0) {
6164 static int warntab[sizeof(tokentab) / sizeof(tokentab[0])];
6165 int class = tokentab[mid].class;
6167 if ((class == LEX_INCLUDE || class == LEX_EVAL)
6172 if ((tokentab[mid].flags & GAWKX) && ! (warntab[mid] & GAWKX)) {
6173 lintwarn(_("`%s' is a gawk extension"),
6174 tokentab[mid].operator);
6175 warntab[mid] |= GAWKX;
6177 if ((tokentab[mid].flags & RESX) && ! (warntab[mid] & RESX)) {
6178 lintwarn(_("`%s' is a Bell Labs extension"),
6179 tokentab[mid].operator);
6180 warntab[mid] |= RESX;
6182 if ((tokentab[mid].flags & NOT_POSIX) && ! (warntab[mid] & NOT_POSIX)) {
6183 lintwarn(_("POSIX does not allow `%s'"),
6184 tokentab[mid].operator);
6185 warntab[mid] |= NOT_POSIX;
6188 if (do_lint_old && (tokentab[mid].flags & NOT_OLD)
6189 && ! (warntab[mid] & NOT_OLD)
6191 warning(_("`%s' is not supported in old awk"),
6192 tokentab[mid].operator);
6193 warntab[mid] |= NOT_OLD;
6196 if (tokentab[mid].flags & BREAK)
6198 if (tokentab[mid].flags & CONTINUE)
6206 if (in_main_context())
6208 emalloc(tokkey, char *, tok - tokstart + 1, "yylex");
6210 memcpy(tokkey + 1, tokstart, tok - tokstart);
6211 yylval = GET_INSTRUCTION(Op_token);
6212 yylval->lextok = tokkey;
6220 yylval = bcalloc(tokentab[mid].value, 3, sourceline);
6228 return lasttok = class;
6231 yylval = bcalloc(tokentab[mid].value, 2, sourceline);
6235 yylval = GET_INSTRUCTION(tokentab[mid].value);
6236 if (class == LEX_BUILTIN || class == LEX_LENGTH)
6237 yylval->builtin_idx = mid;
6240 return lasttok = class;
6243 tokkey = estrdup(tokstart, tok - tokstart);
6244 if (*lexptr == '(') {
6245 yylval = bcalloc(Op_token, 2, sourceline);
6246 yylval->lextok = tokkey;
6247 return lasttok = FUNC_CALL;
6249 static short goto_warned = FALSE;
6251 yylval = GET_INSTRUCTION(Op_token);
6252 yylval->lextok = tokkey;
6254 #define SMART_ALECK 1
6255 if (SMART_ALECK && do_lint
6256 && ! goto_warned && strcasecmp(tokkey, "goto") == 0) {
6258 lintwarn(_("`goto' considered harmful!\n"));
6260 return lasttok = NAME;
6263 #undef GET_INSTRUCTION
6267 /* mk_symbol --- allocates a symbol for the symbol table. */
6270 mk_symbol(NODETYPE type, NODE *value)
6279 r->parent_array = NULL;
6280 r->var_assign = (Func_ptr) 0;
6284 /* snode --- instructions for builtin functions. Checks for arg. count
6285 and supplies defaults where possible. */
6287 static INSTRUCTION *
6288 snode(INSTRUCTION *subn, INSTRUCTION *r)
6295 int idx = r->builtin_idx;
6299 for (tp = subn->nexti; tp; tp = tp->nexti) {
6306 /* check against how many args. are allowed for this builtin */
6307 args_allowed = tokentab[idx].flags & ARGS;
6308 if (args_allowed && (args_allowed & A(nexp)) == 0) {
6309 yyerror(_("%d is invalid as number of arguments for %s"),
6310 nexp, tokentab[idx].operator);
6314 /* special processing for sub, gsub and gensub */
6316 if (tokentab[idx].value == Op_sub_builtin) {
6317 const char *operator = tokentab[idx].operator;
6321 arg = subn->nexti; /* first arg list */
6322 (void) mk_rexp(arg);
6324 if (strcmp(operator, "gensub") != 0) {
6327 if (strcmp(operator, "gsub") == 0)
6328 r->sub_flags |= GSUB;
6330 arg = arg->lasti->nexti; /* 2nd arg list */
6334 expr = list_create(instruction(Op_push_i));
6335 expr->nexti->memory = mk_number((AWKNUM) 0.0, (PERM|NUMCUR|NUMBER));
6336 (void) mk_expression_list(subn,
6337 list_append(expr, instruction(Op_field_spec)));
6340 arg = arg->lasti->nexti; /* third arg list */
6342 if (ip->opcode == Op_push_i) {
6344 lintwarn(_("%s: string literal as last arg of substitute has no effect"),
6346 r->sub_flags |= LITERAL;
6348 if (make_assignable(ip) == NULL)
6349 yyerror(_("%s third parameter is not a changeable object"),
6352 ip->do_reference = TRUE;
6355 r->expr_count = count_expressions(&subn, FALSE);
6358 (void) list_append(subn, r);
6360 /* add after_assign code */
6361 if (ip->opcode == Op_push_lhs && ip->memory->type == Node_var && ip->memory->var_assign) {
6362 (void) list_append(subn, instruction(Op_var_assign));
6363 subn->lasti->assign_ctxt = Op_sub_builtin;
6364 subn->lasti->assign_var = ip->memory->var_assign;
6365 } else if (ip->opcode == Op_field_spec_lhs) {
6366 (void) list_append(subn, instruction(Op_field_assign));
6367 subn->lasti->assign_ctxt = Op_sub_builtin;
6368 subn->lasti->field_assign = (Func_ptr) 0;
6369 ip->target_assign = subn->lasti;
6376 r->sub_flags |= GENSUB;
6378 ip = instruction(Op_push_i);
6379 ip->memory = mk_number((AWKNUM) 0.0, (PERM|NUMCUR|NUMBER));
6380 (void) mk_expression_list(subn,
6381 list_append(list_create(ip), instruction(Op_field_spec)));
6384 r->expr_count = count_expressions(&subn, FALSE);
6385 return list_append(subn, r);
6389 r->builtin = tokentab[idx].ptr;
6391 /* special case processing for a few builtins */
6393 if (r->builtin == do_length) {
6395 /* no args. Use $0 */
6399 list = list_create(r);
6400 (void) list_prepend(list, instruction(Op_field_spec));
6401 (void) list_prepend(list, instruction(Op_push_i));
6402 list->nexti->memory = mk_number((AWKNUM) 0.0, (PERM|NUMCUR|NUMBER));
6406 if (arg->nexti == arg->lasti && arg->nexti->opcode == Op_push)
6407 arg->nexti->opcode = Op_push_arg; /* argument may be array */
6409 } else if (r->builtin == do_isarray) {
6411 if (arg->nexti == arg->lasti && arg->nexti->opcode == Op_push)
6412 arg->nexti->opcode = Op_push_arg; /* argument may be array */
6413 } else if (r->builtin == do_match) {
6414 static short warned = FALSE;
6416 arg = subn->nexti->lasti->nexti; /* 2nd arg list */
6417 (void) mk_rexp(arg);
6419 if (nexp == 3) { /* 3rd argument there */
6420 if (do_lint && ! warned) {
6422 lintwarn(_("match: third argument is a gawk extension"));
6424 if (do_traditional) {
6425 yyerror(_("match: third argument is a gawk extension"));
6429 arg = arg->lasti->nexti; /* third arg list */
6431 if (/*ip == arg->nexti && */ ip->opcode == Op_push)
6432 ip->opcode = Op_push_array;
6434 } else if (r->builtin == do_split) {
6435 arg = subn->nexti->lasti->nexti; /* 2nd arg list */
6437 if (ip->opcode == Op_push)
6438 ip->opcode = Op_push_array;
6441 expr = list_create(instruction(Op_push));
6442 expr->nexti->memory = FS_node;
6443 (void) mk_expression_list(subn, expr);
6445 arg = arg->lasti->nexti;
6448 n->re_flags |= FS_DFLT;
6450 arg = arg->lasti->nexti;
6452 if (ip->opcode == Op_push)
6453 ip->opcode = Op_push_array;
6455 } else if (r->builtin == do_patsplit) {
6456 arg = subn->nexti->lasti->nexti; /* 2nd arg list */
6458 if (ip->opcode == Op_push)
6459 ip->opcode = Op_push_array;
6462 expr = list_create(instruction(Op_push));
6463 expr->nexti->memory = FPAT_node;
6464 (void) mk_expression_list(subn, expr);
6466 arg = arg->lasti->nexti;
6469 arg = arg->lasti->nexti;
6471 if (ip->opcode == Op_push)
6472 ip->opcode = Op_push_array;
6474 } else if (r->builtin == do_close) {
6475 static short warned = FALSE;
6477 if (do_lint && ! warned) {
6479 lintwarn(_("close: second argument is a gawk extension"));
6481 if (do_traditional) {
6482 yyerror(_("close: second argument is a gawk extension"));
6486 } else if (do_intl /* --gen-po */
6487 && r->builtin == do_dcgettext /* dcgettext(...) */
6488 && subn->nexti->lasti->opcode == Op_push_i /* 1st arg is constant */
6489 && (subn->nexti->lasti->memory->flags & STRCUR) != 0) { /* it's a string constant */
6490 /* ala xgettext, dcgettext("some string" ...) dumps the string */
6491 NODE *str = subn->nexti->lasti->memory;
6493 if ((str->flags & INTLSTR) != 0)
6494 warning(_("use of dcgettext(_\"...\") is incorrect: remove leading underscore"));
6495 /* don't dump it, the lexer already did */
6497 dumpintlstr(str->stptr, str->stlen);
6498 } else if (do_intl /* --gen-po */
6499 && r->builtin == do_dcngettext /* dcngettext(...) */
6500 && subn->nexti->lasti->opcode == Op_push_i /* 1st arg is constant */
6501 && (subn->nexti->lasti->memory->flags & STRCUR) != 0 /* it's a string constant */
6502 && subn->nexti->lasti->nexti->lasti->opcode == Op_push_i /* 2nd arg is constant too */
6503 && (subn->nexti->lasti->nexti->lasti->memory->flags & STRCUR) != 0) { /* it's a string constant */
6504 /* ala xgettext, dcngettext("some string", "some plural" ...) dumps the string */
6505 NODE *str1 = subn->nexti->lasti->memory;
6506 NODE *str2 = subn->nexti->lasti->nexti->lasti->memory;
6508 if (((str1->flags | str2->flags) & INTLSTR) != 0)
6509 warning(_("use of dcngettext(_\"...\") is incorrect: remove leading underscore"));
6511 dumpintlstr2(str1->stptr, str1->stlen, str2->stptr, str2->stlen);
6512 } else if (r->builtin == do_asort || r->builtin == do_asorti) {
6513 arg = subn->nexti; /* 1st arg list */
6515 if (ip->opcode == Op_push)
6516 ip->opcode = Op_push_array;
6520 if (ip->opcode == Op_push)
6521 ip->opcode = Op_push_array;
6525 else if (r->builtin == do_adump) {
6526 ip = subn->nexti->lasti;
6527 if (ip->opcode == Op_push)
6528 ip->opcode = Op_push_array;
6533 r->expr_count = count_expressions(&subn, FALSE);
6534 return list_append(subn, r);
6538 return list_create(r);
6541 /* append_param --- append PNAME to the list of parameters
6542 * for the current function.
6546 append_param(char *pname)
6548 static NODE *savetail = NULL;
6551 p = make_param(pname);
6552 if (func_params == NULL) {
6555 } else if (savetail != NULL) {
6556 savetail->rnode = p;
6561 /* dup_parms --- return TRUE if there are duplicate parameters */
6564 dup_parms(INSTRUCTION *fp, NODE *func)
6567 const char *fname, **names;
6568 int count, i, j, dups;
6571 if (func == NULL) /* error earlier */
6574 fname = func->param;
6575 count = func->param_cnt;
6576 params = func->rnode;
6578 if (count == 0) /* no args, no problem */
6581 if (params == NULL) /* error earlier */
6584 emalloc(names, const char **, count * sizeof(char *), "dup_parms");
6587 for (np = params; np != NULL; np = np->rnode) {
6588 if (np->param == NULL) { /* error earlier, give up, go home */
6592 names[i++] = np->param;
6596 for (i = 1; i < count; i++) {
6597 for (j = 0; j < i; j++) {
6598 if (strcmp(names[i], names[j]) == 0) {
6600 error_ln(fp->source_line,
6601 _("function `%s': parameter #%d, `%s', duplicates parameter #%d"),
6602 fname, i + 1, names[j], j+1);
6608 return (dups > 0 ? TRUE : FALSE);
6611 /* parms_shadow --- check if parameters shadow globals */
6614 parms_shadow(INSTRUCTION *pc, int *shadow)
6621 func = pc->func_body;
6622 fname = func->lnode->param;
6624 #if 0 /* can't happen, already exited if error ? */
6625 if (fname == NULL || func == NULL) /* error earlier */
6629 pcount = func->lnode->param_cnt;
6631 if (pcount == 0) /* no args, no problem */
6634 source = pc->source_file;
6635 sourceline = pc->source_line;
6637 * Use warning() and not lintwarn() so that can warn
6638 * about all shadowed parameters.
6640 for (i = 0; i < pcount; i++) {
6641 if (lookup(func->parmlist[i]) != NULL) {
6643 _("function `%s': parameter `%s' shadows global variable"),
6644 fname, func->parmlist[i]);
6656 * Install a name in the symbol table, even if it is already there.
6657 * Caller must check against redefinition if that is desired.
6662 install_symbol(char *name, NODE *value)
6669 (*install_func)(name);
6673 bucket = hash(name, len, (unsigned long) HASHSIZE, NULL);
6675 hp->type = Node_hashnode;
6676 hp->hnext = variables[bucket];
6677 variables[bucket] = hp;
6681 hp->hvalue->vname = name;
6685 /* lookup --- find the most recent hash node for name installed by install_symbol */
6688 lookup(const char *name)
6694 for (bucket = variables[hash(name, len, (unsigned long) HASHSIZE, NULL)];
6695 bucket != NULL; bucket = bucket->hnext)
6696 if (bucket->hlength == len && strncmp(bucket->hname, name, len) == 0)
6697 return bucket->hvalue;
6701 /* sym_comp --- compare two symbol (variable or function) names */
6704 sym_comp(const void *v1, const void *v2)
6706 const NODE *const *npp1, *const *npp2;
6707 const NODE *n1, *n2;
6710 npp1 = (const NODE *const *) v1;
6711 npp2 = (const NODE *const *) v2;
6715 if (n1->hlength > n2->hlength)
6716 minlen = n1->hlength;
6718 minlen = n2->hlength;
6720 return strncmp(n1->hname, n2->hname, minlen);
6723 /* valinfo --- dump var info */
6726 valinfo(NODE *n, int (*print_func)(FILE *, const char *, ...), FILE *fp)
6728 if (n == Nnull_string)
6729 print_func(fp, "uninitialized scalar\n");
6730 else if (n->flags & STRING) {
6731 pp_string_fp(print_func, fp, n->stptr, n->stlen, '"', FALSE);
6732 print_func(fp, "\n");
6733 } else if (n->flags & NUMBER)
6734 print_func(fp, "%.17g\n", n->numbr);
6735 else if (n->flags & STRCUR) {
6736 pp_string_fp(print_func, fp, n->stptr, n->stlen, '"', FALSE);
6737 print_func(fp, "\n");
6738 } else if (n->flags & NUMCUR)
6739 print_func(fp, "%.17g\n", n->numbr);
6741 print_func(fp, "?? flags %s\n", flags2str(n->flags));
6744 /* get_varlist --- list of global variables */
6753 emalloc(table, NODE **, (var_count + 1) * sizeof(NODE *), "get_varlist");
6754 update_global_values();
6755 for (i = j = 0; i < HASHSIZE; i++)
6756 for (p = variables[i]; p != NULL; p = p->hnext)
6758 assert(j == var_count);
6761 qsort(table, j, sizeof(NODE *), sym_comp);
6767 /* print_vars --- print names and values of global variables */
6770 print_vars(int (*print_func)(FILE *, const char *, ...), FILE *fp)
6776 table = get_varlist();
6777 for (i = 0; (p = table[i]) != NULL; i++) {
6778 if (p->hvalue->type == Node_func)
6780 print_func(fp, "%.*s: ", (int) p->hlength, p->hname);
6781 if (p->hvalue->type == Node_var_array)
6782 print_func(fp, "array, %ld elements\n", p->hvalue->table_size);
6783 else if (p->hvalue->type == Node_var_new)
6784 print_func(fp, "untyped variable\n");
6785 else if (p->hvalue->type == Node_var)
6786 valinfo(p->hvalue->var_value, print_func, fp);
6791 /* dump_vars --- dump the symbol table */
6794 dump_vars(const char *fname)
6800 else if ((fp = fopen(fname, "w")) == NULL) {
6801 warning(_("could not open `%s' for writing (%s)"), fname, strerror(errno));
6802 warning(_("sending variable list to standard error"));
6806 print_vars(fprintf, fp);
6807 if (fp != stderr && fclose(fp) != 0)
6808 warning(_("%s: close failed (%s)"), fname, strerror(errno));
6811 /* release_all_vars --- free all variable memory */
6819 for (i = 0; i < HASHSIZE; i++) {
6820 for (p = variables[i]; p != NULL; p = next) {
6823 if (p->hvalue->type == Node_func)
6825 else if (p->hvalue->type == Node_var_array)
6826 assoc_clear(p->hvalue);
6827 else if (p->hvalue->type != Node_var_new)
6828 unref(p->hvalue->var_value);
6831 freenode(p->hvalue);
6837 /* dump_funcs --- print all functions */
6842 if (func_count <= 0)
6845 (void) foreach_func((int (*)(INSTRUCTION *, void *)) pp_func, TRUE, (void *) 0);
6848 /* shadow_funcs --- check all functions for parameters that shadow globals */
6853 static int calls = 0;
6856 if (func_count <= 0)
6860 fatal(_("shadow_funcs() called twice!"));
6862 (void) foreach_func((int (*)(INSTRUCTION *, void *)) parms_shadow, TRUE, &shadow);
6864 /* End with fatal if the user requested it. */
6865 if (shadow && lintfunc != warning)
6866 lintwarn(_("there were shadowed variables."));
6871 * check if name is already installed; if so, it had better have Null value,
6872 * in which case def is added as the value. Otherwise, install name with def
6875 * Extra work, build up and save a list of the parameter names in a table
6876 * and hang it off params->parmlist. This is used to set the `vname' field
6877 * of each function parameter during a function call. See eval.c.
6881 func_install(INSTRUCTION *func, INSTRUCTION *def)
6884 NODE *r, *n, *thisfunc, *hp;
6885 char **pnames = NULL;
6890 params = func_params;
6892 /* check for function foo(foo) { ... }. bleah. */
6893 for (n = params->rnode; n != NULL; n = n->rnode) {
6894 if (strcmp(n->param, params->param) == 0) {
6895 error_ln(func->source_line,
6896 _("function `%s': can't use function name as parameter name"), params->param);
6898 } else if (is_std_var(n->param)) {
6899 error_ln(func->source_line,
6900 _("function `%s': can't use special variable `%s' as a function parameter"),
6901 params->param, n->param);
6906 thisfunc = NULL; /* turn off warnings */
6908 fname = params->param;
6909 /* symbol table management */
6910 hp = remove_symbol(params->param); /* remove function name out of symbol table */
6915 error_ln(func->source_line,
6916 _("function name `%s' previously defined"), fname);
6918 } else if (fname == builtin_func) /* not a valid function name */
6921 /* add an implicit return at end;
6922 * also used by 'return' command in debugger
6925 (void) list_append(def, instruction(Op_push_i));
6926 def->lasti->memory = Nnull_string;
6927 (void) list_append(def, instruction(Op_K_return));
6930 (void) list_prepend(def, instruction(Op_exec_count));
6932 /* func->opcode is Op_func */
6933 (func + 1)->firsti = def->nexti;
6934 (func + 1)->lasti = def->lasti;
6935 (func + 2)->first_line = func->source_line;
6936 (func + 2)->last_line = lastline;
6938 func->nexti = def->nexti;
6941 (void) list_append(rule_list, func + 1); /* debugging */
6943 /* install the function */
6944 thisfunc = mk_symbol(Node_func, params);
6945 (void) install_symbol(fname, thisfunc);
6946 thisfunc->code_ptr = func;
6947 func->func_body = thisfunc;
6949 for (n = params->rnode; n != NULL; n = n->rnode)
6953 emalloc(pnames, char **, (pcount + 1) * sizeof(char *), "func_install");
6954 for (i = 0, n = params->rnode; i < pcount; i++, n = n->rnode)
6955 pnames[i] = n->param;
6956 pnames[pcount] = NULL;
6958 thisfunc->parmlist = pnames;
6960 /* update lint table info */
6961 func_use(fname, FUNC_DEFINE);
6963 func_count++; /* used in profiler / pretty printer */
6966 /* remove params from symbol table */
6967 pop_params(params->rnode);
6971 /* remove_symbol --- remove a variable from the symbol table */
6974 remove_symbol(char *name)
6976 NODE *bucket, **save;
6980 save = &(variables[hash(name, len, (unsigned long) HASHSIZE, NULL)]);
6981 for (bucket = *save; bucket != NULL; bucket = bucket->hnext) {
6982 if (len == bucket->hlength && strncmp(bucket->hname, name, len) == 0) {
6984 *save = bucket->hnext;
6987 save = &(bucket->hnext);
6992 /* pop_params --- remove list of function parameters from symbol table */
6995 * pop parameters out of the symbol table. do this in reverse order to
6996 * avoid reading freed memory if there were duplicated parameters.
6999 pop_params(NODE *params)
7004 pop_params(params->rnode);
7005 hp = remove_symbol(params->param);
7010 /* make_param --- make NAME into a function parameter */
7013 make_param(char *name)
7018 r->type = Node_param_list;
7020 r->param_cnt = param_counter++;
7021 return (install_symbol(name, r));
7024 static struct fdesc {
7029 } *ftable[HASHSIZE];
7031 /* func_use --- track uses and definitions of functions */
7034 func_use(const char *name, enum defref how)
7041 ind = hash(name, len, HASHSIZE, NULL);
7043 for (fp = ftable[ind]; fp != NULL; fp = fp->next) {
7044 if (strcmp(fp->name, name) == 0) {
7045 if (how == FUNC_DEFINE)
7053 /* not in the table, fall through to allocate a new one */
7055 emalloc(fp, struct fdesc *, sizeof(struct fdesc), "func_use");
7056 memset(fp, '\0', sizeof(struct fdesc));
7057 emalloc(fp->name, char *, len + 1, "func_use");
7058 strcpy(fp->name, name);
7059 if (how == FUNC_DEFINE)
7063 fp->next = ftable[ind];
7067 /* check_funcs --- verify functions that are called but not defined */
7072 struct fdesc *fp, *next;
7075 if (! in_main_context())
7078 for (i = 0; i < HASHSIZE; i++) {
7079 for (fp = ftable[i]; fp != NULL; fp = fp->next) {
7081 /* making this the default breaks old code. sigh. */
7082 if (fp->defined == 0) {
7084 _("function `%s' called but never defined"), fp->name);
7088 if (do_lint && fp->defined == 0)
7090 _("function `%s' called but never defined"), fp->name);
7092 if (do_lint && fp->used == 0) {
7093 lintwarn(_("function `%s' defined but never called directly"),
7100 /* now let's free all the memory */
7101 for (i = 0; i < HASHSIZE; i++) {
7102 for (fp = ftable[i]; fp != NULL; fp = next) {
7111 /* param_sanity --- look for parameters that are regexp constants */
7114 param_sanity(INSTRUCTION *arglist)
7116 INSTRUCTION *argl, *arg;
7119 if (arglist == NULL)
7121 for (argl = arglist->nexti; argl; ) {
7123 if (arg->opcode == Op_match_rec)
7124 warning_ln(arg->source_line,
7125 _("regexp constant for parameter #%d yields boolean value"), i);
7131 /* foreach_func --- execute given function for each awk function in symbol table. */
7134 foreach_func(int (*pfunc)(INSTRUCTION *, void *), int sort, void *data)
7144 * Walk through symbol table counting functions.
7145 * Could be more than func_count if there are
7146 * extension functions.
7148 for (i = j = 0; i < HASHSIZE; i++) {
7149 for (p = variables[i]; p != NULL; p = p->hnext) {
7150 if (p->hvalue->type == Node_func) {
7159 emalloc(tab, NODE **, j * sizeof(NODE *), "foreach_func");
7161 /* now walk again, copying info */
7162 for (i = j = 0; i < HASHSIZE; i++) {
7163 for (p = variables[i]; p != NULL; p = p->hnext) {
7164 if (p->hvalue->type == Node_func) {
7172 qsort(tab, j, sizeof(NODE *), sym_comp);
7174 for (i = 0; i < j; i++) {
7175 if ((ret = pfunc(tab[i]->hvalue->code_ptr, data)) != 0)
7184 for (i = 0; i < HASHSIZE; i++) {
7185 for (p = variables[i]; p != NULL; p = p->hnext) {
7186 if (p->hvalue->type == Node_func
7187 && (ret = pfunc(p->hvalue->code_ptr, data)) != 0)
7194 /* deferred variables --- those that are only defined if needed. */
7197 * Is there any reason to use a hash table for deferred variables? At the
7198 * moment, there are only 1 to 3 such variables, so it may not be worth
7199 * the overhead. If more modules start using this facility, it should
7200 * probably be converted into a hash table.
7203 static struct deferred_variable {
7204 NODE *(*load_func)(void);
7205 struct deferred_variable *next;
7206 char name[1]; /* variable-length array */
7207 } *deferred_variables;
7209 /* register_deferred_variable --- add a var name and loading function to the list */
7212 register_deferred_variable(const char *name, NODE *(*load_func)(void))
7214 struct deferred_variable *dv;
7215 size_t sl = strlen(name);
7217 emalloc(dv, struct deferred_variable *, sizeof(*dv)+sl,
7218 "register_deferred_variable");
7219 dv->load_func = load_func;
7220 dv->next = deferred_variables;
7221 memcpy(dv->name, name, sl+1);
7222 deferred_variables = dv;
7225 /* variable --- make sure NAME is in the symbol table */
7228 variable(char *name, NODETYPE type)
7232 if ((r = lookup(name)) != NULL) {
7233 if (r->type == Node_func) {
7234 error(_("function `%s' called with space between name and `(',\nor used as a variable or an array"),
7237 r->type = Node_var_new; /* continue parsing instead of exiting */
7241 struct deferred_variable *dv;
7243 for (dv = deferred_variables; TRUE; dv = dv->next) {
7246 * This is the only case in which we may not free the string.
7248 if (type == Node_var)
7249 r = mk_symbol(type, Nnull_string);
7251 r = mk_symbol(type, (NODE *) NULL);
7252 return install_symbol(name, r);
7254 if (strcmp(name, dv->name) == 0) {
7255 r = (*dv->load_func)();
7264 /* make_regnode --- make a regular expression node */
7267 make_regnode(int type, NODE *exp)
7272 memset(n, 0, sizeof(NODE));
7276 if (type == Node_regex) {
7277 n->re_reg = make_regexp(exp->stptr, exp->stlen, FALSE, TRUE, FALSE);
7278 if (n->re_reg == NULL) {
7283 n->re_flags = CONSTANT;
7289 /* mk_rexp --- make a regular expression constant */
7292 mk_rexp(INSTRUCTION *list)
7297 if (ip == list->lasti && ip->opcode == Op_match_rec)
7298 ip->opcode = Op_push_re;
7300 ip = instruction(Op_push_re);
7301 ip->memory = make_regnode(Node_dynregex, NULL);
7302 ip->nexti = list->lasti->nexti;
7303 list->lasti->nexti = ip;
7309 /* isnoeffect --- when used as a statement, has no side effects */
7312 isnoeffect(OPCODE type)
7329 case Op_unary_minus:
7346 break; /* keeps gcc -Wall happy */
7352 /* make_assignable --- make this operand an assignable one if posiible */
7354 static INSTRUCTION *
7355 make_assignable(INSTRUCTION *ip)
7357 switch (ip->opcode) {
7359 if (ip->memory->type == Node_param_list
7360 && (ip->memory->flags & FUNC) != 0)
7362 ip->opcode = Op_push_lhs;
7365 ip->opcode = Op_field_spec_lhs;
7368 ip->opcode = Op_subscript_lhs;
7371 break; /* keeps gcc -Wall happy */
7376 /* stopme --- for debugging */
7379 stopme(int nargs ATTRIBUTE_UNUSED)
7384 /* dumpintlstr --- write out an initial .po file entry for the string */
7387 dumpintlstr(const char *str, size_t len)
7391 /* See the GNU gettext distribution for details on the file format */
7393 if (source != NULL) {
7394 /* ala the gettext sources, remove leading `./'s */
7395 for (cp = source; cp[0] == '.' && cp[1] == '/'; cp += 2)
7397 printf("#: %s:%d\n", cp, sourceline);
7401 pp_string_fp(fprintf, stdout, str, len, '"', TRUE);
7403 printf("msgstr \"\"\n\n");
7407 /* dumpintlstr2 --- write out an initial .po file entry for the string and its plural */
7410 dumpintlstr2(const char *str1, size_t len1, const char *str2, size_t len2)
7414 /* See the GNU gettext distribution for details on the file format */
7416 if (source != NULL) {
7417 /* ala the gettext sources, remove leading `./'s */
7418 for (cp = source; cp[0] == '.' && cp[1] == '/'; cp += 2)
7420 printf("#: %s:%d\n", cp, sourceline);
7424 pp_string_fp(fprintf, stdout, str1, len1, '"', TRUE);
7426 printf("msgid_plural ");
7427 pp_string_fp(fprintf, stdout, str2, len2, '"', TRUE);
7429 printf("msgstr[0] \"\"\nmsgstr[1] \"\"\n\n");
7433 /* isarray --- can this type be subscripted? */
7440 case Node_var_array:
7442 case Node_param_list:
7443 return (n->flags & FUNC) == 0;
7444 case Node_array_ref:
7448 break; /* keeps gcc -Wall happy */
7454 /* mk_binary --- instructions for binary operators */
7456 static INSTRUCTION *
7457 mk_binary(INSTRUCTION *s1, INSTRUCTION *s2, INSTRUCTION *op)
7459 INSTRUCTION *ip1,*ip2;
7463 if (s2->lasti == ip2 && ip2->opcode == Op_push_i) {
7464 /* do any numeric constant folding */
7467 && ip1 == s1->lasti && ip1->opcode == Op_push_i
7468 && (ip1->memory->flags & (STRCUR|STRING)) == 0
7469 && (ip2->memory->flags & (STRCUR|STRING)) == 0
7471 NODE *n1 = ip1->memory, *n2 = ip2->memory;
7472 res = force_number(n1);
7473 (void) force_number(n2);
7474 switch (op->opcode) {
7479 if (n2->numbr == 0.0) {
7480 /* don't fatalize, allow parsing rest of the input */
7481 error_ln(op->source_line, _("division by zero attempted"));
7488 if (n2->numbr == 0.0) {
7489 /* don't fatalize, allow parsing rest of the input */
7490 error_ln(op->source_line, _("division by zero attempted in `%%'"));
7494 res = fmod(res, n2->numbr);
7495 #else /* ! HAVE_FMOD */
7496 (void) modf(res / n2->numbr, &res);
7497 res = n1->numbr - res * n2->numbr;
7498 #endif /* ! HAVE_FMOD */
7507 res = calc_exp(res, n2->numbr);
7513 op->opcode = Op_push_i;
7514 op->memory = mk_number(res, (PERM|NUMCUR|NUMBER));
7516 n1->flags |= MALLOC;
7518 n2->flags |= MALLOC;
7525 return list_create(op);
7527 /* do basic arithmetic optimisation */
7528 /* convert (Op_push_i Node_val) + (Op_plus) to (Op_plus_i Node_val) */
7529 switch (op->opcode) {
7531 op->opcode = Op_times_i;
7534 op->opcode = Op_quotient_i;
7537 op->opcode = Op_mod_i;
7540 op->opcode = Op_plus_i;
7543 op->opcode = Op_minus_i;
7546 op->opcode = Op_exp_i;
7552 op->memory = ip2->memory;
7554 bcfree(s2); /* Op_list */
7555 return list_append(s1, op);
7560 /* append lists s1, s2 and add `op' bytecode */
7561 (void) list_merge(s1, s2);
7562 return list_append(s1, op);
7565 /* mk_boolean --- instructions for boolean and, or */
7567 static INSTRUCTION *
7568 mk_boolean(INSTRUCTION *left, INSTRUCTION *right, INSTRUCTION *op)
7571 OPCODE opc, final_opc;
7573 opc = op->opcode; /* Op_and or Op_or */
7574 final_opc = (opc == Op_or) ? Op_or_final : Op_and_final;
7576 add_lint(right, LINT_assign_in_cond);
7580 if (tp->opcode != final_opc) { /* x || y */
7581 list_append(right, instruction(final_opc));
7582 add_lint(left, LINT_assign_in_cond);
7583 (void) list_append(left, op);
7584 left->lasti->target_jmp = right->lasti;
7586 /* NB: target_stmt points to previous Op_and(Op_or) in a chain;
7587 * target_stmt only used in the parser (see below).
7590 left->lasti->target_stmt = left->lasti;
7591 right->lasti->target_stmt = left->lasti;
7592 } else { /* optimization for x || y || z || ... */
7595 op->opcode = final_opc;
7596 (void) list_append(right, op);
7597 op->target_stmt = tp;
7599 tp->target_jmp = op;
7601 /* update jump targets */
7602 for (ip = tp->target_stmt; ; ip = ip->target_stmt) {
7603 assert(ip->opcode == opc);
7604 assert(ip->target_jmp == tp);
7605 /* if (ip->opcode == opc && ip->target_jmp == tp) */
7606 ip->target_jmp = op;
7607 if (ip->target_stmt == ip)
7612 return list_merge(left, right);
7615 /* mk_condition --- if-else and conditional */
7617 static INSTRUCTION *
7618 mk_condition(INSTRUCTION *cond, INSTRUCTION *ifp, INSTRUCTION *true_branch,
7619 INSTRUCTION *elsep, INSTRUCTION *false_branch)
7625 * t: [Op_jmp_false f ]
7641 if (false_branch == NULL) {
7642 false_branch = list_create(instruction(Op_no_op));
7643 if (elsep != NULL) { /* else { } */
7645 (void) list_prepend(false_branch, elsep);
7650 /* assert(elsep != NULL); */
7652 /* avoid a series of no_op's: if .. else if .. else if .. */
7653 if (false_branch->lasti->opcode != Op_no_op)
7654 (void) list_append(false_branch, instruction(Op_no_op));
7656 (void) list_prepend(false_branch, elsep);
7657 false_branch->nexti->branch_end = false_branch->lasti;
7658 (void) list_prepend(false_branch, instruction(Op_exec_count));
7663 (void) list_prepend(false_branch, instruction(Op_jmp));
7664 false_branch->nexti->target_jmp = false_branch->lasti;
7666 add_lint(cond, LINT_assign_in_cond);
7667 ip = list_append(cond, instruction(Op_jmp_false));
7668 ip->lasti->target_jmp = false_branch->nexti->nexti;
7671 (void) list_prepend(ip, ifp);
7672 (void) list_append(ip, instruction(Op_exec_count));
7673 ip->nexti->branch_if = ip->lasti;
7674 ip->nexti->branch_else = false_branch->nexti;
7678 if (true_branch != NULL)
7679 list_merge(ip, true_branch);
7680 return list_merge(ip, false_branch);
7683 enum defline { FIRST_LINE, LAST_LINE };
7685 /* find_line -- find the first(last) line in a list of (pattern) instructions */
7688 find_line(INSTRUCTION *pattern, enum defline what)
7693 for (ip = pattern->nexti; ip; ip = ip->nexti) {
7694 if (what == LAST_LINE) {
7695 if (ip->source_line > lineno)
7696 lineno = ip->source_line;
7697 } else { /* FIRST_LINE */
7698 if (ip->source_line > 0
7699 && (lineno == 0 || ip->source_line < lineno))
7700 lineno = ip->source_line;
7702 if (ip == pattern->lasti)
7709 /* append_rule --- pattern-action instructions */
7711 static INSTRUCTION *
7712 append_rule(INSTRUCTION *pattern, INSTRUCTION *action)
7733 (void) list_append(action, instruction(Op_no_op));
7734 (rp + 1)->firsti = action->nexti;
7735 (rp + 1)->lasti = action->lasti;
7736 (rp + 2)->first_line = pattern->source_line;
7737 (rp + 2)->last_line = lastline;
7738 ip = list_prepend(action, rp);
7741 rp = bcalloc(Op_rule, 3, 0);
7743 rp->source_file = source;
7744 tp = instruction(Op_no_op);
7746 if (pattern == NULL) {
7747 /* assert(action != NULL); */
7749 (void) list_prepend(action, instruction(Op_exec_count));
7750 (rp + 1)->firsti = action->nexti;
7751 (rp + 1)->lasti = tp;
7752 (rp + 2)->first_line = firstline;
7753 (rp + 2)->last_line = lastline;
7754 rp->source_line = firstline;
7755 ip = list_prepend(list_append(action, tp), rp);
7757 (void) list_append(pattern, instruction(Op_jmp_false));
7758 pattern->lasti->target_jmp = tp;
7759 (rp + 2)->first_line = find_line(pattern, FIRST_LINE);
7760 rp->source_line = (rp + 2)->first_line;
7761 if (action == NULL) {
7762 (rp + 2)->last_line = find_line(pattern, LAST_LINE);
7763 action = list_create(instruction(Op_K_print_rec));
7765 (void) list_prepend(action, instruction(Op_exec_count));
7767 (rp + 2)->last_line = lastline;
7770 (void) list_prepend(pattern, instruction(Op_exec_count));
7771 (void) list_prepend(action, instruction(Op_exec_count));
7773 (rp + 1)->firsti = action->nexti;
7774 (rp + 1)->lasti = tp;
7776 list_merge(list_prepend(pattern, rp),
7783 list_append(rule_list, rp + 1);
7785 if (rule_block[rule] == NULL)
7786 rule_block[rule] = ip;
7788 (void) list_merge(rule_block[rule], ip);
7790 return rule_block[rule];
7793 /* mk_assignment --- assignment bytecodes */
7795 static INSTRUCTION *
7796 mk_assignment(INSTRUCTION *lhs, INSTRUCTION *rhs, INSTRUCTION *op)
7802 switch (tp->opcode) {
7804 tp->opcode = Op_field_spec_lhs;
7807 tp->opcode = Op_subscript_lhs;
7811 tp->opcode = Op_push_lhs;
7817 tp->do_reference = (op->opcode != Op_assign); /* check for uninitialized reference */
7820 ip = list_merge(rhs, lhs);
7824 (void) list_append(ip, op);
7826 if (tp->opcode == Op_push_lhs
7827 && tp->memory->type == Node_var
7828 && tp->memory->var_assign
7830 tp->do_reference = FALSE; /* no uninitialized reference checking
7831 * for a special variable.
7833 (void) list_append(ip, instruction(Op_var_assign));
7834 ip->lasti->assign_var = tp->memory->var_assign;
7835 } else if (tp->opcode == Op_field_spec_lhs) {
7836 (void) list_append(ip, instruction(Op_field_assign));
7837 ip->lasti->field_assign = (Func_ptr) 0;
7838 tp->target_assign = ip->lasti;
7844 /* optimize_assignment --- peephole optimization for assignment */
7846 static INSTRUCTION *
7847 optimize_assignment(INSTRUCTION *exp)
7854 * Optimize assignment statements array[subs] = x; var = x; $n = x;
7855 * string concatenation of the form s = s t.
7857 * 1) Array element assignment array[subs] = x:
7858 * Replaces Op_push_array + Op_subscript_lhs + Op_assign + Op_pop
7859 * with single instruction Op_store_sub.
7860 * Limitation: 1 dimension and sub is simple var/value.
7862 * 2) Simple variable assignment var = x:
7863 * Replaces Op_push_lhs + Op_assign + Op_pop with Op_store_var.
7865 * 3) Field assignment $n = x:
7866 * Replaces Op_field_spec_lhs + Op_assign + Op_field_assign + Op_pop
7867 * with Op_store_field.
7869 * 4) Optimization for string concatenation:
7870 * For cases like x = x y, uses realloc to include y in x;
7871 * also eliminates instructions Op_push_lhs and Op_pop.
7875 * N.B.: do not append Op_pop instruction to the returned
7876 * instruction list if optimized. None of these
7877 * optimized instructions pushes the r-value of assignment
7878 * onto the runtime stack.
7885 || ( i1->opcode != Op_assign
7886 && i1->opcode != Op_field_assign)
7888 return list_append(exp, instruction(Op_pop));
7890 for (i2 = exp->nexti; i2 != i1; i2 = i2->nexti) {
7891 switch (i2->opcode) {
7893 if (i2->nexti->opcode == Op_push_lhs /* l.h.s is a simple variable */
7894 && (i2->concat_flag & CSVAR) /* 1st exp in r.h.s is a simple variable;
7895 * see Op_concat in the grammer above.
7897 && i2->nexti->memory == exp->nexti->memory /* and the same as in l.h.s */
7898 && i2->nexti->nexti == i1
7899 && i1->opcode == Op_assign
7901 /* s = s ... optimization */
7903 /* avoid stuff like x = x (x = y) or x = x gsub(/./, "b", x);
7904 * check for l-value reference to this variable in the r.h.s.
7905 * Also, avoid function calls in general to guard against
7906 * global variable assignment.
7909 for (i3 = exp->nexti->nexti; i3 != i2; i3 = i3->nexti) {
7910 if ((i3->opcode == Op_push_lhs && i3->memory == i2->nexti->memory)
7911 || i3->opcode == Op_func_call)
7912 return list_append(exp, instruction(Op_pop)); /* no optimization */
7915 /* remove the variable from r.h.s */
7917 exp->nexti = i3->nexti;
7920 if (--i2->expr_count == 1) /* one less expression in Op_concat */
7921 i2->opcode = Op_no_op;
7924 assert(i3->opcode == Op_push_lhs);
7925 i3->opcode = Op_assign_concat; /* change Op_push_lhs to Op_assign_concat */
7927 bcfree(i1); /* Op_assign */
7928 exp->lasti = i3; /* update Op_list */
7933 case Op_field_spec_lhs:
7934 if (i2->nexti->opcode == Op_assign
7935 && i2->nexti->nexti == i1
7936 && i1->opcode == Op_field_assign
7939 i2->opcode = Op_store_field;
7940 bcfree(i2->nexti); /* Op_assign */
7942 bcfree(i1); /* Op_field_assign */
7943 exp->lasti = i2; /* update Op_list */
7949 if (i2->nexti->nexti->opcode == Op_subscript_lhs) {
7950 i3 = i2->nexti->nexti;
7951 if (i3->sub_count == 1
7953 && i1->opcode == Op_assign
7955 /* array[sub] = .. */
7956 i3->opcode = Op_store_sub;
7957 i3->memory = i2->memory;
7958 i3->expr_count = 1; /* sub_count shadows memory,
7959 * so use expr_count instead.
7962 i2->opcode = Op_no_op;
7963 bcfree(i1); /* Op_assign */
7964 exp->lasti = i3; /* update Op_list */
7972 && i1->opcode == Op_assign
7975 i2->opcode = Op_store_var;
7977 bcfree(i1); /* Op_assign */
7978 exp->lasti = i2; /* update Op_list */
7988 /* no optimization */
7989 return list_append(exp, instruction(Op_pop));
7993 /* mk_getline --- make instructions for getline */
7995 static INSTRUCTION *
7996 mk_getline(INSTRUCTION *op, INSTRUCTION *var, INSTRUCTION *redir, int redirtype)
8000 INSTRUCTION *asgn = NULL;
8003 * getline [var] < [file]
8005 * [ file (simp_exp)]
8007 * [ Op_K_getline_redir|NULL|redir_type|into_var]
8012 if (redir == NULL) {
8013 int sline = op->source_line;
8015 op = bcalloc(Op_K_getline, 2, sline);
8016 (op + 1)->target_endfile = ip_endfile;
8017 (op + 1)->target_beginfile = ip_beginfile;
8021 tp = make_assignable(var->lasti);
8024 /* check if we need after_assign bytecode */
8025 if (tp->opcode == Op_push_lhs
8026 && tp->memory->type == Node_var
8027 && tp->memory->var_assign
8029 asgn = instruction(Op_var_assign);
8030 asgn->assign_ctxt = op->opcode;
8031 asgn->assign_var = tp->memory->var_assign;
8032 } else if (tp->opcode == Op_field_spec_lhs) {
8033 asgn = instruction(Op_field_assign);
8034 asgn->assign_ctxt = op->opcode;
8035 asgn->field_assign = (Func_ptr) 0; /* determined at run time */
8036 tp->target_assign = asgn;
8038 if (redir != NULL) {
8039 ip = list_merge(redir, var);
8040 (void) list_append(ip, op);
8042 ip = list_append(var, op);
8043 } else if (redir != NULL)
8044 ip = list_append(redir, op);
8046 ip = list_create(op);
8047 op->into_var = (var != NULL);
8048 op->redir_type = (redir != NULL) ? redirtype : 0;
8050 return (asgn == NULL ? ip : list_append(ip, asgn));
8054 /* mk_for_loop --- for loop bytecodes */
8056 static INSTRUCTION *
8057 mk_for_loop(INSTRUCTION *forp, INSTRUCTION *init, INSTRUCTION *cond,
8058 INSTRUCTION *incr, INSTRUCTION *body)
8061 * ------------------------
8062 * init (may be NULL)
8063 * ------------------------
8065 * cond (Op_no_op if NULL)
8066 * ------------------------
8067 * [ Op_jmp_false tb ]
8068 * ------------------------
8069 * body (may be NULL)
8070 * ------------------------
8072 * incr (may be NULL)
8074 * ------------------------
8078 INSTRUCTION *ip, *tbreak, *tcont;
8080 INSTRUCTION *pp_cond;
8083 tbreak = instruction(Op_no_op);
8086 add_lint(cond, LINT_assign_in_cond);
8087 pp_cond = cond->nexti;
8089 (void) list_append(ip, instruction(Op_jmp_false));
8090 ip->lasti->target_jmp = tbreak;
8092 pp_cond = instruction(Op_no_op);
8093 ip = list_create(pp_cond);
8097 ip = list_merge(init, ip);
8100 (void) list_append(ip, instruction(Op_exec_count));
8101 (forp + 1)->forloop_cond = pp_cond;
8102 (forp + 1)->forloop_body = ip->lasti;
8106 (void) list_merge(ip, body);
8108 jmp = instruction(Op_jmp);
8109 jmp->target_jmp = pp_cond;
8113 tcont = incr->nexti;
8114 (void) list_merge(ip, incr);
8117 (void) list_append(ip, jmp);
8118 ret = list_append(ip, tbreak);
8119 fix_break_continue(ret, tbreak, tcont);
8122 forp->target_break = tbreak;
8123 forp->target_continue = tcont;
8124 ret = list_prepend(ret, forp);
8131 /* add_lint --- add lint warning bytecode if needed */
8134 add_lint(INSTRUCTION *list, LINTTYPE linttype)
8140 case LINT_assign_in_cond:
8142 if (ip->opcode == Op_var_assign || ip->opcode == Op_field_assign) {
8143 assert(ip != list->nexti);
8144 for (ip = list->nexti; ip->nexti != list->lasti; ip = ip->nexti)
8148 if (ip->opcode == Op_assign || ip->opcode == Op_assign_concat) {
8149 list_append(list, instruction(Op_lint));
8150 list->lasti->lint_type = linttype;
8154 case LINT_no_effect:
8155 if (list->lasti->opcode == Op_pop && list->nexti != list->lasti) {
8156 for (ip = list->nexti; ip->nexti != list->lasti; ip = ip->nexti)
8159 if (do_lint) { /* compile-time warning */
8160 if (isnoeffect(ip->opcode))
8161 lintwarn_ln(ip->source_line, ("statement may have no effect"));
8164 if (ip->opcode == Op_push) { /* run-time warning */
8165 list_append(list, instruction(Op_lint));
8166 list->lasti->lint_type = linttype;
8177 /* mk_expression_list --- list of bytecode lists */
8179 static INSTRUCTION *
8180 mk_expression_list(INSTRUCTION *list, INSTRUCTION *s1)
8184 /* we can't just combine all bytecodes, since we need to
8185 * process individual expressions for a few builtins in snode() (-:
8188 /* -- list of lists */
8189 /* [Op_list| ... ]------
8191 * [Op_list| ... ] -- |
8194 * [Op_list| ... ] -- |
8200 assert(s1 != NULL && s1->opcode == Op_list);
8202 list = instruction(Op_list);
8204 list->lasti = s1->lasti;
8208 /* append expression to the end of the list */
8212 list->lasti = s1->lasti;
8216 /* count_expressions --- fixup expression_list from mk_expression_list.
8217 * returns no of expressions in list. isarg is true
8218 * for function arguments.
8222 count_expressions(INSTRUCTION **list, int isarg)
8225 INSTRUCTION *r = NULL;
8228 if (*list == NULL) /* error earlier */
8231 for (expr = (*list)->nexti; expr; ) {
8232 INSTRUCTION *t1, *t2;
8235 if (isarg && t1 == t2 && t1->opcode == Op_push)
8236 t1->opcode = Op_push_param;
8240 (void) list_merge(r, expr);
8245 if (! isarg && count > max_args)
8252 /* fix_break_continue --- fix up break & continue codes in loop bodies */
8255 fix_break_continue(INSTRUCTION *list, INSTRUCTION *b_target, INSTRUCTION *c_target)
8259 list->lasti->nexti = NULL; /* just to make sure */
8261 for (ip = list->nexti; ip != NULL; ip = ip->nexti) {
8262 switch (ip->opcode) {
8264 if (ip->target_jmp == NULL)
8265 ip->target_jmp = b_target;
8269 if (ip->target_jmp == NULL)
8270 ip->target_jmp = c_target;
8274 /* this is to keep the compiler happy. sheesh. */
8281 /* append_symbol --- append symbol to the list of symbols
8282 * installed in the symbol table.
8286 append_symbol(char *name)
8290 /* N.B.: func_install removes func name and reinstalls it;
8291 * and we get two entries for it here!. destroy_symbol()
8292 * will find and destroy the Node_func which is what we want.
8296 hp->hname = name; /* shallow copy */
8297 hp->hnext = symbol_list->hnext;
8298 symbol_list->hnext = hp;
8301 /* release_symbol --- free symbol list and optionally remove symbol from symbol table */
8304 release_symbols(NODE *symlist, int keep_globals)
8308 for (hp = symlist->hnext; hp != NULL; hp = n) {
8309 if (! keep_globals) {
8310 /* destroys globals, function, and params
8311 * if still in symbol table and not removed by func_install
8312 * due to syntax error.
8314 destroy_symbol(hp->hname);
8319 symlist->hnext = NULL;
8322 /* destroy_symbol --- remove a symbol from symbol table
8323 * and free all associated memory.
8327 destroy_symbol(char *name)
8331 symbol = lookup(name);
8335 if (symbol->type == Node_func) {
8340 varnames = func->parmlist;
8341 if (varnames != NULL)
8344 /* function parameters of type Node_param_list */
8345 for (n = func->lnode->rnode; n != NULL; ) {
8352 freenode(func->lnode);
8355 } else if (symbol->type == Node_var_array)
8356 assoc_clear(symbol);
8357 else if (symbol->type == Node_var)
8358 unref(symbol->var_value);
8360 /* remove from symbol table */
8361 hp = remove_symbol(name);
8363 freenode(hp->hvalue);
8367 #define pool_size d.dl
8369 static INSTRUCTION *pool_list;
8370 static AWK_CONTEXT *curr_ctxt = NULL;
8372 /* new_context --- create a new execution context. */
8379 emalloc(ctxt, AWK_CONTEXT *, sizeof(AWK_CONTEXT), "new_context");
8380 memset(ctxt, 0, sizeof(AWK_CONTEXT));
8381 ctxt->srcfiles.next = ctxt->srcfiles.prev = &ctxt->srcfiles;
8382 ctxt->rule_list.opcode = Op_list;
8383 ctxt->rule_list.lasti = &ctxt->rule_list;
8387 /* set_context --- change current execution context. */
8390 set_context(AWK_CONTEXT *ctxt)
8392 pool_list = &ctxt->pools;
8393 symbol_list = &ctxt->symbols;
8394 srcfiles = &ctxt->srcfiles;
8395 rule_list = &ctxt->rule_list;
8396 install_func = ctxt->install_func;
8403 * Switch to the given context after saving the current one. The set
8404 * of active execution contexts forms a stack; the global or main context
8405 * is at the bottom of the stack.
8409 push_context(AWK_CONTEXT *ctxt)
8411 ctxt->prev = curr_ctxt;
8412 /* save current source and sourceline */
8413 if (curr_ctxt != NULL) {
8414 curr_ctxt->sourceline = sourceline;
8415 curr_ctxt->source = source;
8422 /* pop_context --- switch to previous execution context. */
8429 assert(curr_ctxt != NULL);
8430 ctxt = curr_ctxt->prev;
8431 /* restore source and sourceline */
8432 sourceline = ctxt->sourceline;
8433 source = ctxt->source;
8437 /* in_main_context --- are we in the main context ? */
8442 assert(curr_ctxt != NULL);
8443 return (curr_ctxt->prev == NULL);
8446 /* free_context --- free context structure and related data. */
8449 free_context(AWK_CONTEXT *ctxt, int keep_globals)
8456 assert(curr_ctxt != ctxt);
8458 /* free all code including function codes */
8459 free_bcpool(&ctxt->pools);
8461 release_symbols(&ctxt->symbols, keep_globals);
8463 for (s = &ctxt->srcfiles; s != &ctxt->srcfiles; s = sn) {
8465 if (s->stype != SRC_CMDLINE && s->stype != SRC_STDIN)
8473 /* free_bc_internal --- free internal memory of an instruction. */
8476 free_bc_internal(INSTRUCTION *cp)
8480 switch(cp->opcode) {
8482 if (cp->func_name != NULL
8483 && cp->func_name != builtin_func
8485 efree(cp->func_name);
8492 if (m->re_reg != NULL)
8494 if (m->re_exp != NULL)
8496 if (m->re_text != NULL)
8500 case Op_token: /* token lost during error recovery in yyparse */
8501 if (cp->lextok != NULL)
8512 /* INSTR_CHUNK must be > largest code size (3) */
8513 #define INSTR_CHUNK 127
8515 /* bcfree --- deallocate instruction */
8518 bcfree(INSTRUCTION *cp)
8521 cp->nexti = pool_list->freei;
8522 pool_list->freei = cp;
8525 /* bcalloc --- allocate a new instruction */
8528 bcalloc(OPCODE op, int size, int srcline)
8533 /* wide instructions Op_rule, Op_func_call .. */
8534 emalloc(cp, INSTRUCTION *, (size + 1) * sizeof(INSTRUCTION), "bcalloc");
8535 cp->pool_size = size;
8536 cp->nexti = pool_list->nexti;
8537 pool_list->nexti = cp++;
8541 pool = pool_list->freei;
8544 emalloc(cp, INSTRUCTION *, (INSTR_CHUNK + 1) * sizeof(INSTRUCTION), "bcalloc");
8546 cp->pool_size = INSTR_CHUNK;
8547 cp->nexti = pool_list->nexti;
8548 pool_list->nexti = cp;
8550 last = &pool[INSTR_CHUNK - 1];
8551 for (; cp <= last; cp++) {
8559 pool_list->freei = cp->nexti;
8562 memset(cp, 0, size * sizeof(INSTRUCTION));
8564 cp->source_line = srcline;
8568 /* free_bcpool --- free list of instruction memory pools */
8571 free_bcpool(INSTRUCTION *pl)
8573 INSTRUCTION *pool, *tmp;
8575 for (pool = pl->nexti; pool != NULL; pool = tmp) {
8576 INSTRUCTION *cp, *last;
8578 psiz = pool->pool_size;
8579 if (psiz == INSTR_CHUNK)
8583 for (cp = pool + 1; cp <= last ; cp++) {
8584 if (cp->opcode != 0)
8585 free_bc_internal(cp);
8590 memset(pl, 0, sizeof(INSTRUCTION));
8594 static inline INSTRUCTION *
8595 list_create(INSTRUCTION *x)
8599 l = instruction(Op_list);
8605 static inline INSTRUCTION *
8606 list_append(INSTRUCTION *l, INSTRUCTION *x)
8609 if (l->opcode != Op_list)
8612 l->lasti->nexti = x;
8617 static inline INSTRUCTION *
8618 list_prepend(INSTRUCTION *l, INSTRUCTION *x)
8621 if (l->opcode != Op_list)
8624 x->nexti = l->nexti;
8629 static inline INSTRUCTION *
8630 list_merge(INSTRUCTION *l1, INSTRUCTION *l2)
8633 if (l1->opcode != Op_list)
8635 if (l2->opcode != Op_list)
8638 l1->lasti->nexti = l2->nexti;
8639 l1->lasti = l2->lasti;
8644 /* See if name is a special token. */
8647 check_special(const char *name)
8651 #if 'a' == 0x81 /* it's EBCDIC */
8652 static int did_sort = FALSE;
8655 qsort((void *) tokentab,
8656 sizeof(tokentab) / sizeof(tokentab[0]),
8657 sizeof(tokentab[0]), tokcompare);
8663 high = (sizeof(tokentab) / sizeof(tokentab[0])) - 1;
8664 while (low <= high) {
8665 mid = (low + high) / 2;
8666 i = *name - tokentab[mid].operator[0];
8668 i = strcmp(name, tokentab[mid].operator);
8670 if (i < 0) /* token < mid */
8672 else if (i > 0) /* token > mid */
8675 if ((do_traditional && (tokentab[mid].flags & GAWKX))
8676 || (do_posix && (tokentab[mid].flags & NOT_POSIX)))
8685 * This provides a private version of functions that act like VMS's
8686 * variable-length record filesystem, where there was a bug on
8687 * certain source files.
8690 static FILE *fp = NULL;
8692 /* read_one_line --- return one input line at a time. mainly for debugging. */
8695 read_one_line(int fd, void *buffer, size_t count)
8699 /* Minor potential memory leak here. Too bad. */
8701 fp = fdopen(fd, "r");
8703 fprintf(stderr, "ugh. fdopen: %s\n", strerror(errno));
8704 gawk_exit(EXIT_FAILURE);
8708 if (fgets(buf, sizeof buf, fp) == NULL)
8711 memcpy(buffer, buf, strlen(buf));
8715 /* one_line_close --- close the open file being read with read_one_line() */
8718 one_line_close(int fd)
8722 if (fp == NULL || fd != fileno(fp))
8723 fatal("debugging read/close screwed up!");