From 6824298ab4d3da40763af4d2d466a72745b8b593 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 25 May 2023 14:22:10 +0200 Subject: hush: fix ELIF cmd1;cmd2 THEN ... not executing cmd2, closes 15571 function old new delta run_list 1012 1024 +12 Signed-off-by: Denys Vlasenko --- shell/ash_test/ash-misc/elif1.right | 4 ++++ shell/ash_test/ash-misc/elif1.tests | 6 ++++++ shell/ash_test/ash-misc/elif2.right | 2 ++ shell/ash_test/ash-misc/elif2.tests | 8 ++++++++ shell/hush.c | 24 ++++++++++++++++-------- shell/hush_test/hush-misc/elif1.right | 4 ++++ shell/hush_test/hush-misc/elif1.tests | 6 ++++++ shell/hush_test/hush-misc/elif2.right | 2 ++ shell/hush_test/hush-misc/elif2.tests | 8 ++++++++ 9 files changed, 56 insertions(+), 8 deletions(-) create mode 100644 shell/ash_test/ash-misc/elif1.right create mode 100755 shell/ash_test/ash-misc/elif1.tests create mode 100644 shell/ash_test/ash-misc/elif2.right create mode 100755 shell/ash_test/ash-misc/elif2.tests create mode 100644 shell/hush_test/hush-misc/elif1.right create mode 100755 shell/hush_test/hush-misc/elif1.tests create mode 100644 shell/hush_test/hush-misc/elif2.right create mode 100755 shell/hush_test/hush-misc/elif2.tests (limited to 'shell') diff --git a/shell/ash_test/ash-misc/elif1.right b/shell/ash_test/ash-misc/elif1.right new file mode 100644 index 000000000..36dc59fed --- /dev/null +++ b/shell/ash_test/ash-misc/elif1.right @@ -0,0 +1,4 @@ +ELIF1 +ELIF2 +ELIF THEN +Ok:0 diff --git a/shell/ash_test/ash-misc/elif1.tests b/shell/ash_test/ash-misc/elif1.tests new file mode 100755 index 000000000..77b8a25ea --- /dev/null +++ b/shell/ash_test/ash-misc/elif1.tests @@ -0,0 +1,6 @@ +if false; then + : +elif echo 'ELIF1'; echo 'ELIF2'; then + echo "ELIF THEN" +fi +echo "Ok:$?" diff --git a/shell/ash_test/ash-misc/elif2.right b/shell/ash_test/ash-misc/elif2.right new file mode 100644 index 000000000..8f2851f91 --- /dev/null +++ b/shell/ash_test/ash-misc/elif2.right @@ -0,0 +1,2 @@ +THEN +Ok:0 diff --git a/shell/ash_test/ash-misc/elif2.tests b/shell/ash_test/ash-misc/elif2.tests new file mode 100755 index 000000000..3e5876f05 --- /dev/null +++ b/shell/ash_test/ash-misc/elif2.tests @@ -0,0 +1,8 @@ +if true; then + echo "THEN" +elif echo "ELIF false"; false; then + echo "ELIF THEN" +else + echo "ELSE" +fi +echo "Ok:$?" diff --git a/shell/hush.c b/shell/hush.c index 810dafd35..1f7b58d4f 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -9758,7 +9758,7 @@ static int run_list(struct pipe *pi) smallint last_rword; /* ditto */ #endif - debug_printf_exec("run_list start lvl %d\n", G.run_list_level); + debug_printf_exec("run_list lvl %d start\n", G.run_list_level); debug_enter(); #if ENABLE_HUSH_LOOPS @@ -9817,7 +9817,7 @@ static int run_list(struct pipe *pi) break; IF_HAS_KEYWORDS(rword = pi->res_word;) - debug_printf_exec(": rword=%d cond_code=%d last_rword=%d\n", + debug_printf_exec(": rword:%d cond_code:%d last_rword:%d\n", rword, cond_code, last_rword); sv_errexit_depth = G.errexit_depth; @@ -9851,23 +9851,29 @@ static int run_list(struct pipe *pi) } } last_followup = pi->followup; - IF_HAS_KEYWORDS(last_rword = rword;) #if ENABLE_HUSH_IF - if (cond_code) { + if (cond_code != 0) { if (rword == RES_THEN) { /* if false; then ... fi has exitcode 0! */ G.last_exitcode = rcode = EXIT_SUCCESS; /* "if THEN cmd": skip cmd */ + debug_printf_exec("skipped THEN cmd because IF condition was false\n"); + last_rword = rword; continue; } } else { - if (rword == RES_ELSE || rword == RES_ELIF) { + if (rword == RES_ELSE + || (rword == RES_ELIF && last_rword != RES_ELIF) + ) { /* "if then ... ELSE/ELIF cmd": * skip cmd and all following ones */ + debug_printf_exec("skipped ELSE/ELIF branch because IF condition was true\n"); break; } + //if (rword == RES_THEN): "if THEN cmd", run cmd (fall through) } #endif + IF_HAS_KEYWORDS(last_rword = rword;) #if ENABLE_HUSH_LOOPS if (rword == RES_FOR) { /* && pi->num_cmds - always == 1 */ if (!for_lcur) { @@ -9943,7 +9949,7 @@ static int run_list(struct pipe *pi) ); /* TODO: which FNM_xxx flags to use? */ cond_code = (fnmatch(pattern, case_word, /*flags:*/ 0) != 0); - debug_printf_exec("fnmatch(pattern:'%s',str:'%s'):%d\n", + debug_printf_exec("cond_code=fnmatch(pattern:'%s',str:'%s'):%d\n", pattern, case_word, cond_code); free(pattern); if (cond_code == 0) { @@ -10069,8 +10075,10 @@ static int run_list(struct pipe *pi) /* Analyze how result affects subsequent commands */ #if ENABLE_HUSH_IF - if (rword == RES_IF || rword == RES_ELIF) + if (rword == RES_IF || rword == RES_ELIF) { + debug_printf_exec("cond_code=rcode:%d\n", rcode); cond_code = rcode; + } #endif check_jobs_and_continue: checkjobs(NULL, 0 /*(no pid to wait for)*/); @@ -10111,7 +10119,7 @@ static int run_list(struct pipe *pi) free(case_word); #endif debug_leave(); - debug_printf_exec("run_list lvl %d return %d\n", G.run_list_level + 1, rcode); + debug_printf_exec("run_list lvl %d return %d\n", G.run_list_level, rcode); return rcode; } diff --git a/shell/hush_test/hush-misc/elif1.right b/shell/hush_test/hush-misc/elif1.right new file mode 100644 index 000000000..36dc59fed --- /dev/null +++ b/shell/hush_test/hush-misc/elif1.right @@ -0,0 +1,4 @@ +ELIF1 +ELIF2 +ELIF THEN +Ok:0 diff --git a/shell/hush_test/hush-misc/elif1.tests b/shell/hush_test/hush-misc/elif1.tests new file mode 100755 index 000000000..77b8a25ea --- /dev/null +++ b/shell/hush_test/hush-misc/elif1.tests @@ -0,0 +1,6 @@ +if false; then + : +elif echo 'ELIF1'; echo 'ELIF2'; then + echo "ELIF THEN" +fi +echo "Ok:$?" diff --git a/shell/hush_test/hush-misc/elif2.right b/shell/hush_test/hush-misc/elif2.right new file mode 100644 index 000000000..8f2851f91 --- /dev/null +++ b/shell/hush_test/hush-misc/elif2.right @@ -0,0 +1,2 @@ +THEN +Ok:0 diff --git a/shell/hush_test/hush-misc/elif2.tests b/shell/hush_test/hush-misc/elif2.tests new file mode 100755 index 000000000..3e5876f05 --- /dev/null +++ b/shell/hush_test/hush-misc/elif2.tests @@ -0,0 +1,8 @@ +if true; then + echo "THEN" +elif echo "ELIF false"; false; then + echo "ELIF THEN" +else + echo "ELSE" +fi +echo "Ok:$?" -- cgit v1.2.3-55-g6feb From b5be8da350b59ddc1925c485f2acb9c8f5b79b7e Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 25 May 2023 15:24:56 +0200 Subject: hush: make "false" built-in function old new delta bltins1 384 396 +12 builtin_false - 6 +6 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 1/0 up/down: 18/0) Total: 18 bytes Signed-off-by: Denys Vlasenko --- shell/hush.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'shell') diff --git a/shell/hush.c b/shell/hush.c index 1f7b58d4f..cdaa67a3b 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -1061,6 +1061,7 @@ static int builtin_export(char **argv) FAST_FUNC; #if ENABLE_HUSH_READONLY static int builtin_readonly(char **argv) FAST_FUNC; #endif +static int builtin_false(char **argv) FAST_FUNC; #if ENABLE_HUSH_JOB static int builtin_fg_bg(char **argv) FAST_FUNC; static int builtin_jobs(char **argv) FAST_FUNC; @@ -1161,6 +1162,7 @@ static const struct built_in_command bltins1[] ALIGN_PTR = { #if ENABLE_HUSH_EXPORT BLTIN("export" , builtin_export , "Set environment variables"), #endif + BLTIN("false" , builtin_false , NULL), #if ENABLE_HUSH_JOB BLTIN("fg" , builtin_fg_bg , "Bring job to foreground"), #endif @@ -10831,6 +10833,11 @@ static int FAST_FUNC builtin_true(char **argv UNUSED_PARAM) return 0; } +static int FAST_FUNC builtin_false(char **argv UNUSED_PARAM) +{ + return 1; +} + #if ENABLE_HUSH_TEST || ENABLE_HUSH_ECHO || ENABLE_HUSH_PRINTF || ENABLE_HUSH_KILL static NOINLINE int run_applet_main(char **argv, int (*applet_main_func)(int argc, char **argv)) { -- cgit v1.2.3-55-g6feb