awk: fix beavior of "exit" without parameter

function                                             old     new   delta
evaluate                                            3336    3339      +3
awk_exit                                              93      94      +1
awk_main                                             829     827      -2
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/1 up/down: 4/-2)                Total: 2 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2021-07-02 22:28:51 +02:00
parent 8bb03da906
commit 4d902ea9de
2 changed files with 27 additions and 18 deletions

View File

@ -578,6 +578,8 @@ struct globals2 {
rstream next_input_file__rsm; rstream next_input_file__rsm;
smallint next_input_file__files_happen; smallint next_input_file__files_happen;
smalluint exitcode;
unsigned evaluate__seed; unsigned evaluate__seed;
var *evaluate__fnargs; var *evaluate__fnargs;
regex_t evaluate__sreg; regex_t evaluate__sreg;
@ -655,7 +657,7 @@ static const char EMSG_UNDEF_FUNC[] ALIGN1 = "Call to undefined function";
static const char EMSG_NO_MATH[] ALIGN1 = "Math support is not compiled in"; static const char EMSG_NO_MATH[] ALIGN1 = "Math support is not compiled in";
static const char EMSG_NEGATIVE_FIELD[] ALIGN1 = "Access to negative field"; static const char EMSG_NEGATIVE_FIELD[] ALIGN1 = "Access to negative field";
static int awk_exit(int) NORETURN; static int awk_exit(void) NORETURN;
static void syntax_error(const char *message) NORETURN; static void syntax_error(const char *message) NORETURN;
static void syntax_error(const char *message) static void syntax_error(const char *message)
@ -2779,7 +2781,6 @@ static var *evaluate(node *op, var *res)
if ((opinfo & OF_REQUIRED) && !op1) if ((opinfo & OF_REQUIRED) && !op1)
syntax_error(EMSG_TOO_FEW_ARGS); syntax_error(EMSG_TOO_FEW_ARGS);
L.v = evaluate(op1, TMPVAR0); L.v = evaluate(op1, TMPVAR0);
}
if (opinfo & OF_STR1) { if (opinfo & OF_STR1) {
L.s = getvar_s(L.v); L.s = getvar_s(L.v);
debug_printf_eval("L.s:'%s'\n", L.s); debug_printf_eval("L.s:'%s'\n", L.s);
@ -2788,6 +2789,7 @@ static var *evaluate(node *op, var *res)
L_d = getvar_i(L.v); L_d = getvar_i(L.v);
debug_printf_eval("L_d:%f\n", L_d); debug_printf_eval("L_d:%f\n", L_d);
} }
}
/* NB: Must get string/numeric values of L (done above) /* NB: Must get string/numeric values of L (done above)
* _before_ evaluate()'ing R.v: if both L and R are $NNNs, * _before_ evaluate()'ing R.v: if both L and R are $NNNs,
* and right one is large, then L.v points to Fields[NNN1], * and right one is large, then L.v points to Fields[NNN1],
@ -2799,11 +2801,11 @@ static var *evaluate(node *op, var *res)
R.v = evaluate(op->r.n, TMPVAR1); R.v = evaluate(op->r.n, TMPVAR1);
//TODO: L.v may be invalid now, set L.v to NULL to catch bugs? //TODO: L.v may be invalid now, set L.v to NULL to catch bugs?
//L.v = NULL; //L.v = NULL;
}
if (opinfo & OF_STR2) { if (opinfo & OF_STR2) {
R.s = getvar_s(R.v); R.s = getvar_s(R.v);
debug_printf_eval("R.s:'%s'\n", R.s); debug_printf_eval("R.s:'%s'\n", R.s);
} }
}
debug_printf_eval("switch(0x%x)\n", XC(opinfo & OPCLSMASK)); debug_printf_eval("switch(0x%x)\n", XC(opinfo & OPCLSMASK));
switch (XC(opinfo & OPCLSMASK)) { switch (XC(opinfo & OPCLSMASK)) {
@ -2955,7 +2957,9 @@ static var *evaluate(node *op, var *res)
case XC( OC_EXIT ): case XC( OC_EXIT ):
debug_printf_eval("EXIT\n"); debug_printf_eval("EXIT\n");
awk_exit(L_d); if (op1)
G.exitcode = (int)L_d;
awk_exit();
/* -- recursive node type -- */ /* -- recursive node type -- */
@ -3414,7 +3418,7 @@ static var *evaluate(node *op, var *res)
/* -------- main & co. -------- */ /* -------- main & co. -------- */
static int awk_exit(int r) static int awk_exit(void)
{ {
unsigned i; unsigned i;
@ -3435,7 +3439,7 @@ static int awk_exit(int r)
} }
} }
exit(r); exit(G.exitcode);
} }
int awk_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int awk_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
@ -3560,7 +3564,7 @@ int awk_main(int argc UNUSED_PARAM, char **argv)
evaluate(beginseq.first, &G.main__tmpvar); evaluate(beginseq.first, &G.main__tmpvar);
if (!mainseq.first && !endseq.first) if (!mainseq.first && !endseq.first)
awk_exit(EXIT_SUCCESS); awk_exit();
/* input file could already be opened in BEGIN block */ /* input file could already be opened in BEGIN block */
if (!iF) if (!iF)
@ -3587,6 +3591,6 @@ int awk_main(int argc UNUSED_PARAM, char **argv)
iF = next_input_file(); iF = next_input_file();
} }
awk_exit(EXIT_SUCCESS); awk_exit();
/*return 0;*/ /*return 0;*/
} }

View File

@ -445,4 +445,9 @@ testing 'awk $NF is empty' \
'' \ '' \
'a=====123=' 'a=====123='
testing "awk exit N propagates through END's exit" \
"awk 'BEGIN { exit 42 } END { exit }'; echo \$?" \
"42\n" \
'' ''
exit $FAILCOUNT exit $FAILCOUNT