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