2 * eval.c - gawk bytecode interpreter
6 * Copyright (C) 1986, 1988, 1989, 1991-2011 the Free Software Foundation, Inc.
8 * This file is part of GAWK, the GNU implementation of the
9 * AWK Programming Language.
11 * GAWK is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 3 of the License, or
14 * (at your option) any later version.
16 * GAWK is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
28 extern void after_beginfile(IOBUF **curfile);
29 extern double pow(double x, double y);
30 extern double modf(double x, double *yp);
31 extern double fmod(double x, double y);
35 IOBUF *curfile = NULL; /* current data file */
39 extern int pre_execute(INSTRUCTION **);
40 extern void post_execute(INSTRUCTION *);
42 #define r_interpret interpret
46 * Flag which executable this is; done here because eval.c is compiled
47 * differently for each of them.
49 enum exe_mode which_gawk =
51 exe_profiling /* pgawk */
54 exe_debugging /* dgawk */
56 exe_normal /* normal gawk */
62 NODE *_t; /* used as a temporary in macros */
71 #define INCREMENT(n) n++
73 #define INCREMENT(n) /* nothing */
76 /* This rather ugly macro is for VMS C */
80 #define C(c) ((char)c)
82 * This table is used by the regexp routines to do case independent
83 * matching. Basically, every ascii character maps to itself, except
84 * uppercase letters map to lower case ones. This table has 256
85 * entries, for ISO 8859-1. Note also that if the system this
86 * is compiled on doesn't use 7-bit ascii, casetable[] should not be
87 * defined to the linker, so gawk should not load.
89 * Do NOT make this array static, it is used in several spots, not
93 * This table is also used for IGNORECASE for == and !=, and index().
94 * Although with GLIBC, we could use tolower() everywhere and RE_ICASE
95 * for the regex matcher, precomputing this table once gives us a
96 * performance improvement. I also think it's better for portability
97 * to non-GLIBC systems. All the world is not (yet :-) GNU/Linux.
99 #if 'a' == 97 /* it's ascii */
101 '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
102 '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
103 '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
104 '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
105 /* ' ' '!' '"' '#' '$' '%' '&' ''' */
106 '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
107 /* '(' ')' '*' '+' ',' '-' '.' '/' */
108 '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
109 /* '0' '1' '2' '3' '4' '5' '6' '7' */
110 '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
111 /* '8' '9' ':' ';' '<' '=' '>' '?' */
112 '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
113 /* '@' 'A' 'B' 'C' 'D' 'E' 'F' 'G' */
114 '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
115 /* 'H' 'I' 'J' 'K' 'L' 'M' 'N' 'O' */
116 '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
117 /* 'P' 'Q' 'R' 'S' 'T' 'U' 'V' 'W' */
118 '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
119 /* 'X' 'Y' 'Z' '[' '\' ']' '^' '_' */
120 '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
121 /* '`' 'a' 'b' 'c' 'd' 'e' 'f' 'g' */
122 '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
123 /* 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' */
124 '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
125 /* 'p' 'q' 'r' 's' 't' 'u' 'v' 'w' */
126 '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
127 /* 'x' 'y' 'z' '{' '|' '}' '~' */
128 '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177',
131 C('\200'), C('\201'), C('\202'), C('\203'), C('\204'), C('\205'), C('\206'), C('\207'),
132 C('\210'), C('\211'), C('\212'), C('\213'), C('\214'), C('\215'), C('\216'), C('\217'),
133 C('\220'), C('\221'), C('\222'), C('\223'), C('\224'), C('\225'), C('\226'), C('\227'),
134 C('\230'), C('\231'), C('\232'), C('\233'), C('\234'), C('\235'), C('\236'), C('\237'),
135 C('\240'), C('\241'), C('\242'), C('\243'), C('\244'), C('\245'), C('\246'), C('\247'),
136 C('\250'), C('\251'), C('\252'), C('\253'), C('\254'), C('\255'), C('\256'), C('\257'),
137 C('\260'), C('\261'), C('\262'), C('\263'), C('\264'), C('\265'), C('\266'), C('\267'),
138 C('\270'), C('\271'), C('\272'), C('\273'), C('\274'), C('\275'), C('\276'), C('\277'),
139 C('\340'), C('\341'), C('\342'), C('\343'), C('\344'), C('\345'), C('\346'), C('\347'),
140 C('\350'), C('\351'), C('\352'), C('\353'), C('\354'), C('\355'), C('\356'), C('\357'),
141 C('\360'), C('\361'), C('\362'), C('\363'), C('\364'), C('\365'), C('\366'), C('\327'),
142 C('\370'), C('\371'), C('\372'), C('\373'), C('\374'), C('\375'), C('\376'), C('\337'),
143 C('\340'), C('\341'), C('\342'), C('\343'), C('\344'), C('\345'), C('\346'), C('\347'),
144 C('\350'), C('\351'), C('\352'), C('\353'), C('\354'), C('\355'), C('\356'), C('\357'),
145 C('\360'), C('\361'), C('\362'), C('\363'), C('\364'), C('\365'), C('\366'), C('\367'),
146 C('\370'), C('\371'), C('\372'), C('\373'), C('\374'), C('\375'), C('\376'), C('\377'),
148 #elif 'a' == 0x81 /* it's EBCDIC */
150 /*00 NU SH SX EX PF HT LC DL */
151 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
152 /*08 SM VT FF CR SO SI */
153 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
154 /*10 DE D1 D2 TM RS NL BS IL */
155 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
156 /*18 CN EM CC C1 FS GS RS US */
157 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
158 /*20 DS SS FS BP LF EB EC */
159 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
160 /*28 SM C2 EQ AK BL */
161 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
162 /*30 SY PN RS UC ET */
163 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
165 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
167 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
168 /*48 CENT . < ( + | */
169 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
171 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
173 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
175 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
177 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
179 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
180 /*78 ` : # @ ' = " */
181 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
182 /*80 a b c d e f g */
183 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
185 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
186 /*90 j k l m n o p */
187 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
189 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
190 /*A0 ~ s t u v w x */
191 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
193 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
195 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7,
197 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
198 /*C0 { A B C D E F G */
199 0xC0, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
201 0x88, 0x89, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
202 /*D0 } J K L M N O P */
203 0xD0, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
205 0x98, 0x99, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
206 /*E0 \ S T U V W X */
207 0xE0, 0xE1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
209 0xA8, 0xA9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
210 /*F0 0 1 2 3 4 5 6 7 */
211 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
213 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
216 #include "You lose. You will need a translation table for your character set."
221 /* load_casetable --- for a non-ASCII locale, redo the table */
226 #if defined(LC_CTYPE)
229 static int loaded = FALSE;
231 if (loaded || do_traditional)
235 cp = setlocale(LC_CTYPE, NULL);
237 /* this is not per standard, but it's pretty safe */
238 if (cp == NULL || strcmp(cp, "C") == 0 || strcmp(cp, "POSIX") == 0)
242 for (i = 0200; i <= 0377; i++) {
243 if (isalpha(i) && islower(i) && i != toupper(i))
244 casetable[i] = toupper(i);
251 * This table maps node types to strings for debugging.
252 * KEEP IN SYNC WITH awk.h!!!!
255 static const char *const nodetypes[] = {
271 "Node_final --- this should never appear",
277 * This table maps Op codes to strings.
278 * KEEP IN SYNC WITH awk.h!!!!
281 static struct optypetab {
285 { "Op_illegal", NULL },
286 { "Op_times", " * " },
287 { "Op_times_i", " * " },
288 { "Op_quotient", " / " },
289 { "Op_quotient_i", " / " },
291 { "Op_mod_i", " % " },
292 { "Op_plus", " + " },
293 { "Op_plus_i", " + " },
294 { "Op_minus", " - " },
295 { "Op_minus_i", " - " },
297 { "Op_exp_i", " ^ " },
298 { "Op_concat", " " },
299 { "Op_line_range", NULL },
300 { "Op_cond_pair", ", " },
301 { "Op_subscript", "[]" },
302 { "Op_sub_array", "[]" },
303 { "Op_preincrement", "++" },
304 { "Op_predecrement", "--" },
305 { "Op_postincrement", "++" },
306 { "Op_postdecrement", "--" },
307 { "Op_unary_minus", "-" },
308 { "Op_field_spec", "$" },
310 { "Op_assign", " = " },
311 { "Op_store_var", " = " },
312 { "Op_store_sub", " = " },
313 { "Op_store_field", " = " },
314 { "Op_assign_times", " *= " },
315 { "Op_assign_quotient", " /= " },
316 { "Op_assign_mod", " %= " },
317 { "Op_assign_plus", " += " },
318 { "Op_assign_minus", " -= " },
319 { "Op_assign_exp", " ^= " },
320 { "Op_assign_concat", " " },
321 { "Op_and", " && " },
322 { "Op_and_final", NULL },
324 { "Op_or_final", NULL },
325 { "Op_equal", " == " },
326 { "Op_notequal", " != " },
327 { "Op_less", " < " },
328 { "Op_greater", " > " },
329 { "Op_leq", " <= " },
330 { "Op_geq", " >= " },
331 { "Op_match", " ~ " },
332 { "Op_match_rec", NULL },
333 { "Op_nomatch", " !~ " },
335 { "Op_K_case", "case" },
336 { "Op_K_default", "default" },
337 { "Op_K_break", "break" },
338 { "Op_K_continue", "continue" },
339 { "Op_K_print", "print" },
340 { "Op_K_print_rec", "print" },
341 { "Op_K_printf", "printf" },
342 { "Op_K_next", "next" },
343 { "Op_K_exit", "exit" },
344 { "Op_K_return", "return" },
345 { "Op_K_delete", "delete" },
346 { "Op_K_delete_loop", NULL },
347 { "Op_K_getline_redir", "getline" },
348 { "Op_K_getline", "getline" },
349 { "Op_K_nextfile", "nextfile" },
350 { "Op_builtin", NULL },
351 { "Op_sub_builtin", NULL },
352 { "Op_in_array", " in " },
353 { "Op_func_call", NULL },
354 { "Op_indirect_func_call", NULL },
356 { "Op_push_arg", NULL },
357 { "Op_push_i", NULL },
358 { "Op_push_re", NULL },
359 { "Op_push_array", NULL },
360 { "Op_push_param", NULL },
361 { "Op_push_lhs", NULL },
362 { "Op_subscript_lhs", "[]" },
363 { "Op_field_spec_lhs", "$" },
364 { "Op_no_op", NULL },
367 { "Op_jmp_true", NULL },
368 { "Op_jmp_false", NULL },
369 { "Op_get_record", NULL },
370 { "Op_newfile", NULL },
371 { "Op_arrayfor_init", NULL },
372 { "Op_arrayfor_incr", NULL },
373 { "Op_arrayfor_final", NULL },
374 { "Op_var_update", NULL },
375 { "Op_var_assign", NULL },
376 { "Op_field_assign", NULL },
377 { "Op_after_beginfile", NULL },
378 { "Op_after_endfile", NULL },
379 { "Op_ext_func", NULL },
381 { "Op_exec_count", NULL },
382 { "Op_breakpoint", NULL },
384 { "Op_atexit", NULL },
386 { "Op_token", NULL },
387 { "Op_symbol", NULL },
390 { "Op_K_for", "for" },
391 { "Op_K_arrayfor", "for" },
392 { "Op_K_while", "while" },
393 { "Op_K_switch", "switch" },
395 { "Op_K_else", "else" },
396 { "Op_K_function", "function" },
397 { "Op_cond_exp", NULL },
398 { "Op_final --- this should never appear", NULL },
402 /* nodetype2str --- convert a node type into a printable value */
405 nodetype2str(NODETYPE type)
409 if (type >= Node_illegal && type <= Node_final)
410 return nodetypes[(int) type];
412 sprintf(buf, _("unknown nodetype %d"), (int) type);
416 /* opcode2str --- convert a opcode type into a printable value */
419 opcode2str(OPCODE op)
421 if (op >= Op_illegal && op < Op_final)
422 return optypes[(int) op].desc;
423 fatal(_("unknown opcode %d"), (int) op);
430 if (op >= Op_illegal && op < Op_final) {
431 if (optypes[(int) op].operator != NULL)
432 return optypes[(int) op].operator;
434 fatal(_("opcode %s not an operator or keyword"),
435 optypes[(int) op].desc);
437 fatal(_("unknown opcode %d"), (int) op);
442 /* flags2str --- make a flags value readable */
445 flags2str(int flagval)
447 static const struct flagtab values[] = {
448 { MALLOC, "MALLOC" },
450 { STRING, "STRING" },
451 { STRCUR, "STRCUR" },
452 { NUMCUR, "NUMCUR" },
453 { NUMBER, "NUMBER" },
454 { MAYBE_NUM, "MAYBE_NUM" },
455 { ARRAYMAXED, "ARRAYMAXED" },
458 { INTLSTR, "INTLSTR" },
459 { NUMIND, "NUMIND" },
461 { WSTRCUR, "WSTRCUR" },
466 return genflags2str(flagval, values);
469 /* genflags2str --- general routine to convert a flag value to a string */
472 genflags2str(int flagval, const struct flagtab *tab)
474 static char buffer[BUFSIZ];
476 int i, space_left, space_needed;
480 for (i = 0; tab[i].name != NULL; i++) {
481 if ((flagval & tab[i].val) != 0) {
483 * note the trick, we want 1 or 0 for whether we need
486 space_needed = (strlen(tab[i].name) + (sp != buffer));
487 if (space_left < space_needed)
488 fatal(_("buffer overflow in genflags2str"));
494 strcpy(sp, tab[i].name);
496 space_left -= strlen(sp);
504 /* posix_compare --- compare strings using strcoll */
507 posix_compare(NODE *s1, NODE *s2)
513 save1 = s1->stptr[s1->stlen];
514 s1->stptr[s1->stlen] = '\0';
516 save2 = s2->stptr[s2->stlen];
517 s2->stptr[s2->stlen] = '\0';
519 if (gawk_mb_cur_max == 1) {
520 if (strlen(s1->stptr) == s1->stlen && strlen(s2->stptr) == s2->stlen)
521 ret = strcoll(s1->stptr, s2->stptr);
527 if (s1->stlen < s2->stlen)
532 b1[1] = b2[1] = '\0';
533 for (i = ret = 0, p1 = s1->stptr, p2 = s2->stptr;
538 ret = strcoll(b1, b2);
542 * Either worked through the strings or ret != 0.
543 * In either case, ret will be the right thing to return.
548 /* Similar logic, using wide characters */
549 (void) force_wstring(s1);
550 (void) force_wstring(s2);
552 if (wcslen(s1->wstptr) == s1->wstlen && wcslen(s2->wstptr) == s2->wstlen)
553 ret = wcscoll(s1->wstptr, s2->wstptr);
555 wchar_t b1[2], b2[2];
559 if (s1->wstlen < s2->wstlen)
564 b1[1] = b2[1] = L'\0';
565 for (i = ret = 0, p1 = s1->wstptr, p2 = s2->wstptr;
570 ret = wcscoll(b1, b2);
574 * Either worked through the strings or ret != 0.
575 * In either case, ret will be the right thing to return.
580 s1->stptr[s1->stlen] = save1;
581 s2->stptr[s2->stlen] = save2;
586 /* cmp_nodes --- compare two nodes, returning negative, 0, positive */
589 cmp_nodes(NODE *t1, NODE *t2)
598 if (t1->flags & MAYBE_NUM)
599 (void) force_number(t1);
600 if (t2->flags & MAYBE_NUM)
601 (void) force_number(t2);
602 if ((t1->flags & NUMBER) && (t2->flags & NUMBER)) {
603 if (t1->numbr == t2->numbr)
605 /* don't subtract, in case one or both are infinite */
606 else if (t1->numbr < t2->numbr)
613 (void) force_string(t1);
614 (void) force_string(t2);
618 if (len1 == 0 || len2 == 0)
622 return posix_compare(t1, t2);
624 l = (ldiff <= 0 ? len1 : len2);
626 const unsigned char *cp1 = (const unsigned char *) t1->stptr;
627 const unsigned char *cp2 = (const unsigned char *) t2->stptr;
630 if (gawk_mb_cur_max > 1) {
631 ret = strncasecmpmbs((const unsigned char *) cp1,
632 (const unsigned char *) cp2, l);
635 /* Could use tolower() here; see discussion above. */
636 for (ret = 0; l-- > 0 && ret == 0; cp1++, cp2++)
637 ret = casetable[*cp1] - casetable[*cp2];
639 ret = memcmp(t1->stptr, t2->stptr, l);
640 return (ret == 0 ? ldiff : ret);
644 #if defined(PROFILING) || defined(DEBUGGING)
648 static long max_fcall;
650 /* NB: frame numbering scheme as in GDB. frame_ptr => frame #0. */
653 if (fcall_list == NULL) {
655 emalloc(fcall_list, NODE **, (max_fcall + 1) * sizeof(NODE *), "push_frame");
656 } else if (fcall_count == max_fcall) {
658 erealloc(fcall_list, NODE **, (max_fcall + 1) * sizeof(NODE *), "push_frame");
662 memmove(fcall_list + 2, fcall_list + 1, (fcall_count - 1) * sizeof(NODE *));
670 extern void frame_popped();
673 memmove(fcall_list + 1, fcall_list + 2, (fcall_count - 1) * sizeof(NODE *));
675 assert(fcall_count >= 0);
680 #else /* not PROFILING or DEBUGGING */
681 #define push_frame(p) /* nothing */
682 #define pop_frame() /* nothing */
688 /* dump_fcall_stack --- print a backtrace of the awk function calls */
691 dump_fcall_stack(FILE *fp)
696 if (fcall_count == 0)
698 fprintf(fp, _("\n\t# Function Call Stack:\n\n"));
701 func = frame_ptr->func_node;
702 fprintf(fp, "\t# %3ld. %s\n", i, func->lnode->param);
704 /* outer frames except main */
705 for (i = 1; i < fcall_count; i++) {
708 fprintf(fp, "\t# %3ld. %s\n", i, func->lnode->param);
711 fprintf(fp, "\t# %3ld. -- main --\n", fcall_count);
714 #endif /* PROFILING */
716 /* set_IGNORECASE --- update IGNORECASE as appropriate */
721 static short warned = FALSE;
723 if ((do_lint || do_traditional) && ! warned) {
725 lintwarn(_("`IGNORECASE' is a gawk extension"));
730 else if ((IGNORECASE_node->var_value->flags & (STRING|STRCUR)) != 0) {
731 if ((IGNORECASE_node->var_value->flags & MAYBE_NUM) == 0)
732 IGNORECASE = (force_string(IGNORECASE_node->var_value)->stlen > 0);
734 IGNORECASE = (force_number(IGNORECASE_node->var_value) != 0.0);
735 } else if ((IGNORECASE_node->var_value->flags & (NUMCUR|NUMBER)) != 0)
736 IGNORECASE = (force_number(IGNORECASE_node->var_value) != 0.0);
738 IGNORECASE = FALSE; /* shouldn't happen */
740 set_RS(); /* set_RS() calls set_FS() if need be, for us */
743 /* set_BINMODE --- set translation mode (OS/2, DOS, others) */
748 static short warned = FALSE;
752 if ((do_lint || do_traditional) && ! warned) {
754 lintwarn(_("`BINMODE' is a gawk extension"));
758 else if ((BINMODE_node->var_value->flags & NUMBER) != 0) {
759 BINMODE = (int) force_number(BINMODE_node->var_value);
760 /* Make sure the value is rational. */
763 else if (BINMODE > 3)
766 else if ((BINMODE_node->var_value->flags & STRING) != 0) {
767 v = BINMODE_node->var_value;
771 * Allow only one of the following:
772 * "0", "1", "2", "3",
773 * "r", "w", "rw", "wr"
774 * ANYTHING ELSE goes to 3. So there.
783 BINMODE = p[0] - '0';
812 lintwarn(_("BINMODE value `%s' is invalid, treated as 3"), p);
818 BINMODE = 3; /* shouldn't happen */
821 /* set_OFS --- update OFS related variables when OFS assigned to */
826 OFS = force_string(OFS_node->var_value)->stptr;
827 OFSlen = OFS_node->var_value->stlen;
831 /* set_ORS --- update ORS related variables when ORS assigned to */
836 ORS = force_string(ORS_node->var_value)->stptr;
837 ORSlen = ORS_node->var_value->stlen;
841 /* fmt_ok --- is the conversion format a valid one? */
843 NODE **fmt_list = NULL;
844 static int fmt_ok(NODE *n);
845 static int fmt_index(NODE *n);
850 NODE *tmp = force_string(n);
851 const char *p = tmp->stptr;
852 #if ! defined(PRINTF_HAS_F_FORMAT) || PRINTF_HAS_F_FORMAT != 1
853 static const char float_formats[] = "efgEG";
855 static const char float_formats[] = "efgEFG";
857 #if defined(HAVE_LOCALE_H)
858 static const char flags[] = " +-#'";
860 static const char flags[] = " +-#";
865 while (*p && strchr(flags, *p) != NULL) /* flags */
867 while (*p && isdigit((unsigned char) *p)) /* width - %*.*g is NOT allowed */
869 if (*p == '\0' || (*p != '.' && ! isdigit((unsigned char) *p)))
873 while (*p && isdigit((unsigned char) *p)) /* precision */
875 if (*p == '\0' || strchr(float_formats, *p) == NULL)
882 /* fmt_index --- track values of OFMT and CONVFMT to keep semantics correct */
888 static int fmt_num = 4;
889 static int fmt_hiwater = 0;
891 if (fmt_list == NULL)
892 emalloc(fmt_list, NODE **, fmt_num*sizeof(*fmt_list), "fmt_index");
893 (void) force_string(n);
894 while (ix < fmt_hiwater) {
895 if (cmp_nodes(fmt_list[ix], n) == 0)
900 n->stptr[n->stlen] = '\0';
901 if (do_lint && ! fmt_ok(n))
902 lintwarn(_("bad `%sFMT' specification `%s'"),
903 n == CONVFMT_node->var_value ? "CONV"
904 : n == OFMT_node->var_value ? "O"
907 if (fmt_hiwater >= fmt_num) {
909 erealloc(fmt_list, NODE **, fmt_num * sizeof(*fmt_list), "fmt_index");
911 fmt_list[fmt_hiwater] = dupnode(n);
912 return fmt_hiwater++;
915 /* set_OFMT --- track OFMT correctly */
920 OFMTidx = fmt_index(OFMT_node->var_value);
921 OFMT = fmt_list[OFMTidx]->stptr;
924 /* set_CONVFMT --- track CONVFMT correctly */
929 CONVFMTidx = fmt_index(CONVFMT_node->var_value);
930 CONVFMT = fmt_list[CONVFMTidx]->stptr;
933 /* set_LINT --- update LINT as appropriate */
939 int old_lint = do_lint;
941 if ((LINT_node->var_value->flags & (STRING|STRCUR)) != 0) {
942 if ((LINT_node->var_value->flags & MAYBE_NUM) == 0) {
946 do_lint = (force_string(LINT_node->var_value)->stlen > 0);
947 lintval = LINT_node->var_value->stptr;
948 lintlen = LINT_node->var_value->stlen;
951 if (lintlen == 5 && strncmp(lintval, "fatal", 5) == 0)
953 else if (lintlen == 7 && strncmp(lintval, "invalid", 7) == 0)
954 do_lint = LINT_INVALID;
960 if (force_number(LINT_node->var_value) != 0.0)
966 } else if ((LINT_node->var_value->flags & (NUMCUR|NUMBER)) != 0) {
967 if (force_number(LINT_node->var_value) != 0.0)
973 do_lint = FALSE; /* shouldn't happen */
978 /* explicitly use warning() here, in case lintfunc == r_fatal */
979 if (old_lint != do_lint && old_lint && do_lint == FALSE)
980 warning(_("turning off `--lint' due to assignment to `LINT'"));
981 #endif /* ! NO_LINT */
984 /* set_TEXTDOMAIN --- update TEXTDOMAIN variable when TEXTDOMAIN assigned to */
991 TEXTDOMAIN = force_string(TEXTDOMAIN_node->var_value)->stptr;
992 len = TEXTDOMAIN_node->var_value->stlen;
993 TEXTDOMAIN[len] = '\0';
995 * Note: don't call textdomain(); this value is for
996 * the awk program, not for gawk itself.
1000 /* update_ERRNO_saved --- update the value of ERRNO based on argument */
1003 update_ERRNO_saved(int errcode)
1008 cp = strerror(errcode);
1012 unref(ERRNO_node->var_value);
1013 ERRNO_node->var_value = make_string(cp, strlen(cp));
1016 /* update_ERRNO --- update the value of ERRNO based on errno */
1021 update_ERRNO_saved(errno);
1024 /* update_NR --- update the value of NR */
1029 if (NR_node->var_value->numbr != NR) {
1030 unref(NR_node->var_value);
1031 NR_node->var_value = make_number((AWKNUM) NR);
1035 /* update_NF --- update the value of NF */
1040 if (NF == -1 || NF_node->var_value->numbr != NF) {
1042 (void) get_field(UNLIMITED - 1, NULL); /* parse record */
1043 unref(NF_node->var_value);
1044 NF_node->var_value = make_number((AWKNUM) NF);
1048 /* update_FNR --- update the value of FNR */
1053 if (FNR_node->var_value->numbr != FNR) {
1054 unref(FNR_node->var_value);
1055 FNR_node->var_value = make_number((AWKNUM) FNR);
1061 NODE *frame_ptr; /* current frame */
1062 STACK_ITEM *stack_ptr = NULL;
1063 STACK_ITEM *stack_bottom;
1064 STACK_ITEM *stack_top;
1065 static unsigned long STACK_SIZE = 256; /* initial size of stack */
1066 int max_args = 0; /* maximum # of arguments to printf, print, sprintf,
1067 * or # of array subscripts, or adjacent strings
1068 * to be concatenated.
1070 NODE **args_array = NULL;
1072 /* grow_stack --- grow the size of runtime stack */
1074 /* N.B. stack_ptr points to the topmost occupied location
1075 * on the stack, not the first free location.
1081 if (stack_ptr == NULL) {
1084 if ((val = getenv("GAWK_STACKSIZE")) != NULL) {
1085 if (isdigit((unsigned char) *val)) {
1086 unsigned long n = 0;
1087 for (; *val && isdigit((unsigned char) *val); val++)
1088 n = (n * 10) + *val - '0';
1094 emalloc(stack_bottom, STACK_ITEM *, STACK_SIZE * sizeof(STACK_ITEM), "grow_stack");
1095 stack_ptr = stack_bottom - 1;
1096 stack_top = stack_bottom + STACK_SIZE - 1;
1098 /* initialize frame pointer */
1100 frame_ptr->type = Node_frame;
1101 frame_ptr->stack = NULL;
1102 frame_ptr->func_node = NULL; /* in main */
1103 frame_ptr->vname = NULL;
1108 erealloc(stack_bottom, STACK_ITEM *, STACK_SIZE * sizeof(STACK_ITEM), "grow_stack");
1109 stack_top = stack_bottom + STACK_SIZE - 1;
1110 stack_ptr = stack_bottom + STACK_SIZE / 2;
1116 * This returns a POINTER to a node pointer (var's value).
1117 * used to store the var's new value.
1121 r_get_lhs(NODE *n, int reference)
1123 int isparam = FALSE;
1125 if (n->type == Node_param_list) {
1126 if ((n->flags & FUNC) != 0)
1127 fatal(_("can't use function name `%s' as variable or array"),
1130 n = GET_PARAM(n->param_cnt);
1134 case Node_var_array:
1135 fatal(_("attempt to use array `%s' in a scalar context"),
1137 case Node_array_ref:
1138 if (n->orig_array->type == Node_var_array)
1139 fatal(_("attempt to use array `%s' in a scalar context"),
1141 n->orig_array->type = Node_var;
1142 n->orig_array->var_value = Nnull_string;
1146 n->var_value = Nnull_string;
1156 if (do_lint && reference && var_uninitialized(n))
1158 _("reference to uninitialized argument `%s'") :
1159 _("reference to uninitialized variable `%s'")),
1161 return &n->var_value;
1165 /* r_get_field --- get the address of a field node */
1167 static inline NODE **
1168 r_get_field(NODE *n, Func_ptr *assign, int reference)
1176 if ((n->flags & NUMBER) == 0) {
1177 lintwarn(_("attempt to field reference from non-numeric value"));
1179 lintwarn(_("attempt to field reference from null string"));
1183 field_num = (long) force_number(n);
1185 fatal(_("attempt to access field %ld"), field_num);
1187 if (field_num == 0 && field0_valid) { /* short circuit */
1188 lhs = &fields_arr[0];
1190 *assign = reset_record;
1192 lhs = get_field(field_num, assign);
1193 if (do_lint && reference && (*lhs == Null_field || *lhs == Nnull_string))
1194 lintwarn(_("reference to uninitialized field `$%ld'"),
1201 * calc_exp_posint --- calculate x^n for positive integral n,
1202 * using exponentiation by squaring without recursion.
1206 calc_exp_posint(AWKNUM x, long n)
1219 /* calc_exp --- calculate x1^x2 */
1222 calc_exp(AWKNUM x1, AWKNUM x2)
1226 if ((lx = x2) == x2) { /* integer exponent */
1229 return (lx > 0) ? calc_exp_posint(x1, lx)
1230 : 1.0 / calc_exp_posint(x1, -lx);
1232 return (AWKNUM) pow((double) x1, (double) x2);
1236 /* setup_frame --- setup new frame for function call */
1238 static INSTRUCTION *
1239 setup_frame(INSTRUCTION *pc)
1246 int pcount, arg_count, i;
1249 pcount = f->lnode->param_cnt;
1250 varnames = f->parmlist;
1251 arg_count = (pc + 1)->expr_count;
1253 /* check for extra args */
1254 if (arg_count > pcount) {
1256 _("function `%s' called with more arguments than declared"),
1260 if (r->type == Node_val)
1262 } while (--arg_count > pcount);
1266 emalloc(sp, NODE **, pcount * sizeof(NODE *), "setup_frame");
1267 memset(sp, 0, pcount * sizeof(NODE *));
1270 for (i = 0; i < pcount; i++) {
1272 memset(r, 0, sizeof(NODE));
1274 if (i >= arg_count) {
1275 /* local variable */
1276 r->type = Node_var_new;
1277 r->vname = varnames[i];
1281 m = PEEK(arg_count - i - 1); /* arguments in reverse order on runtime stack */
1283 if (m->type == Node_param_list)
1284 m = GET_PARAM(m->param_cnt);
1288 case Node_var_array:
1289 r->type = Node_array_ref;
1290 r->orig_array = r->prev_array = m;
1293 case Node_array_ref:
1294 r->type = Node_array_ref;
1295 r->orig_array = m->orig_array;
1300 /* Untyped (Node_var_new) variable as param became a
1301 * scalar during evaluation of expression for a
1305 r->var_value = Nnull_string;
1316 r->vname = varnames[i];
1318 stack_adj(-arg_count); /* adjust stack pointer */
1320 if (pc->opcode == Op_indirect_func_call) {
1321 r = POP(); /* indirect var */
1325 frame_ptr->vname = source; /* save current source */
1327 push_frame(frame_ptr);
1329 /* save current frame in stack */
1332 /* setup new frame */
1334 frame_ptr->type = Node_frame;
1335 frame_ptr->stack = sp;
1336 frame_ptr->prev_frame_size = (stack_ptr - stack_bottom); /* size of the previous stack frame */
1337 frame_ptr->func_node = f;
1338 frame_ptr->vname = NULL;
1339 frame_ptr->reti = pc; /* on return execute pc->nexti */
1345 /* restore_frame --- clean up the stack and update frame */
1347 static INSTRUCTION *
1348 restore_frame(NODE *fp)
1356 func = frame_ptr->func_node;
1357 n = func->lnode->param_cnt;
1358 sp = frame_ptr->stack;
1360 for (; n > 0; n--) {
1362 if (r->type == Node_var) /* local variable */
1363 DEREF(r->var_value);
1364 else if (r->type == Node_var_array) /* local array */
1368 if (frame_ptr->stack != NULL)
1369 efree(frame_ptr->stack);
1370 ri = frame_ptr->reti; /* execution in calling frame
1371 * resumes from ri->nexti.
1373 freenode(frame_ptr);
1378 /* restore source */
1386 /* free_arrayfor --- free 'for (var in array)' related data */
1389 free_arrayfor(NODE *r)
1391 if (r->var_array != NULL) {
1392 size_t num_elems = r->table_size;
1393 NODE **list = r->var_array;
1394 while (num_elems > 0)
1395 unref(list[--num_elems]);
1402 /* unwind_stack --- pop items off the run-time stack;
1403 * 'n' is the # of items left in the stack.
1407 unwind_stack(long n)
1410 INSTRUCTION *cp = NULL;
1416 sp = stack_bottom + n;
1421 while ((r = POP()) != NULL) {
1424 cp = restore_frame(r);
1432 case Node_instruction:
1436 if (in_main_context())
1437 fatal(_("unwind_stack: unexpected type `%s'"),
1438 nodetype2str(r->type));
1442 * Node_var (e.g: trying to use scalar for array)
1443 * Node_regex/Node_dynregex
1456 /* pop_fcall --- pop off the innermost frame */
1457 #define pop_fcall() unwind_stack(frame_ptr->prev_frame_size)
1459 /* pop the run-time stack */
1460 #define pop_stack() (void) unwind_stack(0)
1464 * This generated compiler warnings from GCC 4.4. Who knows why.
1466 #define eval_condition(t) (((t)->flags & MAYBE_NUM) && force_number(t), \
1467 ((t)->flags & NUMBER) ? ((t)->numbr != 0.0) : ((t)->stlen != 0))
1472 eval_condition(NODE *t)
1474 if ((t->flags & MAYBE_NUM) != 0)
1477 if ((t->flags & NUMBER) != 0)
1478 return (t->numbr != 0.0);
1480 return (t->stlen != 0);
1483 /* cmp_scalar -- compare two nodes on the stack */
1493 if (t1->type == Node_var_array) {
1495 fatal(_("attempt to use array `%s' in a scalar context"), array_vname(t1));
1497 di = cmp_nodes(t1, t2);
1503 /* op_assign --- assignment operators excluding = */
1506 op_assign(OPCODE op)
1515 lhs = POP_ADDRESS();
1516 x1 = force_number(*lhs);
1520 case Op_assign_plus:
1521 r = *lhs = make_number(x1 + x2);
1523 case Op_assign_minus:
1524 r = *lhs = make_number(x1 - x2);
1526 case Op_assign_times:
1527 r = *lhs = make_number(x1 * x2);
1529 case Op_assign_quotient:
1530 if (x2 == (AWKNUM) 0) {
1532 fatal(_("division by zero attempted in `/='"));
1534 r = *lhs = make_number(x1 / x2);
1537 if (x2 == (AWKNUM) 0) {
1539 fatal(_("division by zero attempted in `%%='"));
1542 r = *lhs = make_number(fmod(x1, x2));
1543 #else /* ! HAVE_FMOD */
1544 (void) modf(x1 / x2, &x);
1546 r = *lhs = make_number(x);
1547 #endif /* ! HAVE_FMOD */
1550 r = *lhs = make_number((AWKNUM) calc_exp((double) x1, (double) x2));
1561 /* PUSH_CODE --- push a code onto the runtime stack */
1564 PUSH_CODE(INSTRUCTION *cp)
1568 r->type = Node_instruction;
1573 /* POP_CODE --- pop a code off the runtime stack */
1587 /* Implementation of BEGINFILE and ENDFILE requires saving an execution
1588 * state and the ability to return to that state. The state is
1589 * defined by the instruction triggering the BEGINFILE/ENDFILE rule, the
1590 * run-time stack, the rule and the source file. The source line is available in
1591 * the instruction and hence is not considered a part of the execution state.
1595 typedef struct exec_state {
1596 struct exec_state *next;
1598 INSTRUCTION *cptr; /* either getline (Op_K_getline) or the
1599 * implicit "open-file, read-record" loop (Op_newfile).
1602 int rule; /* rule for the INSTRUCTION */
1604 long stack_size; /* For this particular usage, it is sufficient to save
1605 * only the size of the call stack. We do not
1606 * store the actual stack pointer to avoid problems
1607 * in case the stack gets realloc-ed.
1610 const char *source; /* source file for the INSTRUCTION */
1613 static EXEC_STATE exec_state_stack;
1615 /* push_exec_state --- save an execution state on stack */
1618 push_exec_state(INSTRUCTION *cp, int rule, char *src, STACK_ITEM *sp)
1622 emalloc(es, EXEC_STATE *, sizeof(EXEC_STATE), "push_exec_state");
1625 es->stack_size = (sp - stack_bottom) + 1;
1627 es->next = exec_state_stack.next;
1628 exec_state_stack.next = es;
1632 /* pop_exec_state --- pop one execution state off the stack */
1634 static INSTRUCTION *
1635 pop_exec_state(int *rule, char **src, long *sz)
1640 es = exec_state_stack.next;
1647 *src = (char *) es->source;
1649 *sz = es->stack_size;
1650 exec_state_stack.next = es->next;
1658 * code is a list of instructions to run. returns the exit value
1659 * from the awk code.
1663 * 1) reference counting done for both number and string values.
1664 * 2) TEMP flag no longer needed (consequence of the above; valref = 0
1665 * is the replacement).
1666 * 3) Stack operations:
1667 * Use REPLACE[_XX] if last stack operation was TOP[_XX],
1668 * PUSH[_XX] if last operation was POP[_XX] instead.
1669 * 4) UPREF and DREF -- see awk.h
1674 r_interpret(INSTRUCTION *code)
1676 INSTRUCTION *pc; /* current instruction */
1681 NODE *f; /* function definition */
1684 int di, pre = FALSE;
1686 #if defined(GAWKDEBUG) || defined(ARRAYDEBUG)
1687 int last_was_stopme = FALSE; /* builtin stopme() called ? */
1689 int stdio_problem = FALSE;
1692 if (args_array == NULL)
1693 emalloc(args_array, NODE **, (max_args + 2)*sizeof(NODE *), "r_interpret");
1695 erealloc(args_array, NODE **, (max_args + 2)*sizeof(NODE *), "r_interpret");
1697 /* array subscript */
1698 #define mk_sub(n) (n == 1 ? POP_STRING() : concat_exp(n, TRUE))
1701 #define JUMPTO(x) do { post_execute(pc); pc = (x); goto top; } while(FALSE)
1703 #define JUMPTO(x) do { pc = (x); goto top; } while(FALSE)
1708 /* N.B.: always use JUMPTO for next instruction, otherwise bad things
1709 * may happen. DO NOT add a real loop (for/while) below to
1710 * replace ' forever {'; this catches failure to use JUMPTO to execute
1711 * next instruction (e.g. continue statement).
1714 /* loop until hit Op_stop instruction */
1718 if (pc->source_line > 0)
1719 sourceline = pc->source_line;
1722 if (! pre_execute(&pc))
1726 switch (pc->opcode) {
1728 currule = pc->in_rule; /* for sole use in Op_K_next, Op_K_nextfile, Op_K_getline* */
1732 source = pc->source_file;
1736 /* avoid false source indications */
1739 (void) nextfile(&curfile, TRUE); /* close input data file */
1743 * if (close_io() != 0 && ! exiting && exit_val == 0)
1746 * Other awks don't care about problems closing open files
1747 * and pipes, in that it doesn't affect their exit status.
1748 * So we no longer do either.
1750 (void) close_io(& stdio_problem);
1752 * However, we do want to exit non-zero if there was a problem
1753 * with stdout/stderr, so we reinstate a slightly different
1754 * version of the above:
1756 if (stdio_problem && ! exiting && exit_val == 0)
1765 PUSH((m->flags & INTLSTR) != 0 ? format_val(CONVFMT, CONVFMTidx, m): m);
1772 int isparam = FALSE;
1774 save_symbol = m = pc->memory;
1775 if (m->type == Node_param_list) {
1776 if ((m->flags & FUNC) != 0)
1777 fatal(_("can't use function name `%s' as variable or array"),
1780 save_symbol = m = GET_PARAM(m->param_cnt);
1781 if (m->type == Node_array_ref)
1787 if (do_lint && var_uninitialized(m))
1789 _("reference to uninitialized argument `%s'") :
1790 _("reference to uninitialized variable `%s'"),
1791 save_symbol->vname);
1799 m->var_value = Nnull_string;
1802 _("reference to uninitialized argument `%s'") :
1803 _("reference to uninitialized variable `%s'"),
1804 save_symbol->vname);
1808 case Node_var_array:
1809 if (pc->opcode == Op_push_arg)
1812 fatal(_("attempt to use array `%s' in a scalar context"),
1813 array_vname(save_symbol));
1822 case Op_push_param: /* function argument */
1824 if (m->type == Node_param_list)
1825 m = GET_PARAM(m->param_cnt);
1826 if (m->type == Node_var) {
1839 lhs = get_lhs(pc->memory, pc->do_reference);
1844 t2 = mk_sub(pc->sub_count);
1846 r = *assoc_lookup(t1, t2, TRUE);
1848 if (r->type == Node_val)
1854 t2 = mk_sub(pc->sub_count);
1856 r = in_array(t1, t2);
1859 r->type = Node_var_array;
1860 r->var_array = NULL;
1861 r->vname = estrdup(t2->stptr, t2->stlen); /* the subscript in parent array */
1862 r->parent_array = t1;
1863 *assoc_lookup(t1, t2, FALSE) = r;
1864 } else if (r->type != Node_var_array)
1865 fatal(_("attempt to use scalar `%s[\"%.*s\"]' as an array"),
1866 array_vname(t1), (int) t2->stlen, t2->stptr);
1871 case Op_subscript_lhs:
1872 t2 = mk_sub(pc->sub_count);
1874 lhs = assoc_lookup(t1, t2, pc->do_reference);
1875 if ((*lhs)->type == Node_var_array)
1876 fatal(_("attempt to use array `%s[\"%.*s\"]' in a scalar context"),
1877 array_vname(t1), (int) t2->stlen, t2->stptr);
1884 lhs = r_get_field(t1, (Func_ptr *) 0, TRUE);
1887 /* This used to look like this:
1888 PUSH(dupnode(*lhs));
1889 but was changed to bypass an apparent bug in the z/OS C compiler.
1890 Please do not remerge. */
1891 r = dupnode(*lhs); /* can't use UPREF here */
1895 case Op_field_spec_lhs:
1897 lhs = r_get_field(t1, &pc->target_assign->field_assign, pc->do_reference);
1905 switch (pc->lint_type) {
1906 case LINT_assign_in_cond:
1907 lintwarn(_("assignment used in conditional context"));
1910 case LINT_no_effect:
1911 lintwarn(_("statement has no effect"));
1923 JUMPTO(pc->target_jmp);
1927 di = eval_condition(r);
1930 JUMPTO(pc->target_jmp);
1935 di = eval_condition(r);
1938 JUMPTO(pc->target_jmp);
1944 di = eval_condition(t1);
1946 if ((pc->opcode == Op_and && di)
1947 || (pc->opcode == Op_or && ! di))
1949 r = make_number((AWKNUM) di);
1951 ni = pc->target_jmp;
1957 r = make_number((AWKNUM) eval_condition(t1));
1964 r = make_number((AWKNUM) ! eval_condition(t1));
1970 r = make_number((AWKNUM) (cmp_scalar() == 0));
1975 r = make_number((AWKNUM) (cmp_scalar() != 0));
1980 r = make_number((AWKNUM) (cmp_scalar() < 0));
1985 r = make_number((AWKNUM) (cmp_scalar() > 0));
1990 r = make_number((AWKNUM) (cmp_scalar() <= 0));
1995 r = make_number((AWKNUM) (cmp_scalar() >= 0));
2000 x2 = force_number(pc->memory);
2007 r = make_number(x1 + x2);
2012 x2 = force_number(pc->memory);
2019 r = make_number(x1 - x2);
2024 x2 = force_number(pc->memory);
2031 r = make_number(x1 * x2);
2036 x2 = force_number(pc->memory);
2043 x = calc_exp(x1, x2);
2049 x2 = force_number(pc->memory);
2056 fatal(_("division by zero attempted"));
2065 x2 = force_number(pc->memory);
2072 fatal(_("division by zero attempted in `%%'"));
2077 #else /* ! HAVE_FMOD */
2078 (void) modf(x1 / x2, &x);
2080 #endif /* ! HAVE_FMOD */
2085 case Op_preincrement:
2087 case Op_postincrement:
2090 lhs = TOP_ADDRESS();
2091 x1 = force_number(*lhs);
2093 r = *lhs = make_number(x1 + x2);
2097 r = make_number(x1);
2102 case Op_predecrement:
2104 case Op_postdecrement:
2108 case Op_unary_minus:
2110 r = make_number(-x1);
2115 /* array[sub] assignment optimization,
2116 * see awkgram.y (optimize_assignment)
2118 t1 = get_array(pc->memory, TRUE); /* array */
2119 t2 = mk_sub(pc->expr_count); /* subscript */
2120 lhs = assoc_lookup(t1, t2, FALSE);
2121 if ((*lhs)->type == Node_var_array)
2122 fatal(_("attempt to use array `%s[\"%.*s\"]' in a scalar context"),
2123 array_vname(t1), (int) t2->stlen, t2->stptr);
2126 *lhs = POP_SCALAR();
2130 /* simple variable assignment optimization,
2131 * see awkgram.y (optimize_assignment)
2134 lhs = get_lhs(pc->memory, FALSE);
2136 *lhs = POP_SCALAR();
2139 case Op_store_field:
2141 /* field assignment optimization,
2142 * see awkgram.y (optimize_assignment)
2147 lhs = r_get_field(t1, &assign, FALSE);
2151 *lhs = POP_SCALAR();
2152 assert(assign != NULL);
2157 case Op_assign_concat:
2158 /* x = x ... string concatenation optimization */
2159 lhs = get_lhs(pc->memory, FALSE);
2160 t1 = force_string(*lhs);
2165 if (t1 != t2 && t1->valref == 1 && (t1->flags & PERM) == 0) {
2166 size_t nlen = t1->stlen + t2->stlen;
2167 erealloc(t1->stptr, char *, nlen + 2, "r_interpret");
2168 memcpy(t1->stptr + t1->stlen, t2->stptr, t2->stlen);
2170 t1->stptr[nlen] = '\0';
2172 size_t nlen = t1->stlen + t2->stlen;
2175 emalloc(p, char *, nlen + 2, "r_interpret");
2176 memcpy(p, t1->stptr, t1->stlen);
2177 memcpy(p + t1->stlen, t2->stptr, t2->stlen);
2179 t1 = *lhs = make_str_node(p, nlen, ALREADY_MALLOCED);
2181 t1->flags &= ~(NUMCUR|NUMBER);
2186 lhs = POP_ADDRESS();
2194 /* numeric assignments */
2195 case Op_assign_plus:
2196 case Op_assign_minus:
2197 case Op_assign_times:
2198 case Op_assign_quotient:
2201 op_assign(pc->opcode);
2204 case Op_var_update: /* update value of NR, FNR or NF */
2209 case Op_field_assign:
2210 if (pc->assign_ctxt == Op_sub_builtin
2211 && TOP()->numbr == 0.0 /* top of stack has a number == 0 */
2213 /* There wasn't any substitutions. If the target is a FIELD,
2214 * this means no field re-splitting or $0 reconstruction.
2215 * Skip the set_FOO routine if the target is a special variable.
2219 } else if ((pc->assign_ctxt == Op_K_getline
2220 || pc->assign_ctxt == Op_K_getline_redir)
2221 && TOP()->numbr <= 0.0 /* top of stack has a number <= 0 */
2223 /* getline returned EOF or error */
2228 if (pc->opcode == Op_var_assign)
2235 r = concat_exp(pc->expr_count, pc->concat_flag & CSUBSEP);
2240 if ((pc + 1)->match_exp) {
2241 /* match a constant regex against switch expression instead of $0. */
2242 m = POP(); /* regex */
2243 t2 = TOP_SCALAR(); /* switch expression */
2244 (void) force_string(t2);
2246 di = (research(rp, t2->stptr, 0, t2->stlen,
2247 avoid_dfa(m, t2->stptr, t2->stlen)) >= 0);
2249 t1 = POP_SCALAR(); /* case value */
2250 t2 = TOP_SCALAR(); /* switch expression */
2251 di = (cmp_nodes(t2, t1) == 0);
2255 if (di) { /* match found */
2258 JUMPTO(pc->target_jmp);
2264 do_delete(t1, pc->expr_count);
2265 stack_adj(-pc->expr_count);
2268 case Op_K_delete_loop:
2270 lhs = POP_ADDRESS(); /* item */
2271 do_delete_loop(t1, lhs);
2276 t2 = mk_sub(pc->expr_count);
2277 di = (in_array(t1, t2) != NULL);
2279 PUSH(make_number((AWKNUM) di));
2282 case Op_arrayfor_init:
2285 NODE *array, *sort_str;
2286 size_t num_elems = 0;
2287 static NODE *sorted_in = NULL;
2288 const char *how_to_sort = "@unsorted";
2291 array = POP_ARRAY();
2293 /* sanity: check if empty */
2294 if (array->var_array == NULL || array->table_size == 0)
2297 num_elems = array->table_size;
2299 if (sorted_in == NULL) /* do this once */
2300 sorted_in = make_string("sorted_in", 9);
2304 * If posix, or if there's no PROCINFO[],
2305 * there's no ["sorted_in"], so no sorting
2307 if (! do_posix && PROCINFO_node != NULL)
2308 sort_str = in_array(PROCINFO_node, sorted_in);
2310 if (sort_str != NULL) {
2311 sort_str = force_string(sort_str);
2312 if (sort_str->stlen > 0)
2313 how_to_sort = sort_str->stptr;
2316 list = assoc_list(array, how_to_sort, SORTED_IN);
2319 * Actual array for use in lint warning
2320 * in Op_arrayfor_incr
2322 list[num_elems] = array;
2326 r->type = Node_arrayfor;
2327 r->var_array = list;
2328 r->table_size = num_elems; /* # of elements in list */
2329 r->array_size = -1; /* current index */
2333 JUMPTO(pc->target_jmp); /* Op_arrayfor_final */
2337 case Op_arrayfor_incr:
2338 r = TOP(); /* Node_arrayfor */
2339 if (++r->array_size == r->table_size) {
2341 array = r->var_array[r->table_size]; /* actual array */
2342 if (do_lint && array->table_size != r->table_size)
2343 lintwarn(_("for loop: array `%s' changed size from %ld to %ld during loop execution"),
2344 array_vname(array), (long) r->table_size, (long) array->table_size);
2345 JUMPTO(pc->target_jmp); /* Op_arrayfor_final */
2348 t1 = r->var_array[r->array_size];
2349 lhs = get_lhs(pc->array_var, FALSE);
2351 *lhs = make_string(t1->ahname_str, t1->ahname_len);
2354 case Op_arrayfor_final:
2356 assert(r->type == Node_arrayfor);
2361 r = pc->builtin(pc->expr_count);
2362 #if defined(GAWKDEBUG) || defined(ARRAYDEBUG)
2364 last_was_stopme = TRUE;
2370 case Op_sub_builtin: /* sub, gsub and gensub */
2371 r = do_sub(pc->expr_count, pc->sub_flags);
2376 do_print(pc->expr_count, pc->redir_type);
2380 do_printf(pc->expr_count, pc->redir_type);
2383 case Op_K_print_rec:
2384 do_print_rec(pc->expr_count, pc->redir_type);
2389 if (m->type == Node_dynregex) {
2399 t1 = *get_field(0, (Func_ptr *) 0);
2403 * Any place where research() is called with a last parameter of
2404 * zero, we need to use the avoid_dfa test. This appears here and
2405 * in the code for Op_K_case.
2407 * A new or improved dfa that distinguishes beginning/end of
2408 * string from beginning/end of line will allow us to get rid of
2411 * The avoid_dfa() function is in re.c; it is not very smart.
2414 di = research(rp, t1->stptr, 0, t1->stlen,
2415 avoid_dfa(m, t1->stptr, t1->stlen));
2416 di = (di == -1) ^ (pc->opcode != Op_nomatch);
2417 if(pc->opcode != Op_match_rec) {
2421 r = make_number((AWKNUM) di);
2430 if (m->type == Node_dynregex) {
2439 case Op_indirect_func_call:
2444 arg_count = (pc + 1)->expr_count;
2445 t1 = PEEK(arg_count); /* indirect var */
2446 assert(t1->type == Node_val); /* @a[1](p) not allowed in grammar */
2447 (void) force_string(t1);
2448 if (t1->stlen > 0) {
2449 /* retrieve function definition node */
2451 if (f != NULL && strcmp(f->vname, t1->stptr) == 0)
2452 /* indirect var hasn't been reassigned */
2454 f = lookup(t1->stptr);
2457 if (f == NULL || f->type != Node_func)
2458 fatal(_("function called indirectly through `%s' does not exist"), pc->func_name);
2459 pc->func_body = f; /* save for next call */
2465 /* retrieve function definition node */
2468 f = lookup(pc->func_name);
2469 if (f == NULL || f->type != Node_func)
2470 fatal(_("function `%s' not defined"), pc->func_name);
2471 pc->func_body = f; /* save for next call */
2474 /* save current frame along with source */
2477 ni = setup_frame(pc);
2479 if (ni->opcode == Op_ext_func) {
2480 /* dynamically set source and line numbers for an extension builtin. */
2481 ni->source_file = source;
2482 ni->source_line = sourceline;
2483 ni->nexti->source_line = sourceline; /* Op_builtin */
2484 ni->nexti->nexti->source_line = sourceline; /* Op_K_return */
2487 /* run the function instructions */
2488 JUMPTO(ni); /* Op_func or Op_ext_func */
2491 m = POP_SCALAR(); /* return value */
2495 /* put the return value back on stack */
2500 case Op_K_getline_redir:
2501 if ((currule == BEGINFILE || currule == ENDFILE)
2502 && pc->into_var == FALSE
2503 && pc->redir_type == redirect_input)
2504 fatal(_("`getline' invalid inside `%s' rule"), ruletab[currule]);
2505 r = do_getline_redir(pc->into_var, pc->redir_type);
2509 case Op_K_getline: /* no redirection */
2510 if (! currule || currule == BEGINFILE || currule == ENDFILE)
2511 fatal(_("non-redirected `getline' invalid inside `%s' rule"),
2516 ret = nextfile(& curfile, FALSE);
2518 r = do_getline(pc->into_var, curfile);
2521 /* Save execution state so that we can return to it
2522 * from Op_after_beginfile or Op_after_endfile.
2525 push_exec_state(pc, currule, source, stack_ptr);
2527 if (curfile == NULL)
2528 JUMPTO((pc + 1)->target_endfile);
2530 JUMPTO((pc + 1)->target_beginfile);
2532 } while (r == NULL); /* EOF */
2537 case Op_after_endfile:
2538 /* Find the execution state to return to */
2539 ni = pop_exec_state(& currule, & source, NULL);
2541 assert(ni->opcode == Op_newfile || ni->opcode == Op_K_getline);
2544 case Op_after_beginfile:
2545 after_beginfile(& curfile);
2547 /* Find the execution state to return to */
2548 ni = pop_exec_state(& currule, & source, NULL);
2550 assert(ni->opcode == Op_newfile || ni->opcode == Op_K_getline);
2551 if (ni->opcode == Op_K_getline
2552 || curfile == NULL /* skipping directory argument */
2556 break; /* read a record, Op_get_record */
2562 ret = nextfile(& curfile, FALSE);
2564 if (ret < 0) /* end of input */
2565 JUMPTO(pc->target_jmp); /* end block or Op_atexit */
2567 if (ret == 0) /* read a record */
2568 JUMPTO((pc + 1)->target_get_record);
2571 /* Save execution state for use in Op_after_beginfile or Op_after_endfile. */
2573 push_exec_state(pc, currule, source, stack_ptr);
2575 if (curfile == NULL) /* EOF */
2576 JUMPTO(pc->target_endfile);
2578 execute beginfile block */
2586 ni = pc->target_newfile;
2587 if (curfile == NULL) {
2588 /* from non-redirected getline, e.g.:
2590 * while (getline > 0) ;
2594 ni = ni->target_jmp; /* end_block or Op_atexit */
2598 if (inrec(curfile, & errcode) != 0) {
2599 if (errcode > 0 && (do_traditional || ! pc->has_endfile))
2600 fatal(_("error reading input file `%s': %s"),
2601 curfile->name, strerror(errcode));
2605 prog (rule) block */
2613 if (currule != Rule && currule != BEGINFILE)
2614 fatal(_("`nextfile' cannot be called from a `%s' rule"),
2617 ret = nextfile(& curfile, TRUE); /* skip current file */
2619 if (currule == BEGINFILE) {
2622 ni = pop_exec_state(& currule, & source, & stack_size);
2624 assert(ni->opcode == Op_K_getline || ni->opcode == Op_newfile);
2626 /* pop stack returning to the state of Op_K_getline or Op_newfile. */
2627 unwind_stack(stack_size);
2630 /* There was an error opening the file;
2631 * don't run ENDFILE block(s).
2636 /* do run ENDFILE block(s) first. */
2638 /* Execution state to return to in Op_after_endfile. */
2639 push_exec_state(ni, currule, source, stack_ptr);
2641 JUMPTO(pc->target_endfile);
2644 Start over with the first rule. */
2646 /* empty the run-time stack to avoid memory leak */
2649 /* Push an execution state for Op_after_endfile to return to */
2650 push_exec_state(pc->target_newfile, currule, source, stack_ptr);
2652 JUMPTO(pc->target_endfile);
2657 /* exit not allowed in user-defined comparison functions for "sorted_in";
2658 * This is done so that END blocks aren't executed more than once.
2661 fatal(_("`exit' cannot be called in the current context"));
2665 exit_val = (int) x1;
2668 exit_val = EXIT_SUCCESS;
2669 else if (exit_val == 1)
2670 exit_val = EXIT_FAILURE;
2672 just pass anything else on through */
2675 if (currule == BEGINFILE || currule == ENDFILE) {
2677 /* Find the rule of the saved execution state (Op_K_getline/Op_newfile).
2678 * This is needed to prevent multiple execution of any END rules:
2679 * gawk 'BEGINFILE { exit(1) } \
2680 * END { while (getline > 0); }' in1 in2
2683 (void) pop_exec_state(& currule, & source, NULL);
2686 pop_stack(); /* empty stack, don't leak memory */
2688 /* Jump to either the first END block instruction
2693 ni = pc->target_atexit;
2695 ni = pc->target_end;
2699 if (currule != Rule)
2700 fatal(_("`next' cannot be called from a `%s' rule"), ruletab[currule]);
2703 JUMPTO(pc->target_jmp); /* Op_get_record, read next record */
2706 #if defined(GAWKDEBUG) || defined(ARRAYDEBUG)
2707 if (last_was_stopme)
2708 last_was_stopme = FALSE;
2718 if (pc->triggered) /* evaluate right expression */
2719 JUMPTO(pc->target_jmp);
2721 evaluate left expression */
2729 t1 = TOP_SCALAR(); /* from right hand side expression */
2730 di = (eval_condition(t1) != 0);
2733 ip = pc->line_range; /* Op_line_range */
2735 if (! ip->triggered && di) {
2736 /* not already triggered and left expression is TRUE */
2738 ip->triggered = TRUE;
2739 JUMPTO(ip->target_jmp); /* evaluate right expression */
2742 result = ip->triggered || di;
2743 ip->triggered ^= di; /* update triggered flag */
2744 r = make_number((AWKNUM) result); /* final value of condition pair */
2746 JUMPTO(pc->target_jmp);
2750 INCREMENT(pc->exec_count);
2766 fatal(_("Sorry, don't know how to interpret `%s'"), opcode2str(pc->opcode));