2
2
* interpret.h --- run a list of instructions.
6
* Copyright (C) 1986, 1988, 1989, 1991-2023,
7
* the Free Software Foundation, Inc.
6
* Copyright (C) 1986, 1988, 1989, 1991-2013 the Free Software Foundation, Inc.
9
8
* This file is part of GAWK, the GNU implementation of the
10
9
* AWK Programming Language.
12
11
* GAWK is free software; you can redistribute it and/or modify
13
12
* it under the terms of the GNU General Public License as published by
14
13
* the Free Software Foundation; either version 3 of the License, or
15
14
* (at your option) any later version.
17
16
* GAWK is distributed in the hope that it will be useful,
18
17
* but WITHOUT ANY WARRANTY; without even the implied warranty of
19
18
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20
19
* GNU General Public License for more details.
22
21
* You should have received a copy of the GNU General Public License
23
22
* along with this program; if not, write to the Free Software
24
23
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
28
* If "r" is a field, valref should normally be > 1, because the field is
29
* created initially with valref 1, and valref should be bumped when it is
30
* pushed onto the stack by Op_field_spec. On the other hand, if we are
31
* assigning to $n, then Op_store_field calls unref(*lhs) before assigning
32
* the new value, so that decrements valref. So if the RHS is a field with
33
* valref 1, that effectively means that this is an assignment like "$n = $n",
34
* so a no-op, other than triggering $0 reconstitution.
37
// not a macro so we can step into it with a debugger
38
#ifndef UNFIELD_DEFINED
39
#define UNFIELD_DEFINED 1
41
unfield(NODE **l, NODE **r)
43
/* if was a field, turn it into a var */
44
if (((*r)->flags & MALLOC) != 0 || (*r)->valref == 1) {
52
#define UNFIELD(l, r) unfield(& (l), & (r))
56
28
r_interpret(INSTRUCTION *code)
106
fprintf(stderr, "+ %s\n", opcode2str(op));
75
switch ((op = pc->opcode)) {
112
currule = pc->in_rule; /* for use in Op_K_next, Op_K_nextfile, Op_K_getline */
113
// 8/2020: See node BEGINFILE/ENDFILE in the manual. We clear the record
114
// since conceptually we are before reading a new record from the
115
// upcoming file but haven't read it yet.
116
if (currule == BEGINFILE)
117
set_record("", 0, NULL);
77
currule = pc->in_rule; /* for sole use in Op_K_next, Op_K_nextfile, Op_K_getline */
119
78
/* fall through */
121
80
source = pc->source_file;
140
98
* and pipes, in that it doesn't affect their exit status.
141
99
* So we no longer do either.
143
(void) close_io(& stdio_problem, & got_EPIPE);
101
(void) close_io(& stdio_problem);
145
103
* However, we do want to exit non-zero if there was a problem
146
104
* with stdout/stderr, so we reinstate a slightly different
170
125
trans = dgettext(TEXTDOMAIN, orig);
171
126
m->stptr[m->stlen] = save;
172
if (trans != orig) // got a translation
173
m = make_string(trans, strlen(trans));
127
m = make_string(trans, strlen(trans));
213
164
case Node_var_new:
214
165
uninitialized_scalar:
217
_("reference to uninitialized argument `%s'") :
218
_("reference to uninitialized variable `%s'"),
221
if (op != Op_push_arg_untyped) {
222
// convert very original untyped to scalar
224
m->var_value = dupnode(Nnull_string);
225
m->flags &= ~(MPFN | MPZN);
227
// set up local param by value
228
m = dupnode(Nnull_string);
238
_("reference to uninitialized argument `%s'") :
239
_("reference to uninitialized variable `%s'"),
242
if (op != Op_push_arg_untyped) {
243
// convert very original untyped to scalar
245
m->var_value = dupnode(Nnull_string);
246
m->flags &= ~(MPFN | MPZN);
248
// set up local param by value
250
m = dupnode(Nnull_string);
167
m->var_value = dupnode(Nnull_string);
170
_("reference to uninitialized argument `%s'") :
171
_("reference to uninitialized variable `%s'"),
173
m = dupnode(Nnull_string);
256
177
case Node_var_array:
257
if (op == Op_push_arg || op == Op_push_arg_untyped)
178
if (op == Op_push_arg)
260
181
fatal(_("attempt to use array `%s' in a scalar context"),
290
212
case Op_subscript:
291
213
t2 = mk_sub(pc->sub_count);
292
t1 = POP_ARRAY(false);
294
if (in_array(t1, t2) == NULL) {
216
if (do_lint && in_array(t1, t2) == NULL) {
295
217
t2 = force_string(t2);
297
if (t1 == func_table) {
298
fatal(_("reference to uninitialized element `%s[\"%.*s\"] is not allowed'"),
299
"FUNCTAB", (int) t2->stlen, t2->stptr);
300
} else if (t1 == symbol_table) {
301
fatal(_("reference to uninitialized element `%s[\"%.*s\"] is not allowed'"),
302
"SYMTAB", (int) t2->stlen, t2->stptr);
303
} else if (do_lint) {
304
lintwarn(_("reference to uninitialized element `%s[\"%.*s\"]'"),
305
array_vname(t1), (int) t2->stlen, t2->stptr);
307
lintwarn(_("subscript of array `%s' is null string"), array_vname(t1));
218
lintwarn(_("reference to uninitialized element `%s[\"%.*s\"]'"),
219
array_vname(t1), (int) t2->stlen, t2->stptr);
221
lintwarn(_("subscript of array `%s' is null string"), array_vname(t1));
311
// continue the regular processing
313
224
/* for FUNCTAB, get the name as the element value */
314
225
if (t1 == func_table) {
315
226
static bool warned = false;
317
if (do_lint_extensions && ! warned) {
228
if (do_lint && ! warned) {
319
230
lintwarn(_("FUNCTAB is a gawk extension"));
331
242
/* for SYMTAB, step through to the actual variable */
332
243
if (t1 == symbol_table) {
333
244
static bool warned = false;
335
if (do_lint_extensions && ! warned) {
246
if (do_lint && ! warned) {
337
248
lintwarn(_("SYMTAB is a gawk extension"));
339
250
if (r->type == Node_var)
340
251
r = r->var_value;
341
else if (r->type == Node_var_new) {
342
// variable may exist but have never been set.
343
r->var_value = dupnode(Nnull_string);
348
if (r->type == Node_val
349
|| r->type == Node_var
350
|| r->type == Node_elem_new)
254
if (r->type == Node_val)
355
259
case Op_sub_array:
356
260
t2 = mk_sub(pc->sub_count);
357
t1 = POP_ARRAY(false);
358
262
r = in_array(t1, t2);
361
t2 = force_string(t2);
363
if (t1 == func_table) {
364
fatal(_("reference to uninitialized element `%s[\"%.*s\"] is not allowed'"),
365
"FUNCTAB", (int) t2->stlen, t2->stptr);
366
} else if (t1 == symbol_table) {
367
fatal(_("reference to uninitialized element `%s[\"%.*s\"] is not allowed'"),
368
"SYMTAB", (int) t2->stlen, t2->stptr);
369
} else if (do_lint) {
370
lintwarn(_("reference to uninitialized element `%s[\"%.*s\"]'"),
371
array_vname(t1), (int) t2->stlen, t2->stptr);
373
lintwarn(_("subscript of array `%s' is null string"), array_vname(t1));
378
264
r = make_array();
379
265
r->parent_array = t1;
380
t2 = force_string(t2);
381
r->vname = estrdup(t2->stptr, t2->stlen); /* the subscript in parent array */
382
assoc_set(t1, t2, r);
383
} else if (r->type == Node_elem_new) {
384
r = force_array(r, false);
385
r->parent_array = t1;
386
t2 = force_string(t2);
387
r->vname = estrdup(t2->stptr, t2->stlen); /* the subscript in parent array */
266
lhs = assoc_lookup(t1, t2);
269
t2 = force_string(t2);
270
r->vname = estrdup(t2->stptr, t2->stlen); /* the subscript in parent array */
272
/* execute post-assignment routine if any */
273
if (t1->astore != NULL)
274
(*t1->astore)(t1, t2);
388
275
} else if (r->type != Node_var_array) {
389
276
t2 = force_string(t2);
390
277
fatal(_("attempt to use scalar `%s[\"%.*s\"]' as an array"),
391
278
array_vname(t1), (int) t2->stlen, t2->stptr);
398
285
case Op_subscript_lhs:
399
286
t2 = mk_sub(pc->sub_count);
400
t1 = POP_ARRAY(false);
401
288
if (do_lint && in_array(t1, t2) == NULL) {
402
289
t2 = force_string(t2);
403
if (pc->do_reference)
290
if (pc->do_reference)
404
291
lintwarn(_("reference to uninitialized element `%s[\"%.*s\"]'"),
405
292
array_vname(t1), (int) t2->stlen, t2->stptr);
406
293
if (t2->stlen == 0)
421
308
* be stored in SYMTAB:
422
309
* 1. Variables that don"t yet have a value (Node_var_new)
423
310
* 2. Variables that have a value (Node_var)
424
* 3. Values that awk code stuck into SYMTAB not related to variables (Node_val)
311
* 3. Values that awk code stuck into SYMTAB not related to variables (Node_value)
425
312
* For 1, since we are giving it a value, we have to change the type to Node_var.
426
313
* For 1 and 2, we have to step through the Node_var to get to the value.
427
* For 3, we fatal out. This avoids confusion on things like
428
* SYMTAB["a foo"] = 42 # variable with a space in its name?
314
* For 3, we just us the value we got from assoc_lookup(), above.
430
316
if (t1 == func_table)
431
317
fatal(_("cannot assign to elements of FUNCTAB"));
432
else if (t1 == symbol_table) {
433
if (( (*lhs)->type == Node_var
318
else if ( t1 == symbol_table
319
&& ( (*lhs)->type == Node_var
434
320
|| (*lhs)->type == Node_var_new)) {
435
update_global_values(); /* make sure stuff like NF, NR, are up to date */
436
(*lhs)->type = Node_var; /* in case was Node_var_new */
437
lhs = & ((*lhs)->var_value); /* extra level of indirection */
439
fatal(_("cannot assign to arbitrary elements of SYMTAB"));
321
update_global_values(); /* make sure stuff like NF, NR, are up to date */
322
(*lhs)->type = Node_var; /* in case was Node_var_new */
323
lhs = & ((*lhs)->var_value); /* extra level of indirection */
442
326
assert(set_idx == NULL);
476
359
lintwarn(_("assignment used in conditional context"));
363
lintwarn(_("statement has no effect"));
480
cant_happen("unexpected lint type value %d", (int) pc->lint_type);
486
// no need to check do_lint, this opcode won't
487
// be generated if that's not true
489
t2 = fixtype(PEEK(1));
490
if ((t1->flags & (STRING|USER_INPUT)) == STRING
491
&& (t2->flags & (STRING|USER_INPUT)) == STRING)
492
lintwarn(_("operator `+' used on two string values"));
496
373
case Op_K_continue:
548
r = node_Boolean[cmp_scalars(SCALAR_EQ)];
425
r = node_Boolean[cmp_scalars() == 0];
553
430
case Op_notequal:
554
r = node_Boolean[cmp_scalars(SCALAR_NEQ)];
431
r = node_Boolean[cmp_scalars() != 0];
560
r = node_Boolean[cmp_scalars(SCALAR_LT)];
437
r = node_Boolean[cmp_scalars() < 0];
566
r = node_Boolean[cmp_scalars(SCALAR_GT)];
443
r = node_Boolean[cmp_scalars() > 0];
572
r = node_Boolean[cmp_scalars(SCALAR_LE)];
449
r = node_Boolean[cmp_scalars() <= 0];
578
r = node_Boolean[cmp_scalars(SCALAR_GE)];
455
r = node_Boolean[cmp_scalars() >= 0];
746
613
* Changing something in FUNCTAB is not allowed.
748
* SYMTAB is a little more messy. Three possibilities for SYMTAB:
615
* SYMTAB is a little more messy. Three kinds of values may
616
* be stored in SYMTAB:
749
617
* 1. Variables that don"t yet have a value (Node_var_new)
750
618
* 2. Variables that have a value (Node_var)
751
* 3. Values that awk code stuck into SYMTAB not related to variables (Node_val)
619
* 3. Values that awk code stuck into SYMTAB not related to variables (Node_value)
752
620
* For 1, since we are giving it a value, we have to change the type to Node_var.
753
621
* For 1 and 2, we have to step through the Node_var to get to the value.
754
* For 3, we fatal out. This avoids confusion on things like
755
* SYMTAB["a foo"] = 42 # variable with a space in its name?
622
* For 3, we just us the value we got from assoc_lookup(), above.
757
624
if (t1 == func_table)
758
625
fatal(_("cannot assign to elements of FUNCTAB"));
759
else if (t1 == symbol_table) {
760
if (( (*lhs)->type == Node_var
626
else if ( t1 == symbol_table
627
&& ( (*lhs)->type == Node_var
761
628
|| (*lhs)->type == Node_var_new)) {
762
update_global_values(); /* make sure stuff like NF, NR, are up to date */
763
(*lhs)->type = Node_var; /* in case was Node_var_new */
764
lhs = & ((*lhs)->var_value); /* extra level of indirection */
766
fatal(_("cannot assign to arbitrary elements of SYMTAB"));
629
(*lhs)->type = Node_var; /* in case was Node_var_new */
630
lhs = & ((*lhs)->var_value); /* extra level of indirection */
773
636
/* execute post-assignment routine if any */
774
637
if (t1->astore != NULL)
782
645
* simple variable assignment optimization,
783
646
* see awkgram.y (optimize_assignment)
786
649
lhs = get_lhs(pc->memory, false);
788
651
r = pc->initval; /* constant initializer */
798
660
case Op_store_field:
799
case Op_store_field_exp:
801
662
/* field assignment optimization,
802
663
* see awkgram.y (optimize_assignment)
807
668
lhs = r_get_field(t1, & assign, false);
811
* N.B. We must call assign() before unref, since
812
* we may need to copy $n values before freeing the
815
673
assert(assign != NULL);
820
/* field variables need the string representation: */
822
if (op == Op_store_field_exp) {
835
684
if (t1 != *lhs) {
843
if (t1 != t2 && t1->valref == 1 && (t1->flags & (MALLOC|MPFN|MPZN)) == MALLOC) {
689
if (t1 != t2 && t1->valref == 1 && (t1->flags & MPFN) == 0) {
844
690
size_t nlen = t1->stlen + t2->stlen;
846
erealloc(t1->stptr, char *, nlen + 1, "r_interpret");
692
erealloc(t1->stptr, char *, nlen + 2, "r_interpret");
847
693
memcpy(t1->stptr + t1->stlen, t2->stptr, t2->stlen);
848
694
t1->stlen = nlen;
849
695
t1->stptr[nlen] = '\0';
850
/* clear flags except WSTRCUR (used below) */
851
t1->flags &= WSTRCUR;
852
/* configure as a string as in make_str_node */
853
t1->flags |= (MALLOC|STRING|STRCUR);
854
t1->stfmt = STFMT_UNUSED;
856
t1->strndmode = MPFR_round_mode;
696
t1->flags &= ~(NUMCUR|NUMBER|NUMINT);
859
699
if ((t1->flags & WSTRCUR) != 0 && (t2->flags & WSTRCUR) != 0) {
860
700
size_t wlen = t1->wstlen + t2->wstlen;
862
702
erealloc(t1->wstptr, wchar_t *,
863
sizeof(wchar_t) * (wlen + 1), "r_interpret");
864
memcpy(t1->wstptr + t1->wstlen, t2->wstptr, t2->wstlen * sizeof(wchar_t));
703
sizeof(wchar_t) * (wlen + 2), "r_interpret");
704
memcpy(t1->wstptr + t1->wstlen, t2->wstptr, t2->wstlen);
865
705
t1->wstlen = wlen;
866
706
t1->wstptr[wlen] = L'\0';
707
t1->flags |= WSTRCUR;
870
size_t nlen = t1->stlen + t2->stlen;
712
size_t nlen = t1->stlen + t2->stlen;
873
emalloc(p, char *, nlen + 1, "r_interpret");
715
emalloc(p, char *, nlen + 2, "r_interpret");
874
716
memcpy(p, t1->stptr, t1->stlen);
875
717
memcpy(p + t1->stlen, t2->stptr, t2->stlen);
876
/* N.B. No NUL-termination required, since make_str_node will do it. */
878
t1 = *lhs = make_str_node(p, nlen, ALREADY_MALLOCED);
719
t1 = *lhs = make_str_node(p, nlen, ALREADY_MALLOCED);
971
808
t2 = TOP_SCALAR(); /* switch expression */
972
809
t2 = force_string(t2);
973
810
rp = re_update(m);
974
di = (research(rp, t2->stptr, 0, t2->stlen, RE_NO_FLAGS) >= 0);
811
di = (research(rp, t2->stptr, 0, t2->stlen,
812
avoid_dfa(m, t2->stptr, t2->stlen)) >= 0);
976
814
t1 = POP_SCALAR(); /* case value */
977
815
t2 = TOP_SCALAR(); /* switch expression */
978
di = (cmp_nodes(t2, t1, true) == 0);
816
di = (cmp_nodes(t2, t1) == 0);
1040
876
if (sort_str != NULL) {
1041
877
sort_str = force_string(sort_str);
1042
if (sort_str->stlen > 0) {
878
if (sort_str->stlen > 0)
1043
879
how_to_sort = sort_str->stptr;
1044
str_terminate(sort_str, save);
1049
882
list = assoc_list(array, how_to_sort, SORTED_IN);
1051
str_restore(sort_str, save);
1095
926
case Op_ext_builtin:
927
case Op_old_ext_builtin:
1097
size_t arg_count = pc->expr_count;
1098
awk_ext_func_t *f = pc[1].c_function;
1099
size_t min_req = f->min_required_args;
1100
size_t max_expect = f->max_expected_args;
929
int arg_count = pc->expr_count;
1101
930
awk_value_t result;
1103
if (arg_count < min_req)
1104
fatal(_("%s: called with %lu arguments, expecting at least %lu"),
1106
(unsigned long) arg_count,
1107
(unsigned long) min_req);
1109
if (do_lint && ! f->suppress_lint && arg_count > max_expect)
1110
lintwarn(_("%s: called with %lu arguments, expecting no more than %lu"),
1112
(unsigned long) arg_count,
1113
(unsigned long) max_expect);
1116
awk_value_t *ef_ret = pc->extfunc(arg_count, & result, f);
1117
r = awk_value_to_node(ef_ret);
933
if (op == Op_ext_builtin)
934
r = awk_value_to_node(pc->extfunc(arg_count, & result));
936
r = pc->builtin(arg_count);
1118
937
(void) POP_CODE();
1119
938
while (arg_count-- > 0) {
1121
if (t1->type == Node_val || t1->type == Node_elem_new)
940
if (t1->type == Node_val)
1124
free_api_string_copies();
1126
if (in_indirect_call) {
1127
// pop function name off the stack
1128
NODE *fname = POP();
1130
in_indirect_call = false;
1157
967
r = POP_STRING();
1158
968
unref(m->re_exp);
1160
} else if (m->type == Node_val) {
1161
assert((m->flags & REGEX) != 0);
1167
974
case Op_match_rec:
1169
976
t1 = *get_field(0, (Func_ptr *) 0);
1171
978
rp = re_update(m);
1172
di = research(rp, t1->stptr, 0, t1->stlen, RE_NO_FLAGS);
980
* Any place where research() is called with a last parameter of
981
* zero, we need to use the avoid_dfa test. This appears here and
982
* in the code for Op_K_case.
984
* A new or improved dfa that distinguishes beginning/end of
985
* string from beginning/end of line will allow us to get rid of
988
* The avoid_dfa() function is in re.c; it is not very smart.
991
di = research(rp, t1->stptr, 0, t1->stlen,
992
avoid_dfa(m, t1->stptr, t1->stlen));
1173
993
di = (di == -1) ^ (op != Op_nomatch);
1174
994
if (op != Op_match_rec) {
1177
if (m->type == Node_dynregex) {
1182
998
r = node_Boolean[di];
1212
1026
fatal(_("indirect function call requires a simple scalar value"));
1214
1028
t1 = force_string(t1);
1215
str_terminate(t1, save);
1216
1029
if (t1->stlen > 0) {
1217
1030
/* retrieve function definition node */
1218
1031
f = pc->func_body;
1219
1032
if (f != NULL && strcmp(f->vname, t1->stptr) == 0) {
1220
1033
/* indirect var hasn't been reassigned */
1222
str_restore(t1, save);
1223
1035
ni = setup_frame(pc);
1224
1036
JUMPTO(ni); /* Op_func */
1226
1038
f = lookup(t1->stptr);
1230
fatal(_("`%s' is not a function, so it cannot be called indirectly"),
1232
} else if (f->type == Node_builtin_func) {
1233
int arg_count = (pc + 1)->expr_count;
1234
builtin_func_t the_func = lookup_builtin(t1->stptr);
1236
assert(the_func != NULL);
1239
if (the_func == (builtin_func_t) do_sub)
1240
r = call_sub(t1->stptr, arg_count);
1241
else if (the_func == do_match)
1242
r = call_match(arg_count);
1243
else if (the_func == do_split || the_func == do_patsplit)
1244
r = call_split_func(t1->stptr, arg_count);
1041
if (f == NULL || f->type != Node_func) {
1042
if (f->type == Node_ext_func || f->type == Node_old_ext_func)
1043
fatal(_("cannot (yet) call extension functions indirectly"));
1246
r = the_func(arg_count);
1247
str_restore(t1, save);
1249
// Normally, setup_frame() handles getting rid of the
1250
// function name. Since we have called the builtin directly,
1251
// we have to manually do this here.
1252
function_name = POP();
1253
DEREF(function_name);
1257
} else if (f->type != Node_func) {
1258
str_restore(t1, save);
1259
if (f->type == Node_ext_func) {
1260
/* code copied from below, keep in sync */
1262
char *fname = pc->func_name;
1263
int arg_count = (pc + 1)->expr_count;
1264
static INSTRUCTION npc[2];
1269
assert(bc->opcode == Op_symbol);
1270
npc[0].opcode = Op_ext_builtin; /* self modifying code */
1271
npc[0].extfunc = bc->extfunc;
1272
npc[0].expr_count = arg_count; /* actual argument count */
1274
npc[1].func_name = fname; /* name of the builtin */
1275
npc[1].c_function = bc->c_function;
1276
in_indirect_call = true;
1280
1045
fatal(_("function called indirectly through `%s' does not exist"),
1283
1048
pc->func_body = f; /* save for next call */
1284
str_restore(t1, save);
1286
1050
ni = setup_frame(pc);
1287
1051
JUMPTO(ni); /* Op_func */
1295
1059
f = pc->func_body;
1296
1060
if (f == NULL) {
1297
1061
f = lookup(pc->func_name);
1298
if (f == NULL || (f->type != Node_func && f->type != Node_ext_func))
1062
if (f == NULL || (f->type != Node_func && f->type != Node_ext_func && f->type != Node_old_ext_func))
1299
1063
fatal(_("function `%s' not defined"), pc->func_name);
1300
1064
pc->func_body = f; /* save for next call */
1303
if (f->type == Node_ext_func) {
1304
/* keep in sync with indirect call code */
1067
if (f->type == Node_ext_func || f->type == Node_old_ext_func) {
1305
1068
INSTRUCTION *bc;
1306
1069
char *fname = pc->func_name;
1307
1070
int arg_count = (pc + 1)->expr_count;
1309
1072
bc = f->code_ptr;
1310
1073
assert(bc->opcode == Op_symbol);
1311
pc->opcode = Op_ext_builtin; /* self modifying code */
1074
if (f->type == Node_ext_func)
1075
pc->opcode = Op_ext_builtin; /* self modifying code */
1077
pc->opcode = Op_old_ext_builtin; /* self modifying code */
1312
1078
pc->extfunc = bc->extfunc;
1313
pc->expr_count = arg_count; /* actual argument count */
1079
pc->expr_count = arg_count; /* actual argument count */
1314
1080
(pc + 1)->func_name = fname; /* name of the builtin */
1315
(pc + 1)->c_function = bc->c_function; /* min and max args */
1081
(pc + 1)->expr_count = bc->expr_count; /* defined max # of arguments */
1321
1087
JUMPTO(ni); /* Op_func */
1324
case Op_K_return_from_eval:
1325
cant_happen("unexpected opcode %s", opcode2str(op));
1328
1090
case Op_K_return:
1329
1091
m = POP_SCALAR(); /* return value */
1331
1093
ni = pop_fcall();
1333
1095
/* put the return value back on stack */
1338
1100
case Op_K_getline_redir:
1339
r = do_getline_redir(pc->into_var, (enum redirval) pc->redir_type);
1101
if ((currule == BEGINFILE || currule == ENDFILE)
1102
&& pc->into_var == false
1103
&& pc->redir_type == redirect_input)
1104
fatal(_("`getline' invalid inside `%s' rule"), ruletab[currule]);
1105
r = do_getline_redir(pc->into_var, pc->redir_type);
1432
if (! inrec(curfile, & errcode)) {
1434
update_ERRNO_int(errcode);
1435
if (do_traditional || ! pc->has_endfile)
1436
fatal(_("error reading input file `%s': %s"),
1198
if (inrec(curfile, & errcode) != 0) {
1199
if (errcode > 0 && (do_traditional || ! pc->has_endfile))
1200
fatal(_("error reading input file `%s': %s"),
1437
1201
curfile->public.name, strerror(errcode));
1473
1236
/* do run ENDFILE block(s) first. */
1475
1238
/* Execution state to return to in Op_after_endfile. */
1476
1239
push_exec_state(ni, currule, source, stack_ptr);
1478
1241
JUMPTO(pc->target_endfile);
1481
1244
Start over with the first rule. */
1483
1246
/* empty the run-time stack to avoid memory leak */
1498
1261
fatal(_("`exit' cannot be called in the current context"));
1500
1263
exiting = true;
1501
if ((t1 = POP_NUMBER()) != Nnull_string) {
1502
exit_val = (int) get_number_si(t1);
1265
exit_val = (int) get_number_si(t1);
1505
exit_val = EXIT_SUCCESS;
1506
else if (exit_val == 1)
1507
exit_val = EXIT_FAILURE;
1509
just pass anything else on through */
1269
exit_val = EXIT_SUCCESS;
1270
else if (exit_val == 1)
1271
exit_val = EXIT_FAILURE;
1273
just pass anything else on through */
1514
1276
if (currule == BEGINFILE || currule == ENDFILE) {