254
250
* This table maps node types to strings for debugging.
255
251
* KEEP IN SYNC WITH awk.h!!!!
257
254
static const char *const nodetypes[] = {
270
"Node_postincrement",
271
"Node_postdecrement",
276
"Node_assign_quotient",
281
"Node_assign_concat",
295
"Node_statement_list",
299
"Node_expression_list",
318
"Node_K_delete_loop",
322
"Node_redirect_output",
323
"Node_redirect_append",
324
"Node_redirect_pipe",
325
"Node_redirect_pipein",
326
"Node_redirect_input",
327
"Node_redirect_twoway",
330
260
"Node_var_array",
337
"Node_indirect_func_call",
343
266
"Node_array_ref",
360
270
"Node_final --- this should never appear",
276
* This table maps Op codes to strings.
277
* KEEP IN SYNC WITH awk.h!!!!
280
static struct optypetab {
284
{ "Op_illegal", NULL },
285
{ "Op_times", " * " },
286
{ "Op_times_i", " * " },
287
{ "Op_quotient", " / " },
288
{ "Op_quotient_i", " / " },
290
{ "Op_mod_i", " % " },
291
{ "Op_plus", " + " },
292
{ "Op_plus_i", " + " },
293
{ "Op_minus", " - " },
294
{ "Op_minus_i", " - " },
296
{ "Op_exp_i", " ^ " },
297
{ "Op_concat", " " },
298
{ "Op_line_range", NULL },
299
{ "Op_cond_pair", ", " },
300
{ "Op_subscript", "[]" },
301
{ "Op_sub_array", "[]" },
302
{ "Op_preincrement", "++" },
303
{ "Op_predecrement", "--" },
304
{ "Op_postincrement", "++" },
305
{ "Op_postdecrement", "--" },
306
{ "Op_unary_minus", "-" },
307
{ "Op_field_spec", "$" },
309
{ "Op_assign", " = " },
310
{ "Op_store_var", " = " },
311
{ "Op_store_sub", " = " },
312
{ "Op_store_field", " = " },
313
{ "Op_assign_times", " *= " },
314
{ "Op_assign_quotient", " /= " },
315
{ "Op_assign_mod", " %= " },
316
{ "Op_assign_plus", " += " },
317
{ "Op_assign_minus", " -= " },
318
{ "Op_assign_exp", " ^= " },
319
{ "Op_assign_concat", " " },
320
{ "Op_and", " && " },
321
{ "Op_and_final", NULL },
323
{ "Op_or_final", NULL },
324
{ "Op_equal", " == " },
325
{ "Op_notequal", " != " },
326
{ "Op_less", " < " },
327
{ "Op_greater", " > " },
328
{ "Op_leq", " <= " },
329
{ "Op_geq", " >= " },
330
{ "Op_match", " ~ " },
331
{ "Op_match_rec", NULL },
332
{ "Op_nomatch", " !~ " },
334
{ "Op_K_case", "case" },
335
{ "Op_K_default", "default" },
336
{ "Op_K_break", "break" },
337
{ "Op_K_continue", "continue" },
338
{ "Op_K_print", "print" },
339
{ "Op_K_print_rec", "print" },
340
{ "Op_K_printf", "printf" },
341
{ "Op_K_next", "next" },
342
{ "Op_K_exit", "exit" },
343
{ "Op_K_return", "return" },
344
{ "Op_K_delete", "delete" },
345
{ "Op_K_delete_loop", NULL },
346
{ "Op_K_getline_redir", "getline" },
347
{ "Op_K_getline", "getline" },
348
{ "Op_K_nextfile", "nextfile" },
349
{ "Op_builtin", NULL },
350
{ "Op_in_array", " in " },
351
{ "Op_func_call", NULL },
352
{ "Op_indirect_func_call", NULL },
354
{ "Op_push_i", NULL },
355
{ "Op_push_re", NULL },
356
{ "Op_push_array", NULL },
357
{ "Op_push_param", NULL },
358
{ "Op_push_lhs", NULL },
359
{ "Op_subscript_lhs", "[]" },
360
{ "Op_field_spec_lhs", "$" },
361
{ "Op_no_op", NULL },
364
{ "Op_jmp_true", NULL },
365
{ "Op_jmp_false", NULL },
366
{ "Op_push_loop", NULL },
367
{ "Op_pop_loop", NULL },
368
{ "Op_get_record", NULL },
369
{ "Op_newfile", NULL },
370
{ "Op_arrayfor_init", NULL },
371
{ "Op_arrayfor_incr", NULL },
372
{ "Op_arrayfor_final", NULL },
373
{ "Op_var_update", NULL },
374
{ "Op_var_assign", NULL },
375
{ "Op_field_assign", NULL },
376
{ "Op_after_beginfile", NULL },
377
{ "Op_after_endfile", NULL },
378
{ "Op_ext_func", NULL },
380
{ "Op_exec_count", NULL },
381
{ "Op_breakpoint", NULL },
383
{ "Op_atexit", NULL },
385
{ "Op_token", NULL },
386
{ "Op_symbol", NULL },
388
{ "Op_case_list", 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 },
364
402
/* nodetype2str --- convert a node type into a printable value */
440
* make_scalar --- make sure that tree is a scalar.
442
* tree is in a scalar context. If it is a variable, accomplish
443
* what's needed; otherwise, do nothing.
445
* Notice that nodes of type Node_var_new have undefined value in var_value
446
* (a.k.a. lnode)---even though awkgram.y:variable() initializes it,
447
* push_args() doesn't. Thus we have to initialize it.
451
make_scalar(NODE *tree)
453
switch (tree->type) {
455
fatal(_("attempt to use array `%s' in a scalar context"),
459
switch (tree->orig_array->type) {
461
fatal(_("attempt to use array `%s' in a scalar context"),
464
tree->orig_array->type = Node_var;
465
tree->orig_array->var_value = Nnull_string;
474
tree->type = Node_var;
475
tree->var_value = Nnull_string;
484
* Tree is a bunch of rules to run. Returns zero if it hit an exit()
488
interpret(register NODE *volatile tree)
490
jmp_buf volatile loop_tag_stack; /* shallow binding stack for loop_tag */
491
static jmp_buf rule_tag; /* tag the rule currently being run, for NEXT
492
* and EXIT statements. It is static because
493
* there are no nested rules */
494
register NODE *volatile t = NULL; /* temporary */
495
NODE **volatile lhs; /* lhs == Left Hand Side for assigns, etc */
496
NODE *volatile stable_tree;
497
int volatile traverse = TRUE; /* True => loop thru tree (Node_rule_list) */
499
/* avoid false source indications */
505
sourceline = tree->source_line;
506
source = tree->source_file;
507
switch (tree->type) {
509
traverse = FALSE; /* False => one for-loop iteration only */
512
for (t = tree; t != NULL; t = t->rnode) {
515
sourceline = tree->source_line;
516
source = tree->source_file;
517
INCREMENT(tree->exec_count);
518
switch (setjmp(rule_tag)) {
519
case 0: /* normal non-jump */
520
/* test pattern, if any */
521
if (tree->lnode == NULL ||
522
eval_condition(tree->lnode)) {
523
/* using the lnode exec_count is kludgey */
524
if (tree->lnode != NULL)
525
INCREMENT(tree->lnode->exec_count);
526
(void) interpret(tree->rnode);
529
case TAG_CONTINUE: /* NEXT statement */
533
case TAG_BREAK: /* EXIT statement */
540
if (! traverse) /* case Node_rule_node */
541
break; /* don't loop */
545
case Node_statement_list:
546
for (t = tree; t != NULL; t = t->rnode)
547
(void) interpret(t->lnode);
551
INCREMENT(tree->exec_count);
552
if (eval_condition(tree->lnode)) {
553
INCREMENT(tree->rnode->exec_count);
554
(void) interpret(tree->rnode->lnode);
556
(void) interpret(tree->rnode->rnode);
568
int match_found = FALSE;
570
PUSH_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
571
INCREMENT(tree->exec_count);
574
switch_value = tree_eval(stable_tree->lnode);
575
switch_body = stable_tree->rnode;
576
case_list = switch_body->lnode;
577
default_list = switch_body->rnode;
579
for (; case_list != NULL; case_list = case_list->rnode) {
580
case_stmt = case_list->lnode;
583
* Once a match is found, all cases will be processed as they fall through,
584
* so continue to execute statements until a break is reached.
587
if (case_stmt->type == Node_K_default)
589
else if (case_stmt->lnode->type == Node_regex) {
592
/* see comments in match_op() code about this. */
593
int kludge_need_start = 0;
595
t1 = force_string(switch_value);
596
rp = re_update(case_stmt->lnode);
598
if (avoid_dfa(tree, t1->stptr, t1->stlen))
599
kludge_need_start = RE_NEED_START;
600
match_found = (research(rp, t1->stptr, 0, t1->stlen, kludge_need_start) >= 0);
601
if (t1 != switch_value)
604
match_found = (cmp_nodes(switch_value, case_stmt->lnode) == 0);
607
/* If a match was found, execute the statements associated with the case. */
609
INCREMENT(case_stmt->exec_count);
610
switch (setjmp(loop_tag)) {
611
case 0: /* Normal non-jump */
612
(void) interpret(case_stmt->rnode);
614
case TAG_CONTINUE: /* continue statement */
615
free_temp(switch_value);
616
RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
617
longjmp(loop_tag, TAG_CONTINUE);
619
case TAG_BREAK: /* break statement */
620
free_temp(switch_value);
621
RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
630
free_temp(switch_value);
633
* If a default section was found, execute the statements associated with it
634
* and execute any trailing case statements if the default falls through.
636
if (! match_found && default_list != NULL) {
637
for (case_list = default_list;
638
case_list != NULL; case_list = case_list->rnode) {
639
case_stmt = case_list->lnode;
641
INCREMENT(case_stmt->exec_count);
642
switch (setjmp(loop_tag)) {
643
case 0: /* Normal non-jump */
644
(void) interpret(case_stmt->rnode);
646
case TAG_CONTINUE: /* continue statement */
647
RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
648
longjmp(loop_tag, TAG_CONTINUE);
650
case TAG_BREAK: /* break statement */
651
RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
659
RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
664
PUSH_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
667
while (eval_condition(stable_tree->lnode)) {
668
INCREMENT(stable_tree->exec_count);
669
switch (setjmp(loop_tag)) {
670
case 0: /* normal non-jump */
671
(void) interpret(stable_tree->rnode);
673
case TAG_CONTINUE: /* continue statement */
675
case TAG_BREAK: /* break statement */
676
RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
682
RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
686
PUSH_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
689
INCREMENT(stable_tree->exec_count);
690
switch (setjmp(loop_tag)) {
691
case 0: /* normal non-jump */
692
(void) interpret(stable_tree->rnode);
694
case TAG_CONTINUE: /* continue statement */
696
case TAG_BREAK: /* break statement */
697
RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
702
} while (eval_condition(stable_tree->lnode));
703
RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
707
PUSH_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
708
(void) interpret(tree->forloop->init);
710
while (eval_condition(stable_tree->forloop->cond)) {
711
INCREMENT(stable_tree->exec_count);
712
switch (setjmp(loop_tag)) {
713
case 0: /* normal non-jump */
714
(void) interpret(stable_tree->lnode);
716
case TAG_CONTINUE: /* continue statement */
717
(void) interpret(stable_tree->forloop->incr);
719
case TAG_BREAK: /* break statement */
720
RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
726
RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
729
case Node_K_arrayfor:
731
Func_ptr after_assign = NULL;
733
NODE *volatile array;
734
NODE *volatile save_array;
735
volatile size_t i, num_elems;
737
volatile int retval = 0;
738
int sort_indices = whiny_users;
740
#define hakvar forloop->init
741
#define arrvar forloop->incr
743
save_array = tree->arrvar;
744
array = get_array(save_array);
746
/* sanity: do nothing if empty */
747
if (array->var_array == NULL || array->table_size == 0)
748
break; /* from switch */
750
/* allocate space for array */
751
num_elems = array->table_size;
752
emalloc(list, NODE **, num_elems * sizeof(NODE *), "for_loop");
755
for (i = j = 0; i < array->array_size; i++) {
756
NODE *t = array->var_array[i];
761
for (; t != NULL; t = t->ahnext) {
762
list[j++] = dupnode(t);
763
assert(list[j-1] == t);
769
qsort(list, num_elems, sizeof(NODE *), comp_func); /* shazzam! */
771
/* now we can run the loop */
772
push_forloop(array->vname, list, num_elems);
773
PUSH_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
775
lhs = get_lhs(tree->hakvar, &after_assign, FALSE);
777
for (i = 0; i < num_elems; i++) {
778
INCREMENT(stable_tree->exec_count);
779
unref(*((NODE **) lhs));
780
*lhs = make_string(list[i]->ahname_str, list[i]->ahname_len);
783
switch (setjmp(loop_tag)) {
785
(void) interpret(stable_tree->lnode);
799
RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
802
if (do_lint && num_elems != array->table_size)
803
lintwarn(_("for loop: array `%s' changed size from %ld to %ld during loop execution"),
804
array_vname(save_array), (long) num_elems, (long) array->table_size);
814
INCREMENT(tree->exec_count);
815
if (! loop_tag_valid) {
817
* Old AT&T nawk treats break outside of loops like
818
* next. New ones catch it at parse time. Allow it if
819
* do_traditional is on, and complain if lint.
821
static short warned = FALSE;
823
if (do_lint && ! warned) {
824
lintwarn(_("`break' outside a loop is not portable"));
827
if (! do_traditional || do_posix)
828
fatal(_("`break' outside a loop is not allowed"));
829
longjmp(rule_tag, TAG_CONTINUE);
831
longjmp(loop_tag, TAG_BREAK);
834
case Node_K_continue:
835
INCREMENT(tree->exec_count);
836
if (! loop_tag_valid) {
838
* Old AT&T nawk treats continue outside of loops like
839
* next. New ones catch it at parse time. Allow it if
840
* do_traditional is on, and complain if lint.
842
static short warned = FALSE;
844
if (do_lint && ! warned) {
845
lintwarn(_("`continue' outside a loop is not portable"));
848
if (! do_traditional || do_posix)
849
fatal(_("`continue' outside a loop is not allowed"));
850
longjmp(rule_tag, TAG_CONTINUE);
852
longjmp(loop_tag, TAG_CONTINUE);
856
INCREMENT(tree->exec_count);
860
case Node_K_print_rec:
861
INCREMENT(tree->exec_count);
866
INCREMENT(tree->exec_count);
871
INCREMENT(tree->exec_count);
872
do_delete(tree->lnode, tree->rnode);
875
case Node_K_delete_loop:
876
INCREMENT(tree->exec_count);
877
do_delete_loop(tree->lnode, tree->rnode);
881
INCREMENT(tree->exec_count);
883
fatal(_("`next' cannot be called from a BEGIN rule"));
884
else if (in_end_rule)
885
fatal(_("`next' cannot be called from an END rule"));
886
else if (in_beginfile_rule)
887
fatal(_("`next' cannot be called from a BEGINFILE rule"));
888
else if (in_endfile_rule)
889
fatal(_("`next' cannot be called from an ENDFILE rule"));
891
/* could add a lint check here for in a loop or function */
892
longjmp(rule_tag, TAG_CONTINUE);
895
case Node_K_nextfile:
896
INCREMENT(tree->exec_count);
897
if (in_begin_rule && ! in_beginfile_rule)
898
fatal(_("`nextfile' cannot be called from a BEGIN rule"));
899
else if (in_end_rule)
900
fatal(_("`nextfile' cannot be called from an END rule"));
902
else if (in_beginfile_rule)
903
fatal(_("`nextfile' cannot be called from a BEGINFILE rule"));
905
else if (in_endfile_rule)
906
fatal(_("`nextfile' cannot be called from an ENDFILE rule"));
908
/* could add a lint check here for in a loop or function */
910
* Have to do this cleanup here, since we don't longjump
911
* back to the main awk rule loop (rule_tag).
920
INCREMENT(tree->exec_count);
922
* In A,K,&W, p. 49, it says that an exit statement "...
923
* causes the program to behave as if the end of input had
924
* occurred; no more input is read, and the END actions, if
925
* any are executed." This implies that the rest of the rules
926
* are not done. So we immediately break out of the main loop.
929
if (tree->lnode != NULL) {
930
t = tree_eval(tree->lnode);
931
exit_val = (int) force_number(t);
934
exit_val = EXIT_SUCCESS;
935
else if (exit_val == 1)
936
exit_val = EXIT_FAILURE;
938
just pass anything else on through */
942
longjmp(rule_tag, TAG_BREAK);
946
INCREMENT(tree->exec_count);
947
t = tree_eval(tree->lnode);
948
if ((t->flags & (PERM|TEMP)) != 0)
951
ret_node = copynode(t); /* don't do a dupnode here */
952
ret_node->flags |= TEMP;
954
longjmp(func_tag, TAG_RETURN);
959
* Appears to be an expression statement. Throw away the
962
if (do_lint && (tree->type == Node_var || tree->type == Node_var_new))
963
lintwarn(_("statement has no effect"));
964
INCREMENT(tree->exec_count);
966
if (t) /* stopme() returns NULL */
974
* calc_exp_posint --- calculate x^n for positive integral n,
975
* using exponentiation by squaring without recursion.
979
calc_exp_posint(AWKNUM x, long n)
992
/* calc_exp --- calculate x1^x2 */
995
calc_exp(AWKNUM x1, AWKNUM x2)
999
if ((lx = x2) == x2) { /* integer exponent */
1002
return (lx > 0) ? calc_exp_posint(x1, lx)
1003
: 1.0 / calc_exp_posint(x1, -lx);
1005
return (AWKNUM) pow((double) x1, (double) x2);
1008
/* r_tree_eval --- evaluate a subtree */
1011
r_tree_eval(register NODE *tree, int iscond)
1013
register NODE *r, *t1, *t2; /* return value & temporary subtrees */
1014
register NODE **lhs;
1021
#ifndef TREE_EVAL_MACRO
1024
if (tree->type == Node_val) {
1025
if (tree->stref <= 0)
1027
return ((tree->flags & INTLSTR) != 0
1028
? r_force_string(tree)
1030
} else if (tree->type == Node_var) {
1031
if (tree->var_value->stref <= 0)
1033
if (! var_uninitialized(tree))
1034
return tree->var_value;
1038
if (tree->type == Node_param_list) {
1039
if ((tree->flags & FUNC) != 0)
1040
fatal(_("can't use function name `%s' as variable or array"),
1043
tree = stack_ptr[tree->param_cnt];
1047
lintwarn(_("reference to uninitialized argument `%s'"),
1049
return Nnull_string;
1052
if (do_lint && var_uninitialized(tree))
1053
lintwarn(_("reference to uninitialized argument `%s'"),
1059
switch (tree->type) {
1061
if (do_lint && var_uninitialized(tree))
1062
lintwarn(_("reference to uninitialized variable `%s'"),
1064
return tree->var_value;
1067
return tmp_number((AWKNUM) (eval_condition(tree->lnode)
1068
&& eval_condition(tree->rnode)));
1071
return tmp_number((AWKNUM) (eval_condition(tree->lnode)
1072
|| eval_condition(tree->rnode)));
1075
return tmp_number((AWKNUM) ! eval_condition(tree->lnode));
1079
return (*tree->builtin)(tree->subnode);
1081
case Node_K_getline:
1082
return do_getline(tree);
1085
return tmp_number((AWKNUM) (in_array(tree->lnode, tree->rnode) != NULL));
1087
case Node_indirect_func_call:
1088
case Node_func_call:
1089
return func_call(tree);
1091
/* unary operations */
1095
case Node_FIELDWIDTHS:
1099
case Node_field_spec:
1100
case Node_subscript:
1101
case Node_IGNORECASE:
1109
case Node_TEXTDOMAIN:
1110
lhs = get_lhs(tree, (Func_ptr *) NULL, TRUE);
1113
case Node_unary_minus:
1114
t1 = tree_eval(tree->subnode);
1115
x = -force_number(t1);
1117
return tmp_number(x);
1120
if (eval_condition(tree->lnode))
1121
return tree_eval(tree->rnode->lnode);
1122
return tree_eval(tree->rnode->rnode);
1128
return match_op(tree);
1135
register NODE **treep;
1136
register NODE **strp;
1137
register size_t len;
1138
register size_t supposed_len;
1140
register char *dest;
1141
int alloc_count, str_count;
1145
* This is an efficiency hack for multiple adjacent string
1146
* concatenations, to avoid recursion and string copies.
1148
* Node_concat trees grow downward to the left, so
1149
* descend to lowest (first) node, accumulating nodes
1150
* to evaluate to strings as we go.
1154
* But first, no arbitrary limits. Count the number of
1155
* nodes and malloc the treelist and strlist arrays.
1156
* There will be alloc_count + 1 items to concatenate. We
1157
* also leave room for an extra pointer at the end to
1158
* use as a sentinel. Thus, start alloc_count at 2.
1161
for (alloc_count = 2; tree != NULL && tree->type == Node_concat;
1165
emalloc(treelist, NODE **, sizeof(NODE *) * alloc_count, "tree_eval");
1166
emalloc(strlist, NODE **, sizeof(NODE *) * alloc_count, "tree_eval");
1168
/* Now, here we go. */
1170
while (tree != NULL && tree->type == Node_concat) {
1171
*treep++ = tree->rnode;
1176
* Now, evaluate to strings in LIFO order, accumulating
1177
* the string length, so we can do a single malloc at the
1180
* Evaluate the expressions first, then get their
1181
* lengthes, in case one of the expressions has a
1182
* side effect that changes one of the others.
1183
* See test/nasty.awk.
1185
* dupnode the results a la do_print, to give us
1186
* more predicable behavior; compare gawk 3.0.6 to
1187
* nawk/mawk on test/nasty.awk.
1190
supposed_len = len = 0;
1191
while (treep >= treelist) {
1194
/* Here lies the wumpus's brother. R.I.P. */
1195
n = force_string(tree_eval(*treep--));
1198
supposed_len += (*strp)->stlen;
1203
str_count = strp - strlist;
1205
for (i = 0; i < str_count; i++) {
1206
len += (*strp)->stlen;
1209
if (do_lint && supposed_len != len)
1210
lintwarn(_("concatenation: side effects in one expression have changed the length of another!"));
1211
emalloc(str, char *, len+2, "tree_eval");
1212
str[len] = str[len+1] = '\0'; /* for good measure */
1215
while (*strp != NULL) {
1216
memcpy(dest, (*strp)->stptr, (*strp)->stlen);
1217
dest += (*strp)->stlen;
1221
r = make_str_node(str, len, ALREADY_MALLOCED);
1230
case Node_assign_concat:
1232
Func_ptr after_assign = NULL;
1236
* Note that something lovely like this:
1238
* BEGIN { a = "a"; a = a (a = "b"); print a }
1240
* is not defined. It could print `ab' or `bb'.
1241
* Gawk 3.1.3 prints `ab', so we do that too, simply
1242
* by evaluating the LHS first. Ugh.
1244
* Thanks to mary1john@earthlink.net for pointing
1247
lhs = get_lhs(tree->lnode, &after_assign, FALSE);
1248
*lhs = force_string(*lhs);
1252
* This is a hack. We temporarily increase the reference count
1253
* on l in case evaluating r might change the original value
1254
* of l. We have to be careful about reducing it afterwards.
1255
* In particular, if the lhs changed during evaluation of the
1256
* rhs, we have to compensate.
1258
* See test/nasty.awk.
1261
r = force_string(tree_eval(tree->rnode));
1265
* Something happened to the original
1266
* during the evaluation of the rhs.
1275
* Don't clobber string constants!
1277
* Also check stref; see test/strcat1.awk,
1278
* the test for l->stref == 1 can't be an
1281
* Thanks again to mary1john@earthlink.net for pointing
1284
if (l != r && (l->flags & PERM) == 0 && l->stref == 1) {
1285
size_t nlen = l->stlen + r->stlen + 2;
1287
erealloc(l->stptr, char *, nlen, "interpret");
1288
memcpy(l->stptr + l->stlen, r->stptr, r->stlen);
1289
l->stlen += r->stlen;
1290
l->stptr[l->stlen] = '\0';
1294
size_t nlen = l->stlen + r->stlen + 2;
1296
emalloc(nval, char *, nlen, "interpret");
1297
memcpy(nval, l->stptr, l->stlen);
1298
memcpy(nval + l->stlen, r->stptr, r->stlen);
1300
*lhs = make_str_node(nval, l->stlen + r->stlen, ALREADY_MALLOCED);
1302
(*lhs)->flags &= ~(NUMCUR|NUMBER);
1303
(*lhs)->flags |= ASSIGNED; /* for function pointers */
1312
Func_ptr after_assign = NULL;
1314
if (do_lint && iscond)
1315
lintwarn(_("assignment used in conditional context"));
1316
r = tree_eval(tree->rnode);
1317
lhs = get_lhs(tree->lnode, &after_assign, FALSE);
1320
if (tree->lnode->type == Node_var)
1321
tree->lnode->var_value->flags |= ASSIGNED; /* needed in handling of indirect function calls */
1328
/* other assignment types are easier because they are numeric */
1329
case Node_preincrement:
1330
case Node_predecrement:
1331
case Node_postincrement:
1332
case Node_postdecrement:
1333
case Node_assign_exp:
1334
case Node_assign_times:
1335
case Node_assign_quotient:
1336
case Node_assign_mod:
1337
case Node_assign_plus:
1338
case Node_assign_minus:
1339
return op_assign(tree);
1341
break; /* handled below */
1345
* Evaluate subtrees in order to do binary operation, then keep going.
1346
* Use dupnode to make sure that these values don't disappear out
1347
* from under us during recursive subexpression evaluation.
1349
t1 = dupnode(tree_eval(tree->lnode));
1350
t2 = dupnode(tree_eval(tree->rnode));
1352
switch (tree->type) {
1359
di = cmp_nodes(t1, t2);
1362
switch (tree->type) {
1364
return tmp_number((AWKNUM) (di == 0));
1366
return tmp_number((AWKNUM) (di != 0));
1368
return tmp_number((AWKNUM) (di < 0));
1370
return tmp_number((AWKNUM) (di > 0));
1372
return tmp_number((AWKNUM) (di <= 0));
1374
return tmp_number((AWKNUM) (di >= 0));
1380
break; /* handled below */
1383
x1 = force_number(t1);
1384
x2 = force_number(t2);
1387
switch (tree->type) {
1389
return tmp_number(calc_exp(x1, x2));
1392
return tmp_number(x1 * x2);
1396
fatal(_("division by zero attempted"));
1398
/* special case for integer division, put in for Cray */
1401
return tmp_number(x1 / x2);
1402
lx = (long) x1 / lx2;
1404
return tmp_number((AWKNUM) lx);
1407
return tmp_number(x1 / x2);
1411
fatal(_("division by zero attempted in `%%'"));
1413
return tmp_number(fmod(x1, x2));
1414
#else /* ! HAVE_FMOD */
1415
(void) modf(x1 / x2, &x);
1416
return tmp_number(x1 - x * x2);
1417
#endif /* ! HAVE_FMOD */
1420
return tmp_number(x1 + x2);
1423
return tmp_number(x1 - x2);
1426
fatal(_("illegal type (%s) in tree_eval"), nodetype2str(tree->type));
1431
/* eval_condition --- is TREE true or false? Returns 0==false, non-zero==true */
1434
eval_condition(register NODE *tree)
1439
if (tree == NULL) /* Null trees are the easiest kinds */
1441
if (tree->type == Node_line_range) {
1443
* Node_line_range is kind of like Node_match, EXCEPT: the
1444
* lnode field (more properly, the condpair field) is a node
1445
* of a Node_cond_pair; whether we evaluate the lnode of that
1446
* node or the rnode depends on the triggered word. More
1447
* precisely: if we are not yet triggered, we tree_eval the
1448
* lnode; if that returns true, we set the triggered word.
1449
* If we are triggered (not ELSE IF, note), we tree_eval the
1450
* rnode, clear triggered if it succeeds, and perform our
1451
* action (regardless of success or failure). We want to be
1452
* able to begin and end on a single input record, so this
1453
* isn't an ELSE IF, as noted above.
1455
if (! tree->triggered) {
1456
if (! eval_condition(tree->condpair->lnode))
1459
tree->triggered = TRUE;
1461
/* Else we are triggered */
1462
if (eval_condition(tree->condpair->rnode))
1463
tree->triggered = FALSE;
1468
* Could just be J.random expression. in which case, null and 0 are
1469
* false, anything else is true
1472
t1 = m_tree_eval(tree, TRUE);
1473
if (t1->flags & MAYBE_NUM)
1474
(void) force_number(t1);
1475
if (t1->flags & NUMBER)
1476
ret = (t1->numbr != 0.0);
1478
ret = (t1->stlen != 0);
1483
504
/* cmp_nodes --- compare two nodes, returning negative, 0, positive */
1486
cmp_nodes(register NODE *t1, register NODE *t2)
507
cmp_nodes(NODE *t1, NODE *t2)
1489
register size_t len1, len2;
1495
516
if (t1->flags & MAYBE_NUM)
1496
517
(void) force_number(t1);
1497
518
if (t2->flags & MAYBE_NUM)
1498
519
(void) force_number(t2);
1499
520
if ((t1->flags & NUMBER) && (t2->flags & NUMBER)) {
1500
521
if (t1->numbr == t2->numbr)
1502
523
/* don't subtract, in case one or both are infinite */
1503
524
else if (t1->numbr < t2->numbr)
1508
531
(void) force_string(t1);
1509
532
(void) force_string(t2);
1510
533
len1 = t1->stlen;
1533
554
return (ret == 0 ? ldiff : ret);
1536
/* op_assign --- do +=, -=, etc. */
1539
op_assign(register NODE *tree)
1544
Func_ptr after_assign = NULL;
1548
* For += etc, do the rhs first, since it can rearrange things,
1549
* and *then* get the lhs.
1551
if (tree->rnode != NULL) {
1552
tmp = tree_eval(tree->rnode);
1553
rval = force_number(tmp);
1556
rval = (AWKNUM) 1.0;
1558
lhs = get_lhs(tree->lnode, &after_assign, TRUE);
1559
lval = force_number(*lhs);
1562
switch(tree->type) {
1563
case Node_postincrement:
1566
case Node_preincrement:
1567
case Node_assign_plus:
1568
*lhs = make_number(lval + rval);
1571
case Node_postdecrement:
1574
case Node_predecrement:
1575
case Node_assign_minus:
1576
*lhs = make_number(lval - rval);
1579
case Node_assign_exp:
1580
*lhs = make_number(calc_exp(lval, rval));
1583
case Node_assign_times:
1584
*lhs = make_number(lval * rval);
1587
case Node_assign_quotient:
1588
if (rval == (AWKNUM) 0)
1589
fatal(_("division by zero attempted in `/='"));
1594
/* special case for integer division, put in for Cray */
1597
*lhs = make_number(lval / rval);
1600
ltemp = (long) lval / ltemp;
1601
if (ltemp * lval == rval)
1602
*lhs = make_number((AWKNUM) ltemp);
1605
*lhs = make_number(lval / rval);
1609
case Node_assign_mod:
1610
if (rval == (AWKNUM) 0)
1611
fatal(_("division by zero attempted in `%%='"));
1613
*lhs = make_number(fmod(lval, rval));
1614
#else /* ! HAVE_FMOD */
1618
(void) modf(lval / rval, &t1);
1619
t2 = lval - rval * t1;
1620
*lhs = make_number(t2);
1622
#endif /* ! HAVE_FMOD */
1629
(*lhs)->flags |= ASSIGNED;
1634
/* for postincrement or postdecrement, return the old value */
1635
return (post ? tmp_number(lval) : *lhs);
1639
* Avoiding memory leaks is difficult. In paticular, any of `next',
1640
* `nextfile', `break' or `continue' (when not in a loop), can longjmp
1641
* out to the outermost level. This leaks memory if it happens in a
1642
* called function. It also leaks memory if it happens in a
1643
* `for (iggy in foo)' loop, since such loops malloc an array of the
1644
* current array indices to loop over, which provides stability.
1646
* The following code takes care of these problems. First comes the
1647
* array-loop management code. This can be a stack of arrays being looped
1648
* on at any one time. This stack serves for both mainline code and
1649
* function body code. As each loop starts and finishes, it pushes its
1650
* info onto this stack and off of it; whether the loop is in a function
1651
* body or not isn't relevant.
1653
* Since the list of indices is created using dupnode(), when popping
1654
* this stack it should be safe to unref() things, and then memory
1655
* will get finally released when the function call stack is popped.
1656
* This means that the loop_stack should be popped first upon a `next'.
1659
static struct loop_info {
1660
const char *varname; /* variable name, for debugging */
1661
NODE **elems; /* list of indices */
1662
size_t nelems; /* how many there are */
1663
} *loop_stack = NULL;
1664
size_t nloops = 0; /* how many slots there are in the stack */
1665
size_t nloops_active = 0; /* how many loops are actively stacked */
1667
/* pop_forloop --- pop one for loop off the stack */
1673
struct loop_info *loop;
1675
assert(nloops_active > 0);
1677
curloop = --nloops_active; /* 0-based indexing */
1678
loop = & loop_stack[curloop];
1680
for (i = 0; i < loop->nelems; i++)
1681
unref(loop->elems[i]);
1686
loop->varname = NULL;
1690
/* pop_forloops --- pop the for loops stack all the way */
1695
while (nloops_active > 0)
1696
pop_forloop(); /* decrements nloops_active for us */
1699
/* push_forloop --- add a single for loop to the stack */
1702
push_forloop(const char *varname, NODE **elems, size_t nelems)
1704
#define NLOOPS 4 /* seems like a good guess */
1705
if (loop_stack == NULL) {
1706
/* allocate stack, set vars */
1708
emalloc(loop_stack, struct loop_info *, nloops * sizeof(struct loop_info),
1710
} else if (nloops_active == nloops) {
1711
/* grow stack, set vars */
1713
erealloc(loop_stack, struct loop_info *, nloops * sizeof(struct loop_info),
1717
loop_stack[nloops_active].varname = varname;
1718
loop_stack[nloops_active].elems = elems;
1719
loop_stack[nloops_active].nelems = nelems;
1725
* N.B. The code that uses fcalls[] *always* uses indexing.
1726
* This avoids severe problems in case fcalls gets realloc()'ed
1727
* during recursive tree_eval()'s or whatever, so that we don't
1728
* have to carefully reassign pointers into the array. The
1729
* minor speed gain from using a pointer was offset too much
1730
* by the hassles to get the code right and commented.
1732
* Thanks and a tip of the hatlo to Brian Kernighan.
1735
static struct fcall {
1736
const char *fname; /* function name */
1737
size_t count; /* how many args */
1738
NODE *arglist; /* list thereof */
1739
NODE **prevstack; /* function stack frame of previous function */
1740
NODE **stack; /* function stack frame of current function */
1743
static long fcall_list_size = 0;
1744
static long curfcall = -1;
1747
* get_curfunc_arg_count --- return number actual parameters
1749
* This is for use by dynamically loaded C extension functions.
1752
get_curfunc_arg_count(void)
1757
assert(curfcall >= 0);
1759
/* count the # of expressions in argument expression list */
1760
for (argc = 0, argp = fcalls[curfcall].arglist;
1761
argp != NULL; argp = argp->rnode)
1767
/* pop_fcall --- pop off a single function call */
1775
assert(curfcall >= 0);
1776
stack_ptr = fcalls[curfcall].prevstack;
1778
sp = fcalls[curfcall].stack;
1780
for (count = fcalls[curfcall].count; count > 0; count--) {
1783
* If, while setting the value of an argument in push_args,
1784
* the recursively evaluating code exits, this argument
1785
* could never have been set to a value. So check for NULL,
1790
if (n->type == Node_var) /* local variable */
1791
unref(n->var_value);
1792
else if (n->type == Node_var_array) /* local array */
1796
if (fcalls[curfcall].stack) {
1797
free((char *) fcalls[curfcall].stack);
1798
fcalls[curfcall].stack = NULL;
1803
/* pop_fcall_stack --- pop off all function args, don't leak memory */
1808
while (curfcall >= 0)
1812
/* push_args --- push function arguments onto the stack */
1815
push_args(int count,
1818
const char *func_name,
1821
NODE *arg, *r, **sp;
1824
if (fcall_list_size == 0) { /* first time */
1825
emalloc(fcalls, struct fcall *, 10 * sizeof(struct fcall),
1827
fcall_list_size = 10;
1830
if (++curfcall >= fcall_list_size) {
1831
fcall_list_size *= 2;
1832
erealloc(fcalls, struct fcall *,
1833
fcall_list_size * sizeof(struct fcall), "push_args");
1837
size_t nbytes = count * sizeof(NODE *);
1839
emalloc(fcalls[curfcall].stack, NODE **, nbytes, "push_args");
1840
memset(fcalls[curfcall].stack, 0, nbytes); /* Make sure these are all NULL pointers. */
1842
fcalls[curfcall].stack = NULL;
1843
fcalls[curfcall].count = count;
1844
fcalls[curfcall].fname = func_name; /* not used, for debugging, just in case */
1845
fcalls[curfcall].arglist = argp;
1846
fcalls[curfcall].prevstack = oldstack;
1848
sp = fcalls[curfcall].stack;
1850
/* for each calling arg. add NODE * on stack */
1851
for (i = 0; i < count; i++) {
1853
memset(r, 0, sizeof(*r));
1856
/* local variable */
1857
r->type = Node_var_new;
1858
r->var_value = Nnull_string;
1859
r->vname = varnames[i];
1864
/* call by reference for arrays; see below also */
1865
if (arg->type == Node_param_list)
1866
arg = fcalls[curfcall].prevstack[arg->param_cnt];
1868
if (arg->type == Node_var_array || arg->type == Node_var_new) {
1869
r->type = Node_array_ref;
1870
r->orig_array = arg;
1871
r->prev_array = arg;
1872
} else if (arg->type == Node_array_ref) {
1874
r->prev_array = arg;
1876
NODE *n = tree_eval(arg);
1879
r->lnode = dupnode(n);
1880
r->rnode = (NODE *) NULL;
1881
r->var_value->flags |= ASSIGNED; /* For indirect function calls */
1884
r->vname = varnames[i];
1889
/* Left over calling args. */
1891
_("function `%s' called with more arguments than declared"),
1893
/* Evaluate them, they may have side effects: */
1896
if (arg->type == Node_param_list)
1897
arg = fcalls[curfcall].prevstack[arg->param_cnt];
1898
if (arg->type != Node_var_array &&
1899
arg->type != Node_array_ref &&
1900
arg->type != Node_var_new)
1901
free_temp(tree_eval(arg));
1902
} while ((argp = argp->rnode) != NULL);
1905
stack_ptr = fcalls[curfcall].stack;
1908
/* func_call --- call a function, call by reference for arrays */
1913
func_call(NODE *tree)
1916
NODE *name, *arg_list;
1918
jmp_buf volatile func_tag_stack;
1919
jmp_buf volatile loop_tag_stack;
1920
int volatile save_loop_tag_valid = FALSE;
1921
NODE *save_ret_node;
1922
extern NODE *ret_node;
1923
size_t current_nloops_active = 0;
1925
/* tree->rnode is a Node_val giving function name */
1926
/* tree->lnode is Node_expression_list of calling args. */
1928
arg_list = tree->lnode;
1931
* After several attempts to both get the semantics right
1932
* and to avoid duplicate code, here is the cleanest code that
1933
* does the right thing.
1938
/* First, decide if we can use a cached funcbody */
1939
if (tree->type == Node_func_call) { /* direct function call */
1940
if (tree->funcbody != NULL) {
1945
/* Get the function body, cache it */
1946
f = lookup(name->stptr);
1948
fatal(_("function `%s' not defined"), name->stptr);
1949
else if (f->type != Node_func)
1950
fatal(_("identifier `%s' is not a function"), name->stptr);
1952
tree->funcbody = f; /* save for next call */
1956
/* Indirect function call */
1958
/* Check for parameters first, since they shadow globals */
1959
if (curfcall >= 0) {
1960
int n = fcalls[curfcall].count;
1965
for (i = 0; i < n; i++) {
1966
parm = fcalls[curfcall].stack[i];
1967
if (strcmp(parm->vname, name->stptr) == 0) {
1974
goto look_for_global_symbol;
1977
name = stack_ptr[i];
1978
if (name->type == Node_var) {
1979
if ((name->var_value->flags & ASSIGNED) == 0 && tree->funcbody) {
1980
/* Should be safe to use cached value */
1985
force_string(name->var_value);
1986
f = lookup(name->var_value->stptr);
1990
if (f->type == Node_func) {
1991
tree->funcbody = f; /* save for next call */
1992
name->var_value->flags &= ~ASSIGNED;
1997
fatal(_("function parameter `%s' is not a scalar and cannot be used for indirect function call"),
2001
look_for_global_symbol:
2003
/* not in a function call, or not a parameter, look it up globally */
2004
f = lookup(name->stptr);
2006
if (f->type == Node_func) {
2007
tree->funcbody = f; /* save for next call */
2008
tree->type = Node_func_call; /* make it a direct call */
2010
* This may not be so silly; it allows a unified syntax which is good
2011
* if someone is generating code. So leave it alone for now.
2014
lintwarn(_("indirect call of real function `%s' is silly"), name->stptr);
2016
} else if (f->type == Node_var) {
2018
NODE *fvalue = f->var_value;
2020
if ((fvalue->flags & ASSIGNED) == 0 && tree->funcbody) {
2025
force_string(f->var_value);
2026
fname = f->var_value->stptr;
2027
f = lookup(f->var_value->stptr);
2028
if (f != NULL && f->type == Node_func) {
2029
tree->funcbody = f; /* save for next call */
2030
fvalue->flags &= ~ASSIGNED;
2034
fatal(_("function `%s' called indirectly through `%s' does not exist"),
2035
fname, name->stptr);
2039
fatal(_("identifier `%s' cannot be used for indirect function call"), name->stptr);
2044
fprintf(stderr, "function `%s' called\n", name->stptr);
2046
push_args(f->lnode->param_cnt, arg_list, stack_ptr, name->stptr,
2050
* Execute function body, saving context, as a return statement
2051
* will longjmp back here.
2053
* Have to save and restore the loop_tag stuff so that a return
2054
* inside a loop in a function body doesn't scrog any loops going
2055
* on in the main program. We save the necessary info in variables
2056
* local to this function so that function nesting works OK.
2057
* We also only bother to save the loop stuff if we're in a loop
2058
* when the function is called.
2060
if (loop_tag_valid) {
2063
save_loop_tag_valid = (volatile int) loop_tag_valid;
2064
PUSH_BINDING(loop_tag_stack, loop_tag, junk);
2065
loop_tag_valid = FALSE;
2067
PUSH_BINDING(func_tag_stack, func_tag, func_tag_valid);
2068
current_nloops_active = nloops_active;
2069
save_ret_node = ret_node;
2070
ret_node = Nnull_string; /* default return value */
2071
INCREMENT(f->exec_count); /* count function calls */
2072
if (setjmp(func_tag) == 0)
2073
(void) interpret(f->rnode);
2075
while (nloops_active > current_nloops_active)
2079
ret_node = (NODE *) save_ret_node;
2080
RESTORE_BINDING(func_tag_stack, func_tag, func_tag_valid);
2083
/* Restore the loop_tag stuff if necessary. */
2084
if (save_loop_tag_valid) {
2087
loop_tag_valid = (int) save_loop_tag_valid;
2088
RESTORE_BINDING(loop_tag_stack, loop_tag, junk);
558
#if defined(PROFILING) || defined(DEBUGGING)
562
static long max_fcall;
564
/* NB: frame numbering scheme as in GDB. frame_ptr => frame #0. */
567
if (fcall_list == NULL) {
569
emalloc(fcall_list, NODE **, (max_fcall + 1) * sizeof(NODE *), "push_frame");
570
} else if (fcall_count == max_fcall) {
572
erealloc(fcall_list, NODE **, (max_fcall + 1) * sizeof(NODE *), "push_frame");
576
memmove(fcall_list + 2, fcall_list + 1, (fcall_count - 1) * sizeof(NODE *));
584
extern void frame_popped();
587
memmove(fcall_list + 1, fcall_list + 2, (fcall_count - 1) * sizeof(NODE *));
589
assert(fcall_count >= 0);
594
#else /* not PROFILING or DEBUGGING */
595
#define push_frame(p) /* nothing */
596
#define pop_frame() /* nothing */
2094
600
#ifdef PROFILING
2095
602
/* dump_fcall_stack --- print a backtrace of the awk function calls */
2098
605
dump_fcall_stack(FILE *fp)
611
if (fcall_count == 0)
2105
613
fprintf(fp, _("\n\t# Function Call Stack:\n\n"));
2106
for (i = curfcall; i >= 0; i--)
2107
fprintf(fp, "\t# %3d. %s\n", i+1, fcalls[i].fname);
2108
fprintf(fp, _("\t# -- main --\n"));
616
func = frame_ptr->func_node;
617
fprintf(fp, "\t# %3ld. %s\n", i, func->lnode->param);
619
/* outer frames except main */
620
for (i = 1; i < fcall_count; i++) {
623
fprintf(fp, "\t# %3ld. %s\n", i, func->lnode->param);
626
fprintf(fp, "\t# %3ld. -- main --\n", fcall_count);
2110
629
#endif /* PROFILING */
2114
* This returns a POINTER to a node pointer. get_lhs(ptr) is the current
2115
* value of the var, or where to store the var's new value
2117
* For the special variables, don't unref their current value if it's
2118
* the same as the internal copy; perhaps the current one is used in
2119
* a concatenation or some other expression somewhere higher up in the
2124
r_get_lhs(register NODE *ptr, Func_ptr *assign, int reference)
2126
register NODE **aptr = NULL;
2130
*assign = NULL; /* for safety */
2131
if (ptr->type == Node_param_list) {
2132
if ((ptr->flags & FUNC) != 0)
2133
fatal(_("can't use function name `%s' as variable or array"), ptr->vname);
2134
ptr = stack_ptr[ptr->param_cnt];
2139
switch (ptr->type) {
2141
if (do_lint && reference && var_uninitialized(ptr))
2142
lintwarn(_("reference to uninitialized variable `%s'"),
2145
aptr = &(ptr->var_value);
2147
if (ptr->var_value->stref <= 0)
2152
case Node_FIELDWIDTHS:
2153
aptr = &(FIELDWIDTHS_node->var_value);
2155
*assign = set_FIELDWIDTHS;
2159
aptr = &(RS_node->var_value);
2165
aptr = &(FS_node->var_value);
2171
aptr = &(FPAT_node->var_value);
2177
if (FNR_node->var_value->numbr != FNR) {
2178
unref(FNR_node->var_value);
2179
FNR_node->var_value = make_number((AWKNUM) FNR);
2181
aptr = &(FNR_node->var_value);
2187
if (NR_node->var_value->numbr != NR) {
2188
unref(NR_node->var_value);
2189
NR_node->var_value = make_number((AWKNUM) NR);
2191
aptr = &(NR_node->var_value);
2197
if (NF == -1 || NF_node->var_value->numbr != NF) {
2199
(void) get_field(UNLIMITED-1, assign); /* parse record */
2200
unref(NF_node->var_value);
2201
NF_node->var_value = make_number((AWKNUM) NF);
2203
aptr = &(NF_node->var_value);
2208
case Node_IGNORECASE:
2209
aptr = &(IGNORECASE_node->var_value);
2211
*assign = set_IGNORECASE;
2215
aptr = &(BINMODE_node->var_value);
2217
*assign = set_BINMODE;
2221
aptr = &(LINT_node->var_value);
2227
aptr = &(OFMT_node->var_value);
2233
aptr = &(CONVFMT_node->var_value);
2235
*assign = set_CONVFMT;
2239
aptr = &(ORS_node->var_value);
2245
aptr = &(OFS_node->var_value);
2251
aptr = &(SUBSEP_node->var_value);
2253
*assign = set_SUBSEP;
2256
case Node_TEXTDOMAIN:
2257
aptr = &(TEXTDOMAIN_node->var_value);
2259
*assign = set_TEXTDOMAIN;
2262
case Node_field_spec:
2266
n = tree_eval(ptr->lnode);
2268
if ((n->flags & NUMBER) == 0) {
2269
lintwarn(_("attempt to field reference from non-numeric value"));
2271
lintwarn(_("attempt to reference from null string"));
2274
field_num = (int) force_number(n);
2277
fatal(_("attempt to access field %d"), field_num);
2278
if (field_num == 0 && field0_valid) { /* short circuit */
2279
aptr = &fields_arr[0];
2281
*assign = reset_record;
2283
aptr = get_field(field_num, assign);
2284
if (do_lint && reference && (*aptr == Null_field || *aptr == Nnull_string))
2285
lintwarn(_("reference to uninitialized field `$%d'"),
2290
case Node_subscript:
2291
n = get_array(ptr->lnode);
2292
aptr = assoc_lookup(n, concat_exp(ptr->rnode), reference);
2297
/* in gawk for a while */
2298
fatal(_("assignment is not allowed to result of builtin function"));
2301
* This is how Christos at Deshaw did it.
2302
* Does this buy us anything?
2304
if (ptr->builtin == NULL)
2305
fatal(_("assignment is not allowed to result of builtin function"));
2306
ptr->callresult = (*ptr->builtin)(ptr->subnode);
2307
aptr = &ptr->callresult;
2312
fprintf(stderr, "type = %s\n", nodetype2str(ptr->type));
2319
/* match_op --- do ~ and !~ */
2322
match_op(register NODE *tree)
2325
register Regexp *rp;
2328
int kludge_need_start = 0; /* FIXME: --- see below */
2330
if (tree->type == Node_nomatch)
2332
if (tree->type == Node_regex)
2333
t1 = *get_field(0, (Func_ptr *) 0);
2335
t1 = force_string(tree_eval(tree->lnode));
2338
rp = re_update(tree);
2342
* Any place where research() is called with a last parameter of
2343
* zero, we need to use the avoid_dfa test. This appears here and
2344
* in the code for Node_K_switch.
2346
* A new or improved dfa that distinguishes beginning/end of
2347
* string from beginning/end of line will allow us to get rid of
2348
* this temporary hack.
2350
* The avoid_dfa() function is in re.c; it is not very smart.
2352
if (avoid_dfa(tree, t1->stptr, t1->stlen))
2353
kludge_need_start = RE_NEED_START;
2354
i = research(rp, t1->stptr, 0, t1->stlen, kludge_need_start);
2355
i = (i == -1) ^ (match == TRUE);
2357
return tmp_number((AWKNUM) i);
2360
631
/* set_IGNORECASE --- update IGNORECASE as appropriate */
2715
996
return (cmp1 != 0 ? cmp1 :
2716
997
len1 < len2 ? -1 : (len1 > len2));
1001
NODE *frame_ptr; /* current frame */
1002
STACK_ITEM *stack_ptr = NULL;
1003
STACK_ITEM *stack_bottom;
1004
STACK_ITEM *stack_top;
1005
static unsigned long STACK_SIZE = 256; /* initial size of stack */
1006
int max_args = 0; /* maximum # of arguments to printf, print, sprintf,
1007
* or # of array subscripts, or adjacent strings
1008
* to be concatenated.
1010
NODE **args_array = NULL;
1012
/* grow_stack --- grow the size of runtime stack */
1014
/* N.B. stack_ptr points to the topmost occupied location
1015
* on the stack, not the first free location.
1021
if (stack_ptr == NULL) {
1023
if ((val = getenv("STACKSIZE")) != NULL) {
1024
if (isdigit(*val)) {
1025
unsigned long n = 0;
1026
for (; *val && isdigit(*val); val++)
1027
n = (n * 10) + *val - '0';
1033
emalloc(stack_bottom, STACK_ITEM *, STACK_SIZE * sizeof(STACK_ITEM), "grow_stack");
1034
stack_ptr = stack_bottom - 1;
1035
stack_top = stack_bottom + STACK_SIZE - 1;
1037
/* initialize frame pointer */
1039
frame_ptr->type = Node_frame;
1040
frame_ptr->stack = NULL;
1041
frame_ptr->func_node = NULL; /* in main */
1042
frame_ptr->vname = NULL;
1043
frame_ptr->loop_count = 0;
1048
erealloc(stack_bottom, STACK_ITEM *, STACK_SIZE * sizeof(STACK_ITEM), "grow_stack");
1049
stack_top = stack_bottom + STACK_SIZE - 1;
1050
stack_ptr = stack_bottom + STACK_SIZE / 2;
1056
* This returns a POINTER to a node pointer (var's value).
1057
* used to store the var's new value.
1061
r_get_lhs(NODE *n, int reference)
1063
int isparam = FALSE;
1065
if (n->type == Node_param_list) {
1066
if ((n->flags & FUNC) != 0)
1067
fatal(_("can't use function name `%s' as variable or array"),
1070
n = GET_PARAM(n->param_cnt);
1074
case Node_var_array:
1075
fatal(_("attempt to use array `%s' in a scalar context"),
1077
case Node_array_ref:
1078
if (n->orig_array->type == Node_var_array)
1079
fatal(_("attempt to use array `%s' in a scalar context"),
1081
n->orig_array->type = Node_var;
1082
n->orig_array->var_value = Nnull_string;
1086
n->var_value = Nnull_string;
1094
/* in gawk for a while */
1095
fatal(_("assignment is not allowed to result of builtin function"));
1102
if (do_lint && reference && var_uninitialized(n))
1104
_("reference to uninitialized argument `%s'") :
1105
_("reference to uninitialized variable `%s'")),
1107
return &n->var_value;
1111
/* r_get_field --- get the address of a field node */
1113
static inline NODE **
1114
r_get_field(NODE *n, Func_ptr *assign, int reference)
1122
if ((n->flags & NUMBER) == 0) {
1123
lintwarn(_("attempt to field reference from non-numeric value"));
1125
lintwarn(_("attempt to field reference from null string"));
1129
field_num = (long) force_number(n);
1131
fatal(_("attempt to access field %ld"), field_num);
1133
if (field_num == 0 && field0_valid) { /* short circuit */
1134
lhs = &fields_arr[0];
1136
*assign = reset_record;
1138
lhs = get_field(field_num, assign);
1139
if (do_lint && reference && (*lhs == Null_field || *lhs == Nnull_string))
1140
lintwarn(_("reference to uninitialized field `$%ld'"),
1147
* calc_exp_posint --- calculate x^n for positive integral n,
1148
* using exponentiation by squaring without recursion.
1152
calc_exp_posint(AWKNUM x, long n)
1165
/* calc_exp --- calculate x1^x2 */
1168
calc_exp(AWKNUM x1, AWKNUM x2)
1172
if ((lx = x2) == x2) { /* integer exponent */
1175
return (lx > 0) ? calc_exp_posint(x1, lx)
1176
: 1.0 / calc_exp_posint(x1, -lx);
1178
return (AWKNUM) pow((double) x1, (double) x2);
1182
/* setup_frame --- setup new frame for function call */
1185
setup_frame(INSTRUCTION *pc)
1192
int pcount, arg_count, i;
1195
pcount = f->lnode->param_cnt;
1196
varnames = f->parmlist;
1197
arg_count = (pc + 1)->expr_count;
1199
/* check for extra args */
1200
if (arg_count > pcount) {
1202
_("function `%s' called with more arguments than declared"),
1206
if (r->type == Node_val)
1208
} while (--arg_count > pcount);
1212
emalloc(sp, NODE **, pcount * sizeof(NODE *), "setup_frame");
1213
memset(sp, 0, pcount * sizeof(NODE *));
1216
for (i = 0; i < pcount; i++) {
1218
memset(r, 0, sizeof(NODE));
1220
if (i >= arg_count) {
1221
/* local variable */
1222
r->type = Node_var_new;
1223
r->vname = varnames[i];
1227
m = PEEK(arg_count - i - 1); /* arguments in reverse order on runtime stack */
1229
if (m->type == Node_param_list)
1230
m = GET_PARAM(m->param_cnt);
1234
case Node_var_array:
1235
r->type = Node_array_ref;
1236
r->orig_array = r->prev_array = m;
1239
case Node_array_ref:
1240
r->type = Node_array_ref;
1241
r->orig_array = m->orig_array;
1253
r->vname = varnames[i];
1255
stack_adj(-arg_count); /* adjust stack pointer */
1257
if (pc->opcode == Op_indirect_func_call) {
1258
r = POP(); /* indirect var */
1262
push_frame(frame_ptr);
1264
/* save current frame in stack */
1266
/* setup new frame */
1268
frame_ptr->type = Node_frame;
1269
frame_ptr->stack = sp;
1270
frame_ptr->func_node = f;
1271
frame_ptr->loop_count = 0;
1272
frame_ptr->vname = NULL;
1274
frame_ptr->reti = (unsigned long) pc; /* on return execute pc->nexti */
1278
/* restore_frame --- clean up the stack and update frame */
1280
static INSTRUCTION *
1281
restore_frame(NODE *fp)
1289
func = frame_ptr->func_node;
1290
n = func->lnode->param_cnt;
1291
sp = frame_ptr->stack;
1293
for (; n > 0; n--) {
1295
if (r->type == Node_var) /* local variable */
1296
DEREF(r->var_value);
1297
else if (r->type == Node_var_array) /* local array */
1301
if (frame_ptr->stack != NULL)
1302
efree(frame_ptr->stack);
1303
ri = (INSTRUCTION *) frame_ptr->reti; /* execution in calling frame
1304
* resumes from ri->nexti.
1306
freenode(frame_ptr);
1314
/* free_arrayfor --- free 'for (var in array)' related data */
1317
free_arrayfor(NODE *r)
1319
if (r->var_array != NULL) {
1320
size_t num_elems = r->table_size;
1321
NODE **list = r->var_array;
1322
while (num_elems > 0)
1323
ahash_unref(list[--num_elems]);
1329
/* unwind_stack --- pop the runtime stack */
1332
unwind_stack(STACK_ITEM *sp_bottom)
1336
while (stack_ptr >= sp_bottom) {
1339
case Node_instruction:
1344
(void) restore_frame(r);
1345
source = frame_ptr->vname;
1357
if (get_context()->level == 0)
1358
fatal(_("unwind_stack: unexpected type `%s'"),
1359
nodetype2str(r->type));
1363
* Node_var (e.g: trying to use scalar for array)
1364
* Node_regex/Node_dynregex
1374
* This generated compiler warnings from GCC 4.4. Who knows why.
1376
#define eval_condition(t) (((t)->flags & MAYBE_NUM) && force_number(t), \
1377
((t)->flags & NUMBER) ? ((t)->numbr != 0.0) : ((t)->stlen != 0))
1382
eval_condition(NODE *t)
1384
if ((t->flags & MAYBE_NUM) != 0)
1387
if ((t->flags & NUMBER) != 0)
1388
return (t->numbr != 0.0);
1390
return (t->stlen != 0);
1393
/* PUSH_CODE --- push a code onto the runtime stack */
1396
PUSH_CODE(INSTRUCTION *cp)
1400
r->type = Node_instruction;
1405
/* POP_CODE --- pop a code off the runtime stack */
1421
* code is a list of instructions to run. returns the exit value
1422
* from the awk code.
1426
* 1) reference counting done for both number and string values.
1427
* 2) TEMP flag no longer needed (consequence of the above; valref = 0
1428
* is the replacement).
1429
* 3) Stack operations:
1430
* Use REPLACE[_XX] if last stack operation was TOP[_XX],
1431
* PUSH[_XX] if last operation was POP[_XX] instead.
1432
* 4) UPREF and DREF -- see awk.h
1437
r_interpret(INSTRUCTION *code)
1439
INSTRUCTION *pc; /* current instruction */
1444
NODE *f; /* function definition */
1447
int di, pre = FALSE;
1454
#if defined(GAWKDEBUG) || defined(ARRAYDEBUG)
1455
int last_was_stopme = FALSE; /* builtin stopme() called ? */
1458
int stdio_problem = FALSE;
1460
if (args_array == NULL)
1461
emalloc(args_array, NODE **, (max_args + 2)*sizeof(NODE *), "r_interpret");
1463
erealloc(args_array, NODE **, (max_args + 2)*sizeof(NODE *), "r_interpret");
1465
/* array subscript */
1466
#define mk_sub(n) (n == 1 ? POP_STRING() : concat_exp(n, TRUE))
1469
#define JUMPTO(x) do { post_execute(pc, in_loop); pc = (x); goto top; } while(FALSE)
1471
#define JUMPTO(x) do { pc = (x); goto top; } while(FALSE)
1476
/* N.B.: always use JUMPTO for next instruction, otherwise bad things
1477
* may happen. DO NOT add a real loop (for/while) below to
1478
* replace ' forever {'; this catches failure to use JUMPTO to execute
1479
* next instruction (e.g. continue statement).
1482
/* loop until hit Op_stop instruction */
1486
if (pc->source_line > 0)
1487
sourceline = pc->source_line;
1490
if (! pre_execute(&pc, in_loop))
1494
switch (pc->opcode) {
1496
currule = pc->in_rule; /* for sole use in Op_K_next, Op_K_nextfile */
1500
source = pc->source_file;
1504
/* avoid false source indications */
1507
(void) nextfile(&curfile, TRUE); /* close input data file */
1511
* if (close_io() != 0 && ! exiting && exit_val == 0)
1514
* Other awks don't care about problems closing open files
1515
* and pipes, in that it doesn't affect their exit status.
1516
* So we no longer do either.
1518
(void) close_io(& stdio_problem);
1520
* However, we do want to exit non-zero if there was a problem
1521
* with stdout/stderr, so we reinstate a slightly different
1522
* version of the above:
1524
if (stdio_problem && ! exiting && exit_val == 0)
1533
PUSH((m->flags & INTLSTR) != 0 ? format_val(CONVFMT, CONVFMTidx, m): m);
1539
int isparam = FALSE;
1541
save_symbol = m = pc->memory;
1542
if (m->type == Node_param_list) {
1543
if ((m->flags & FUNC) != 0)
1544
fatal(_("can't use function name `%s' as variable or array"),
1547
save_symbol = m = GET_PARAM(m->param_cnt);
1548
if (m->type == Node_array_ref)
1554
if (do_lint && var_uninitialized(m))
1556
_("reference to uninitialized argument `%s'") :
1557
_("reference to uninitialized variable `%s'"),
1558
save_symbol->vname);
1566
m->var_value = Nnull_string;
1569
_("reference to uninitialized argument `%s'") :
1570
_("reference to uninitialized variable `%s'"),
1571
save_symbol->vname);
1575
case Node_var_array:
1577
&& pc->nexti->opcode == Op_builtin
1578
&& pc->nexti->builtin == do_length) /* length(array) */
1581
fatal(_("attempt to use array `%s' in a scalar context"),
1582
array_vname(save_symbol));
1591
case Op_push_param: /* function argument */
1593
if (m->type == Node_param_list)
1594
m = GET_PARAM(m->param_cnt);
1595
if (m->type == Node_var) {
1608
lhs = get_lhs(pc->memory, pc->do_reference);
1613
t2 = mk_sub(pc->sub_count);
1615
r = *assoc_lookup(t1, t2, TRUE);
1617
if (r->type == Node_val)
1623
t2 = mk_sub(pc->sub_count);
1625
r = in_array(t1, t2);
1627
const char *arr_name = make_aname(t1, t2);
1629
r->type = Node_var_array;
1630
r->var_array = NULL;
1631
r->vname = estrdup(arr_name, strlen(arr_name));
1632
*assoc_lookup(t1, t2, FALSE) = r;
1633
} else if (r->type != Node_var_array) {
1634
const char *arr_name = make_aname(t1, t2);
1636
fatal(_("attempt to use scalar `%s' as an array"), arr_name);
1642
case Op_subscript_lhs:
1643
t2 = mk_sub(pc->sub_count);
1645
lhs = assoc_lookup(t1, t2, pc->do_reference);
1646
if ((*lhs)->type == Node_var_array) {
1647
const char *arr_name = make_aname(t1, t2);
1649
fatal(_("attempt to use array `%s' in a scalar context"), arr_name);
1657
lhs = r_get_field(t1, (Func_ptr *) 0, TRUE);
1660
/* This used to look like this:
1661
PUSH(dupnode(*lhs));
1662
but was changed to bypass an apparent bug in the z/OS C compiler.
1663
Please do not remerge. */
1664
r = dupnode(*lhs); /* can't use UPREF here */
1668
case Op_field_spec_lhs:
1670
lhs = r_get_field(t1, &pc->target_assign->field_assign, pc->do_reference);
1678
switch (pc->lint_type) {
1679
case LINT_assign_in_cond:
1680
lintwarn(_("assignment used in conditional context"));
1683
case LINT_no_effect:
1684
lintwarn(_("statement has no effect"));
1693
case Op_push_loop: /* for break/continue in loop, switch */
1704
JUMPTO(pc->target_jmp);
1708
di = eval_condition(r);
1711
JUMPTO(pc->target_jmp);
1716
di = eval_condition(r);
1719
JUMPTO(pc->target_jmp);
1725
di = eval_condition(t1);
1727
if ((pc->opcode == Op_and && di)
1728
|| (pc->opcode == Op_or && ! di))
1730
r = make_number((AWKNUM) di);
1732
ni = pc->target_jmp;
1738
r = make_number((AWKNUM) eval_condition(t1));
1745
r = make_number((AWKNUM) ! eval_condition(t1));
1752
/* compare two nodes on the stack */
1753
#define compare(X, Y) \
1754
t2 = POP_SCALAR(); \
1755
t1 = TOP_SCALAR(); \
1756
X = cmp_nodes(t1, t2); \
1759
r = make_number((AWKNUM) (Y)); \
1762
compare(di, di == 0);
1766
compare(di, di != 0);
1770
compare(di, di < 0);
1774
compare(di, di > 0);
1778
compare(di, di <= 0);
1782
compare(di, di >= 0);
1787
x2 = force_number(pc->memory);
1794
r = make_number(x1 + x2);
1799
x2 = force_number(pc->memory);
1806
r = make_number(x1 - x2);
1811
x2 = force_number(pc->memory);
1818
r = make_number(x1 * x2);
1823
x2 = force_number(pc->memory);
1830
x = calc_exp(x1, x2);
1836
x2 = force_number(pc->memory);
1845
fatal(_("division by zero attempted"));
1848
/* special case for integer division, put in for Cray */
1853
lx = (long) x1 / lx2;
1867
x2 = force_number(pc->memory);
1877
fatal(_("division by zero attempted in `%%'"));
1881
#else /* ! HAVE_FMOD */
1882
(void) modf(x1 / x2, &x);
1884
#endif /* ! HAVE_FMOD */
1889
case Op_preincrement:
1891
case Op_postincrement:
1894
lhs = TOP_ADDRESS();
1895
x1 = force_number(*lhs);
1897
r = *lhs = make_number(x1 + x2);
1901
r = make_number(x1);
1906
case Op_predecrement:
1908
case Op_postdecrement:
1912
case Op_unary_minus:
1914
r = make_number(-x1);
1919
/* array[sub] assignment optimization,
1920
* see awkgram.y (optimize_assignment)
1922
t1 = get_array(pc->memory, TRUE); /* array */
1923
t2 = mk_sub(pc->expr_count); /* subscript */
1924
lhs = assoc_lookup(t1, t2, FALSE);
1925
if ((*lhs)->type == Node_var_array) {
1926
const char *arr_name = make_aname(t1, t2);
1928
fatal(_("attempt to use array `%s' in a scalar context"), arr_name);
1932
*lhs = POP_SCALAR();
1936
/* simple variable assignment optimization,
1937
* see awkgram.y (optimize_assignment)
1940
lhs = get_lhs(pc->memory, FALSE);
1942
*lhs = POP_SCALAR();
1945
case Op_store_field:
1947
/* field assignment optimization,
1948
* see awkgram.y (optimize_assignment)
1953
lhs = r_get_field(t1, &assign, FALSE);
1957
*lhs = POP_SCALAR();
1958
assert(assign != NULL);
1963
case Op_assign_concat:
1964
/* x = x ... string concatenation optimization */
1965
lhs = get_lhs(pc->memory, FALSE);
1966
t1 = force_string(*lhs);
1971
if (t1 != t2 && t1->valref == 1 && (t1->flags & PERM) == 0) {
1972
size_t nlen = t1->stlen + t2->stlen;
1973
erealloc(t1->stptr, char *, nlen + 2, "interpret");
1974
memcpy(t1->stptr + t1->stlen, t2->stptr, t2->stlen);
1976
t1->stptr[nlen] = '\0';
1978
size_t nlen = t1->stlen + t2->stlen;
1981
emalloc(p, char *, nlen + 2, "interpret");
1982
memcpy(p, t1->stptr, t1->stlen);
1983
memcpy(p + t1->stlen, t2->stptr, t2->stlen);
1985
t1 = *lhs = make_str_node(p, nlen, ALREADY_MALLOCED);
1987
t1->flags &= ~(NUMCUR|NUMBER);
1992
lhs = POP_ADDRESS();
2000
case Op_assign_plus:
2001
#define assign_common(X, Y) \
2002
lhs = POP_ADDRESS(); \
2003
X = force_number(*lhs); \
2007
#define assign(X, Y, Z) \
2008
assign_common(X, Y); \
2009
r = *lhs = make_number(Z); \
2013
assign(x1, x2, x1 + x2);
2016
case Op_assign_minus:
2017
assign(x1, x2, x1 - x2);
2020
case Op_assign_times:
2021
assign(x1, x2, x1 * x2);
2024
case Op_assign_quotient:
2025
assign_common(x1, x2);
2026
if (x2 == (AWKNUM) 0) {
2028
fatal(_("division by zero attempted in `/='"));
2031
/* special case for integer division, put in for Cray */
2034
r = *lhs = make_number(x1 / x2);
2039
lx = (long) x1 / lx;
2041
r = *lhs = make_number((AWKNUM) lx);
2044
r = *lhs = make_number(x1 / x2);
2050
assign_common(x1, x2);
2051
if (x2 == (AWKNUM) 0) {
2053
fatal(_("division by zero attempted in `%%='"));
2056
r = *lhs = make_number(fmod(x1, x2));
2057
#else /* ! HAVE_FMOD */
2058
(void) modf(x1 / x2, &x);
2060
r = *lhs = make_number(x);
2061
#endif /* ! HAVE_FMOD */
2067
assign(x1, x2, (AWKNUM) calc_exp((double) x1, (double) x2));
2071
#undef assign_common
2073
case Op_var_update: /* update value of NR, FNR or NF */
2074
pc->memory->var_update();
2078
pc->memory->var_assign();
2081
case Op_field_assign:
2086
r = concat_exp(pc->expr_count, pc->concat_flag & CSUBSEP);
2093
int match_found = FALSE;
2095
t1 = TOP_SCALAR(); /* switch expression */
2096
for (curr = pc->case_val; curr != NULL; curr = curr->nexti) {
2097
if (curr->opcode == Op_K_case) {
2099
if (m->type == Node_regex) {
2100
(void) force_string(t1);
2102
match_found = (research(rp, t1->stptr, 0, t1->stlen,
2103
avoid_dfa(m, t1->stptr, t1->stlen)) >= 0);
2105
match_found = (cmp_nodes(t1, m) == 0);
2112
curr = pc->switch_dflt;
2115
JUMPTO(curr->target_stmt);
2119
assert(in_loop >= 0);
2123
/* assert(ip->opcode == Op_push_loop); */
2124
if (ni->target_continue != NULL)
2128
* This one is for continue in case statement;
2129
* keep searching for one that corresponds
2137
JUMPTO(pc->target_jmp);
2139
fatal(_("`continue' outside a loop is not allowed"));
2143
assert(in_loop >= 0);
2145
fatal(_("`break' outside a loop is not allowed"));
2147
JUMPTO(pc->target_jmp);
2153
do_delete(t1, pc->expr_count);
2154
stack_adj(-pc->expr_count);
2157
case Op_K_delete_loop:
2159
lhs = POP_ADDRESS(); /* item */
2160
do_delete_loop(t1, lhs);
2165
t2 = mk_sub(pc->expr_count);
2166
di = (in_array(t1, t2) != NULL);
2168
PUSH(make_number((AWKNUM) di));
2171
case Op_arrayfor_init:
2175
size_t num_elems = 0;
2177
int sort_indices = whiny_users;
2180
array = POP_ARRAY();
2182
/* sanity: check if empty */
2183
if (array->var_array == NULL || array->table_size == 0)
2186
/* allocate space for array */
2187
num_elems = array->table_size;
2188
emalloc(list, NODE **, (num_elems + 1) * sizeof(NODE *), "interpret");
2191
for (i = j = 0; i < array->array_size; i++) {
2192
r = array->var_array[i];
2195
for (; r != NULL; r = r->ahnext) {
2196
list[j++] = ahash_dupnode(r);
2197
assert(list[j-1] == r);
2202
qsort(list, num_elems, sizeof(NODE *), comp_func); /* shazzam! */
2203
list[num_elems] = array; /* actual array for use in
2204
* lint warning in Op_arrayfor_incr
2209
r->type = Node_arrayfor;
2210
r->var_array = list;
2211
r->table_size = num_elems; /* # of elements in list */
2212
r->array_size = -1; /* current index */
2216
JUMPTO(pc->target_jmp); /* Op_arrayfor_final */
2218
break; /* next instruction is Op_push_loop */
2220
case Op_arrayfor_incr:
2221
r = PEEK(1); /* (break/continue) bytecode from Op_push_loop has
2224
/* assert(r->type == Node_arrayfor); */
2225
if (++r->array_size == r->table_size) {
2227
array = r->var_array[r->table_size]; /* actual array */
2228
if (do_lint && array->table_size != r->table_size)
2229
lintwarn(_("for loop: array `%s' changed size from %ld to %ld during loop execution"),
2230
array_vname(array), (long) r->table_size, (long) array->table_size);
2231
JUMPTO(pc->target_jmp); /* Op_pop_loop */
2234
t1 = r->var_array[r->array_size];
2235
lhs = get_lhs(pc->array_var, FALSE);
2237
*lhs = make_string(t1->ahname_str, t1->ahname_len);
2240
case Op_arrayfor_final:
2242
assert(r->type == Node_arrayfor);
2247
r = pc->builtin(pc->expr_count);
2248
#if defined(GAWKDEBUG) || defined(ARRAYDEBUG)
2250
last_was_stopme = TRUE;
2257
do_print(pc->expr_count, pc->redir_type);
2261
do_printf(pc->expr_count, pc->redir_type);
2264
case Op_K_print_rec:
2265
do_print_rec(pc->expr_count, pc->redir_type);
2270
if (m->type == Node_dynregex) {
2280
t1 = *get_field(0, (Func_ptr *) 0);
2286
* Any place where research() is called with a last parameter of
2287
* zero, we need to use the avoid_dfa test. This appears here and
2288
* in the code for Op_K_switch.
2290
* A new or improved dfa that distinguishes beginning/end of
2291
* string from beginning/end of line will allow us to get rid of
2292
* this temporary hack.
2294
* The avoid_dfa() function is in re.c; it is not very smart.
2297
di = research(rp, t1->stptr, 0, t1->stlen,
2298
avoid_dfa(m, t1->stptr, t1->stlen));
2299
di = (di == -1) ^ (pc->opcode != Op_nomatch);
2300
if(pc->opcode != Op_match_rec) {
2304
r = make_number((AWKNUM) di);
2313
if (m->type == Node_dynregex) {
2322
case Op_indirect_func_call:
2327
arg_count = (pc + 1)->expr_count;
2328
t1 = PEEK(arg_count); /* indirect var */
2329
assert(t1->type == Node_val); /* @a[1](p) not allowed in grammar */
2330
(void) force_string(t1);
2331
if (t1->stlen > 0) {
2332
/* retrieve function definition node */
2335
&& STREQ(f->vname, t1->stptr) /* indirect var hasn't been reassigned */
2338
f = lookup(t1->stptr);
2341
if (f == NULL || f->type != Node_func)
2342
fatal(_("function called indirectly through `%s' does not exist"), pc->func_name);
2343
pc->func_body = f; /* save for next call */
2349
/* retrieve function definition node */
2352
f = lookup(pc->func_name);
2353
if (f == NULL || f->type != Node_func)
2354
fatal(_("function `%s' not defined"), pc->func_name);
2355
pc->func_body = f; /* save for next call */
2358
/* save current frame along with source and loop count.
2359
* NB: 'function fun() { break; } BEGIN { while (1) fun(); }'
2364
frame_ptr->vname = source; /* save current source */
2365
frame_ptr->loop_count = in_loop; /* save loop count */
2369
ni = f->code_ptr; /* function code */
2370
if (ni->opcode == Op_ext_func) {
2371
/* dynamically set source and line numbers for an extension builtin. */
2372
ni->source_file = source;
2373
ni->source_line = sourceline;
2374
ni->nexti->source_line = sourceline; /* Op_builtin */
2375
ni->nexti->nexti->source_line = sourceline; /* Op_K_return */
2378
/* run the function instructions */
2379
JUMPTO(ni); /* Op_func or Op_ext_func */
2382
m = POP_SCALAR(); /* return value */
2385
while (r->type != Node_frame) {
2393
case Node_instruction:
2402
ni = restore_frame(r);
2403
source = frame_ptr->vname;
2404
in_loop = frame_ptr->loop_count;
2406
/* put the return value back on stack */
2410
case Op_K_getline_redir:
2411
r = do_getline_redir(pc->into_var, pc->redir_type);
2415
case Op_K_getline: /* no redirection */
2418
ret = nextfile(&curfile, FALSE);
2420
r = do_getline(pc->into_var, curfile);
2423
if (curfile == NULL)
2424
JUMPTO((pc + 1)->target_endfile);
2426
TOP()->loop_count = in_loop;
2428
JUMPTO((pc + 1)->target_beginfile);
2431
} while (r == NULL); /* EOF */
2435
case Op_after_endfile:
2437
assert(ni->opcode == Op_newfile || ni->opcode == Op_K_getline);
2440
case Op_after_beginfile:
2441
after_beginfile(&curfile);
2442
in_loop = TOP()->loop_count;
2444
if (ni->opcode == Op_K_getline
2445
|| curfile == NULL /* skipping directory argument */
2448
PUSH_CODE(ni); /* for use in Op_K_nextfile and Op_get_record */
2449
break; /* Op_get_record */
2454
ret = nextfile(&curfile, FALSE);
2456
JUMPTO(pc->target_jmp); /* end block or Op_atexit */
2459
if (curfile == NULL)
2460
JUMPTO(pc->target_endfile);
2461
TOP()->loop_count = in_loop;
2463
break; /* beginfile block */
2470
if (curfile == NULL) { /* from getline without redirection */
2471
ni = POP_CODE(); /* Op_newfile */
2472
ni = ni->target_jmp; /* end_block or Op_atexit */
2473
} else if (inrec(curfile) == 0)
2474
break; /* prog block */
2476
ni = POP_CODE(); /* Op_newfile */
2480
if (currule != Rule && currule != BEGINFILE)
2481
fatal(_("`nextfile' cannot be called from a `%s' rule"),
2483
(void) nextfile(&curfile, TRUE);
2484
if (currule == BEGINFILE) {
2488
case Node_instruction:
2490
if (ni->opcode == Op_newfile
2491
|| ni->opcode == Op_K_getline
2493
in_loop = r->loop_count;
2500
(void) restore_frame(r);
2501
source = frame_ptr->vname;
2515
unwind_stack(stack_bottom + 1); /* don't pop Op_newfile */
2517
JUMPTO(pc->target_endfile); /* endfile block */
2522
exit_val = (int) x1;
2525
exit_val = EXIT_SUCCESS;
2526
else if (exit_val == 1)
2527
exit_val = EXIT_FAILURE;
2529
just pass anything else on through */
2531
/* jump to either the first end_block instruction
2534
unwind_stack(stack_bottom);
2536
JUMPTO(pc->target_jmp);
2539
if (currule != Rule)
2540
fatal(_("`next' cannot be called from a `%s' rule"), ruletab[currule]);
2542
/* jump to Op_get_record */
2543
unwind_stack(stack_bottom + 1); /* don't pop Op_newfile */
2545
JUMPTO(pc->target_jmp);
2548
#if defined(GAWKDEBUG) || defined(ARRAYDEBUG)
2549
if (last_was_stopme)
2550
last_was_stopme = FALSE;
2560
if (pc->triggered) /* evaluate right expression */
2561
JUMPTO(pc->target_jmp);
2563
evaluate left expression */
2571
t1 = TOP_SCALAR(); /* from right hand side expression */
2572
di = (eval_condition(t1) != 0);
2575
ip = pc->line_range; /* Op_line_range */
2577
if (! ip->triggered && di) {
2578
/* not already triggered and left expression is TRUE */
2580
ip->triggered = TRUE;
2581
JUMPTO(ip->target_jmp); /* evaluate right expression */
2584
result = ip->triggered || di;
2585
ip->triggered ^= di; /* update triggered flag */
2586
r = make_number((AWKNUM) result); /* final value of condition pair */
2588
JUMPTO(pc->target_jmp);
2592
INCREMENT(pc->exec_count);
2602
fatal(_("Sorry, don't know how to interpret `%s'"), opcode2str(pc->opcode));