1/* A Bison parser, made by GNU Bison 1.875. */ 2 3/* Skeleton parser for Yacc-like parsing with Bison, 4 Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software Foundation, Inc. 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2, or (at your option) 9 any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program; if not, write to the Free Software 18 Foundation, Inc., 59 Temple Place - Suite 330, 19 Boston, MA 02111-1307, USA. */ 20 21/* As a special exception, when this file is copied by Bison into a 22 Bison output file, you may use that output file without restriction. 23 This special exception was added by the Free Software Foundation 24 in version 1.24 of Bison. */ 25 26/* Written by Richard Stallman by simplifying the original so called 27 ``semantic'' parser. */ 28 29/* All symbols defined below should begin with yy or YY, to avoid 30 infringing on user name space. This should be done even for local 31 variables, as they might otherwise be expanded by user macros. 32 There are some unavoidable exceptions within include files to 33 define necessary library symbols; they are noted "INFRINGES ON 34 USER NAME SPACE" below. */ 35 36/* Identify Bison output. */ 37#define YYBISON 1 38 39/* Skeleton name. */ 40#define YYSKELETON_NAME "yacc.c" 41 42/* Pure parsers. */ 43#define YYPURE 0 44 45/* Using locations. */ 46#define YYLSP_NEEDED 0 47 48 49 50/* Tokens. */ 51#ifndef YYTOKENTYPE 52# define YYTOKENTYPE 53 /* Put the tokens into the symbol table, so that GDB and other debuggers 54 know about them. */ 55 enum yytokentype { 56 FUNC_CALL = 258, 57 NAME = 259, 58 REGEXP = 260, 59 ERROR = 261, 60 YNUMBER = 262, 61 YSTRING = 263, 62 RELOP = 264, 63 IO_OUT = 265, 64 IO_IN = 266, 65 ASSIGNOP = 267, 66 ASSIGN = 268, 67 MATCHOP = 269, 68 CONCAT_OP = 270, 69 LEX_BEGIN = 271, 70 LEX_END = 272, 71 LEX_IF = 273, 72 LEX_ELSE = 274, 73 LEX_RETURN = 275, 74 LEX_DELETE = 276, 75 LEX_SWITCH = 277, 76 LEX_CASE = 278, 77 LEX_DEFAULT = 279, 78 LEX_WHILE = 280, 79 LEX_DO = 281, 80 LEX_FOR = 282, 81 LEX_BREAK = 283, 82 LEX_CONTINUE = 284, 83 LEX_PRINT = 285, 84 LEX_PRINTF = 286, 85 LEX_NEXT = 287, 86 LEX_EXIT = 288, 87 LEX_FUNCTION = 289, 88 LEX_GETLINE = 290, 89 LEX_NEXTFILE = 291, 90 LEX_IN = 292, 91 LEX_AND = 293, 92 LEX_OR = 294, 93 INCREMENT = 295, 94 DECREMENT = 296, 95 LEX_BUILTIN = 297, 96 LEX_LENGTH = 298, 97 NEWLINE = 299, 98 SLASH_BEFORE_EQUAL = 300, 99 UNARY = 301 100 }; 101#endif 102#define FUNC_CALL 258 103#define NAME 259 104#define REGEXP 260 105#define ERROR 261 106#define YNUMBER 262 107#define YSTRING 263 108#define RELOP 264 109#define IO_OUT 265 110#define IO_IN 266 111#define ASSIGNOP 267 112#define ASSIGN 268 113#define MATCHOP 269 114#define CONCAT_OP 270 115#define LEX_BEGIN 271 116#define LEX_END 272 117#define LEX_IF 273 118#define LEX_ELSE 274 119#define LEX_RETURN 275 120#define LEX_DELETE 276 121#define LEX_SWITCH 277 122#define LEX_CASE 278 123#define LEX_DEFAULT 279 124#define LEX_WHILE 280 125#define LEX_DO 281 126#define LEX_FOR 282 127#define LEX_BREAK 283 128#define LEX_CONTINUE 284 129#define LEX_PRINT 285 130#define LEX_PRINTF 286 131#define LEX_NEXT 287 132#define LEX_EXIT 288 133#define LEX_FUNCTION 289 134#define LEX_GETLINE 290 135#define LEX_NEXTFILE 291 136#define LEX_IN 292 137#define LEX_AND 293 138#define LEX_OR 294 139#define INCREMENT 295 140#define DECREMENT 296 141#define LEX_BUILTIN 297 142#define LEX_LENGTH 298 143#define NEWLINE 299 144#define SLASH_BEFORE_EQUAL 300 145#define UNARY 301 146 147 148 149 150/* Copy the first part of user declarations. */ 151#line 26 "awkgram.y" 152 153#ifdef GAWKDEBUG 154#define YYDEBUG 12 155#endif 156 157#include "awk.h" 158 159#define CAN_FREE TRUE 160#define DONT_FREE FALSE 161 162#if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__ 163static void yyerror(const char *m, ...) ATTRIBUTE_PRINTF_1; 164#else 165static void yyerror(); /* va_alist */ 166#endif 167static char *get_src_buf P((void)); 168static int yylex P((void)); 169static NODE *node_common P((NODETYPE op)); 170static NODE *snode P((NODE *subn, NODETYPE op, int sindex)); 171static NODE *make_for_loop P((NODE *init, NODE *cond, NODE *incr)); 172static NODE *append_right P((NODE *list, NODE *new)); 173static inline NODE *append_pattern P((NODE **list, NODE *patt)); 174static void func_install P((NODE *params, NODE *def)); 175static void pop_var P((NODE *np, int freeit)); 176static void pop_params P((NODE *params)); 177static NODE *make_param P((char *name)); 178static NODE *mk_rexp P((NODE *exp)); 179static int dup_parms P((NODE *func)); 180static void param_sanity P((NODE *arglist)); 181static int parms_shadow P((const char *fname, NODE *func)); 182static int isnoeffect P((NODETYPE t)); 183static int isassignable P((NODE *n)); 184static void dumpintlstr P((const char *str, size_t len)); 185static void dumpintlstr2 P((const char *str1, size_t len1, const char *str2, size_t len2)); 186static void count_args P((NODE *n)); 187static int isarray P((NODE *n)); 188 189enum defref { FUNC_DEFINE, FUNC_USE }; 190static void func_use P((const char *name, enum defref how)); 191static void check_funcs P((void)); 192 193static int want_regexp; /* lexical scanning kludge */ 194static int can_return; /* parsing kludge */ 195static int begin_or_end_rule = FALSE; /* parsing kludge */ 196static int parsing_end_rule = FALSE; /* for warnings */ 197static int in_print = FALSE; /* lexical scanning kludge for print */ 198static int in_parens = 0; /* lexical scanning kludge for print */ 199static char *lexptr; /* pointer to next char during parsing */ 200static char *lexend; 201static char *lexptr_begin; /* keep track of where we were for error msgs */ 202static char *lexeme; /* beginning of lexeme for debugging */ 203static char *thisline = NULL; 204#define YYDEBUG_LEXER_TEXT (lexeme) 205static int param_counter; 206static char *tokstart = NULL; 207static char *tok = NULL; 208static char *tokend; 209 210static long func_count; /* total number of functions */ 211 212#define HASHSIZE 1021 /* this constant only used here */ 213NODE *variables[HASHSIZE]; 214static int var_count; /* total number of global variables */ 215 216extern char *source; 217extern int sourceline; 218extern struct src *srcfiles; 219extern int numfiles; 220extern int errcount; 221extern NODE *begin_block; 222extern NODE *end_block; 223 224/* 225 * This string cannot occur as a real awk identifier. 226 * Use it as a special token to make function parsing 227 * uniform, but if it's seen, don't install the function. 228 * e.g. 229 * function split(x) { return x } 230 * function x(a) { return a } 231 * should only produce one error message, and not core dump. 232 */ 233static char builtin_func[] = "@builtin"; 234 235 236/* Enabling traces. */ 237#ifndef YYDEBUG 238# define YYDEBUG 0 239#endif 240 241/* Enabling verbose error messages. */ 242#ifdef YYERROR_VERBOSE 243# undef YYERROR_VERBOSE 244# define YYERROR_VERBOSE 1 245#else 246# define YYERROR_VERBOSE 0 247#endif 248 249#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) 250#line 110 "awkgram.y" 251typedef union YYSTYPE { 252 long lval; 253 AWKNUM fval; 254 NODE *nodeval; 255 NODETYPE nodetypeval; 256 char *sval; 257 NODE *(*ptrval) P((void)); 258} YYSTYPE; 259/* Line 191 of yacc.c. */ 260#line 260 "y.tab.c" 261# define yystype YYSTYPE /* obsolescent; will be withdrawn */ 262# define YYSTYPE_IS_DECLARED 1 263# define YYSTYPE_IS_TRIVIAL 1 264#endif 265 266 267 268/* Copy the second part of user declarations. */ 269 270 271/* Line 214 of yacc.c. */ 272#line 272 "y.tab.c" 273 274#if ! defined (yyoverflow) || YYERROR_VERBOSE 275 276/* The parser invokes alloca or malloc; define the necessary symbols. */ 277 278#undef YYSTACK_USE_ALLOCA /* Gawk: nuke alloca once and for all */ 279 280# if YYSTACK_USE_ALLOCA 281# define YYSTACK_ALLOC alloca 282# else 283# ifndef YYSTACK_USE_ALLOCA 284# if defined (alloca) || defined (_ALLOCA_H) 285# define YYSTACK_ALLOC alloca 286# else 287# ifdef __GNUC__ 288# define YYSTACK_ALLOC __builtin_alloca 289# endif 290# endif 291# endif 292# endif 293 294# ifdef YYSTACK_ALLOC 295 /* Pacify GCC's `empty if-body' warning. */ 296# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) 297# else 298# if defined (__STDC__) || defined (__cplusplus) 299# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ 300# define YYSIZE_T size_t 301# endif 302# define YYSTACK_ALLOC malloc 303# define YYSTACK_FREE free 304# endif 305#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */ 306 307 308#if (! defined (yyoverflow) \ 309 && (! defined (__cplusplus) \ 310 || (YYSTYPE_IS_TRIVIAL))) 311 312/* A type that is properly aligned for any stack member. */ 313union yyalloc 314{ 315 short yyss; 316 YYSTYPE yyvs; 317 }; 318 319/* The size of the maximum gap between one aligned stack and the next. */ 320# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) 321 322/* The size of an array large to enough to hold all stacks, each with 323 N elements. */ 324# define YYSTACK_BYTES(N) \ 325 ((N) * (sizeof (short) + sizeof (YYSTYPE)) \ 326 + YYSTACK_GAP_MAXIMUM) 327 328/* Copy COUNT objects from FROM to TO. The source and destination do 329 not overlap. */ 330# ifndef YYCOPY 331# if 1 < __GNUC__ 332# define YYCOPY(To, From, Count) \ 333 __builtin_memcpy (To, From, (Count) * sizeof (*(From))) 334# else 335# define YYCOPY(To, From, Count) \ 336 do \ 337 { \ 338 register YYSIZE_T yyi; \ 339 for (yyi = 0; yyi < (Count); yyi++) \ 340 (To)[yyi] = (From)[yyi]; \ 341 } \ 342 while (0) 343# endif 344# endif 345 346/* Relocate STACK from its old location to the new one. The 347 local variables YYSIZE and YYSTACKSIZE give the old and new number of 348 elements in the stack, and YYPTR gives the new location of the 349 stack. Advance YYPTR to a properly aligned location for the next 350 stack. */ 351# define YYSTACK_RELOCATE(Stack) \ 352 do \ 353 { \ 354 YYSIZE_T yynewbytes; \ 355 YYCOPY (&yyptr->Stack, Stack, yysize); \ 356 Stack = &yyptr->Stack; \ 357 yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ 358 yyptr += yynewbytes / sizeof (*yyptr); \ 359 } \ 360 while (0) 361 362#endif 363 364#if defined (__STDC__) || defined (__cplusplus) 365 typedef signed char yysigned_char; 366#else 367 typedef short yysigned_char; 368#endif 369 370/* YYFINAL -- State number of the termination state. */ 371#define YYFINAL 5 372/* YYLAST -- Last index in YYTABLE. */ 373#define YYLAST 1008 374 375/* YYNTOKENS -- Number of terminals. */ 376#define YYNTOKENS 67 377/* YYNNTS -- Number of nonterminals. */ 378#define YYNNTS 53 379/* YYNRULES -- Number of rules. */ 380#define YYNRULES 155 381/* YYNRULES -- Number of states. */ 382#define YYNSTATES 293 383 384/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ 385#define YYUNDEFTOK 2 386#define YYMAXUTOK 301 387 388#define YYTRANSLATE(YYX) \ 389 ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) 390 391/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ 392static const unsigned char yytranslate[] = 393{ 394 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 395 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 396 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 397 2, 2, 2, 56, 2, 2, 59, 55, 2, 2, 398 60, 61, 53, 51, 48, 52, 2, 54, 2, 2, 399 2, 2, 2, 2, 2, 2, 2, 2, 47, 66, 400 49, 2, 50, 46, 2, 2, 2, 2, 2, 2, 401 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 402 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 403 2, 62, 2, 63, 58, 2, 2, 2, 2, 2, 404 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 405 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 406 2, 2, 2, 64, 2, 65, 2, 2, 2, 2, 407 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 408 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 409 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 410 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 411 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 412 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 413 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 414 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 415 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 416 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 417 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 418 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 419 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 420 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 421 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 422 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 423 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 424 45, 57 425}; 426 427#if YYDEBUG 428/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in 429 YYRHS. */ 430static const unsigned short yyprhs[] = 431{ 432 0, 0, 3, 7, 8, 11, 14, 17, 20, 23, 433 24, 26, 30, 32, 34, 40, 42, 44, 46, 48, 434 50, 51, 59, 60, 64, 66, 68, 69, 72, 75, 435 77, 80, 83, 87, 89, 99, 106, 115, 124, 137, 436 149, 152, 155, 158, 161, 165, 166, 171, 174, 175, 437 180, 186, 189, 194, 196, 197, 199, 201, 202, 205, 438 208, 214, 219, 221, 224, 227, 229, 231, 233, 235, 439 237, 243, 244, 245, 249, 256, 266, 268, 271, 272, 440 274, 275, 278, 279, 281, 283, 287, 289, 292, 296, 441 297, 299, 300, 302, 304, 308, 310, 313, 317, 321, 442 325, 329, 333, 337, 341, 345, 351, 353, 355, 357, 443 360, 362, 364, 366, 368, 370, 373, 379, 381, 384, 444 386, 390, 394, 398, 402, 406, 410, 414, 419, 422, 445 425, 428, 432, 437, 442, 444, 449, 451, 454, 457, 446 459, 461, 464, 467, 468, 470, 472, 477, 480, 483, 447 486, 488, 489, 491, 493, 495 448}; 449 450/* YYRHS -- A `-1'-separated list of the rules' RHS. */ 451static const yysigned_char yyrhs[] = 452{ 453 68, 0, -1, 97, 69, 97, -1, -1, 69, 70, 454 -1, 69, 1, -1, 71, 72, -1, 71, 81, -1, 455 75, 72, -1, -1, 104, -1, 104, 48, 104, -1, 456 16, -1, 17, -1, 113, 80, 114, 116, 97, -1, 457 4, -1, 3, -1, 74, -1, 42, -1, 43, -1, 458 -1, 34, 76, 73, 60, 99, 115, 97, -1, -1, 459 79, 78, 5, -1, 54, -1, 45, -1, -1, 80, 460 82, -1, 80, 1, -1, 96, -1, 117, 97, -1, 461 117, 97, -1, 113, 80, 114, -1, 95, -1, 22, 462 60, 104, 115, 97, 113, 87, 97, 114, -1, 25, 463 60, 104, 115, 97, 82, -1, 26, 97, 82, 25, 464 60, 104, 115, 97, -1, 27, 60, 4, 37, 4, 465 115, 97, 82, -1, 27, 60, 86, 117, 97, 104, 466 117, 97, 86, 115, 97, 82, -1, 27, 60, 86, 467 117, 97, 117, 97, 86, 115, 97, 82, -1, 28, 468 81, -1, 29, 81, -1, 32, 81, -1, 36, 81, 469 -1, 33, 101, 81, -1, -1, 20, 83, 101, 81, 470 -1, 84, 81, -1, -1, 91, 85, 92, 93, -1, 471 21, 4, 62, 103, 63, -1, 21, 4, -1, 21, 472 60, 4, 61, -1, 104, -1, -1, 84, -1, 88, 473 -1, -1, 88, 89, -1, 88, 1, -1, 23, 90, 474 118, 97, 80, -1, 24, 118, 97, 80, -1, 7, 475 -1, 52, 7, -1, 51, 7, -1, 8, -1, 77, 476 -1, 30, -1, 31, -1, 102, -1, 60, 104, 119, 477 103, 115, -1, -1, -1, 10, 94, 108, -1, 18, 478 60, 104, 115, 97, 82, -1, 18, 60, 104, 115, 479 97, 82, 19, 97, 82, -1, 44, -1, 96, 44, 480 -1, -1, 96, -1, -1, 49, 109, -1, -1, 100, 481 -1, 4, -1, 100, 119, 4, -1, 1, -1, 100, 482 1, -1, 100, 119, 1, -1, -1, 104, -1, -1, 483 103, -1, 104, -1, 103, 119, 104, -1, 1, -1, 484 103, 1, -1, 103, 1, 104, -1, 103, 119, 1, 485 -1, 112, 105, 104, -1, 104, 38, 104, -1, 104, 486 39, 104, -1, 104, 14, 104, -1, 104, 37, 4, 487 -1, 104, 107, 104, -1, 104, 46, 104, 47, 104, 488 -1, 108, -1, 13, -1, 12, -1, 45, 13, -1, 489 9, -1, 49, -1, 106, -1, 50, -1, 77, -1, 490 56, 77, -1, 60, 103, 115, 37, 4, -1, 109, 491 -1, 108, 109, -1, 110, -1, 109, 58, 109, -1, 492 109, 53, 109, -1, 109, 54, 109, -1, 109, 55, 493 109, -1, 109, 51, 109, -1, 109, 52, 109, -1, 494 35, 111, 98, -1, 109, 11, 35, 111, -1, 112, 495 40, -1, 112, 41, -1, 56, 109, -1, 60, 104, 496 115, -1, 42, 60, 102, 115, -1, 43, 60, 102, 497 115, -1, 43, -1, 3, 60, 102, 115, -1, 112, 498 -1, 40, 112, -1, 41, 112, -1, 7, -1, 8, 499 -1, 52, 109, -1, 51, 109, -1, -1, 112, -1, 500 4, -1, 4, 62, 103, 63, -1, 59, 110, -1, 501 64, 97, -1, 65, 97, -1, 61, -1, -1, 117, 502 -1, 66, -1, 47, -1, 48, 97, -1 503}; 504 505/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ 506static const unsigned short yyrline[] = 507{ 508 0, 171, 171, 177, 179, 184, 196, 200, 215, 226, 509 229, 233, 243, 248, 256, 261, 263, 265, 276, 277, 510 282, 281, 305, 304, 327, 328, 333, 334, 352, 357, 511 358, 362, 364, 366, 368, 370, 372, 374, 416, 420, 512 425, 428, 431, 440, 460, 463, 462, 469, 481, 481, 513 512, 514, 528, 543, 549, 550, 555, 608, 609, 626, 514 631, 633, 638, 640, 645, 647, 649, 654, 655, 663, 515 664, 670, 675, 675, 686, 691, 698, 699, 702, 704, 516 709, 710, 716, 717, 722, 724, 726, 728, 730, 737, 517 738, 744, 745, 750, 752, 758, 760, 762, 764, 769, 518 775, 777, 779, 785, 787, 793, 795, 800, 802, 804, 519 809, 811, 815, 816, 821, 823, 831, 833, 835, 840, 520 842, 844, 846, 848, 850, 852, 854, 860, 865, 867, 521 872, 874, 876, 879, 881, 889, 897, 898, 900, 902, 522 904, 907, 915, 927, 928, 933, 935, 949, 954, 958, 523 962, 965, 967, 971, 975, 978 524}; 525#endif 526 527#if YYDEBUG || YYERROR_VERBOSE 528/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. 529 First, the terminals, then, starting at YYNTOKENS, nonterminals. */ 530static const char *const yytname[] = 531{ 532 "$end", "error", "$undefined", "FUNC_CALL", "NAME", "REGEXP", "ERROR", 533 "YNUMBER", "YSTRING", "RELOP", "IO_OUT", "IO_IN", "ASSIGNOP", "ASSIGN", 534 "MATCHOP", "CONCAT_OP", "LEX_BEGIN", "LEX_END", "LEX_IF", "LEX_ELSE", 535 "LEX_RETURN", "LEX_DELETE", "LEX_SWITCH", "LEX_CASE", "LEX_DEFAULT", 536 "LEX_WHILE", "LEX_DO", "LEX_FOR", "LEX_BREAK", "LEX_CONTINUE", 537 "LEX_PRINT", "LEX_PRINTF", "LEX_NEXT", "LEX_EXIT", "LEX_FUNCTION", 538 "LEX_GETLINE", "LEX_NEXTFILE", "LEX_IN", "LEX_AND", "LEX_OR", 539 "INCREMENT", "DECREMENT", "LEX_BUILTIN", "LEX_LENGTH", "NEWLINE", 540 "SLASH_BEFORE_EQUAL", "'?'", "':'", "','", "'<'", "'>'", "'+'", "'-'", 541 "'*'", "'/'", "'%'", "'!'", "UNARY", "'^'", "'$'", "'('", "')'", "'['", 542 "']'", "'{'", "'}'", "';'", "$accept", "start", "program", "rule", 543 "pattern", "action", "func_name", "lex_builtin", "function_prologue", 544 "@1", "regexp", "@2", "a_slash", "statements", "statement_term", 545 "statement", "@3", "simple_stmt", "@4", "opt_simple_stmt", 546 "switch_body", "case_statements", "case_statement", "case_value", 547 "print", "print_expression_list", "output_redir", "@5", "if_statement", 548 "nls", "opt_nls", "input_redir", "opt_param_list", "param_list", 549 "opt_exp", "opt_expression_list", "expression_list", "exp", 550 "assign_operator", "relop_or_less", "a_relop", "common_exp", "simp_exp", 551 "non_post_simp_exp", "opt_variable", "variable", "l_brace", "r_brace", 552 "r_paren", "opt_semi", "semi", "colon", "comma", 0 553}; 554#endif 555 556# ifdef YYPRINT 557/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to 558 token YYLEX-NUM. */ 559static const unsigned short yytoknum[] = 560{ 561 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 562 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 563 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 564 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 565 295, 296, 297, 298, 299, 300, 63, 58, 44, 60, 566 62, 43, 45, 42, 47, 37, 33, 301, 94, 36, 567 40, 41, 91, 93, 123, 125, 59 568}; 569# endif 570 571/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ 572static const unsigned char yyr1[] = 573{ 574 0, 67, 68, 69, 69, 69, 70, 70, 70, 71, 575 71, 71, 71, 71, 72, 73, 73, 73, 74, 74, 576 76, 75, 78, 77, 79, 79, 80, 80, 80, 81, 577 81, 82, 82, 82, 82, 82, 82, 82, 82, 82, 578 82, 82, 82, 82, 82, 83, 82, 82, 85, 84, 579 84, 84, 84, 84, 86, 86, 87, 88, 88, 88, 580 89, 89, 90, 90, 90, 90, 90, 91, 91, 92, 581 92, 93, 94, 93, 95, 95, 96, 96, 97, 97, 582 98, 98, 99, 99, 100, 100, 100, 100, 100, 101, 583 101, 102, 102, 103, 103, 103, 103, 103, 103, 104, 584 104, 104, 104, 104, 104, 104, 104, 105, 105, 105, 585 106, 106, 107, 107, 108, 108, 108, 108, 108, 109, 586 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 587 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 588 110, 110, 110, 111, 111, 112, 112, 112, 113, 114, 589 115, 116, 116, 117, 118, 119 590}; 591 592/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ 593static const unsigned char yyr2[] = 594{ 595 0, 2, 3, 0, 2, 2, 2, 2, 2, 0, 596 1, 3, 1, 1, 5, 1, 1, 1, 1, 1, 597 0, 7, 0, 3, 1, 1, 0, 2, 2, 1, 598 2, 2, 3, 1, 9, 6, 8, 8, 12, 11, 599 2, 2, 2, 2, 3, 0, 4, 2, 0, 4, 600 5, 2, 4, 1, 0, 1, 1, 0, 2, 2, 601 5, 4, 1, 2, 2, 1, 1, 1, 1, 1, 602 5, 0, 0, 3, 6, 9, 1, 2, 0, 1, 603 0, 2, 0, 1, 1, 3, 1, 2, 3, 0, 604 1, 0, 1, 1, 3, 1, 2, 3, 3, 3, 605 3, 3, 3, 3, 3, 5, 1, 1, 1, 2, 606 1, 1, 1, 1, 1, 2, 5, 1, 2, 1, 607 3, 3, 3, 3, 3, 3, 3, 4, 2, 2, 608 2, 3, 4, 4, 1, 4, 1, 2, 2, 1, 609 1, 2, 2, 0, 1, 1, 4, 2, 2, 2, 610 1, 0, 1, 1, 1, 2 611}; 612 613/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state 614 STATE-NUM when YYTABLE doesn't specify something else to do. Zero 615 means the default is an error. */ 616static const unsigned char yydefact[] = 617{ 618 78, 76, 0, 79, 3, 1, 77, 0, 5, 0, 619 145, 139, 140, 12, 13, 20, 143, 0, 0, 0, 620 134, 25, 0, 0, 24, 0, 0, 0, 4, 0, 621 0, 114, 22, 2, 10, 106, 117, 119, 136, 0, 622 0, 0, 80, 144, 137, 138, 0, 0, 0, 0, 623 142, 136, 141, 115, 130, 147, 136, 95, 0, 93, 624 78, 153, 6, 7, 29, 26, 78, 8, 0, 110, 625 0, 0, 0, 0, 0, 0, 111, 113, 112, 0, 626 118, 0, 0, 0, 0, 0, 0, 0, 108, 107, 627 128, 129, 0, 0, 0, 0, 93, 0, 16, 15, 628 18, 19, 0, 17, 0, 126, 0, 0, 0, 96, 629 78, 150, 0, 0, 131, 148, 0, 30, 23, 102, 630 103, 100, 101, 0, 11, 104, 143, 124, 125, 121, 631 122, 123, 120, 109, 99, 135, 146, 0, 81, 132, 632 133, 97, 155, 0, 98, 94, 28, 0, 45, 0, 633 0, 0, 78, 0, 0, 0, 67, 68, 0, 89, 634 0, 78, 27, 0, 48, 33, 53, 26, 151, 78, 635 0, 127, 86, 84, 0, 0, 116, 0, 89, 51, 636 0, 0, 0, 0, 54, 40, 41, 42, 0, 90, 637 43, 149, 47, 0, 0, 78, 152, 31, 105, 78, 638 87, 0, 0, 0, 0, 0, 0, 0, 0, 145, 639 55, 0, 44, 0, 71, 69, 32, 14, 21, 88, 640 85, 78, 46, 0, 52, 78, 78, 0, 0, 78, 641 93, 72, 49, 0, 50, 0, 0, 0, 0, 0, 642 0, 0, 74, 57, 35, 0, 78, 0, 78, 0, 643 73, 78, 78, 0, 78, 0, 78, 54, 70, 0, 644 0, 59, 0, 0, 58, 36, 37, 54, 0, 75, 645 34, 62, 65, 0, 0, 66, 0, 154, 78, 0, 646 78, 64, 63, 78, 26, 78, 0, 26, 0, 0, 647 39, 0, 38 648}; 649 650/* YYDEFGOTO[NTERM-NUM]. */ 651static const short yydefgoto[] = 652{ 653 -1, 2, 7, 28, 29, 62, 102, 103, 30, 41, 654 31, 68, 32, 116, 63, 162, 178, 163, 193, 211, 655 252, 253, 264, 276, 164, 214, 232, 241, 165, 3, 656 4, 105, 174, 175, 188, 94, 95, 166, 93, 78, 657 79, 35, 36, 37, 42, 38, 167, 168, 114, 195, 658 169, 278, 113 659}; 660 661/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing 662 STATE-NUM. */ 663#define YYPACT_NINF -236 664static const short yypact[] = 665{ 666 -15, -236, 31, -3, -236, -236, -236, 292, -236, -8, 667 -2, -236, -236, -236, -236, -236, 26, 26, 26, 4, 668 6, -236, 934, 934, -236, 876, 262, 717, -236, -16, 669 3, -236, -236, -236, 769, 934, 480, -236, 554, 656, 670 717, 33, 49, -236, -236, -236, 656, 656, 934, 905, 671 41, -1, 41, -236, 41, -236, -236, -236, 117, 695, 672 -15, -236, -236, -236, -3, -236, -15, -236, 101, -236, 673 905, 103, 905, 905, 905, 905, -236, -236, -236, 905, 674 480, 74, 934, 934, 934, 934, 934, 934, -236, -236, 675 -236, -236, 100, 905, 54, 17, 958, 32, -236, -236, 676 -236, -236, 56, -236, 934, -236, 54, 54, 695, 905, 677 -15, -236, 86, 739, -236, -236, 454, -236, -236, 133, 678 -236, 184, 166, 823, 958, 7, 26, 136, 136, 41, 679 41, 41, 41, -236, 958, -236, -236, 43, 538, -236, 680 -236, 958, -236, 121, -236, 958, -236, 68, -236, 2, 681 69, 70, -15, 71, 61, 61, -236, -236, 61, 905, 682 61, -15, -236, 61, -236, -236, 958, -236, 73, -15, 683 905, -236, -236, -236, 54, 123, -236, 905, 905, 81, 684 131, 905, 905, 580, 793, -236, -236, -236, 61, 958, 685 -236, -236, -236, 520, 454, -15, -236, -236, 958, -15, 686 -236, 45, 695, 61, 717, 83, 695, 695, 130, -11, 687 -236, 73, -236, 717, 147, -236, -236, -236, -236, -236, 688 -236, -15, -236, 34, -236, -15, -15, 108, 169, -15, 689 508, -236, -236, 580, -236, 3, 580, 905, 54, 634, 690 717, 905, 155, -236, -236, 695, -15, 502, -15, 117, 691 934, -15, -15, 19, -15, 580, -15, 847, -236, 580, 692 111, -236, 201, 132, -236, -236, -236, 847, 54, -236, 693 -236, -236, -236, 178, 179, -236, 132, -236, -15, 54, 694 -15, -236, -236, -15, -236, -15, 580, -236, 346, 580, 695 -236, 400, -236 696}; 697 698/* YYPGOTO[NTERM-NUM]. */ 699static const short yypgoto[] = 700{ 701 -236, -236, -236, -236, -236, 165, -236, -236, -236, -236, 702 -24, -236, -236, -150, 152, -178, -236, -165, -236, -235, 703 -236, -236, -236, -236, -236, -236, -236, -236, -236, -22, 704 -7, -236, -236, -236, 21, -32, -17, 47, -236, -236, 705 -236, -41, 66, 175, 76, -14, -5, -181, 52, -236, 706 9, -71, -130 707}; 708 709/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If 710 positive, shift that token. If negative, reduce the rule which 711 number is the opposite. If zero, do what YYDEFACT says. 712 If YYTABLE_NINF, syntax error. */ 713#define YYTABLE_NINF -93 714static const short yytable[] = 715{ 716 33, 53, 43, 44, 45, 208, 179, 64, 51, 51, 717 58, 51, 56, 216, 106, 107, -93, 194, 109, 210, 718 261, 51, 268, 97, 65, 65, 228, -92, 1, 1, 719 10, 5, 279, 109, 51, 109, 98, 99, 66, 90, 720 91, 6, 262, 263, 172, 201, 219, 173, 60, 220, 721 61, 40, 39, 115, 34, 242, -93, -93, 244, 117, 722 40, -92, 180, -56, 46, 110, 47, 60, 51, 51, 723 51, 51, 51, 51, 59, 100, 101, 266, -92, 270, 724 110, 269, 110, -92, -56, 26, 96, 96, 50, 52, 725 51, 54, 210, 96, 96, 136, 108, 234, 104, 87, 726 240, 80, 210, 142, -82, 1, 118, 120, 290, 126, 727 112, 292, 43, 133, 54, 111, 137, 119, 109, 121, 728 122, 123, 124, 143, 200, 176, 125, 61, 177, 181, 729 182, 184, 64, 64, 288, 205, 64, 291, 64, 61, 730 134, 64, 69, 204, 224, 183, 135, -93, 127, 128, 731 129, 130, 131, 132, 191, 227, 141, 231, 139, 140, 732 145, 215, 197, 66, 66, 110, 64, 66, 237, 66, 733 138, 110, 66, 238, 251, 69, 161, 196, 111, 277, 734 70, 64, 76, 77, -83, 281, 282, 223, 217, 84, 735 85, 86, 218, 69, 87, 67, 58, 66, 70, 203, 736 250, 55, 171, 71, 72, 283, 189, 0, 271, 272, 737 0, 0, 66, 0, 233, 76, 77, 198, 235, 236, 738 229, 71, 239, 249, 202, 189, 199, 51, 206, 207, 739 243, 0, 0, 76, 77, 0, 51, 0, 275, 255, 740 96, 257, 0, 0, 259, 260, 21, 265, 248, 267, 741 0, 96, 273, 274, 221, 24, 256, 0, 225, 226, 742 230, 0, 0, 0, 0, 9, 10, 0, 0, 11, 743 12, 284, 0, 286, 0, 0, 287, 0, 289, 0, 744 0, 0, 0, 0, 245, 0, 247, 96, 0, 0, 745 246, 0, -78, 8, 0, 9, 10, 254, 0, 11, 746 12, 258, 17, 18, 19, 20, 185, 186, 13, 14, 747 187, 0, 190, 22, 23, 192, 80, 0, 48, 0, 748 280, 26, 49, 0, 0, 0, 15, 16, 0, 0, 749 0, 285, 17, 18, 19, 20, 1, 21, 0, 0, 750 212, 0, 0, 22, 23, 0, 24, 146, 25, 9, 751 10, 26, 27, 11, 12, 222, -9, 0, -9, 0, 752 0, 0, 0, 0, 147, 0, 148, 149, 150, -61, 753 -61, 151, 152, 153, 154, 155, 156, 157, 158, 159, 754 0, 16, 160, 0, 0, 0, 17, 18, 19, 20, 755 -61, 21, 0, 0, 0, 0, 0, 22, 23, 0, 756 24, 146, 25, 9, 10, 26, 27, 11, 12, 0, 757 60, -61, 61, 0, 0, 0, 0, 0, 147, 0, 758 148, 149, 150, -60, -60, 151, 152, 153, 154, 155, 759 156, 157, 158, 159, 0, 16, 160, 0, 0, 0, 760 17, 18, 19, 20, -60, 21, 0, 0, 0, 0, 761 0, 22, 23, 0, 24, 146, 25, 9, 10, 26, 762 27, 11, 12, 0, 60, -60, 61, 0, 0, 0, 763 0, 0, 147, 0, 148, 149, 150, 0, 0, 151, 764 152, 153, 154, 155, 156, 157, 158, 159, 0, 16, 765 160, 81, 0, 0, 17, 18, 19, 20, 0, 21, 766 0, 0, 0, 0, 0, 22, 23, 0, 24, 0, 767 25, 69, 0, 26, 27, 0, 70, 69, 60, 161, 768 61, 57, 70, 9, 10, 0, 0, 11, 12, 0, 769 -91, 82, 83, 84, 85, 86, 0, 0, 87, 71, 770 72, 73, 0, 0, 0, 71, 72, 73, 74, -93, 771 0, 76, 77, 0, 74, 16, 110, 76, 77, 0, 772 17, 18, 19, 20, -91, 21, 88, 89, 61, 111, 773 0, 22, 23, 0, 24, 0, 25, 0, 0, 26, 774 213, -91, 0, 9, 10, 0, -91, 11, 12, 82, 775 83, 84, 85, 86, 90, 91, 87, 0, 147, 92, 776 148, 149, 150, 0, 0, 151, 152, 153, 154, 155, 777 156, 157, 158, 159, 0, 16, 160, 0, 0, 0, 778 17, 18, 19, 20, 0, 21, 0, 0, 0, 0, 779 0, 22, 23, 0, 24, 0, 25, 9, 10, 26, 780 27, 11, 12, 0, 60, 0, 61, 0, 0, 0, 781 0, 0, 0, 0, 0, 0, 0, 57, 0, 9, 782 10, 0, 0, 11, 12, 0, 0, 0, 0, 16, 783 0, 0, 0, 0, 17, 18, 19, 20, 0, 21, 784 0, 0, 0, 0, 0, 22, 23, 0, 24, 0, 785 25, 16, 0, 26, 27, 0, 17, 18, 19, 20, 786 61, 21, 0, 0, 69, 0, 0, 22, 23, 70, 787 24, 0, 25, 0, 0, 26, 27, -91, 57, 0, 788 9, 10, 0, 0, 11, 12, 0, 0, 0, 0, 789 0, 0, 71, 72, 73, 0, 0, 0, 0, 0, 790 144, 74, 9, 10, 76, 77, 11, 12, 0, 0, 791 0, 0, 16, 0, 0, 0, 111, 17, 18, 19, 792 20, 0, 21, 0, 0, 0, 0, 0, 22, 23, 793 0, 24, 0, 25, 16, 0, 26, 27, 69, 17, 794 18, 19, 20, 70, 21, 0, 0, 0, 0, 0, 795 22, 23, 0, 24, 0, 25, 9, 209, 26, 27, 796 11, 12, 0, 0, 0, 0, 71, 72, 73, 0, 797 0, 0, 0, 0, 149, 74, 0, 75, 76, 77, 798 0, 0, 0, 156, 157, 0, 0, 0, 16, 0, 799 0, 0, 69, 17, 18, 19, 20, 70, 21, 0, 800 0, 0, 0, 0, 22, 23, 0, 24, 0, 25, 801 9, 10, 26, 27, 11, 12, 0, 0, 0, 0, 802 71, 72, 73, 0, 0, 0, 0, 0, 149, 74, 803 170, 0, 76, 77, 0, 0, 0, 156, 157, 9, 804 10, 0, 16, 11, 12, 0, 0, 17, 18, 19, 805 20, 0, 21, 0, 0, 0, 0, 0, 22, 23, 806 0, 24, 0, 25, 0, 0, 26, 27, 9, 10, 807 0, 16, 11, 12, 0, 0, 17, 18, 19, 20, 808 0, 21, 0, 0, 0, 0, 0, 22, 23, 0, 809 24, 0, 48, 0, 0, 26, 49, 9, 10, 0, 810 16, 11, 12, 0, 0, 17, 18, 19, 20, 0, 811 21, 0, 0, 0, 0, 0, 22, 23, 0, 24, 812 0, 25, 0, 0, 26, 27, 0, 69, 0, 16, 813 0, 0, 70, 0, 17, 18, 19, 20, 0, 0, 814 0, 0, 0, 0, 0, 22, 23, 0, 0, 0, 815 48, 0, 0, 26, 49, 71, 72, 73, 0, 0, 816 0, 0, 0, 0, 74, 0, 0, 76, 77 817}; 818 819static const short yycheck[] = 820{ 821 7, 25, 16, 17, 18, 183, 4, 29, 22, 23, 822 27, 25, 26, 194, 46, 47, 9, 167, 1, 184, 823 1, 35, 257, 40, 29, 30, 37, 10, 44, 44, 824 4, 0, 267, 1, 48, 1, 3, 4, 29, 40, 825 41, 44, 23, 24, 1, 175, 1, 4, 64, 4, 826 66, 62, 60, 60, 7, 233, 49, 50, 236, 66, 827 62, 44, 60, 44, 60, 48, 60, 64, 82, 83, 828 84, 85, 86, 87, 27, 42, 43, 255, 61, 260, 829 48, 259, 48, 66, 65, 59, 39, 40, 22, 23, 830 104, 25, 257, 46, 47, 63, 49, 63, 49, 58, 831 230, 35, 267, 110, 61, 44, 5, 4, 286, 35, 832 58, 289, 126, 13, 48, 61, 60, 70, 1, 72, 833 73, 74, 75, 37, 1, 4, 79, 66, 60, 60, 834 60, 60, 154, 155, 284, 4, 158, 287, 160, 66, 835 93, 163, 9, 62, 61, 152, 94, 14, 82, 83, 836 84, 85, 86, 87, 161, 25, 109, 10, 106, 107, 837 113, 193, 169, 154, 155, 48, 188, 158, 60, 160, 838 104, 48, 163, 4, 19, 9, 65, 168, 61, 47, 839 14, 203, 49, 50, 61, 7, 7, 204, 195, 53, 840 54, 55, 199, 9, 58, 30, 213, 188, 14, 178, 841 241, 26, 126, 37, 38, 276, 159, -1, 7, 8, 842 -1, -1, 203, -1, 221, 49, 50, 170, 225, 226, 843 211, 37, 229, 240, 177, 178, 174, 241, 181, 182, 844 235, -1, -1, 49, 50, -1, 250, -1, 262, 246, 845 193, 248, -1, -1, 251, 252, 45, 254, 239, 256, 846 -1, 204, 51, 52, 202, 54, 247, -1, 206, 207, 847 213, -1, -1, -1, -1, 3, 4, -1, -1, 7, 848 8, 278, -1, 280, -1, -1, 283, -1, 285, -1, 849 -1, -1, -1, -1, 237, -1, 239, 240, -1, -1, 850 238, -1, 0, 1, -1, 3, 4, 245, -1, 7, 851 8, 249, 40, 41, 42, 43, 154, 155, 16, 17, 852 158, -1, 160, 51, 52, 163, 250, -1, 56, -1, 853 268, 59, 60, -1, -1, -1, 34, 35, -1, -1, 854 -1, 279, 40, 41, 42, 43, 44, 45, -1, -1, 855 188, -1, -1, 51, 52, -1, 54, 1, 56, 3, 856 4, 59, 60, 7, 8, 203, 64, -1, 66, -1, 857 -1, -1, -1, -1, 18, -1, 20, 21, 22, 23, 858 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 859 -1, 35, 36, -1, -1, -1, 40, 41, 42, 43, 860 44, 45, -1, -1, -1, -1, -1, 51, 52, -1, 861 54, 1, 56, 3, 4, 59, 60, 7, 8, -1, 862 64, 65, 66, -1, -1, -1, -1, -1, 18, -1, 863 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 864 30, 31, 32, 33, -1, 35, 36, -1, -1, -1, 865 40, 41, 42, 43, 44, 45, -1, -1, -1, -1, 866 -1, 51, 52, -1, 54, 1, 56, 3, 4, 59, 867 60, 7, 8, -1, 64, 65, 66, -1, -1, -1, 868 -1, -1, 18, -1, 20, 21, 22, -1, -1, 25, 869 26, 27, 28, 29, 30, 31, 32, 33, -1, 35, 870 36, 11, -1, -1, 40, 41, 42, 43, -1, 45, 871 -1, -1, -1, -1, -1, 51, 52, -1, 54, -1, 872 56, 9, -1, 59, 60, -1, 14, 9, 64, 65, 873 66, 1, 14, 3, 4, -1, -1, 7, 8, -1, 874 10, 51, 52, 53, 54, 55, -1, -1, 58, 37, 875 38, 39, -1, -1, -1, 37, 38, 39, 46, 11, 876 -1, 49, 50, -1, 46, 35, 48, 49, 50, -1, 877 40, 41, 42, 43, 44, 45, 12, 13, 66, 61, 878 -1, 51, 52, -1, 54, -1, 56, -1, -1, 59, 879 60, 61, -1, 3, 4, -1, 66, 7, 8, 51, 880 52, 53, 54, 55, 40, 41, 58, -1, 18, 45, 881 20, 21, 22, -1, -1, 25, 26, 27, 28, 29, 882 30, 31, 32, 33, -1, 35, 36, -1, -1, -1, 883 40, 41, 42, 43, -1, 45, -1, -1, -1, -1, 884 -1, 51, 52, -1, 54, -1, 56, 3, 4, 59, 885 60, 7, 8, -1, 64, -1, 66, -1, -1, -1, 886 -1, -1, -1, -1, -1, -1, -1, 1, -1, 3, 887 4, -1, -1, 7, 8, -1, -1, -1, -1, 35, 888 -1, -1, -1, -1, 40, 41, 42, 43, -1, 45, 889 -1, -1, -1, -1, -1, 51, 52, -1, 54, -1, 890 56, 35, -1, 59, 60, -1, 40, 41, 42, 43, 891 66, 45, -1, -1, 9, -1, -1, 51, 52, 14, 892 54, -1, 56, -1, -1, 59, 60, 61, 1, -1, 893 3, 4, -1, -1, 7, 8, -1, -1, -1, -1, 894 -1, -1, 37, 38, 39, -1, -1, -1, -1, -1, 895 1, 46, 3, 4, 49, 50, 7, 8, -1, -1, 896 -1, -1, 35, -1, -1, -1, 61, 40, 41, 42, 897 43, -1, 45, -1, -1, -1, -1, -1, 51, 52, 898 -1, 54, -1, 56, 35, -1, 59, 60, 9, 40, 899 41, 42, 43, 14, 45, -1, -1, -1, -1, -1, 900 51, 52, -1, 54, -1, 56, 3, 4, 59, 60, 901 7, 8, -1, -1, -1, -1, 37, 38, 39, -1, 902 -1, -1, -1, -1, 21, 46, -1, 48, 49, 50, 903 -1, -1, -1, 30, 31, -1, -1, -1, 35, -1, 904 -1, -1, 9, 40, 41, 42, 43, 14, 45, -1, 905 -1, -1, -1, -1, 51, 52, -1, 54, -1, 56, 906 3, 4, 59, 60, 7, 8, -1, -1, -1, -1, 907 37, 38, 39, -1, -1, -1, -1, -1, 21, 46, 908 47, -1, 49, 50, -1, -1, -1, 30, 31, 3, 909 4, -1, 35, 7, 8, -1, -1, 40, 41, 42, 910 43, -1, 45, -1, -1, -1, -1, -1, 51, 52, 911 -1, 54, -1, 56, -1, -1, 59, 60, 3, 4, 912 -1, 35, 7, 8, -1, -1, 40, 41, 42, 43, 913 -1, 45, -1, -1, -1, -1, -1, 51, 52, -1, 914 54, -1, 56, -1, -1, 59, 60, 3, 4, -1, 915 35, 7, 8, -1, -1, 40, 41, 42, 43, -1, 916 45, -1, -1, -1, -1, -1, 51, 52, -1, 54, 917 -1, 56, -1, -1, 59, 60, -1, 9, -1, 35, 918 -1, -1, 14, -1, 40, 41, 42, 43, -1, -1, 919 -1, -1, -1, -1, -1, 51, 52, -1, -1, -1, 920 56, -1, -1, 59, 60, 37, 38, 39, -1, -1, 921 -1, -1, -1, -1, 46, -1, -1, 49, 50 922}; 923 924/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing 925 symbol of state STATE-NUM. */ 926static const unsigned char yystos[] = 927{ 928 0, 44, 68, 96, 97, 0, 44, 69, 1, 3, 929 4, 7, 8, 16, 17, 34, 35, 40, 41, 42, 930 43, 45, 51, 52, 54, 56, 59, 60, 70, 71, 931 75, 77, 79, 97, 104, 108, 109, 110, 112, 60, 932 62, 76, 111, 112, 112, 112, 60, 60, 56, 60, 933 109, 112, 109, 77, 109, 110, 112, 1, 103, 104, 934 64, 66, 72, 81, 96, 113, 117, 72, 78, 9, 935 14, 37, 38, 39, 46, 48, 49, 50, 106, 107, 936 109, 11, 51, 52, 53, 54, 55, 58, 12, 13, 937 40, 41, 45, 105, 102, 103, 104, 103, 3, 4, 938 42, 43, 73, 74, 49, 98, 102, 102, 104, 1, 939 48, 61, 115, 119, 115, 97, 80, 97, 5, 104, 940 4, 104, 104, 104, 104, 104, 35, 109, 109, 109, 941 109, 109, 109, 13, 104, 115, 63, 60, 109, 115, 942 115, 104, 97, 37, 1, 104, 1, 18, 20, 21, 943 22, 25, 26, 27, 28, 29, 30, 31, 32, 33, 944 36, 65, 82, 84, 91, 95, 104, 113, 114, 117, 945 47, 111, 1, 4, 99, 100, 4, 60, 83, 4, 946 60, 60, 60, 97, 60, 81, 81, 81, 101, 104, 947 81, 97, 81, 85, 80, 116, 117, 97, 104, 115, 948 1, 119, 104, 101, 62, 4, 104, 104, 82, 4, 949 84, 86, 81, 60, 92, 102, 114, 97, 97, 1, 950 4, 115, 81, 103, 61, 115, 115, 25, 37, 117, 951 104, 10, 93, 97, 63, 97, 97, 60, 4, 97, 952 119, 94, 82, 113, 82, 104, 115, 104, 117, 103, 953 108, 19, 87, 88, 115, 97, 117, 97, 115, 97, 954 97, 1, 23, 24, 89, 97, 82, 97, 86, 82, 955 114, 7, 8, 51, 52, 77, 90, 47, 118, 86, 956 115, 7, 7, 118, 97, 115, 97, 97, 80, 97, 957 82, 80, 82 958}; 959 960#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) 961# define YYSIZE_T __SIZE_TYPE__ 962#endif 963#if ! defined (YYSIZE_T) && defined (size_t) 964# define YYSIZE_T size_t 965#endif 966#if ! defined (YYSIZE_T) 967# if defined (__STDC__) || defined (__cplusplus) 968# include <stddef.h> /* INFRINGES ON USER NAME SPACE */ 969# define YYSIZE_T size_t 970# endif 971#endif 972#if ! defined (YYSIZE_T) 973# define YYSIZE_T unsigned int 974#endif 975 976#define yyerrok (yyerrstatus = 0) 977#define yyclearin (yychar = YYEMPTY) 978#define YYEMPTY (-2) 979#define YYEOF 0 980 981#define YYACCEPT goto yyacceptlab 982#define YYABORT goto yyabortlab 983#define YYERROR goto yyerrlab1 984 985/* Like YYERROR except do call yyerror. This remains here temporarily 986 to ease the transition to the new meaning of YYERROR, for GCC. 987 Once GCC version 2 has supplanted version 1, this can go. */ 988 989#define YYFAIL goto yyerrlab 990 991#define YYRECOVERING() (!!yyerrstatus) 992 993#define YYBACKUP(Token, Value) \ 994do \ 995 if (yychar == YYEMPTY && yylen == 1) \ 996 { \ 997 yychar = (Token); \ 998 yylval = (Value); \ 999 yytoken = YYTRANSLATE (yychar); \ 1000 YYPOPSTACK; \ 1001 goto yybackup; \ 1002 } \ 1003 else \ 1004 { \ 1005 yyerror ("syntax error: cannot back up");\ 1006 YYERROR; \ 1007 } \ 1008while (0) 1009 1010#define YYTERROR 1 1011#define YYERRCODE 256 1012 1013/* YYLLOC_DEFAULT -- Compute the default location (before the actions 1014 are run). */ 1015 1016#ifndef YYLLOC_DEFAULT 1017# define YYLLOC_DEFAULT(Current, Rhs, N) \ 1018 Current.first_line = Rhs[1].first_line; \ 1019 Current.first_column = Rhs[1].first_column; \ 1020 Current.last_line = Rhs[N].last_line; \ 1021 Current.last_column = Rhs[N].last_column; 1022#endif 1023 1024/* YYLEX -- calling `yylex' with the right arguments. */ 1025 1026#ifdef YYLEX_PARAM 1027# define YYLEX yylex (YYLEX_PARAM) 1028#else 1029# define YYLEX yylex () 1030#endif 1031 1032/* Enable debugging if requested. */ 1033#if YYDEBUG 1034 1035# ifndef YYFPRINTF 1036# include <stdio.h> /* INFRINGES ON USER NAME SPACE */ 1037# define YYFPRINTF fprintf 1038# endif 1039 1040# define YYDPRINTF(Args) \ 1041do { \ 1042 if (yydebug) \ 1043 YYFPRINTF Args; \ 1044} while (0) 1045 1046# define YYDSYMPRINT(Args) \ 1047do { \ 1048 if (yydebug) \ 1049 yysymprint Args; \ 1050} while (0) 1051 1052# define YYDSYMPRINTF(Title, Token, Value, Location) \ 1053do { \ 1054 if (yydebug) \ 1055 { \ 1056 YYFPRINTF (stderr, "%s ", Title); \ 1057 yysymprint (stderr, \ 1058 Token, Value); \ 1059 YYFPRINTF (stderr, "\n"); \ 1060 } \ 1061} while (0) 1062 1063/*------------------------------------------------------------------. 1064| yy_stack_print -- Print the state stack from its BOTTOM up to its | 1065| TOP (cinluded). | 1066`------------------------------------------------------------------*/ 1067 1068#if defined (__STDC__) || defined (__cplusplus) 1069static void 1070yy_stack_print (short *bottom, short *top) 1071#else 1072static void 1073yy_stack_print (bottom, top) 1074 short *bottom; 1075 short *top; 1076#endif 1077{ 1078 YYFPRINTF (stderr, "Stack now"); 1079 for (/* Nothing. */; bottom <= top; ++bottom) 1080 YYFPRINTF (stderr, " %d", *bottom); 1081 YYFPRINTF (stderr, "\n"); 1082} 1083 1084# define YY_STACK_PRINT(Bottom, Top) \ 1085do { \ 1086 if (yydebug) \ 1087 yy_stack_print ((Bottom), (Top)); \ 1088} while (0) 1089 1090 1091/*------------------------------------------------. 1092| Report that the YYRULE is going to be reduced. | 1093`------------------------------------------------*/ 1094 1095#if defined (__STDC__) || defined (__cplusplus) 1096static void 1097yy_reduce_print (int yyrule) 1098#else 1099static void 1100yy_reduce_print (yyrule) 1101 int yyrule; 1102#endif 1103{ 1104 int yyi; 1105 unsigned int yylineno = yyrline[yyrule]; 1106 YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ", 1107 yyrule - 1, yylineno); 1108 /* Print the symbols being reduced, and their result. */ 1109 for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++) 1110 YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]); 1111 YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]); 1112} 1113 1114# define YY_REDUCE_PRINT(Rule) \ 1115do { \ 1116 if (yydebug) \ 1117 yy_reduce_print (Rule); \ 1118} while (0) 1119 1120/* Nonzero means print parse trace. It is left uninitialized so that 1121 multiple parsers can coexist. */ 1122int yydebug; 1123#else /* !YYDEBUG */ 1124# define YYDPRINTF(Args) 1125# define YYDSYMPRINT(Args) 1126# define YYDSYMPRINTF(Title, Token, Value, Location) 1127# define YY_STACK_PRINT(Bottom, Top) 1128# define YY_REDUCE_PRINT(Rule) 1129#endif /* !YYDEBUG */ 1130 1131 1132/* YYINITDEPTH -- initial size of the parser's stacks. */ 1133#ifndef YYINITDEPTH 1134# define YYINITDEPTH 200 1135#endif 1136 1137/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only 1138 if the built-in stack extension method is used). 1139 1140 Do not make this value too large; the results are undefined if 1141 SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH) 1142 evaluated with infinite-precision integer arithmetic. */ 1143 1144#if YYMAXDEPTH == 0 1145# undef YYMAXDEPTH 1146#endif 1147 1148#ifndef YYMAXDEPTH 1149# define YYMAXDEPTH 10000 1150#endif 1151 1152 1153 1154#if YYERROR_VERBOSE 1155 1156# ifndef yystrlen 1157# if defined (__GLIBC__) && defined (_STRING_H) 1158# define yystrlen strlen 1159# else 1160/* Return the length of YYSTR. */ 1161static YYSIZE_T 1162# if defined (__STDC__) || defined (__cplusplus) 1163yystrlen (const char *yystr) 1164# else 1165yystrlen (yystr) 1166 const char *yystr; 1167# endif 1168{ 1169 register const char *yys = yystr; 1170 1171 while (*yys++ != '\0') 1172 continue; 1173 1174 return yys - yystr - 1; 1175} 1176# endif 1177# endif 1178 1179# ifndef yystpcpy 1180# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE) 1181# define yystpcpy stpcpy 1182# else 1183/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in 1184 YYDEST. */ 1185static char * 1186# if defined (__STDC__) || defined (__cplusplus) 1187yystpcpy (char *yydest, const char *yysrc) 1188# else 1189yystpcpy (yydest, yysrc) 1190 char *yydest; 1191 const char *yysrc; 1192# endif 1193{ 1194 register char *yyd = yydest; 1195 register const char *yys = yysrc; 1196 1197 while ((*yyd++ = *yys++) != '\0') 1198 continue; 1199 1200 return yyd - 1; 1201} 1202# endif 1203# endif 1204 1205#endif /* !YYERROR_VERBOSE */ 1206 1207 1208 1209#if YYDEBUG 1210/*--------------------------------. 1211| Print this symbol on YYOUTPUT. | 1212`--------------------------------*/ 1213 1214#if defined (__STDC__) || defined (__cplusplus) 1215static void 1216yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep) 1217#else 1218static void 1219yysymprint (yyoutput, yytype, yyvaluep) 1220 FILE *yyoutput; 1221 int yytype; 1222 YYSTYPE *yyvaluep; 1223#endif 1224{ 1225 /* Pacify ``unused variable'' warnings. */ 1226 (void) yyvaluep; 1227 1228 if (yytype < YYNTOKENS) 1229 { 1230 YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); 1231# ifdef YYPRINT 1232 YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); 1233# endif 1234 } 1235 else 1236 YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); 1237 1238 switch (yytype) 1239 { 1240 default: 1241 break; 1242 } 1243 YYFPRINTF (yyoutput, ")"); 1244} 1245 1246#endif /* ! YYDEBUG */ 1247/*-----------------------------------------------. 1248| Release the memory associated to this symbol. | 1249`-----------------------------------------------*/ 1250 1251#if defined (__STDC__) || defined (__cplusplus) 1252static void 1253yydestruct (int yytype, YYSTYPE *yyvaluep) 1254#else 1255static void 1256yydestruct (yytype, yyvaluep) 1257 int yytype; 1258 YYSTYPE *yyvaluep; 1259#endif 1260{ 1261 /* Pacify ``unused variable'' warnings. */ 1262 (void) yyvaluep; 1263 1264 switch (yytype) 1265 { 1266 1267 default: 1268 break; 1269 } 1270} 1271 1272 1273/* Prevent warnings from -Wmissing-prototypes. */ 1274 1275#ifdef YYPARSE_PARAM 1276# if defined (__STDC__) || defined (__cplusplus) 1277int yyparse (void *YYPARSE_PARAM); 1278# else 1279int yyparse (); 1280# endif 1281#else /* ! YYPARSE_PARAM */ 1282#if defined (__STDC__) || defined (__cplusplus) 1283int yyparse (void); 1284#else 1285int yyparse (); 1286#endif 1287#endif /* ! YYPARSE_PARAM */ 1288 1289 1290 1291/* The lookahead symbol. */ 1292int yychar; 1293 1294/* The semantic value of the lookahead symbol. */ 1295YYSTYPE yylval; 1296 1297/* Number of syntax errors so far. */ 1298int yynerrs; 1299 1300 1301 1302/*----------. 1303| yyparse. | 1304`----------*/ 1305 1306#ifdef YYPARSE_PARAM 1307# if defined (__STDC__) || defined (__cplusplus) 1308int yyparse (void *YYPARSE_PARAM) 1309# else 1310int yyparse (YYPARSE_PARAM) 1311 void *YYPARSE_PARAM; 1312# endif 1313#else /* ! YYPARSE_PARAM */ 1314#if defined (__STDC__) || defined (__cplusplus) 1315int 1316yyparse (void) 1317#else 1318int 1319yyparse () 1320 1321#endif 1322#endif 1323{ 1324 1325 register int yystate; 1326 register int yyn; 1327 int yyresult; 1328 /* Number of tokens to shift before error messages enabled. */ 1329 int yyerrstatus; 1330 /* Lookahead token as an internal (translated) token number. */ 1331 int yytoken = 0; 1332 1333 /* Three stacks and their tools: 1334 `yyss': related to states, 1335 `yyvs': related to semantic values, 1336 `yyls': related to locations. 1337 1338 Refer to the stacks thru separate pointers, to allow yyoverflow 1339 to reallocate them elsewhere. */ 1340 1341 /* The state stack. */ 1342 short yyssa[YYINITDEPTH]; 1343 short *yyss = yyssa; 1344 register short *yyssp; 1345 1346 /* The semantic value stack. */ 1347 YYSTYPE yyvsa[YYINITDEPTH]; 1348 YYSTYPE *yyvs = yyvsa; 1349 register YYSTYPE *yyvsp; 1350 1351 1352 1353#define YYPOPSTACK (yyvsp--, yyssp--) 1354 1355 YYSIZE_T yystacksize = YYINITDEPTH; 1356 1357 /* The variables used to return semantic value and location from the 1358 action routines. */ 1359 YYSTYPE yyval; 1360 1361 1362 /* When reducing, the number of symbols on the RHS of the reduced 1363 rule. */ 1364 int yylen; 1365 1366 YYDPRINTF ((stderr, "Starting parse\n")); 1367 1368 yystate = 0; 1369 yyerrstatus = 0; 1370 yynerrs = 0; 1371 yychar = YYEMPTY; /* Cause a token to be read. */ 1372 1373 /* Initialize stack pointers. 1374 Waste one element of value and location stack 1375 so that they stay on the same level as the state stack. 1376 The wasted elements are never initialized. */ 1377 1378 yyssp = yyss; 1379 yyvsp = yyvs; 1380 1381 goto yysetstate; 1382 1383/*------------------------------------------------------------. 1384| yynewstate -- Push a new state, which is found in yystate. | 1385`------------------------------------------------------------*/ 1386 yynewstate: 1387 /* In all cases, when you get here, the value and location stacks 1388 have just been pushed. so pushing a state here evens the stacks. 1389 */ 1390 yyssp++; 1391 1392 yysetstate: 1393 *yyssp = yystate; 1394 1395 if (yyss + yystacksize - 1 <= yyssp) 1396 { 1397 /* Get the current used size of the three stacks, in elements. */ 1398 YYSIZE_T yysize = yyssp - yyss + 1; 1399 1400#ifdef yyoverflow 1401 { 1402 /* Give user a chance to reallocate the stack. Use copies of 1403 these so that the &'s don't force the real ones into 1404 memory. */ 1405 YYSTYPE *yyvs1 = yyvs; 1406 short *yyss1 = yyss; 1407 1408 1409 /* Each stack pointer address is followed by the size of the 1410 data in use in that stack, in bytes. This used to be a 1411 conditional around just the two extra args, but that might 1412 be undefined if yyoverflow is a macro. */ 1413 yyoverflow ("parser stack overflow", 1414 &yyss1, yysize * sizeof (*yyssp), 1415 &yyvs1, yysize * sizeof (*yyvsp), 1416 1417 &yystacksize); 1418 1419 yyss = yyss1; 1420 yyvs = yyvs1; 1421 } 1422#else /* no yyoverflow */ 1423# ifndef YYSTACK_RELOCATE 1424 goto yyoverflowlab; 1425# else 1426 /* Extend the stack our own way. */ 1427 if (YYMAXDEPTH <= yystacksize) 1428 goto yyoverflowlab; 1429 yystacksize *= 2; 1430 if (YYMAXDEPTH < yystacksize) 1431 yystacksize = YYMAXDEPTH; 1432 1433 { 1434 short *yyss1 = yyss; 1435 union yyalloc *yyptr = 1436 (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); 1437 if (! yyptr) 1438 goto yyoverflowlab; 1439 YYSTACK_RELOCATE (yyss); 1440 YYSTACK_RELOCATE (yyvs); 1441 1442# undef YYSTACK_RELOCATE 1443 if (yyss1 != yyssa) 1444 YYSTACK_FREE (yyss1); 1445 } 1446# endif 1447#endif /* no yyoverflow */ 1448 1449 yyssp = yyss + yysize - 1; 1450 yyvsp = yyvs + yysize - 1; 1451 1452 1453 YYDPRINTF ((stderr, "Stack size increased to %lu\n", 1454 (unsigned long int) yystacksize)); 1455 1456 if (yyss + yystacksize - 1 <= yyssp) 1457 YYABORT; 1458 } 1459 1460 YYDPRINTF ((stderr, "Entering state %d\n", yystate)); 1461 1462 goto yybackup; 1463 1464/*-----------. 1465| yybackup. | 1466`-----------*/ 1467yybackup: 1468 1469/* Do appropriate processing given the current state. */ 1470/* Read a lookahead token if we need one and don't already have one. */ 1471/* yyresume: */ 1472 1473 /* First try to decide what to do without reference to lookahead token. */ 1474 1475 yyn = yypact[yystate]; 1476 if (yyn == YYPACT_NINF) 1477 goto yydefault; 1478 1479 /* Not known => get a lookahead token if don't already have one. */ 1480 1481 /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ 1482 if (yychar == YYEMPTY) 1483 { 1484 YYDPRINTF ((stderr, "Reading a token: ")); 1485 yychar = YYLEX; 1486 } 1487 1488 if (yychar <= YYEOF) 1489 { 1490 yychar = yytoken = YYEOF; 1491 YYDPRINTF ((stderr, "Now at end of input.\n")); 1492 } 1493 else 1494 { 1495 yytoken = YYTRANSLATE (yychar); 1496 YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc); 1497 } 1498 1499 /* If the proper action on seeing token YYTOKEN is to reduce or to 1500 detect an error, take that action. */ 1501 yyn += yytoken; 1502 if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) 1503 goto yydefault; 1504 yyn = yytable[yyn]; 1505 if (yyn <= 0) 1506 { 1507 if (yyn == 0 || yyn == YYTABLE_NINF) 1508 goto yyerrlab; 1509 yyn = -yyn; 1510 goto yyreduce; 1511 } 1512 1513 if (yyn == YYFINAL) 1514 YYACCEPT; 1515 1516 /* Shift the lookahead token. */ 1517 YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken])); 1518 1519 /* Discard the token being shifted unless it is eof. */ 1520 if (yychar != YYEOF) 1521 yychar = YYEMPTY; 1522 1523 *++yyvsp = yylval; 1524 1525 1526 /* Count tokens shifted since error; after three, turn off error 1527 status. */ 1528 if (yyerrstatus) 1529 yyerrstatus--; 1530 1531 yystate = yyn; 1532 goto yynewstate; 1533 1534 1535/*-----------------------------------------------------------. 1536| yydefault -- do the default action for the current state. | 1537`-----------------------------------------------------------*/ 1538yydefault: 1539 yyn = yydefact[yystate]; 1540 if (yyn == 0) 1541 goto yyerrlab; 1542 goto yyreduce; 1543 1544 1545/*-----------------------------. 1546| yyreduce -- Do a reduction. | 1547`-----------------------------*/ 1548yyreduce: 1549 /* yyn is the number of a rule to reduce with. */ 1550 yylen = yyr2[yyn]; 1551 1552 /* If YYLEN is nonzero, implement the default value of the action: 1553 `$$ = $1'. 1554 1555 Otherwise, the following line sets YYVAL to garbage. 1556 This behavior is undocumented and Bison 1557 users should not rely upon it. Assigning to YYVAL 1558 unconditionally makes the parser a bit smaller, and it avoids a 1559 GCC warning that YYVAL may be used uninitialized. */ 1560 yyval = yyvsp[1-yylen]; 1561 1562 1563 YY_REDUCE_PRINT (yyn); 1564 switch (yyn) 1565 { 1566 case 2: 1567#line 172 "awkgram.y" 1568 { 1569 check_funcs(); 1570 } 1571 break; 1572 1573 case 4: 1574#line 180 "awkgram.y" 1575 { 1576 begin_or_end_rule = parsing_end_rule = FALSE; 1577 yyerrok; 1578 } 1579 break; 1580 1581 case 5: 1582#line 185 "awkgram.y" 1583 { 1584 begin_or_end_rule = parsing_end_rule = FALSE; 1585 /* 1586 * If errors, give up, don't produce an infinite 1587 * stream of syntax error messages. 1588 */ 1589 /* yyerrok; */ 1590 } 1591 break; 1592 1593 case 6: 1594#line 197 "awkgram.y" 1595 { 1596 yyvsp[-1].nodeval->rnode = yyvsp[0].nodeval; 1597 } 1598 break; 1599 1600 case 7: 1601#line 201 "awkgram.y" 1602 { 1603 if (yyvsp[-1].nodeval->lnode != NULL) { 1604 /* pattern rule with non-empty pattern */ 1605 yyvsp[-1].nodeval->rnode = node(NULL, Node_K_print_rec, NULL); 1606 } else { 1607 /* an error */ 1608 if (begin_or_end_rule) 1609 warning(_("%s blocks must have an action part"), 1610 (parsing_end_rule ? "END" : "BEGIN")); 1611 else 1612 warning(_("each rule must have a pattern or an action part")); 1613 errcount++; 1614 } 1615 } 1616 break; 1617 1618 case 8: 1619#line 216 "awkgram.y" 1620 { 1621 can_return = FALSE; 1622 if (yyvsp[-1].nodeval) 1623 func_install(yyvsp[-1].nodeval, yyvsp[0].nodeval); 1624 yyerrok; 1625 } 1626 break; 1627 1628 case 9: 1629#line 226 "awkgram.y" 1630 { 1631 yyval.nodeval = append_pattern(&expression_value, (NODE *) NULL); 1632 } 1633 break; 1634 1635 case 10: 1636#line 230 "awkgram.y" 1637 { 1638 yyval.nodeval = append_pattern(&expression_value, yyvsp[0].nodeval); 1639 } 1640 break; 1641 1642 case 11: 1643#line 234 "awkgram.y" 1644 { 1645 NODE *r; 1646 1647 getnode(r); 1648 r->type = Node_line_range; 1649 r->condpair = node(yyvsp[-2].nodeval, Node_cond_pair, yyvsp[0].nodeval); 1650 r->triggered = FALSE; 1651 yyval.nodeval = append_pattern(&expression_value, r); 1652 } 1653 break; 1654 1655 case 12: 1656#line 244 "awkgram.y" 1657 { 1658 begin_or_end_rule = TRUE; 1659 yyval.nodeval = append_pattern(&begin_block, (NODE *) NULL); 1660 } 1661 break; 1662 1663 case 13: 1664#line 249 "awkgram.y" 1665 { 1666 begin_or_end_rule = parsing_end_rule = TRUE; 1667 yyval.nodeval = append_pattern(&end_block, (NODE *) NULL); 1668 } 1669 break; 1670 1671 case 14: 1672#line 257 "awkgram.y" 1673 { yyval.nodeval = yyvsp[-3].nodeval; } 1674 break; 1675 1676 case 15: 1677#line 262 "awkgram.y" 1678 { yyval.sval = yyvsp[0].sval; } 1679 break; 1680 1681 case 16: 1682#line 264 "awkgram.y" 1683 { yyval.sval = yyvsp[0].sval; } 1684 break; 1685 1686 case 17: 1687#line 266 "awkgram.y" 1688 { 1689 yyerror(_("`%s' is a built-in function, it cannot be redefined"), 1690 tokstart); 1691 errcount++; 1692 yyval.sval = builtin_func; 1693 /* yyerrok; */ 1694 } 1695 break; 1696 1697 case 20: 1698#line 282 "awkgram.y" 1699 { 1700 param_counter = 0; 1701 } 1702 break; 1703 1704 case 21: 1705#line 286 "awkgram.y" 1706 { 1707 NODE *t; 1708 1709 t = make_param(yyvsp[-4].sval); 1710 t->flags |= FUNC; 1711 yyval.nodeval = append_right(t, yyvsp[-2].nodeval); 1712 can_return = TRUE; 1713 /* check for duplicate parameter names */ 1714 if (dup_parms(yyval.nodeval)) 1715 errcount++; 1716 } 1717 break; 1718 1719 case 22: 1720#line 305 "awkgram.y" 1721 { ++want_regexp; } 1722 break; 1723 1724 case 23: 1725#line 307 "awkgram.y" 1726 { 1727 NODE *n; 1728 size_t len = strlen(yyvsp[0].sval); 1729 1730 if (do_lint && (yyvsp[0].sval)[0] == '*') { 1731 /* possible C comment */ 1732 if ((yyvsp[0].sval)[len-1] == '*') 1733 lintwarn(_("regexp constant `/%s/' looks like a C comment, but is not"), tokstart); 1734 } 1735 getnode(n); 1736 n->type = Node_regex; 1737 n->re_exp = make_string(yyvsp[0].sval, len); 1738 n->re_reg = make_regexp(yyvsp[0].sval, len, FALSE); 1739 n->re_text = NULL; 1740 n->re_flags = CONST; 1741 yyval.nodeval = n; 1742 } 1743 break; 1744 1745 case 26: 1746#line 333 "awkgram.y" 1747 { yyval.nodeval = NULL; } 1748 break; 1749 1750 case 27: 1751#line 335 "awkgram.y" 1752 { 1753 if (yyvsp[0].nodeval == NULL) 1754 yyval.nodeval = yyvsp[-1].nodeval; 1755 else { 1756 if (do_lint && isnoeffect(yyvsp[0].nodeval->type)) 1757 lintwarn(_("statement may have no effect")); 1758 if (yyvsp[-1].nodeval == NULL) 1759 yyval.nodeval = yyvsp[0].nodeval; 1760 else 1761 yyval.nodeval = append_right( 1762 (yyvsp[-1].nodeval->type == Node_statement_list ? yyvsp[-1].nodeval 1763 : node(yyvsp[-1].nodeval, Node_statement_list, (NODE *) NULL)), 1764 (yyvsp[0].nodeval->type == Node_statement_list ? yyvsp[0].nodeval 1765 : node(yyvsp[0].nodeval, Node_statement_list, (NODE *) NULL))); 1766 } 1767 yyerrok; 1768 } 1769 break; 1770 1771 case 28: 1772#line 353 "awkgram.y" 1773 { yyval.nodeval = NULL; } 1774 break; 1775 1776 case 31: 1777#line 363 "awkgram.y" 1778 { yyval.nodeval = NULL; } 1779 break; 1780 1781 case 32: 1782#line 365 "awkgram.y" 1783 { yyval.nodeval = yyvsp[-1].nodeval; } 1784 break; 1785 1786 case 33: 1787#line 367 "awkgram.y" 1788 { yyval.nodeval = yyvsp[0].nodeval; } 1789 break; 1790 1791 case 34: 1792#line 369 "awkgram.y" 1793 { yyval.nodeval = node(yyvsp[-6].nodeval, Node_K_switch, yyvsp[-2].nodeval); } 1794 break; 1795 1796 case 35: 1797#line 371 "awkgram.y" 1798 { yyval.nodeval = node(yyvsp[-3].nodeval, Node_K_while, yyvsp[0].nodeval); } 1799 break; 1800 1801 case 36: 1802#line 373 "awkgram.y" 1803 { yyval.nodeval = node(yyvsp[-2].nodeval, Node_K_do, yyvsp[-5].nodeval); } 1804 break; 1805 1806 case 37: 1807#line 375 "awkgram.y" 1808 { 1809 /* 1810 * Efficiency hack. Recognize the special case of 1811 * 1812 * for (iggy in foo) 1813 * delete foo[iggy] 1814 * 1815 * and treat it as if it were 1816 * 1817 * delete foo 1818 * 1819 * Check that the body is a `delete a[i]' statement, 1820 * and that both the loop var and array names match. 1821 */ 1822 if (yyvsp[0].nodeval != NULL && yyvsp[0].nodeval->type == Node_K_delete) { 1823 NODE *arr, *sub; 1824 1825 assert(yyvsp[0].nodeval->rnode->type == Node_expression_list); 1826 arr = yyvsp[0].nodeval->lnode; /* array var */ 1827 sub = yyvsp[0].nodeval->rnode->lnode; /* index var */ 1828 1829 if ( (arr->type == Node_var_new 1830 || arr->type == Node_var_array 1831 || arr->type == Node_param_list) 1832 && (sub->type == Node_var_new 1833 || sub->type == Node_var 1834 || sub->type == Node_param_list) 1835 && strcmp(yyvsp[-5].sval, sub->vname) == 0 1836 && strcmp(yyvsp[-3].sval, arr->vname) == 0) { 1837 yyvsp[0].nodeval->type = Node_K_delete_loop; 1838 yyval.nodeval = yyvsp[0].nodeval; 1839 } 1840 else 1841 goto regular_loop; 1842 } else { 1843 regular_loop: 1844 yyval.nodeval = node(yyvsp[0].nodeval, Node_K_arrayfor, 1845 make_for_loop(variable(yyvsp[-5].sval, CAN_FREE, Node_var), 1846 (NODE *) NULL, variable(yyvsp[-3].sval, CAN_FREE, Node_var_array))); 1847 } 1848 } 1849 break; 1850 1851 case 38: 1852#line 417 "awkgram.y" 1853 { 1854 yyval.nodeval = node(yyvsp[0].nodeval, Node_K_for, (NODE *) make_for_loop(yyvsp[-9].nodeval, yyvsp[-6].nodeval, yyvsp[-3].nodeval)); 1855 } 1856 break; 1857 1858 case 39: 1859#line 421 "awkgram.y" 1860 { 1861 yyval.nodeval = node(yyvsp[0].nodeval, Node_K_for, 1862 (NODE *) make_for_loop(yyvsp[-8].nodeval, (NODE *) NULL, yyvsp[-3].nodeval)); 1863 } 1864 break; 1865 1866 case 40: 1867#line 427 "awkgram.y" 1868 { yyval.nodeval = node((NODE *) NULL, Node_K_break, (NODE *) NULL); } 1869 break; 1870 1871 case 41: 1872#line 430 "awkgram.y" 1873 { yyval.nodeval = node((NODE *) NULL, Node_K_continue, (NODE *) NULL); } 1874 break; 1875 1876 case 42: 1877#line 432 "awkgram.y" 1878 { NODETYPE type; 1879 1880 if (begin_or_end_rule) 1881 yyerror(_("`%s' used in %s action"), "next", 1882 (parsing_end_rule ? "END" : "BEGIN")); 1883 type = Node_K_next; 1884 yyval.nodeval = node((NODE *) NULL, type, (NODE *) NULL); 1885 } 1886 break; 1887 1888 case 43: 1889#line 441 "awkgram.y" 1890 { 1891 if (do_traditional) { 1892 /* 1893 * can't use yyerror, since may have overshot 1894 * the source line 1895 */ 1896 errcount++; 1897 error(_("`nextfile' is a gawk extension")); 1898 } 1899 if (do_lint) 1900 lintwarn(_("`nextfile' is a gawk extension")); 1901 if (begin_or_end_rule) { 1902 /* same thing */ 1903 errcount++; 1904 error(_("`%s' used in %s action"), "nextfile", 1905 (parsing_end_rule ? "END" : "BEGIN")); 1906 } 1907 yyval.nodeval = node((NODE *) NULL, Node_K_nextfile, (NODE *) NULL); 1908 } 1909 break; 1910 1911 case 44: 1912#line 461 "awkgram.y" 1913 { yyval.nodeval = node(yyvsp[-1].nodeval, Node_K_exit, (NODE *) NULL); } 1914 break; 1915 1916 case 45: 1917#line 463 "awkgram.y" 1918 { 1919 if (! can_return) 1920 yyerror(_("`return' used outside function context")); 1921 } 1922 break; 1923 1924 case 46: 1925#line 468 "awkgram.y" 1926 { yyval.nodeval = node(yyvsp[-1].nodeval, Node_K_return, (NODE *) NULL); } 1927 break; 1928 1929 case 48: 1930#line 481 "awkgram.y" 1931 { in_print = TRUE; in_parens = 0; } 1932 break; 1933 1934 case 49: 1935#line 482 "awkgram.y" 1936 { 1937 /* 1938 * Optimization: plain `print' has no expression list, so $3 is null. 1939 * If $3 is an expression list with one element (rnode == null) 1940 * and lnode is a field spec for field 0, we have `print $0'. 1941 * For both, use Node_K_print_rec, which is faster for these two cases. 1942 */ 1943 if (yyvsp[-3].nodetypeval == Node_K_print && 1944 (yyvsp[-1].nodeval == NULL 1945 || (yyvsp[-1].nodeval->type == Node_expression_list 1946 && yyvsp[-1].nodeval->rnode == NULL 1947 && yyvsp[-1].nodeval->lnode->type == Node_field_spec 1948 && yyvsp[-1].nodeval->lnode->lnode->type == Node_val 1949 && yyvsp[-1].nodeval->lnode->lnode->numbr == 0.0)) 1950 ) { 1951 static int warned = FALSE; 1952 1953 yyval.nodeval = node(NULL, Node_K_print_rec, yyvsp[0].nodeval); 1954 1955 if (do_lint && yyvsp[-1].nodeval == NULL && begin_or_end_rule && ! warned) { 1956 warned = TRUE; 1957 lintwarn( 1958 _("plain `print' in BEGIN or END rule should probably be `print \"\"'")); 1959 } 1960 } else { 1961 yyval.nodeval = node(yyvsp[-1].nodeval, yyvsp[-3].nodetypeval, yyvsp[0].nodeval); 1962 if (yyval.nodeval->type == Node_K_printf) 1963 count_args(yyval.nodeval); 1964 } 1965 } 1966 break; 1967 1968 case 50: 1969#line 513 "awkgram.y" 1970 { yyval.nodeval = node(variable(yyvsp[-3].sval, CAN_FREE, Node_var_array), Node_K_delete, yyvsp[-1].nodeval); } 1971 break; 1972 1973 case 51: 1974#line 515 "awkgram.y" 1975 { 1976 if (do_lint) 1977 lintwarn(_("`delete array' is a gawk extension")); 1978 if (do_traditional) { 1979 /* 1980 * can't use yyerror, since may have overshot 1981 * the source line 1982 */ 1983 errcount++; 1984 error(_("`delete array' is a gawk extension")); 1985 } 1986 yyval.nodeval = node(variable(yyvsp[0].sval, CAN_FREE, Node_var_array), Node_K_delete, (NODE *) NULL); 1987 } 1988 break; 1989 1990 case 52: 1991#line 529 "awkgram.y" 1992 { 1993 /* this is for tawk compatibility. maybe the warnings should always be done. */ 1994 if (do_lint) 1995 lintwarn(_("`delete(array)' is a non-portable tawk extension")); 1996 if (do_traditional) { 1997 /* 1998 * can't use yyerror, since may have overshot 1999 * the source line 2000 */ 2001 errcount++; 2002 error(_("`delete(array)' is a non-portable tawk extension")); 2003 } 2004 yyval.nodeval = node(variable(yyvsp[-1].sval, CAN_FREE, Node_var_array), Node_K_delete, (NODE *) NULL); 2005 } 2006 break; 2007 2008 case 53: 2009#line 544 "awkgram.y" 2010 { yyval.nodeval = yyvsp[0].nodeval; } 2011 break; 2012 2013 case 54: 2014#line 549 "awkgram.y" 2015 { yyval.nodeval = NULL; } 2016 break; 2017 2018 case 55: 2019#line 551 "awkgram.y" 2020 { yyval.nodeval = yyvsp[0].nodeval; } 2021 break; 2022 2023 case 56: 2024#line 556 "awkgram.y" 2025 { 2026 if (yyvsp[0].nodeval == NULL) { 2027 yyval.nodeval = NULL; 2028 } else { 2029 NODE *dflt = NULL; 2030 NODE *head = yyvsp[0].nodeval; 2031 NODE *curr; 2032 2033 const char **case_values = NULL; 2034 2035 int maxcount = 128; 2036 int case_count = 0; 2037 int i; 2038 2039 emalloc(case_values, const char **, sizeof(char*) * maxcount, "switch_body"); 2040 for (curr = yyvsp[0].nodeval; curr != NULL; curr = curr->rnode) { 2041 /* Assure that case statement values are unique. */ 2042 if (curr->lnode->type == Node_K_case) { 2043 char *caseval; 2044 2045 if (curr->lnode->lnode->type == Node_regex) 2046 caseval = curr->lnode->lnode->re_exp->stptr; 2047 else 2048 caseval = force_string(tree_eval(curr->lnode->lnode))->stptr; 2049 2050 for (i = 0; i < case_count; i++) 2051 if (strcmp(caseval, case_values[i]) == 0) 2052 yyerror(_("duplicate case values in switch body: %s"), caseval); 2053 2054 if (case_count >= maxcount) { 2055 maxcount += 128; 2056 erealloc(case_values, const char **, sizeof(char*) * maxcount, "switch_body"); 2057 } 2058 case_values[case_count++] = caseval; 2059 } else { 2060 /* Otherwise save a pointer to the default node. */ 2061 if (dflt != NULL) 2062 yyerror(_("Duplicate `default' detected in switch body")); 2063 dflt = curr; 2064 } 2065 } 2066 2067 free(case_values); 2068 2069 /* Create the switch body. */ 2070 yyval.nodeval = node(head, Node_switch_body, dflt); 2071 } 2072 } 2073 break; 2074 2075 case 57: 2076#line 608 "awkgram.y" 2077 { yyval.nodeval = NULL; } 2078 break; 2079 2080 case 58: 2081#line 610 "awkgram.y" 2082 { 2083 if (yyvsp[0].nodeval == NULL) 2084 yyval.nodeval = yyvsp[-1].nodeval; 2085 else { 2086 if (do_lint && isnoeffect(yyvsp[0].nodeval->type)) 2087 lintwarn(_("statement may have no effect")); 2088 if (yyvsp[-1].nodeval == NULL) 2089 yyval.nodeval = node(yyvsp[0].nodeval, Node_case_list, (NODE *) NULL); 2090 else 2091 yyval.nodeval = append_right( 2092 (yyvsp[-1].nodeval->type == Node_case_list ? yyvsp[-1].nodeval : node(yyvsp[-1].nodeval, Node_case_list, (NODE *) NULL)), 2093 (yyvsp[0].nodeval->type == Node_case_list ? yyvsp[0].nodeval : node(yyvsp[0].nodeval, Node_case_list, (NODE *) NULL)) 2094 ); 2095 } 2096 yyerrok; 2097 } 2098 break; 2099 2100 case 59: 2101#line 627 "awkgram.y" 2102 { yyval.nodeval = NULL; } 2103 break; 2104 2105 case 60: 2106#line 632 "awkgram.y" 2107 { yyval.nodeval = node(yyvsp[-3].nodeval, Node_K_case, yyvsp[0].nodeval); } 2108 break; 2109 2110 case 61: 2111#line 634 "awkgram.y" 2112 { yyval.nodeval = node((NODE *) NULL, Node_K_default, yyvsp[0].nodeval); } 2113 break; 2114 2115 case 62: 2116#line 639 "awkgram.y" 2117 { yyval.nodeval = yyvsp[0].nodeval; } 2118 break; 2119 2120 case 63: 2121#line 641 "awkgram.y" 2122 { 2123 yyvsp[0].nodeval->numbr = -(force_number(yyvsp[0].nodeval)); 2124 yyval.nodeval = yyvsp[0].nodeval; 2125 } 2126 break; 2127 2128 case 64: 2129#line 646 "awkgram.y" 2130 { yyval.nodeval = yyvsp[0].nodeval; } 2131 break; 2132 2133 case 65: 2134#line 648 "awkgram.y" 2135 { yyval.nodeval = yyvsp[0].nodeval; } 2136 break; 2137 2138 case 66: 2139#line 650 "awkgram.y" 2140 { yyval.nodeval = yyvsp[0].nodeval; } 2141 break; 2142 2143 case 70: 2144#line 665 "awkgram.y" 2145 { yyval.nodeval = node(yyvsp[-3].nodeval, Node_expression_list, yyvsp[-1].nodeval); } 2146 break; 2147 2148 case 71: 2149#line 670 "awkgram.y" 2150 { 2151 in_print = FALSE; 2152 in_parens = 0; 2153 yyval.nodeval = NULL; 2154 } 2155 break; 2156 2157 case 72: 2158#line 675 "awkgram.y" 2159 { in_print = FALSE; in_parens = 0; } 2160 break; 2161 2162 case 73: 2163#line 676 "awkgram.y" 2164 { 2165 yyval.nodeval = node(yyvsp[0].nodeval, yyvsp[-2].nodetypeval, (NODE *) NULL); 2166 if (yyvsp[-2].nodetypeval == Node_redirect_twoway 2167 && yyvsp[0].nodeval->type == Node_K_getline 2168 && yyvsp[0].nodeval->rnode->type == Node_redirect_twoway) 2169 yyerror(_("multistage two-way pipelines don't work")); 2170 } 2171 break; 2172 2173 case 74: 2174#line 687 "awkgram.y" 2175 { 2176 yyval.nodeval = node(yyvsp[-3].nodeval, Node_K_if, 2177 node(yyvsp[0].nodeval, Node_if_branches, (NODE *) NULL)); 2178 } 2179 break; 2180 2181 case 75: 2182#line 693 "awkgram.y" 2183 { yyval.nodeval = node(yyvsp[-6].nodeval, Node_K_if, 2184 node(yyvsp[-3].nodeval, Node_if_branches, yyvsp[0].nodeval)); } 2185 break; 2186 2187 case 80: 2188#line 709 "awkgram.y" 2189 { yyval.nodeval = NULL; } 2190 break; 2191 2192 case 81: 2193#line 711 "awkgram.y" 2194 { yyval.nodeval = node(yyvsp[0].nodeval, Node_redirect_input, (NODE *) NULL); } 2195 break; 2196 2197 case 82: 2198#line 716 "awkgram.y" 2199 { yyval.nodeval = NULL; } 2200 break; 2201 2202 case 83: 2203#line 718 "awkgram.y" 2204 { yyval.nodeval = yyvsp[0].nodeval; } 2205 break; 2206 2207 case 84: 2208#line 723 "awkgram.y" 2209 { yyval.nodeval = make_param(yyvsp[0].sval); } 2210 break; 2211 2212 case 85: 2213#line 725 "awkgram.y" 2214 { yyval.nodeval = append_right(yyvsp[-2].nodeval, make_param(yyvsp[0].sval)); yyerrok; } 2215 break; 2216 2217 case 86: 2218#line 727 "awkgram.y" 2219 { yyval.nodeval = NULL; } 2220 break; 2221 2222 case 87: 2223#line 729 "awkgram.y" 2224 { yyval.nodeval = NULL; } 2225 break; 2226 2227 case 88: 2228#line 731 "awkgram.y" 2229 { yyval.nodeval = NULL; } 2230 break; 2231 2232 case 89: 2233#line 737 "awkgram.y" 2234 { yyval.nodeval = NULL; } 2235 break; 2236 2237 case 90: 2238#line 739 "awkgram.y" 2239 { yyval.nodeval = yyvsp[0].nodeval; } 2240 break; 2241 2242 case 91: 2243#line 744 "awkgram.y" 2244 { yyval.nodeval = NULL; } 2245 break; 2246 2247 case 92: 2248#line 746 "awkgram.y" 2249 { yyval.nodeval = yyvsp[0].nodeval; } 2250 break; 2251 2252 case 93: 2253#line 751 "awkgram.y" 2254 { yyval.nodeval = node(yyvsp[0].nodeval, Node_expression_list, (NODE *) NULL); } 2255 break; 2256 2257 case 94: 2258#line 753 "awkgram.y" 2259 { 2260 yyval.nodeval = append_right(yyvsp[-2].nodeval, 2261 node(yyvsp[0].nodeval, Node_expression_list, (NODE *) NULL)); 2262 yyerrok; 2263 } 2264 break; 2265 2266 case 95: 2267#line 759 "awkgram.y" 2268 { yyval.nodeval = NULL; } 2269 break; 2270 2271 case 96: 2272#line 761 "awkgram.y" 2273 { yyval.nodeval = NULL; } 2274 break; 2275 2276 case 97: 2277#line 763 "awkgram.y" 2278 { yyval.nodeval = NULL; } 2279 break; 2280 2281 case 98: 2282#line 765 "awkgram.y" 2283 { yyval.nodeval = NULL; } 2284 break; 2285 2286 case 99: 2287#line 770 "awkgram.y" 2288 { 2289 if (do_lint && yyvsp[0].nodeval->type == Node_regex) 2290 lintwarn(_("regular expression on right of assignment")); 2291 yyval.nodeval = node(yyvsp[-2].nodeval, yyvsp[-1].nodetypeval, yyvsp[0].nodeval); 2292 } 2293 break; 2294 2295 case 100: 2296#line 776 "awkgram.y" 2297 { yyval.nodeval = node(yyvsp[-2].nodeval, Node_and, yyvsp[0].nodeval); } 2298 break; 2299 2300 case 101: 2301#line 778 "awkgram.y" 2302 { yyval.nodeval = node(yyvsp[-2].nodeval, Node_or, yyvsp[0].nodeval); } 2303 break; 2304 2305 case 102: 2306#line 780 "awkgram.y" 2307 { 2308 if (yyvsp[-2].nodeval->type == Node_regex) 2309 warning(_("regular expression on left of `~' or `!~' operator")); 2310 yyval.nodeval = node(yyvsp[-2].nodeval, yyvsp[-1].nodetypeval, mk_rexp(yyvsp[0].nodeval)); 2311 } 2312 break; 2313 2314 case 103: 2315#line 786 "awkgram.y" 2316 { yyval.nodeval = node(variable(yyvsp[0].sval, CAN_FREE, Node_var_array), Node_in_array, yyvsp[-2].nodeval); } 2317 break; 2318 2319 case 104: 2320#line 788 "awkgram.y" 2321 { 2322 if (do_lint && yyvsp[0].nodeval->type == Node_regex) 2323 lintwarn(_("regular expression on right of comparison")); 2324 yyval.nodeval = node(yyvsp[-2].nodeval, yyvsp[-1].nodetypeval, yyvsp[0].nodeval); 2325 } 2326 break; 2327 2328 case 105: 2329#line 794 "awkgram.y" 2330 { yyval.nodeval = node(yyvsp[-4].nodeval, Node_cond_exp, node(yyvsp[-2].nodeval, Node_if_branches, yyvsp[0].nodeval));} 2331 break; 2332 2333 case 106: 2334#line 796 "awkgram.y" 2335 { yyval.nodeval = yyvsp[0].nodeval; } 2336 break; 2337 2338 case 107: 2339#line 801 "awkgram.y" 2340 { yyval.nodetypeval = yyvsp[0].nodetypeval; } 2341 break; 2342 2343 case 108: 2344#line 803 "awkgram.y" 2345 { yyval.nodetypeval = yyvsp[0].nodetypeval; } 2346 break; 2347 2348 case 109: 2349#line 805 "awkgram.y" 2350 { yyval.nodetypeval = Node_assign_quotient; } 2351 break; 2352 2353 case 110: 2354#line 810 "awkgram.y" 2355 { yyval.nodetypeval = yyvsp[0].nodetypeval; } 2356 break; 2357 2358 case 111: 2359#line 812 "awkgram.y" 2360 { yyval.nodetypeval = Node_less; } 2361 break; 2362 2363 case 113: 2364#line 817 "awkgram.y" 2365 { yyval.nodetypeval = Node_greater; } 2366 break; 2367 2368 case 114: 2369#line 822 "awkgram.y" 2370 { yyval.nodeval = yyvsp[0].nodeval; } 2371 break; 2372 2373 case 115: 2374#line 824 "awkgram.y" 2375 { 2376 yyval.nodeval = node(node(make_number(0.0), 2377 Node_field_spec, 2378 (NODE *) NULL), 2379 Node_nomatch, 2380 yyvsp[0].nodeval); 2381 } 2382 break; 2383 2384 case 116: 2385#line 832 "awkgram.y" 2386 { yyval.nodeval = node(variable(yyvsp[0].sval, CAN_FREE, Node_var_array), Node_in_array, yyvsp[-3].nodeval); } 2387 break; 2388 2389 case 117: 2390#line 834 "awkgram.y" 2391 { yyval.nodeval = yyvsp[0].nodeval; } 2392 break; 2393 2394 case 118: 2395#line 836 "awkgram.y" 2396 { yyval.nodeval = node(yyvsp[-1].nodeval, Node_concat, yyvsp[0].nodeval); } 2397 break; 2398 2399 case 120: 2400#line 843 "awkgram.y" 2401 { yyval.nodeval = node(yyvsp[-2].nodeval, Node_exp, yyvsp[0].nodeval); } 2402 break; 2403 2404 case 121: 2405#line 845 "awkgram.y" 2406 { yyval.nodeval = node(yyvsp[-2].nodeval, Node_times, yyvsp[0].nodeval); } 2407 break; 2408 2409 case 122: 2410#line 847 "awkgram.y" 2411 { yyval.nodeval = node(yyvsp[-2].nodeval, Node_quotient, yyvsp[0].nodeval); } 2412 break; 2413 2414 case 123: 2415#line 849 "awkgram.y" 2416 { yyval.nodeval = node(yyvsp[-2].nodeval, Node_mod, yyvsp[0].nodeval); } 2417 break; 2418 2419 case 124: 2420#line 851 "awkgram.y" 2421 { yyval.nodeval = node(yyvsp[-2].nodeval, Node_plus, yyvsp[0].nodeval); } 2422 break; 2423 2424 case 125: 2425#line 853 "awkgram.y" 2426 { yyval.nodeval = node(yyvsp[-2].nodeval, Node_minus, yyvsp[0].nodeval); } 2427 break; 2428 2429 case 126: 2430#line 855 "awkgram.y" 2431 { 2432 if (do_lint && parsing_end_rule && yyvsp[0].nodeval == NULL) 2433 lintwarn(_("non-redirected `getline' undefined inside END action")); 2434 yyval.nodeval = node(yyvsp[-1].nodeval, Node_K_getline, yyvsp[0].nodeval); 2435 } 2436 break; 2437 2438 case 127: 2439#line 861 "awkgram.y" 2440 { 2441 yyval.nodeval = node(yyvsp[0].nodeval, Node_K_getline, 2442 node(yyvsp[-3].nodeval, yyvsp[-2].nodetypeval, (NODE *) NULL)); 2443 } 2444 break; 2445 2446 case 128: 2447#line 866 "awkgram.y" 2448 { yyval.nodeval = node(yyvsp[-1].nodeval, Node_postincrement, (NODE *) NULL); } 2449 break; 2450 2451 case 129: 2452#line 868 "awkgram.y" 2453 { yyval.nodeval = node(yyvsp[-1].nodeval, Node_postdecrement, (NODE *) NULL); } 2454 break; 2455 2456 case 130: 2457#line 873 "awkgram.y" 2458 { yyval.nodeval = node(yyvsp[0].nodeval, Node_not, (NODE *) NULL); } 2459 break; 2460 2461 case 131: 2462#line 875 "awkgram.y" 2463 { yyval.nodeval = yyvsp[-1].nodeval; } 2464 break; 2465 2466 case 132: 2467#line 878 "awkgram.y" 2468 { yyval.nodeval = snode(yyvsp[-1].nodeval, Node_builtin, (int) yyvsp[-3].lval); } 2469 break; 2470 2471 case 133: 2472#line 880 "awkgram.y" 2473 { yyval.nodeval = snode(yyvsp[-1].nodeval, Node_builtin, (int) yyvsp[-3].lval); } 2474 break; 2475 2476 case 134: 2477#line 882 "awkgram.y" 2478 { 2479 if (do_lint) 2480 lintwarn(_("call of `length' without parentheses is not portable")); 2481 yyval.nodeval = snode((NODE *) NULL, Node_builtin, (int) yyvsp[0].lval); 2482 if (do_posix) 2483 warning(_("call of `length' without parentheses is deprecated by POSIX")); 2484 } 2485 break; 2486 2487 case 135: 2488#line 890 "awkgram.y" 2489 { 2490 yyval.nodeval = node(yyvsp[-1].nodeval, Node_func_call, make_string(yyvsp[-3].sval, strlen(yyvsp[-3].sval))); 2491 yyval.nodeval->funcbody = NULL; 2492 func_use(yyvsp[-3].sval, FUNC_USE); 2493 param_sanity(yyvsp[-1].nodeval); 2494 free(yyvsp[-3].sval); 2495 } 2496 break; 2497 2498 case 137: 2499#line 899 "awkgram.y" 2500 { yyval.nodeval = node(yyvsp[0].nodeval, Node_preincrement, (NODE *) NULL); } 2501 break; 2502 2503 case 138: 2504#line 901 "awkgram.y" 2505 { yyval.nodeval = node(yyvsp[0].nodeval, Node_predecrement, (NODE *) NULL); } 2506 break; 2507 2508 case 139: 2509#line 903 "awkgram.y" 2510 { yyval.nodeval = yyvsp[0].nodeval; } 2511 break; 2512 2513 case 140: 2514#line 905 "awkgram.y" 2515 { yyval.nodeval = yyvsp[0].nodeval; } 2516 break; 2517 2518 case 141: 2519#line 908 "awkgram.y" 2520 { 2521 if (yyvsp[0].nodeval->type == Node_val && (yyvsp[0].nodeval->flags & (STRCUR|STRING)) == 0) { 2522 yyvsp[0].nodeval->numbr = -(force_number(yyvsp[0].nodeval)); 2523 yyval.nodeval = yyvsp[0].nodeval; 2524 } else 2525 yyval.nodeval = node(yyvsp[0].nodeval, Node_unary_minus, (NODE *) NULL); 2526 } 2527 break; 2528 2529 case 142: 2530#line 916 "awkgram.y" 2531 { 2532 /* 2533 * was: $$ = $2 2534 * POSIX semantics: force a conversion to numeric type 2535 */ 2536 yyval.nodeval = node (make_number(0.0), Node_plus, yyvsp[0].nodeval); 2537 } 2538 break; 2539 2540 case 143: 2541#line 927 "awkgram.y" 2542 { yyval.nodeval = NULL; } 2543 break; 2544 2545 case 144: 2546#line 929 "awkgram.y" 2547 { yyval.nodeval = yyvsp[0].nodeval; } 2548 break; 2549 2550 case 145: 2551#line 934 "awkgram.y" 2552 { yyval.nodeval = variable(yyvsp[0].sval, CAN_FREE, Node_var_new); } 2553 break; 2554 2555 case 146: 2556#line 936 "awkgram.y" 2557 { 2558 NODE *n; 2559 2560 if ((n = lookup(yyvsp[-3].sval)) != NULL && ! isarray(n)) 2561 yyerror(_("use of non-array as array")); 2562 else if (yyvsp[-1].nodeval == NULL) { 2563 fatal(_("invalid subscript expression")); 2564 } else if (yyvsp[-1].nodeval->rnode == NULL) { 2565 yyval.nodeval = node(variable(yyvsp[-3].sval, CAN_FREE, Node_var_array), Node_subscript, yyvsp[-1].nodeval->lnode); 2566 freenode(yyvsp[-1].nodeval); 2567 } else 2568 yyval.nodeval = node(variable(yyvsp[-3].sval, CAN_FREE, Node_var_array), Node_subscript, yyvsp[-1].nodeval); 2569 } 2570 break; 2571 2572 case 147: 2573#line 950 "awkgram.y" 2574 { yyval.nodeval = node(yyvsp[0].nodeval, Node_field_spec, (NODE *) NULL); } 2575 break; 2576 2577 case 149: 2578#line 958 "awkgram.y" 2579 { yyerrok; } 2580 break; 2581 2582 case 150: 2583#line 962 "awkgram.y" 2584 { yyerrok; } 2585 break; 2586 2587 case 153: 2588#line 971 "awkgram.y" 2589 { yyerrok; } 2590 break; 2591 2592 case 154: 2593#line 975 "awkgram.y" 2594 { yyerrok; } 2595 break; 2596 2597 case 155: 2598#line 978 "awkgram.y" 2599 { yyerrok; } 2600 break; 2601 2602 2603 } 2604 2605/* Line 991 of yacc.c. */ 2606#line 2604 "y.tab.c" 2607 2608 yyvsp -= yylen; 2609 yyssp -= yylen; 2610 2611 2612 YY_STACK_PRINT (yyss, yyssp); 2613 2614 *++yyvsp = yyval; 2615 2616 2617 /* Now `shift' the result of the reduction. Determine what state 2618 that goes to, based on the state we popped back to and the rule 2619 number reduced by. */ 2620 2621 yyn = yyr1[yyn]; 2622 2623 yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; 2624 if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) 2625 yystate = yytable[yystate]; 2626 else 2627 yystate = yydefgoto[yyn - YYNTOKENS]; 2628 2629 goto yynewstate; 2630 2631 2632/*------------------------------------. 2633| yyerrlab -- here on detecting error | 2634`------------------------------------*/ 2635yyerrlab: 2636 /* If not already recovering from an error, report this error. */ 2637 if (!yyerrstatus) 2638 { 2639 ++yynerrs; 2640#if YYERROR_VERBOSE 2641 yyn = yypact[yystate]; 2642 2643 if (YYPACT_NINF < yyn && yyn < YYLAST) 2644 { 2645 YYSIZE_T yysize = 0; 2646 int yytype = YYTRANSLATE (yychar); 2647 char *yymsg; 2648 int yyx, yycount; 2649 2650 yycount = 0; 2651 /* Start YYX at -YYN if negative to avoid negative indexes in 2652 YYCHECK. */ 2653 for (yyx = yyn < 0 ? -yyn : 0; 2654 yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++) 2655 if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) 2656 yysize += yystrlen (yytname[yyx]) + 15, yycount++; 2657 yysize += yystrlen ("syntax error, unexpected ") + 1; 2658 yysize += yystrlen (yytname[yytype]); 2659 yymsg = (char *) YYSTACK_ALLOC (yysize); 2660 if (yymsg != 0) 2661 { 2662 char *yyp = yystpcpy (yymsg, "syntax error, unexpected "); 2663 yyp = yystpcpy (yyp, yytname[yytype]); 2664 2665 if (yycount < 5) 2666 { 2667 yycount = 0; 2668 for (yyx = yyn < 0 ? -yyn : 0; 2669 yyx < (int) (sizeof (yytname) / sizeof (char *)); 2670 yyx++) 2671 if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) 2672 { 2673 const char *yyq = ! yycount ? ", expecting " : " or "; 2674 yyp = yystpcpy (yyp, yyq); 2675 yyp = yystpcpy (yyp, yytname[yyx]); 2676 yycount++; 2677 } 2678 } 2679 yyerror (yymsg); 2680 YYSTACK_FREE (yymsg); 2681 } 2682 else 2683 yyerror ("syntax error; also virtual memory exhausted"); 2684 } 2685 else 2686#endif /* YYERROR_VERBOSE */ 2687 yyerror ("syntax error"); 2688 } 2689 2690 2691 2692 if (yyerrstatus == 3) 2693 { 2694 /* If just tried and failed to reuse lookahead token after an 2695 error, discard it. */ 2696 2697 /* Return failure if at end of input. */ 2698 if (yychar == YYEOF) 2699 { 2700 /* Pop the error token. */ 2701 YYPOPSTACK; 2702 /* Pop the rest of the stack. */ 2703 while (yyss < yyssp) 2704 { 2705 YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); 2706 yydestruct (yystos[*yyssp], yyvsp); 2707 YYPOPSTACK; 2708 } 2709 YYABORT; 2710 } 2711 2712 YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc); 2713 yydestruct (yytoken, &yylval); 2714 yychar = YYEMPTY; 2715 2716 } 2717 2718 /* Else will try to reuse lookahead token after shifting the error 2719 token. */ 2720 goto yyerrlab2; 2721 2722 2723/*----------------------------------------------------. 2724| yyerrlab1 -- error raised explicitly by an action. | 2725`----------------------------------------------------*/ 2726yyerrlab1: 2727 2728 /* Suppress GCC warning that yyerrlab1 is unused when no action 2729 invokes YYERROR. */ 2730#if defined (__GNUC_MINOR__) && 2093 <= (__GNUC__ * 1000 + __GNUC_MINOR__) 2731 __attribute__ ((__unused__)) 2732#endif 2733 2734 2735 goto yyerrlab2; 2736 2737 2738/*---------------------------------------------------------------. 2739| yyerrlab2 -- pop states until the error token can be shifted. | 2740`---------------------------------------------------------------*/ 2741yyerrlab2: 2742 yyerrstatus = 3; /* Each real token shifted decrements this. */ 2743 2744 for (;;) 2745 { 2746 yyn = yypact[yystate]; 2747 if (yyn != YYPACT_NINF) 2748 { 2749 yyn += YYTERROR; 2750 if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) 2751 { 2752 yyn = yytable[yyn]; 2753 if (0 < yyn) 2754 break; 2755 } 2756 } 2757 2758 /* Pop the current state because it cannot handle the error token. */ 2759 if (yyssp == yyss) 2760 YYABORT; 2761 2762 YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); 2763 yydestruct (yystos[yystate], yyvsp); 2764 yyvsp--; 2765 yystate = *--yyssp; 2766 2767 YY_STACK_PRINT (yyss, yyssp); 2768 } 2769 2770 if (yyn == YYFINAL) 2771 YYACCEPT; 2772 2773 YYDPRINTF ((stderr, "Shifting error token, ")); 2774 2775 *++yyvsp = yylval; 2776 2777 2778 yystate = yyn; 2779 goto yynewstate; 2780 2781 2782/*-------------------------------------. 2783| yyacceptlab -- YYACCEPT comes here. | 2784`-------------------------------------*/ 2785yyacceptlab: 2786 yyresult = 0; 2787 goto yyreturn; 2788 2789/*-----------------------------------. 2790| yyabortlab -- YYABORT comes here. | 2791`-----------------------------------*/ 2792yyabortlab: 2793 yyresult = 1; 2794 goto yyreturn; 2795 2796#ifndef yyoverflow 2797/*----------------------------------------------. 2798| yyoverflowlab -- parser overflow comes here. | 2799`----------------------------------------------*/ 2800yyoverflowlab: 2801 yyerror ("parser stack overflow"); 2802 yyresult = 2; 2803 /* Fall through. */ 2804#endif 2805 2806yyreturn: 2807#ifndef yyoverflow 2808 if (yyss != yyssa) 2809 YYSTACK_FREE (yyss); 2810#endif 2811 return yyresult; 2812} 2813 2814 2815#line 981 "awkgram.y" 2816 2817 2818struct token { 2819 const char *operator; /* text to match */ 2820 NODETYPE value; /* node type */ 2821 int class; /* lexical class */ 2822 unsigned flags; /* # of args. allowed and compatability */ 2823# define ARGS 0xFF /* 0, 1, 2, 3 args allowed (any combination */ 2824# define A(n) (1<<(n)) 2825# define VERSION_MASK 0xFF00 /* old awk is zero */ 2826# define NOT_OLD 0x0100 /* feature not in old awk */ 2827# define NOT_POSIX 0x0200 /* feature not in POSIX */ 2828# define GAWKX 0x0400 /* gawk extension */ 2829# define RESX 0x0800 /* Bell Labs Research extension */ 2830 NODE *(*ptr) P((NODE *)); /* function that implements this keyword */ 2831}; 2832 2833/* Tokentab is sorted ascii ascending order, so it can be binary searched. */ 2834/* Function pointers come from declarations in awk.h. */ 2835 2836static const struct token tokentab[] = { 2837{"BEGIN", Node_illegal, LEX_BEGIN, 0, 0}, 2838{"END", Node_illegal, LEX_END, 0, 0}, 2839#ifdef ARRAYDEBUG 2840{"adump", Node_builtin, LEX_BUILTIN, GAWKX|A(1), do_adump}, 2841#endif 2842{"and", Node_builtin, LEX_BUILTIN, GAWKX|A(2), do_and}, 2843{"asort", Node_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2), do_asort}, 2844{"asorti", Node_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2), do_asorti}, 2845{"atan2", Node_builtin, LEX_BUILTIN, NOT_OLD|A(2), do_atan2}, 2846{"bindtextdomain", Node_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2), do_bindtextdomain}, 2847{"break", Node_K_break, LEX_BREAK, 0, 0}, 2848#ifdef ALLOW_SWITCH 2849{"case", Node_K_case, LEX_CASE, GAWKX, 0}, 2850#endif 2851{"close", Node_builtin, LEX_BUILTIN, NOT_OLD|A(1)|A(2), do_close}, 2852{"compl", Node_builtin, LEX_BUILTIN, GAWKX|A(1), do_compl}, 2853{"continue", Node_K_continue, LEX_CONTINUE, 0, 0}, 2854{"cos", Node_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_cos}, 2855{"dcgettext", Node_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2)|A(3), do_dcgettext}, 2856{"dcngettext", Node_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2)|A(3)|A(4)|A(5), do_dcngettext}, 2857#ifdef ALLOW_SWITCH 2858{"default", Node_K_default, LEX_DEFAULT, GAWKX, 0}, 2859#endif 2860{"delete", Node_K_delete, LEX_DELETE, NOT_OLD, 0}, 2861{"do", Node_K_do, LEX_DO, NOT_OLD, 0}, 2862{"else", Node_illegal, LEX_ELSE, 0, 0}, 2863{"exit", Node_K_exit, LEX_EXIT, 0, 0}, 2864{"exp", Node_builtin, LEX_BUILTIN, A(1), do_exp}, 2865{"extension", Node_builtin, LEX_BUILTIN, GAWKX|A(2), do_ext}, 2866{"fflush", Node_builtin, LEX_BUILTIN, RESX|A(0)|A(1), do_fflush}, 2867{"for", Node_K_for, LEX_FOR, 0, 0}, 2868{"func", Node_K_function, LEX_FUNCTION, NOT_POSIX|NOT_OLD, 0}, 2869{"function", Node_K_function, LEX_FUNCTION, NOT_OLD, 0}, 2870{"gensub", Node_builtin, LEX_BUILTIN, GAWKX|A(3)|A(4), do_gensub}, 2871{"getline", Node_K_getline, LEX_GETLINE, NOT_OLD, 0}, 2872{"gsub", Node_builtin, LEX_BUILTIN, NOT_OLD|A(2)|A(3), do_gsub}, 2873{"if", Node_K_if, LEX_IF, 0, 0}, 2874{"in", Node_illegal, LEX_IN, 0, 0}, 2875{"index", Node_builtin, LEX_BUILTIN, A(2), do_index}, 2876{"int", Node_builtin, LEX_BUILTIN, A(1), do_int}, 2877{"length", Node_builtin, LEX_LENGTH, A(0)|A(1), do_length}, 2878{"log", Node_builtin, LEX_BUILTIN, A(1), do_log}, 2879{"lshift", Node_builtin, LEX_BUILTIN, GAWKX|A(2), do_lshift}, 2880{"match", Node_builtin, LEX_BUILTIN, NOT_OLD|A(2)|A(3), do_match}, 2881{"mktime", Node_builtin, LEX_BUILTIN, GAWKX|A(1), do_mktime}, 2882{"next", Node_K_next, LEX_NEXT, 0, 0}, 2883{"nextfile", Node_K_nextfile, LEX_NEXTFILE, GAWKX, 0}, 2884{"or", Node_builtin, LEX_BUILTIN, GAWKX|A(2), do_or}, 2885{"print", Node_K_print, LEX_PRINT, 0, 0}, 2886{"printf", Node_K_printf, LEX_PRINTF, 0, 0}, 2887{"rand", Node_builtin, LEX_BUILTIN, NOT_OLD|A(0), do_rand}, 2888{"return", Node_K_return, LEX_RETURN, NOT_OLD, 0}, 2889{"rshift", Node_builtin, LEX_BUILTIN, GAWKX|A(2), do_rshift}, 2890{"sin", Node_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_sin}, 2891{"split", Node_builtin, LEX_BUILTIN, A(2)|A(3), do_split}, 2892{"sprintf", Node_builtin, LEX_BUILTIN, 0, do_sprintf}, 2893{"sqrt", Node_builtin, LEX_BUILTIN, A(1), do_sqrt}, 2894{"srand", Node_builtin, LEX_BUILTIN, NOT_OLD|A(0)|A(1), do_srand}, 2895#if defined(GAWKDEBUG) || defined(ARRAYDEBUG) /* || ... */ 2896{"stopme", Node_builtin, LEX_BUILTIN, GAWKX|A(0), stopme}, 2897#endif 2898{"strftime", Node_builtin, LEX_BUILTIN, GAWKX|A(0)|A(1)|A(2), do_strftime}, 2899{"strtonum", Node_builtin, LEX_BUILTIN, GAWKX|A(1), do_strtonum}, 2900{"sub", Node_builtin, LEX_BUILTIN, NOT_OLD|A(2)|A(3), do_sub}, 2901{"substr", Node_builtin, LEX_BUILTIN, A(2)|A(3), do_substr}, 2902#ifdef ALLOW_SWITCH 2903{"switch", Node_K_switch, LEX_SWITCH, GAWKX, 0}, 2904#endif 2905{"system", Node_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_system}, 2906{"systime", Node_builtin, LEX_BUILTIN, GAWKX|A(0), do_systime}, 2907{"tolower", Node_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_tolower}, 2908{"toupper", Node_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_toupper}, 2909{"while", Node_K_while, LEX_WHILE, 0, 0}, 2910{"xor", Node_builtin, LEX_BUILTIN, GAWKX|A(2), do_xor}, 2911}; 2912 2913#ifdef MBS_SUPPORT 2914/* Variable containing the current shift state. */ 2915static mbstate_t cur_mbstate; 2916/* Ring buffer containing current characters. */ 2917#define MAX_CHAR_IN_RING_BUFFER 8 2918#define RING_BUFFER_SIZE (MAX_CHAR_IN_RING_BUFFER * MB_LEN_MAX) 2919static char cur_char_ring[RING_BUFFER_SIZE]; 2920/* Index for ring buffers. */ 2921static int cur_ring_idx; 2922/* This macro means that last nextc() return a singlebyte character 2923 or 1st byte of a multibyte character. */ 2924#define nextc_is_1stbyte (cur_char_ring[cur_ring_idx] == 1) 2925#endif /* MBS_SUPPORT */ 2926 2927/* getfname --- return name of a builtin function (for pretty printing) */ 2928 2929const char * 2930getfname(register NODE *(*fptr)(NODE *)) 2931{ 2932 register int i, j; 2933 2934 j = sizeof(tokentab) / sizeof(tokentab[0]); 2935 /* linear search, no other way to do it */ 2936 for (i = 0; i < j; i++) 2937 if (tokentab[i].ptr == fptr) 2938 return tokentab[i].operator; 2939 2940 return NULL; 2941} 2942 2943/* yyerror --- print a syntax error message, show where */ 2944 2945/* 2946 * Function identifier purposely indented to avoid mangling 2947 * by ansi2knr. Sigh. 2948 */ 2949 2950static void 2951#if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__ 2952 yyerror(const char *m, ...) 2953#else 2954/* VARARGS0 */ 2955 yyerror(va_alist) 2956 va_dcl 2957#endif 2958{ 2959 va_list args; 2960 const char *mesg = NULL; 2961 register char *bp, *cp; 2962 char *scan; 2963 char *buf; 2964 int count; 2965 static char end_of_file_line[] = "(END OF FILE)"; 2966 char save; 2967 2968 errcount++; 2969 /* Find the current line in the input file */ 2970 if (lexptr && lexeme) { 2971 if (thisline == NULL) { 2972 cp = lexeme; 2973 if (*cp == '\n') { 2974 cp--; 2975 mesg = _("unexpected newline or end of string"); 2976 } 2977 for (; cp != lexptr_begin && *cp != '\n'; --cp) 2978 continue; 2979 if (*cp == '\n') 2980 cp++; 2981 thisline = cp; 2982 } 2983 /* NL isn't guaranteed */ 2984 bp = lexeme; 2985 while (bp < lexend && *bp && *bp != '\n') 2986 bp++; 2987 } else { 2988 thisline = end_of_file_line; 2989 bp = thisline + strlen(thisline); 2990 } 2991 2992 /* 2993 * Saving and restoring *bp keeps valgrind happy, 2994 * since the guts of glibc uses strlen, even though 2995 * we're passing an explict precision. Sigh. 2996 */ 2997 save = *bp; 2998 *bp = '\0'; 2999 3000 msg("%.*s", (int) (bp - thisline), thisline); 3001 3002 *bp = save; 3003 3004#if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__ 3005 va_start(args, m); 3006 if (mesg == NULL) 3007 mesg = m; 3008#else 3009 va_start(args); 3010 if (mesg == NULL) 3011 mesg = va_arg(args, char *); 3012#endif 3013 count = (bp - thisline) + strlen(mesg) + 2 + 1; 3014 emalloc(buf, char *, count, "yyerror"); 3015 3016 bp = buf; 3017 3018 if (lexptr != NULL) { 3019 scan = thisline; 3020 while (scan < lexeme) 3021 if (*scan++ == '\t') 3022 *bp++ = '\t'; 3023 else 3024 *bp++ = ' '; 3025 *bp++ = '^'; 3026 *bp++ = ' '; 3027 } 3028 strcpy(bp, mesg); 3029 err("", buf, args); 3030 va_end(args); 3031 free(buf); 3032} 3033 3034/* get_src_buf --- read the next buffer of source program */ 3035 3036static char * 3037get_src_buf() 3038{ 3039 static int samefile = FALSE; 3040 static int nextfile = 0; 3041 static char *buf = NULL; 3042 static int fd; 3043 int n; 3044 register char *scan; 3045 static size_t len = 0; 3046 static int did_newline = FALSE; 3047 int newfile; 3048 struct stat sbuf; 3049 3050# define SLOP 128 /* enough space to hold most source lines */ 3051 3052again: 3053 newfile = FALSE; 3054 if (nextfile > numfiles) 3055 return NULL; 3056 3057 if (srcfiles[nextfile].stype == CMDLINE) { 3058 if (len == 0) { 3059 len = strlen(srcfiles[nextfile].val); 3060 if (len == 0) { 3061 /* 3062 * Yet Another Special case: 3063 * gawk '' /path/name 3064 * Sigh. 3065 */ 3066 static int warned = FALSE; 3067 3068 if (do_lint && ! warned) { 3069 warned = TRUE; 3070 lintwarn(_("empty program text on command line")); 3071 } 3072 ++nextfile; 3073 goto again; 3074 } 3075 sourceline = 1; 3076 lexptr = lexptr_begin = srcfiles[nextfile].val; 3077 lexend = lexptr + len; 3078 } else if (! did_newline && *(lexptr-1) != '\n') { 3079 /* 3080 * The following goop is to ensure that the source 3081 * ends with a newline and that the entire current 3082 * line is available for error messages. 3083 */ 3084 int offset; 3085 3086 did_newline = TRUE; 3087 offset = lexptr - lexeme; 3088 for (scan = lexeme; scan > lexptr_begin; scan--) 3089 if (*scan == '\n') { 3090 scan++; 3091 break; 3092 } 3093 len = lexptr - scan; 3094 emalloc(buf, char *, len+1, "get_src_buf"); 3095 memcpy(buf, scan, len); 3096 thisline = buf; 3097 lexptr = buf + len; 3098 *lexptr = '\n'; 3099 lexeme = lexptr - offset; 3100 lexptr_begin = buf; 3101 lexend = lexptr + 1; 3102 } else { 3103 len = 0; 3104 lexeme = lexptr = lexptr_begin = NULL; 3105 } 3106 if (lexptr == NULL && ++nextfile <= numfiles) 3107 goto again; 3108 return lexptr; 3109 } 3110 if (! samefile) { 3111 source = srcfiles[nextfile].val; 3112 if (source == NULL) { 3113 if (buf != NULL) { 3114 free(buf); 3115 buf = NULL; 3116 } 3117 len = 0; 3118 return lexeme = lexptr = lexptr_begin = NULL; 3119 } 3120 fd = pathopen(source); 3121 if (fd <= INVALID_HANDLE) { 3122 char *in; 3123 3124 /* suppress file name and line no. in error mesg */ 3125 in = source; 3126 source = NULL; 3127 fatal(_("can't open source file `%s' for reading (%s)"), 3128 in, strerror(errno)); 3129 } 3130 len = optimal_bufsize(fd, & sbuf); 3131 newfile = TRUE; 3132 if (buf != NULL) 3133 free(buf); 3134 emalloc(buf, char *, len + SLOP, "get_src_buf"); 3135 lexptr_begin = buf + SLOP; 3136 samefile = TRUE; 3137 sourceline = 1; 3138 } else { 3139 /* 3140 * Here, we retain the current source line (up to length SLOP) 3141 * in the beginning of the buffer that was overallocated above 3142 */ 3143 int offset; 3144 int linelen; 3145 3146 offset = lexptr - lexeme; 3147 for (scan = lexeme; scan > lexptr_begin; scan--) 3148 if (*scan == '\n') { 3149 scan++; 3150 break; 3151 } 3152 linelen = lexptr - scan; 3153 if (linelen > SLOP) 3154 linelen = SLOP; 3155 thisline = buf + SLOP - linelen; 3156 memcpy(thisline, scan, linelen); 3157 lexeme = buf + SLOP - offset; 3158 lexptr_begin = thisline; 3159 } 3160 n = read(fd, buf + SLOP, len); 3161 if (n == -1) 3162 fatal(_("can't read sourcefile `%s' (%s)"), 3163 source, strerror(errno)); 3164 if (n == 0) { 3165 if (newfile) { 3166 static int warned = FALSE; 3167 3168 if (do_lint && ! warned) { 3169 warned = TRUE; 3170 lintwarn(_("source file `%s' is empty"), source); 3171 } 3172 } 3173 if (fd != fileno(stdin)) /* safety */ 3174 close(fd); 3175 samefile = FALSE; 3176 nextfile++; 3177 if (lexeme) 3178 *lexeme = '\0'; 3179 len = 0; 3180 goto again; 3181 } 3182 lexptr = buf + SLOP; 3183 lexend = lexptr + n; 3184 return buf; 3185} 3186 3187/* tokadd --- add a character to the token buffer */ 3188 3189#define tokadd(x) (*tok++ = (x), tok == tokend ? tokexpand() : tok) 3190 3191/* tokexpand --- grow the token buffer */ 3192 3193char * 3194tokexpand() 3195{ 3196 static int toksize = 60; 3197 int tokoffset; 3198 3199 tokoffset = tok - tokstart; 3200 toksize *= 2; 3201 if (tokstart != NULL) 3202 erealloc(tokstart, char *, toksize, "tokexpand"); 3203 else 3204 emalloc(tokstart, char *, toksize, "tokexpand"); 3205 tokend = tokstart + toksize; 3206 tok = tokstart + tokoffset; 3207 return tok; 3208} 3209 3210/* nextc --- get the next input character */ 3211 3212#ifdef MBS_SUPPORT 3213 3214static int 3215nextc(void) 3216{ 3217 if (gawk_mb_cur_max > 1) { 3218 /* Update the buffer index. */ 3219 cur_ring_idx = (cur_ring_idx == RING_BUFFER_SIZE - 1)? 0 : 3220 cur_ring_idx + 1; 3221 3222 /* Did we already check the current character? */ 3223 if (cur_char_ring[cur_ring_idx] == 0) { 3224 /* No, we need to check the next character on the buffer. */ 3225 int idx, work_ring_idx = cur_ring_idx; 3226 mbstate_t tmp_state; 3227 size_t mbclen; 3228 3229 if (!lexptr || lexptr >= lexend) 3230 if (!get_src_buf()) { 3231 return EOF; 3232 } 3233 3234 for (idx = 0 ; lexptr + idx < lexend ; idx++) { 3235 tmp_state = cur_mbstate; 3236 mbclen = mbrlen(lexptr, idx + 1, &tmp_state); 3237 3238 if (mbclen == 1 || mbclen == (size_t)-1 || mbclen == 0) { 3239 /* It is a singlebyte character, non-complete multibyte 3240 character or EOF. We treat it as a singlebyte 3241 character. */ 3242 cur_char_ring[work_ring_idx] = 1; 3243 break; 3244 } else if (mbclen == (size_t)-2) { 3245 /* It is not a complete multibyte character. */ 3246 cur_char_ring[work_ring_idx] = idx + 1; 3247 } else { 3248 /* mbclen > 1 */ 3249 cur_char_ring[work_ring_idx] = mbclen; 3250 break; 3251 } 3252 work_ring_idx = (work_ring_idx == RING_BUFFER_SIZE - 1)? 3253 0 : work_ring_idx + 1; 3254 } 3255 cur_mbstate = tmp_state; 3256 3257 /* Put a mark on the position on which we write next character. */ 3258 work_ring_idx = (work_ring_idx == RING_BUFFER_SIZE - 1)? 3259 0 : work_ring_idx + 1; 3260 cur_char_ring[work_ring_idx] = 0; 3261 } 3262 3263 return (int) (unsigned char) *lexptr++; 3264 } 3265 else { 3266 int c; 3267 3268 if (lexptr && lexptr < lexend) 3269 c = (int) (unsigned char) *lexptr++; 3270 else if (get_src_buf()) 3271 c = (int) (unsigned char) *lexptr++; 3272 else 3273 c = EOF; 3274 3275 return c; 3276 } 3277} 3278 3279#else /* MBS_SUPPORT */ 3280 3281#if GAWKDEBUG 3282int 3283nextc(void) 3284{ 3285 int c; 3286 3287 if (lexptr && lexptr < lexend) 3288 c = (int) (unsigned char) *lexptr++; 3289 else if (get_src_buf()) 3290 c = (int) (unsigned char) *lexptr++; 3291 else 3292 c = EOF; 3293 3294 return c; 3295} 3296#else 3297#define nextc() ((lexptr && lexptr < lexend) ? \ 3298 ((int) (unsigned char) *lexptr++) : \ 3299 (get_src_buf() ? ((int) (unsigned char) *lexptr++) : EOF) \ 3300 ) 3301#endif 3302 3303#endif /* MBS_SUPPORT */ 3304 3305/* pushback --- push a character back on the input */ 3306 3307#ifdef MBS_SUPPORT 3308 3309static void 3310pushback(void) 3311{ 3312 if (gawk_mb_cur_max > 1) { 3313 cur_ring_idx = (cur_ring_idx == 0)? RING_BUFFER_SIZE - 1 : 3314 cur_ring_idx - 1; 3315 (lexptr && lexptr > lexptr_begin ? lexptr-- : lexptr); 3316 } else 3317 (lexptr && lexptr > lexptr_begin ? lexptr-- : lexptr); 3318} 3319 3320#else 3321 3322#define pushback() (lexptr && lexptr > lexptr_begin ? lexptr-- : lexptr) 3323 3324#endif /* MBS_SUPPORT */ 3325 3326/* allow_newline --- allow newline after &&, ||, ? and : */ 3327 3328static void 3329allow_newline(void) 3330{ 3331 int c; 3332 3333 for (;;) { 3334 c = nextc(); 3335 if (c == EOF) 3336 break; 3337 if (c == '#') { 3338 while ((c = nextc()) != '\n' && c != EOF) 3339 continue; 3340 if (c == EOF) 3341 break; 3342 } 3343 if (c == '\n') 3344 sourceline++; 3345 if (! ISSPACE(c)) { 3346 pushback(); 3347 break; 3348 } 3349 } 3350} 3351 3352/* yylex --- Read the input and turn it into tokens. */ 3353 3354static int 3355yylex(void) 3356{ 3357 register int c; 3358 int seen_e = FALSE; /* These are for numbers */ 3359 int seen_point = FALSE; 3360 int esc_seen; /* for literal strings */ 3361 int low, mid, high; 3362 static int did_newline = FALSE; 3363 char *tokkey; 3364 static int lasttok = 0, eof_warned = FALSE; 3365 int inhex = FALSE; 3366 int intlstr = FALSE; 3367 3368 if (nextc() == EOF) { 3369 if (lasttok != NEWLINE) { 3370 lasttok = NEWLINE; 3371 if (do_lint && ! eof_warned) { 3372 lintwarn(_("source file does not end in newline")); 3373 eof_warned = TRUE; 3374 } 3375 return NEWLINE; /* fake it */ 3376 } 3377 return 0; 3378 } 3379 pushback(); 3380#if defined OS2 || defined __EMX__ 3381 /* 3382 * added for OS/2's extproc feature of cmd.exe 3383 * (like #! in BSD sh) 3384 */ 3385 if (strncasecmp(lexptr, "extproc ", 8) == 0) { 3386 while (*lexptr && *lexptr != '\n') 3387 lexptr++; 3388 } 3389#endif 3390 lexeme = lexptr; 3391 thisline = NULL; 3392 if (want_regexp) { 3393 int in_brack = 0; /* count brackets, [[:alnum:]] allowed */ 3394 /* 3395 * Counting brackets is non-trivial. [[] is ok, 3396 * and so is [\]], with a point being that /[/]/ as a regexp 3397 * constant has to work. 3398 * 3399 * Do not count [ or ] if either one is preceded by a \. 3400 * A `[' should be counted if 3401 * a) it is the first one so far (in_brack == 0) 3402 * b) it is the `[' in `[:' 3403 * A ']' should be counted if not preceded by a \, since 3404 * it is either closing `:]' or just a plain list. 3405 * According to POSIX, []] is how you put a ] into a set. 3406 * Try to handle that too. 3407 * 3408 * The code for \ handles \[ and \]. 3409 */ 3410 3411 want_regexp = FALSE; 3412 tok = tokstart; 3413 for (;;) { 3414 c = nextc(); 3415#ifdef MBS_SUPPORT 3416 if (gawk_mb_cur_max == 1 || nextc_is_1stbyte) 3417#endif 3418 switch (c) { 3419 case '[': 3420 /* one day check for `.' and `=' too */ 3421 if (nextc() == ':' || in_brack == 0) 3422 in_brack++; 3423 pushback(); 3424 break; 3425 case ']': 3426 if (tokstart[0] == '[' 3427 && (tok == tokstart + 1 3428 || (tok == tokstart + 2 3429 && tokstart[1] == '^'))) 3430 /* do nothing */; 3431 else 3432 in_brack--; 3433 break; 3434 case '\\': 3435 if ((c = nextc()) == EOF) { 3436 yyerror(_("unterminated regexp ends with `\\' at end of file")); 3437 goto end_regexp; /* kludge */ 3438 } else if (c == '\n') { 3439 sourceline++; 3440 continue; 3441 } else { 3442 tokadd('\\'); 3443 tokadd(c); 3444 continue; 3445 } 3446 break; 3447 case '/': /* end of the regexp */ 3448 if (in_brack > 0) 3449 break; 3450end_regexp: 3451 tokadd('\0'); 3452 yylval.sval = tokstart; 3453 return lasttok = REGEXP; 3454 case '\n': 3455 pushback(); 3456 yyerror(_("unterminated regexp")); 3457 goto end_regexp; /* kludge */ 3458 case EOF: 3459 yyerror(_("unterminated regexp at end of file")); 3460 goto end_regexp; /* kludge */ 3461 } 3462 tokadd(c); 3463 } 3464 } 3465retry: 3466 while ((c = nextc()) == ' ' || c == '\t') 3467 continue; 3468 3469 lexeme = lexptr ? lexptr - 1 : lexptr; 3470 thisline = NULL; 3471 tok = tokstart; 3472 yylval.nodetypeval = Node_illegal; 3473 3474#ifdef MBS_SUPPORT 3475 if (gawk_mb_cur_max == 1 || nextc_is_1stbyte) 3476#endif 3477 switch (c) { 3478 case EOF: 3479 if (lasttok != NEWLINE) { 3480 lasttok = NEWLINE; 3481 if (do_lint && ! eof_warned) { 3482 lintwarn(_("source file does not end in newline")); 3483 eof_warned = TRUE; 3484 } 3485 return NEWLINE; /* fake it */ 3486 } 3487 return 0; 3488 3489 case '\n': 3490 sourceline++; 3491 return lasttok = NEWLINE; 3492 3493 case '#': /* it's a comment */ 3494 while ((c = nextc()) != '\n') { 3495 if (c == EOF) { 3496 if (lasttok != NEWLINE) { 3497 lasttok = NEWLINE; 3498 if (do_lint && ! eof_warned) { 3499 lintwarn( 3500 _("source file does not end in newline")); 3501 eof_warned = TRUE; 3502 } 3503 return NEWLINE; /* fake it */ 3504 } 3505 return 0; 3506 } 3507 } 3508 sourceline++; 3509 return lasttok = NEWLINE; 3510 3511 case '\\': 3512#ifdef RELAXED_CONTINUATION 3513 /* 3514 * This code puports to allow comments and/or whitespace 3515 * after the `\' at the end of a line used for continuation. 3516 * Use it at your own risk. We think it's a bad idea, which 3517 * is why it's not on by default. 3518 */ 3519 if (! do_traditional) { 3520 /* strip trailing white-space and/or comment */ 3521 while ((c = nextc()) == ' ' || c == '\t') 3522 continue; 3523 if (c == '#') { 3524 if (do_lint) 3525 lintwarn( 3526 _("use of `\\ #...' line continuation is not portable")); 3527 while ((c = nextc()) != '\n') 3528 if (c == EOF) 3529 break; 3530 } 3531 pushback(); 3532 } 3533#endif /* RELAXED_CONTINUATION */ 3534 if (nextc() == '\n') { 3535 sourceline++; 3536 goto retry; 3537 } else { 3538 yyerror(_("backslash not last character on line")); 3539 exit(1); 3540 } 3541 break; 3542 3543 case ':': 3544 case '?': 3545 if (! do_posix) 3546 allow_newline(); 3547 return lasttok = c; 3548 3549 /* 3550 * in_parens is undefined unless we are parsing a print 3551 * statement (in_print), but why bother with a check? 3552 */ 3553 case ')': 3554 in_parens--; 3555 return lasttok = c; 3556 3557 case '(': 3558 in_parens++; 3559 /* FALL THROUGH */ 3560 case '$': 3561 case ';': 3562 case '{': 3563 case ',': 3564 case '[': 3565 case ']': 3566 return lasttok = c; 3567 3568 case '*': 3569 if ((c = nextc()) == '=') { 3570 yylval.nodetypeval = Node_assign_times; 3571 return lasttok = ASSIGNOP; 3572 } else if (do_posix) { 3573 pushback(); 3574 return lasttok = '*'; 3575 } else if (c == '*') { 3576 /* make ** and **= aliases for ^ and ^= */ 3577 static int did_warn_op = FALSE, did_warn_assgn = FALSE; 3578 3579 if (nextc() == '=') { 3580 if (! did_warn_assgn) { 3581 did_warn_assgn = TRUE; 3582 if (do_lint) 3583 lintwarn(_("POSIX does not allow operator `**='")); 3584 if (do_lint_old) 3585 warning(_("old awk does not support operator `**='")); 3586 } 3587 yylval.nodetypeval = Node_assign_exp; 3588 return ASSIGNOP; 3589 } else { 3590 pushback(); 3591 if (! did_warn_op) { 3592 did_warn_op = TRUE; 3593 if (do_lint) 3594 lintwarn(_("POSIX does not allow operator `**'")); 3595 if (do_lint_old) 3596 warning(_("old awk does not support operator `**'")); 3597 } 3598 return lasttok = '^'; 3599 } 3600 } 3601 pushback(); 3602 return lasttok = '*'; 3603 3604 case '/': 3605 if (nextc() == '=') { 3606 pushback(); 3607 return lasttok = SLASH_BEFORE_EQUAL; 3608 } 3609 pushback(); 3610 return lasttok = '/'; 3611 3612 case '%': 3613 if (nextc() == '=') { 3614 yylval.nodetypeval = Node_assign_mod; 3615 return lasttok = ASSIGNOP; 3616 } 3617 pushback(); 3618 return lasttok = '%'; 3619 3620 case '^': 3621 { 3622 static int did_warn_op = FALSE, did_warn_assgn = FALSE; 3623 3624 if (nextc() == '=') { 3625 if (do_lint_old && ! did_warn_assgn) { 3626 did_warn_assgn = TRUE; 3627 warning(_("operator `^=' is not supported in old awk")); 3628 } 3629 yylval.nodetypeval = Node_assign_exp; 3630 return lasttok = ASSIGNOP; 3631 } 3632 pushback(); 3633 if (do_lint_old && ! did_warn_op) { 3634 did_warn_op = TRUE; 3635 warning(_("operator `^' is not supported in old awk")); 3636 } 3637 return lasttok = '^'; 3638 } 3639 3640 case '+': 3641 if ((c = nextc()) == '=') { 3642 yylval.nodetypeval = Node_assign_plus; 3643 return lasttok = ASSIGNOP; 3644 } 3645 if (c == '+') 3646 return lasttok = INCREMENT; 3647 pushback(); 3648 return lasttok = '+'; 3649 3650 case '!': 3651 if ((c = nextc()) == '=') { 3652 yylval.nodetypeval = Node_notequal; 3653 return lasttok = RELOP; 3654 } 3655 if (c == '~') { 3656 yylval.nodetypeval = Node_nomatch; 3657 return lasttok = MATCHOP; 3658 } 3659 pushback(); 3660 return lasttok = '!'; 3661 3662 case '<': 3663 if (nextc() == '=') { 3664 yylval.nodetypeval = Node_leq; 3665 return lasttok = RELOP; 3666 } 3667 yylval.nodetypeval = Node_less; 3668 pushback(); 3669 return lasttok = '<'; 3670 3671 case '=': 3672 if (nextc() == '=') { 3673 yylval.nodetypeval = Node_equal; 3674 return lasttok = RELOP; 3675 } 3676 yylval.nodetypeval = Node_assign; 3677 pushback(); 3678 return lasttok = ASSIGN; 3679 3680 case '>': 3681 if ((c = nextc()) == '=') { 3682 yylval.nodetypeval = Node_geq; 3683 return lasttok = RELOP; 3684 } else if (c == '>') { 3685 yylval.nodetypeval = Node_redirect_append; 3686 return lasttok = IO_OUT; 3687 } 3688 pushback(); 3689 if (in_print && in_parens == 0) { 3690 yylval.nodetypeval = Node_redirect_output; 3691 return lasttok = IO_OUT; 3692 } 3693 yylval.nodetypeval = Node_greater; 3694 return lasttok = '>'; 3695 3696 case '~': 3697 yylval.nodetypeval = Node_match; 3698 return lasttok = MATCHOP; 3699 3700 case '}': 3701 /* 3702 * Added did newline stuff. Easier than 3703 * hacking the grammar. 3704 */ 3705 if (did_newline) { 3706 did_newline = FALSE; 3707 return lasttok = c; 3708 } 3709 did_newline++; 3710 --lexptr; /* pick up } next time */ 3711 return lasttok = NEWLINE; 3712 3713 case '"': 3714 string: 3715 esc_seen = FALSE; 3716 while ((c = nextc()) != '"') { 3717 if (c == '\n') { 3718 pushback(); 3719 yyerror(_("unterminated string")); 3720 exit(1); 3721 } 3722#ifdef MBS_SUPPORT 3723 if (gawk_mb_cur_max == 1 || nextc_is_1stbyte) 3724#endif 3725 if (c == '\\') { 3726 c = nextc(); 3727 if (c == '\n') { 3728 sourceline++; 3729 continue; 3730 } 3731 esc_seen = TRUE; 3732 tokadd('\\'); 3733 } 3734 if (c == EOF) { 3735 pushback(); 3736 yyerror(_("unterminated string")); 3737 exit(1); 3738 } 3739 tokadd(c); 3740 } 3741 yylval.nodeval = make_str_node(tokstart, 3742 tok - tokstart, esc_seen ? SCAN : 0); 3743 yylval.nodeval->flags |= PERM; 3744 if (intlstr) { 3745 yylval.nodeval->flags |= INTLSTR; 3746 intlstr = FALSE; 3747 if (do_intl) 3748 dumpintlstr(yylval.nodeval->stptr, 3749 yylval.nodeval->stlen); 3750 } 3751 return lasttok = YSTRING; 3752 3753 case '-': 3754 if ((c = nextc()) == '=') { 3755 yylval.nodetypeval = Node_assign_minus; 3756 return lasttok = ASSIGNOP; 3757 } 3758 if (c == '-') 3759 return lasttok = DECREMENT; 3760 pushback(); 3761 return lasttok = '-'; 3762 3763 case '.': 3764 c = nextc(); 3765 pushback(); 3766 if (! ISDIGIT(c)) 3767 return lasttok = '.'; 3768 else 3769 c = '.'; 3770 /* FALL THROUGH */ 3771 case '0': 3772 case '1': 3773 case '2': 3774 case '3': 3775 case '4': 3776 case '5': 3777 case '6': 3778 case '7': 3779 case '8': 3780 case '9': 3781 /* It's a number */ 3782 for (;;) { 3783 int gotnumber = FALSE; 3784 3785 tokadd(c); 3786 switch (c) { 3787 case 'x': 3788 case 'X': 3789 if (do_traditional) 3790 goto done; 3791 if (tok == tokstart + 2) 3792 inhex = TRUE; 3793 break; 3794 case '.': 3795 if (seen_point) { 3796 gotnumber = TRUE; 3797 break; 3798 } 3799 seen_point = TRUE; 3800 break; 3801 case 'e': 3802 case 'E': 3803 if (inhex) 3804 break; 3805 if (seen_e) { 3806 gotnumber = TRUE; 3807 break; 3808 } 3809 seen_e = TRUE; 3810 if ((c = nextc()) == '-' || c == '+') 3811 tokadd(c); 3812 else 3813 pushback(); 3814 break; 3815 case 'a': 3816 case 'A': 3817 case 'b': 3818 case 'B': 3819 case 'c': 3820 case 'C': 3821 case 'D': 3822 case 'd': 3823 case 'f': 3824 case 'F': 3825 if (do_traditional || ! inhex) 3826 goto done; 3827 /* fall through */ 3828 case '0': 3829 case '1': 3830 case '2': 3831 case '3': 3832 case '4': 3833 case '5': 3834 case '6': 3835 case '7': 3836 case '8': 3837 case '9': 3838 break; 3839 default: 3840 done: 3841 gotnumber = TRUE; 3842 } 3843 if (gotnumber) 3844 break; 3845 c = nextc(); 3846 } 3847 if (c != EOF) 3848 pushback(); 3849 else if (do_lint && ! eof_warned) { 3850 lintwarn(_("source file does not end in newline")); 3851 eof_warned = TRUE; 3852 } 3853 tokadd('\0'); 3854 if (! do_traditional && isnondecimal(tokstart)) { 3855 static short warned = FALSE; 3856 if (do_lint && ! warned) { 3857 warned = TRUE; 3858 lintwarn("numeric constant `%.*s' treated as octal or hexadecimal", 3859 strlen(tokstart)-1, tokstart); 3860 } 3861 yylval.nodeval = make_number(nondec2awknum(tokstart, strlen(tokstart))); 3862 } else 3863 yylval.nodeval = make_number(atof(tokstart)); 3864 yylval.nodeval->flags |= PERM; 3865 return lasttok = YNUMBER; 3866 3867 case '&': 3868 if ((c = nextc()) == '&') { 3869 yylval.nodetypeval = Node_and; 3870 allow_newline(); 3871 return lasttok = LEX_AND; 3872 } 3873 pushback(); 3874 return lasttok = '&'; 3875 3876 case '|': 3877 if ((c = nextc()) == '|') { 3878 yylval.nodetypeval = Node_or; 3879 allow_newline(); 3880 return lasttok = LEX_OR; 3881 } else if (! do_traditional && c == '&') { 3882 yylval.nodetypeval = Node_redirect_twoway; 3883 return lasttok = (in_print && in_parens == 0 ? IO_OUT : IO_IN); 3884 } 3885 pushback(); 3886 if (in_print && in_parens == 0) { 3887 yylval.nodetypeval = Node_redirect_pipe; 3888 return lasttok = IO_OUT; 3889 } else { 3890 yylval.nodetypeval = Node_redirect_pipein; 3891 return lasttok = IO_IN; 3892 } 3893 } 3894 3895 if (c != '_' && ! ISALPHA(c)) { 3896 yyerror(_("invalid char '%c' in expression"), c); 3897 exit(1); 3898 } 3899 3900 /* 3901 * Lots of fog here. Consider: 3902 * 3903 * print "xyzzy"$_"foo" 3904 * 3905 * Without the check for ` lasttok != '$'' ', this is parsed as 3906 * 3907 * print "xxyzz" $(_"foo") 3908 * 3909 * With the check, it is "correctly" parsed as three 3910 * string concatenations. Sigh. This seems to be 3911 * "more correct", but this is definitely one of those 3912 * occasions where the interactions are funny. 3913 */ 3914 if (! do_traditional && c == '_' && lasttok != '$') { 3915 if ((c = nextc()) == '"') { 3916 intlstr = TRUE; 3917 goto string; 3918 } 3919 pushback(); 3920 c = '_'; 3921 } 3922 3923 /* it's some type of name-type-thing. Find its length. */ 3924 tok = tokstart; 3925 while (is_identchar(c)) { 3926 tokadd(c); 3927 c = nextc(); 3928 } 3929 tokadd('\0'); 3930 emalloc(tokkey, char *, tok - tokstart, "yylex"); 3931 memcpy(tokkey, tokstart, tok - tokstart); 3932 if (c != EOF) 3933 pushback(); 3934 else if (do_lint && ! eof_warned) { 3935 lintwarn(_("source file does not end in newline")); 3936 eof_warned = TRUE; 3937 } 3938 3939 /* See if it is a special token. */ 3940 low = 0; 3941 high = (sizeof(tokentab) / sizeof(tokentab[0])) - 1; 3942 while (low <= high) { 3943 int i; 3944 3945 mid = (low + high) / 2; 3946 c = *tokstart - tokentab[mid].operator[0]; 3947 i = c ? c : strcmp(tokstart, tokentab[mid].operator); 3948 3949 if (i < 0) /* token < mid */ 3950 high = mid - 1; 3951 else if (i > 0) /* token > mid */ 3952 low = mid + 1; 3953 else { 3954 if (do_lint) { 3955 if (tokentab[mid].flags & GAWKX) 3956 lintwarn(_("`%s' is a gawk extension"), 3957 tokentab[mid].operator); 3958 if (tokentab[mid].flags & RESX) 3959 lintwarn(_("`%s' is a Bell Labs extension"), 3960 tokentab[mid].operator); 3961 if (tokentab[mid].flags & NOT_POSIX) 3962 lintwarn(_("POSIX does not allow `%s'"), 3963 tokentab[mid].operator); 3964 } 3965 if (do_lint_old && (tokentab[mid].flags & NOT_OLD)) 3966 warning(_("`%s' is not supported in old awk"), 3967 tokentab[mid].operator); 3968 if ((do_traditional && (tokentab[mid].flags & GAWKX)) 3969 || (do_posix && (tokentab[mid].flags & NOT_POSIX))) 3970 break; 3971 if (tokentab[mid].class == LEX_BUILTIN 3972 || tokentab[mid].class == LEX_LENGTH 3973 ) 3974 yylval.lval = mid; 3975 else 3976 yylval.nodetypeval = tokentab[mid].value; 3977 3978 free(tokkey); 3979 return lasttok = tokentab[mid].class; 3980 } 3981 } 3982 3983 yylval.sval = tokkey; 3984 if (*lexptr == '(') 3985 return lasttok = FUNC_CALL; 3986 else { 3987 static short goto_warned = FALSE; 3988 3989#define SMART_ALECK 1 3990 if (SMART_ALECK && do_lint 3991 && ! goto_warned && strcasecmp(tokkey, "goto") == 0) { 3992 goto_warned = TRUE; 3993 lintwarn(_("`goto' considered harmful!\n")); 3994 } 3995 return lasttok = NAME; 3996 } 3997} 3998 3999/* node_common --- common code for allocating a new node */ 4000 4001static NODE * 4002node_common(NODETYPE op) 4003{ 4004 register NODE *r; 4005 4006 getnode(r); 4007 r->type = op; 4008 r->flags = MALLOC; 4009 /* if lookahead is NL, lineno is 1 too high */ 4010 if (lexeme && *lexeme == '\n') 4011 r->source_line = sourceline - 1; 4012 else 4013 r->source_line = sourceline; 4014 r->source_file = source; 4015 return r; 4016} 4017 4018/* node --- allocates a node with defined lnode and rnode. */ 4019 4020NODE * 4021node(NODE *left, NODETYPE op, NODE *right) 4022{ 4023 register NODE *r; 4024 4025 r = node_common(op); 4026 r->lnode = left; 4027 r->rnode = right; 4028 return r; 4029} 4030 4031/* snode --- allocate a node with defined subnode and builtin for builtin 4032 functions. Checks for arg. count and supplies defaults where 4033 possible. */ 4034 4035static NODE * 4036snode(NODE *subn, NODETYPE op, int idx) 4037{ 4038 register NODE *r; 4039 register NODE *n; 4040 int nexp = 0; 4041 int args_allowed; 4042 4043 r = node_common(op); 4044 4045 /* traverse expression list to see how many args. given */ 4046 for (n = subn; n != NULL; n = n->rnode) { 4047 nexp++; 4048 if (nexp > 5) 4049 break; 4050 } 4051 4052 /* check against how many args. are allowed for this builtin */ 4053 args_allowed = tokentab[idx].flags & ARGS; 4054 if (args_allowed && (args_allowed & A(nexp)) == 0) 4055 fatal(_("%d is invalid as number of arguments for %s"), 4056 nexp, tokentab[idx].operator); 4057 4058 r->builtin = tokentab[idx].ptr; 4059 4060 /* special case processing for a few builtins */ 4061 if (nexp == 0 && r->builtin == do_length) { 4062 subn = node(node(make_number(0.0), Node_field_spec, (NODE *) NULL), 4063 Node_expression_list, 4064 (NODE *) NULL); 4065 } else if (r->builtin == do_match) { 4066 static short warned = FALSE; 4067 4068 if (subn->rnode->lnode->type != Node_regex) 4069 subn->rnode->lnode = mk_rexp(subn->rnode->lnode); 4070 4071 if (subn->rnode->rnode != NULL) { /* 3rd argument there */ 4072 if (do_lint && ! warned) { 4073 warned = TRUE; 4074 lintwarn(_("match: third argument is a gawk extension")); 4075 } 4076 if (do_traditional) 4077 fatal(_("match: third argument is a gawk extension")); 4078 } 4079 } else if (r->builtin == do_sub || r->builtin == do_gsub) { 4080 if (subn->lnode->type != Node_regex) 4081 subn->lnode = mk_rexp(subn->lnode); 4082 if (nexp == 2) 4083 append_right(subn, node(node(make_number(0.0), 4084 Node_field_spec, 4085 (NODE *) NULL), 4086 Node_expression_list, 4087 (NODE *) NULL)); 4088 else if (subn->rnode->rnode->lnode->type == Node_val) { 4089 if (do_lint) 4090 lintwarn(_("%s: string literal as last arg of substitute has no effect"), 4091 (r->builtin == do_sub) ? "sub" : "gsub"); 4092 } else if (! isassignable(subn->rnode->rnode->lnode)) { 4093 yyerror(_("%s third parameter is not a changeable object"), 4094 (r->builtin == do_sub) ? "sub" : "gsub"); 4095 } 4096 } else if (r->builtin == do_gensub) { 4097 if (subn->lnode->type != Node_regex) 4098 subn->lnode = mk_rexp(subn->lnode); 4099 if (nexp == 3) 4100 append_right(subn, node(node(make_number(0.0), 4101 Node_field_spec, 4102 (NODE *) NULL), 4103 Node_expression_list, 4104 (NODE *) NULL)); 4105 } else if (r->builtin == do_split) { 4106 if (nexp == 2) 4107 append_right(subn, 4108 node(FS_node, Node_expression_list, (NODE *) NULL)); 4109 n = subn->rnode->rnode->lnode; 4110 if (n->type != Node_regex) 4111 subn->rnode->rnode->lnode = mk_rexp(n); 4112 if (nexp == 2) 4113 subn->rnode->rnode->lnode->re_flags |= FS_DFLT; 4114 } else if (r->builtin == do_close) { 4115 static short warned = FALSE; 4116 4117 if ( nexp == 2) { 4118 if (do_lint && nexp == 2 && ! warned) { 4119 warned = TRUE; 4120 lintwarn(_("close: second argument is a gawk extension")); 4121 } 4122 if (do_traditional) 4123 fatal(_("close: second argument is a gawk extension")); 4124 } 4125 } else if (do_intl /* --gen-po */ 4126 && r->builtin == do_dcgettext /* dcgettext(...) */ 4127 && subn->lnode->type == Node_val /* 1st arg is constant */ 4128 && (subn->lnode->flags & STRCUR) != 0) { /* it's a string constant */ 4129 /* ala xgettext, dcgettext("some string" ...) dumps the string */ 4130 NODE *str = subn->lnode; 4131 4132 if ((str->flags & INTLSTR) != 0) 4133 warning(_("use of dcgettext(_\"...\") is incorrect: remove leading underscore")); 4134 /* don't dump it, the lexer already did */ 4135 else 4136 dumpintlstr(str->stptr, str->stlen); 4137 } else if (do_intl /* --gen-po */ 4138 && r->builtin == do_dcngettext /* dcngettext(...) */ 4139 && subn->lnode->type == Node_val /* 1st arg is constant */ 4140 && (subn->lnode->flags & STRCUR) != 0 /* it's a string constant */ 4141 && subn->rnode->lnode->type == Node_val /* 2nd arg is constant too */ 4142 && (subn->rnode->lnode->flags & STRCUR) != 0) { /* it's a string constant */ 4143 /* ala xgettext, dcngettext("some string", "some plural" ...) dumps the string */ 4144 NODE *str1 = subn->lnode; 4145 NODE *str2 = subn->rnode->lnode; 4146 4147 if (((str1->flags | str2->flags) & INTLSTR) != 0) 4148 warning(_("use of dcngettext(_\"...\") is incorrect: remove leading underscore")); 4149 else 4150 dumpintlstr2(str1->stptr, str1->stlen, str2->stptr, str2->stlen); 4151 } 4152 4153 r->subnode = subn; 4154 if (r->builtin == do_sprintf) { 4155 count_args(r); 4156 r->lnode->printf_count = r->printf_count; /* hack */ 4157 } 4158 return r; 4159} 4160 4161/* make_for_loop --- build a for loop */ 4162 4163static NODE * 4164make_for_loop(NODE *init, NODE *cond, NODE *incr) 4165{ 4166 register FOR_LOOP_HEADER *r; 4167 NODE *n; 4168 4169 emalloc(r, FOR_LOOP_HEADER *, sizeof(FOR_LOOP_HEADER), "make_for_loop"); 4170 getnode(n); 4171 n->type = Node_illegal; 4172 r->init = init; 4173 r->cond = cond; 4174 r->incr = incr; 4175 n->sub.nodep.r.hd = r; 4176 return n; 4177} 4178 4179/* dup_parms --- return TRUE if there are duplicate parameters */ 4180 4181static int 4182dup_parms(NODE *func) 4183{ 4184 register NODE *np; 4185 const char *fname, **names; 4186 int count, i, j, dups; 4187 NODE *params; 4188 4189 if (func == NULL) /* error earlier */ 4190 return TRUE; 4191 4192 fname = func->param; 4193 count = func->param_cnt; 4194 params = func->rnode; 4195 4196 if (count == 0) /* no args, no problem */ 4197 return FALSE; 4198 4199 if (params == NULL) /* error earlier */ 4200 return TRUE; 4201 4202 emalloc(names, const char **, count * sizeof(char *), "dup_parms"); 4203 4204 i = 0; 4205 for (np = params; np != NULL; np = np->rnode) { 4206 if (np->param == NULL) { /* error earlier, give up, go home */ 4207 free(names); 4208 return TRUE; 4209 } 4210 names[i++] = np->param; 4211 } 4212 4213 dups = 0; 4214 for (i = 1; i < count; i++) { 4215 for (j = 0; j < i; j++) { 4216 if (strcmp(names[i], names[j]) == 0) { 4217 dups++; 4218 error( 4219 _("function `%s': parameter #%d, `%s', duplicates parameter #%d"), 4220 fname, i+1, names[j], j+1); 4221 } 4222 } 4223 } 4224 4225 free(names); 4226 return (dups > 0 ? TRUE : FALSE); 4227} 4228 4229/* parms_shadow --- check if parameters shadow globals */ 4230 4231static int 4232parms_shadow(const char *fname, NODE *func) 4233{ 4234 int count, i; 4235 int ret = FALSE; 4236 4237 if (fname == NULL || func == NULL) /* error earlier */ 4238 return FALSE; 4239 4240 count = func->lnode->param_cnt; 4241 4242 if (count == 0) /* no args, no problem */ 4243 return FALSE; 4244 4245 /* 4246 * Use warning() and not lintwarn() so that can warn 4247 * about all shadowed parameters. 4248 */ 4249 for (i = 0; i < count; i++) { 4250 if (lookup(func->parmlist[i]) != NULL) { 4251 warning( 4252 _("function `%s': parameter `%s' shadows global variable"), 4253 fname, func->parmlist[i]); 4254 ret = TRUE; 4255 } 4256 } 4257 4258 return ret; 4259} 4260 4261/* 4262 * install: 4263 * Install a name in the symbol table, even if it is already there. 4264 * Caller must check against redefinition if that is desired. 4265 */ 4266 4267NODE * 4268install(char *name, NODE *value) 4269{ 4270 register NODE *hp; 4271 register size_t len; 4272 register int bucket; 4273 4274 var_count++; 4275 len = strlen(name); 4276 bucket = hash(name, len, (unsigned long) HASHSIZE); 4277 getnode(hp); 4278 hp->type = Node_hashnode; 4279 hp->hnext = variables[bucket]; 4280 variables[bucket] = hp; 4281 hp->hlength = len; 4282 hp->hvalue = value; 4283 hp->hname = name; 4284 hp->hvalue->vname = name; 4285 return hp->hvalue; 4286} 4287 4288/* lookup --- find the most recent hash node for name installed by install */ 4289 4290NODE * 4291lookup(const char *name) 4292{ 4293 register NODE *bucket; 4294 register size_t len; 4295 4296 len = strlen(name); 4297 for (bucket = variables[hash(name, len, (unsigned long) HASHSIZE)]; 4298 bucket != NULL; bucket = bucket->hnext) 4299 if (bucket->hlength == len && STREQN(bucket->hname, name, len)) 4300 return bucket->hvalue; 4301 4302 return NULL; 4303} 4304 4305/* var_comp --- compare two variable names */ 4306 4307static int 4308var_comp(const void *v1, const void *v2) 4309{ 4310 const NODE *const *npp1, *const *npp2; 4311 const NODE *n1, *n2; 4312 int minlen; 4313 4314 npp1 = (const NODE *const *) v1; 4315 npp2 = (const NODE *const *) v2; 4316 n1 = *npp1; 4317 n2 = *npp2; 4318 4319 if (n1->hlength > n2->hlength) 4320 minlen = n1->hlength; 4321 else 4322 minlen = n2->hlength; 4323 4324 return strncmp(n1->hname, n2->hname, minlen); 4325} 4326 4327/* valinfo --- dump var info */ 4328 4329static void 4330valinfo(NODE *n, FILE *fp) 4331{ 4332 if (n->flags & STRING) { 4333 fprintf(fp, "string ("); 4334 pp_string_fp(fp, n->stptr, n->stlen, '"', FALSE); 4335 fprintf(fp, ")\n"); 4336 } else if (n->flags & NUMBER) 4337 fprintf(fp, "number (%.17g)\n", n->numbr); 4338 else if (n->flags & STRCUR) { 4339 fprintf(fp, "string value ("); 4340 pp_string_fp(fp, n->stptr, n->stlen, '"', FALSE); 4341 fprintf(fp, ")\n"); 4342 } else if (n->flags & NUMCUR) 4343 fprintf(fp, "number value (%.17g)\n", n->numbr); 4344 else 4345 fprintf(fp, "?? flags %s\n", flags2str(n->flags)); 4346} 4347 4348 4349/* dump_vars --- dump the symbol table */ 4350 4351void 4352dump_vars(const char *fname) 4353{ 4354 int i, j; 4355 NODE **table; 4356 NODE *p; 4357 FILE *fp; 4358 4359 emalloc(table, NODE **, var_count * sizeof(NODE *), "dump_vars"); 4360 4361 if (fname == NULL) 4362 fp = stderr; 4363 else if ((fp = fopen(fname, "w")) == NULL) { 4364 warning(_("could not open `%s' for writing (%s)"), fname, strerror(errno)); 4365 warning(_("sending profile to standard error")); 4366 fp = stderr; 4367 } 4368 4369 for (i = j = 0; i < HASHSIZE; i++) 4370 for (p = variables[i]; p != NULL; p = p->hnext) 4371 table[j++] = p; 4372 4373 assert(j == var_count); 4374 4375 /* Shazzam! */ 4376 qsort(table, j, sizeof(NODE *), var_comp); 4377 4378 for (i = 0; i < j; i++) { 4379 p = table[i]; 4380 if (p->hvalue->type == Node_func) 4381 continue; 4382 fprintf(fp, "%.*s: ", (int) p->hlength, p->hname); 4383 if (p->hvalue->type == Node_var_array) 4384 fprintf(fp, "array, %ld elements\n", p->hvalue->table_size); 4385 else if (p->hvalue->type == Node_var_new) 4386 fprintf(fp, "unused variable\n"); 4387 else if (p->hvalue->type == Node_var) 4388 valinfo(p->hvalue->var_value, fp); 4389 else { 4390 NODE **lhs = get_lhs(p->hvalue, NULL, FALSE); 4391 4392 valinfo(*lhs, fp); 4393 } 4394 } 4395 4396 if (fp != stderr && fclose(fp) != 0) 4397 warning(_("%s: close failed (%s)"), fname, strerror(errno)); 4398 4399 free(table); 4400} 4401 4402/* release_all_vars --- free all variable memory */ 4403 4404void 4405release_all_vars() 4406{ 4407 int i; 4408 NODE *p, *next; 4409 4410 for (i = 0; i < HASHSIZE; i++) 4411 for (p = variables[i]; p != NULL; p = next) { 4412 next = p->hnext; 4413 4414 if (p->hvalue->type == Node_func) 4415 continue; 4416 else if (p->hvalue->type == Node_var_array) 4417 assoc_clear(p->hvalue); 4418 else if (p->hvalue->type != Node_var_new) { 4419 NODE **lhs = get_lhs(p->hvalue, NULL, FALSE); 4420 4421 unref(*lhs); 4422 } 4423 unref(p); 4424 } 4425} 4426 4427/* finfo --- for use in comparison and sorting of function names */ 4428 4429struct finfo { 4430 const char *name; 4431 size_t nlen; 4432 NODE *func; 4433}; 4434 4435/* fcompare --- comparison function for qsort */ 4436 4437static int 4438fcompare(const void *p1, const void *p2) 4439{ 4440 const struct finfo *f1, *f2; 4441 int minlen; 4442 4443 f1 = (const struct finfo *) p1; 4444 f2 = (const struct finfo *) p2; 4445 4446 if (f1->nlen > f2->nlen) 4447 minlen = f2->nlen; 4448 else 4449 minlen = f1->nlen; 4450 4451 return strncmp(f1->name, f2->name, minlen); 4452} 4453 4454/* dump_funcs --- print all functions */ 4455 4456void 4457dump_funcs() 4458{ 4459 int i, j; 4460 NODE *p; 4461 static struct finfo *tab = NULL; 4462 4463 if (func_count == 0) 4464 return; 4465 4466 /* 4467 * Walk through symbol table countng functions. 4468 * Could be more than func_count if there are 4469 * extension functions. 4470 */ 4471 for (i = j = 0; i < HASHSIZE; i++) { 4472 for (p = variables[i]; p != NULL; p = p->hnext) { 4473 if (p->hvalue->type == Node_func) { 4474 j++; 4475 } 4476 } 4477 } 4478 4479 if (tab == NULL) 4480 emalloc(tab, struct finfo *, j * sizeof(struct finfo), "dump_funcs"); 4481 4482 /* now walk again, copying info */ 4483 for (i = j = 0; i < HASHSIZE; i++) { 4484 for (p = variables[i]; p != NULL; p = p->hnext) { 4485 if (p->hvalue->type == Node_func) { 4486 tab[j].name = p->hname; 4487 tab[j].nlen = p->hlength; 4488 tab[j].func = p->hvalue; 4489 j++; 4490 } 4491 } 4492 } 4493 4494 4495 /* Shazzam! */ 4496 qsort(tab, j, sizeof(struct finfo), fcompare); 4497 4498 for (i = 0; i < j; i++) 4499 pp_func(tab[i].name, tab[i].nlen, tab[i].func); 4500 4501 free(tab); 4502} 4503 4504/* shadow_funcs --- check all functions for parameters that shadow globals */ 4505 4506void 4507shadow_funcs() 4508{ 4509 int i, j; 4510 NODE *p; 4511 struct finfo *tab; 4512 static int calls = 0; 4513 int shadow = FALSE; 4514 4515 if (func_count == 0) 4516 return; 4517 4518 if (calls++ != 0) 4519 fatal(_("shadow_funcs() called twice!")); 4520 4521 emalloc(tab, struct finfo *, func_count * sizeof(struct finfo), "shadow_funcs"); 4522 4523 for (i = j = 0; i < HASHSIZE; i++) { 4524 for (p = variables[i]; p != NULL; p = p->hnext) { 4525 if (p->hvalue->type == Node_func) { 4526 tab[j].name = p->hname; 4527 tab[j].nlen = p->hlength; 4528 tab[j].func = p->hvalue; 4529 j++; 4530 } 4531 } 4532 } 4533 4534 assert(j == func_count); 4535 4536 /* Shazzam! */ 4537 qsort(tab, func_count, sizeof(struct finfo), fcompare); 4538 4539 for (i = 0; i < j; i++) 4540 shadow |= parms_shadow(tab[i].name, tab[i].func); 4541 4542 free(tab); 4543 4544 /* End with fatal if the user requested it. */ 4545 if (shadow && lintfunc != warning) 4546 lintwarn(_("there were shadowed variables.")); 4547} 4548 4549/* 4550 * append_right: 4551 * Add new to the rightmost branch of LIST. This uses n^2 time, so we make 4552 * a simple attempt at optimizing it. 4553 */ 4554 4555static NODE * 4556append_right(NODE *list, NODE *new) 4557{ 4558 register NODE *oldlist; 4559 static NODE *savefront = NULL, *savetail = NULL; 4560 4561 if (list == NULL || new == NULL) 4562 return list; 4563 4564 oldlist = list; 4565 if (savefront == oldlist) 4566 list = savetail; /* Be careful: maybe list->rnode != NULL */ 4567 else 4568 savefront = oldlist; 4569 4570 while (list->rnode != NULL) 4571 list = list->rnode; 4572 savetail = list->rnode = new; 4573 return oldlist; 4574} 4575 4576/* 4577 * append_pattern: 4578 * A wrapper around append_right, used for rule lists. 4579 */ 4580static inline NODE * 4581append_pattern(NODE **list, NODE *patt) 4582{ 4583 NODE *n = node(patt, Node_rule_node, (NODE *) NULL); 4584 4585 if (*list == NULL) 4586 *list = n; 4587 else { 4588 NODE *n1 = node(n, Node_rule_list, (NODE *) NULL); 4589 if ((*list)->type != Node_rule_list) 4590 *list = node(*list, Node_rule_list, n1); 4591 else 4592 (void) append_right(*list, n1); 4593 } 4594 return n; 4595} 4596 4597/* 4598 * func_install: 4599 * check if name is already installed; if so, it had better have Null value, 4600 * in which case def is added as the value. Otherwise, install name with def 4601 * as value. 4602 * 4603 * Extra work, build up and save a list of the parameter names in a table 4604 * and hang it off params->parmlist. This is used to set the `vname' field 4605 * of each function parameter during a function call. See eval.c. 4606 */ 4607 4608static void 4609func_install(NODE *params, NODE *def) 4610{ 4611 NODE *r, *n, *thisfunc; 4612 char **pnames, *names, *sp; 4613 size_t pcount = 0, space = 0; 4614 int i; 4615 4616 /* check for function foo(foo) { ... }. bleah. */ 4617 for (n = params->rnode; n != NULL; n = n->rnode) { 4618 if (strcmp(n->param, params->param) == 0) 4619 fatal(_("function `%s': can't use function name as parameter name"), 4620 params->param); 4621 } 4622 4623 thisfunc = NULL; /* turn off warnings */ 4624 4625 /* symbol table managment */ 4626 pop_var(params, FALSE); 4627 r = lookup(params->param); 4628 if (r != NULL) { 4629 fatal(_("function name `%s' previously defined"), params->param); 4630 } else if (params->param == builtin_func) /* not a valid function name */ 4631 goto remove_params; 4632 4633 /* install the function */ 4634 thisfunc = node(params, Node_func, def); 4635 (void) install(params->param, thisfunc); 4636 4637 /* figure out amount of space to allocate for variable names */ 4638 for (n = params->rnode; n != NULL; n = n->rnode) { 4639 pcount++; 4640 space += strlen(n->param) + 1; 4641 } 4642 4643 /* allocate it and fill it in */ 4644 if (pcount != 0) { 4645 emalloc(names, char *, space, "func_install"); 4646 emalloc(pnames, char **, pcount * sizeof(char *), "func_install"); 4647 sp = names; 4648 for (i = 0, n = params->rnode; i < pcount; i++, n = n->rnode) { 4649 pnames[i] = sp; 4650 strcpy(sp, n->param); 4651 sp += strlen(n->param) + 1; 4652 } 4653 thisfunc->parmlist = pnames; 4654 } else { 4655 thisfunc->parmlist = NULL; 4656 } 4657 4658 /* update lint table info */ 4659 func_use(params->param, FUNC_DEFINE); 4660 4661 func_count++; /* used by profiling / pretty printer */ 4662 4663remove_params: 4664 /* remove params from symbol table */ 4665 pop_params(params->rnode); 4666} 4667 4668/* pop_var --- remove a variable from the symbol table */ 4669 4670static void 4671pop_var(NODE *np, int freeit) 4672{ 4673 register NODE *bucket, **save; 4674 register size_t len; 4675 char *name; 4676 4677 name = np->param; 4678 len = strlen(name); 4679 save = &(variables[hash(name, len, (unsigned long) HASHSIZE)]); 4680 for (bucket = *save; bucket != NULL; bucket = bucket->hnext) { 4681 if (len == bucket->hlength && STREQN(bucket->hname, name, len)) { 4682 var_count--; 4683 *save = bucket->hnext; 4684 freenode(bucket); 4685 if (freeit) 4686 free(np->param); 4687 return; 4688 } 4689 save = &(bucket->hnext); 4690 } 4691} 4692 4693/* pop_params --- remove list of function parameters from symbol table */ 4694 4695/* 4696 * pop parameters out of the symbol table. do this in reverse order to 4697 * avoid reading freed memory if there were duplicated parameters. 4698 */ 4699static void 4700pop_params(NODE *params) 4701{ 4702 if (params == NULL) 4703 return; 4704 pop_params(params->rnode); 4705 pop_var(params, TRUE); 4706} 4707 4708/* make_param --- make NAME into a function parameter */ 4709 4710static NODE * 4711make_param(char *name) 4712{ 4713 NODE *r; 4714 4715 getnode(r); 4716 r->type = Node_param_list; 4717 r->rnode = NULL; 4718 r->param = name; 4719 r->param_cnt = param_counter++; 4720 return (install(name, r)); 4721} 4722 4723static struct fdesc { 4724 char *name; 4725 short used; 4726 short defined; 4727 struct fdesc *next; 4728} *ftable[HASHSIZE]; 4729 4730/* func_use --- track uses and definitions of functions */ 4731 4732static void 4733func_use(const char *name, enum defref how) 4734{ 4735 struct fdesc *fp; 4736 int len; 4737 int ind; 4738 4739 len = strlen(name); 4740 ind = hash(name, len, HASHSIZE); 4741 4742 for (fp = ftable[ind]; fp != NULL; fp = fp->next) { 4743 if (strcmp(fp->name, name) == 0) { 4744 if (how == FUNC_DEFINE) 4745 fp->defined++; 4746 else 4747 fp->used++; 4748 return; 4749 } 4750 } 4751 4752 /* not in the table, fall through to allocate a new one */ 4753 4754 emalloc(fp, struct fdesc *, sizeof(struct fdesc), "func_use"); 4755 memset(fp, '\0', sizeof(struct fdesc)); 4756 emalloc(fp->name, char *, len + 1, "func_use"); 4757 strcpy(fp->name, name); 4758 if (how == FUNC_DEFINE) 4759 fp->defined++; 4760 else 4761 fp->used++; 4762 fp->next = ftable[ind]; 4763 ftable[ind] = fp; 4764} 4765 4766/* check_funcs --- verify functions that are called but not defined */ 4767 4768static void 4769check_funcs() 4770{ 4771 struct fdesc *fp, *next; 4772 int i; 4773 4774 for (i = 0; i < HASHSIZE; i++) { 4775 for (fp = ftable[i]; fp != NULL; fp = fp->next) { 4776#ifdef REALLYMEAN 4777 /* making this the default breaks old code. sigh. */ 4778 if (fp->defined == 0) { 4779 error( 4780 _("function `%s' called but never defined"), fp->name); 4781 errcount++; 4782 } 4783#else 4784 if (do_lint && fp->defined == 0) 4785 lintwarn( 4786 _("function `%s' called but never defined"), fp->name); 4787#endif 4788 if (do_lint && fp->used == 0) { 4789 lintwarn(_("function `%s' defined but never called"), 4790 fp->name); 4791 } 4792 } 4793 } 4794 4795 /* now let's free all the memory */ 4796 for (i = 0; i < HASHSIZE; i++) { 4797 for (fp = ftable[i]; fp != NULL; fp = next) { 4798 next = fp->next; 4799 free(fp->name); 4800 free(fp); 4801 } 4802 } 4803} 4804 4805/* param_sanity --- look for parameters that are regexp constants */ 4806 4807static void 4808param_sanity(NODE *arglist) 4809{ 4810 NODE *argp, *arg; 4811 int i; 4812 4813 for (i = 1, argp = arglist; argp != NULL; argp = argp->rnode, i++) { 4814 arg = argp->lnode; 4815 if (arg->type == Node_regex) 4816 warning(_("regexp constant for parameter #%d yields boolean value"), i); 4817 } 4818} 4819 4820/* variable --- make sure NAME is in the symbol table */ 4821 4822NODE * 4823variable(char *name, int can_free, NODETYPE type) 4824{ 4825 register NODE *r; 4826 4827 if ((r = lookup(name)) != NULL) { 4828 if (r->type == Node_func) 4829 fatal(_("function `%s' called with space between name and `(',\n%s"), 4830 r->vname, 4831 _("or used as a variable or an array")); 4832 } else { 4833 /* not found */ 4834 if (! do_traditional && STREQ(name, "PROCINFO")) 4835 r = load_procinfo(); 4836 else if (STREQ(name, "ENVIRON")) 4837 r = load_environ(); 4838 else { 4839 /* 4840 * This is the only case in which we may not free the string. 4841 */ 4842 NODE *n; 4843 4844 if (type == Node_var) 4845 n = node(Nnull_string, type, (NODE *) NULL); 4846 else 4847 n = node((NODE *) NULL, type, (NODE *) NULL); 4848 4849 return install(name, n); 4850 } 4851 } 4852 if (can_free) 4853 free(name); 4854 return r; 4855} 4856 4857/* mk_rexp --- make a regular expression constant */ 4858 4859static NODE * 4860mk_rexp(NODE *exp) 4861{ 4862 NODE *n; 4863 4864 if (exp->type == Node_regex) 4865 return exp; 4866 4867 getnode(n); 4868 n->type = Node_dynregex; 4869 n->re_exp = exp; 4870 n->re_text = NULL; 4871 n->re_reg = NULL; 4872 n->re_flags = 0; 4873 return n; 4874} 4875 4876/* isnoeffect --- when used as a statement, has no side effects */ 4877 4878/* 4879 * To be completely general, we should recursively walk the parse 4880 * tree, to make sure that all the subexpressions also have no effect. 4881 * Instead, we just weaken the actual warning that's printed, up above 4882 * in the grammar. 4883 */ 4884 4885static int 4886isnoeffect(NODETYPE type) 4887{ 4888 switch (type) { 4889 case Node_times: 4890 case Node_quotient: 4891 case Node_mod: 4892 case Node_plus: 4893 case Node_minus: 4894 case Node_subscript: 4895 case Node_concat: 4896 case Node_exp: 4897 case Node_unary_minus: 4898 case Node_field_spec: 4899 case Node_and: 4900 case Node_or: 4901 case Node_equal: 4902 case Node_notequal: 4903 case Node_less: 4904 case Node_greater: 4905 case Node_leq: 4906 case Node_geq: 4907 case Node_match: 4908 case Node_nomatch: 4909 case Node_not: 4910 case Node_val: 4911 case Node_in_array: 4912 case Node_NF: 4913 case Node_NR: 4914 case Node_FNR: 4915 case Node_FS: 4916 case Node_RS: 4917 case Node_FIELDWIDTHS: 4918 case Node_IGNORECASE: 4919 case Node_OFS: 4920 case Node_ORS: 4921 case Node_OFMT: 4922 case Node_CONVFMT: 4923 case Node_BINMODE: 4924 case Node_LINT: 4925 case Node_TEXTDOMAIN: 4926 return TRUE; 4927 default: 4928 break; /* keeps gcc -Wall happy */ 4929 } 4930 4931 return FALSE; 4932} 4933 4934/* isassignable --- can this node be assigned to? */ 4935 4936static int 4937isassignable(register NODE *n) 4938{ 4939 switch (n->type) { 4940 case Node_var_new: 4941 case Node_var: 4942 case Node_FIELDWIDTHS: 4943 case Node_RS: 4944 case Node_FS: 4945 case Node_FNR: 4946 case Node_NR: 4947 case Node_NF: 4948 case Node_IGNORECASE: 4949 case Node_OFMT: 4950 case Node_CONVFMT: 4951 case Node_ORS: 4952 case Node_OFS: 4953 case Node_LINT: 4954 case Node_BINMODE: 4955 case Node_TEXTDOMAIN: 4956 case Node_field_spec: 4957 case Node_subscript: 4958 return TRUE; 4959 case Node_param_list: 4960 return ((n->flags & FUNC) == 0); /* ok if not func name */ 4961 default: 4962 break; /* keeps gcc -Wall happy */ 4963 } 4964 return FALSE; 4965} 4966 4967/* stopme --- for debugging */ 4968 4969NODE * 4970stopme(NODE *tree ATTRIBUTE_UNUSED) 4971{ 4972 return 0; 4973} 4974 4975/* dumpintlstr --- write out an initial .po file entry for the string */ 4976 4977static void 4978dumpintlstr(const char *str, size_t len) 4979{ 4980 char *cp; 4981 4982 /* See the GNU gettext distribution for details on the file format */ 4983 4984 if (source != NULL) { 4985 /* ala the gettext sources, remove leading `./'s */ 4986 for (cp = source; cp[0] == '.' && cp[1] == '/'; cp += 2) 4987 continue; 4988 printf("#: %s:%d\n", cp, sourceline); 4989 } 4990 4991 printf("msgid "); 4992 pp_string_fp(stdout, str, len, '"', TRUE); 4993 putchar('\n'); 4994 printf("msgstr \"\"\n\n"); 4995 fflush(stdout); 4996} 4997 4998/* dumpintlstr2 --- write out an initial .po file entry for the string and its plural */ 4999 5000static void 5001dumpintlstr2(const char *str1, size_t len1, const char *str2, size_t len2) 5002{ 5003 char *cp; 5004 5005 /* See the GNU gettext distribution for details on the file format */ 5006 5007 if (source != NULL) { 5008 /* ala the gettext sources, remove leading `./'s */ 5009 for (cp = source; cp[0] == '.' && cp[1] == '/'; cp += 2) 5010 continue; 5011 printf("#: %s:%d\n", cp, sourceline); 5012 } 5013 5014 printf("msgid "); 5015 pp_string_fp(stdout, str1, len1, '"', TRUE); 5016 putchar('\n'); 5017 printf("msgid_plural "); 5018 pp_string_fp(stdout, str2, len2, '"', TRUE); 5019 putchar('\n'); 5020 printf("msgstr[0] \"\"\nmsgstr[1] \"\"\n\n"); 5021 fflush(stdout); 5022} 5023 5024/* count_args --- count the number of printf arguments */ 5025 5026static void 5027count_args(NODE *tree) 5028{ 5029 size_t count = 0; 5030 NODE *save_tree; 5031 5032 assert(tree->type == Node_K_printf 5033 || (tree->type == Node_builtin && tree->builtin == do_sprintf)); 5034 save_tree = tree; 5035 5036 tree = tree->lnode; /* printf format string */ 5037 5038 for (count = 0; tree != NULL; tree = tree->rnode) 5039 count++; 5040 5041 save_tree->printf_count = count; 5042} 5043 5044/* isarray --- can this type be subscripted? */ 5045 5046static int 5047isarray(NODE *n) 5048{ 5049 switch (n->type) { 5050 case Node_var_new: 5051 case Node_var_array: 5052 return TRUE; 5053 case Node_param_list: 5054 return ((n->flags & FUNC) == 0); 5055 case Node_array_ref: 5056 cant_happen(); 5057 break; 5058 default: 5059 break; /* keeps gcc -Wall happy */ 5060 } 5061 5062 return FALSE; 5063} 5064 5065 5066