← Commit list

6824298ab

Denys Vlasenko
Denys Vlasenko
2023-05-25
SUCCESS Duration: 170s

Subject

hush: fix ELIF cmd1;cmd2 THEN ... not executing cmd2, closes 15571

Binary

No binary (build failed)

Architecture & Compiler Flags

Architecture: x86_64-linux-gnu Compiler: gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0

—

Build Log

(log yok)

Commit Diff GitHub →

shell/ash_test/ash-misc/elif1.right+4 -0
@@ -0,0 +1,4 @@
+ELIF1
+ELIF2
+ELIF THEN
+Ok:0
shell/ash_test/ash-misc/elif1.tests+6 -0
@@ -0,0 +1,6 @@
+if false; then
+ :
+elif echo 'ELIF1'; echo 'ELIF2'; then
+ echo "ELIF THEN"
+fi
+echo "Ok:$?"
shell/ash_test/ash-misc/elif2.right+2 -0
@@ -0,0 +1,2 @@
+THEN
+Ok:0
shell/ash_test/ash-misc/elif2.tests+8 -0
@@ -0,0 +1,8 @@
+if true; then
+ echo "THEN"
+elif echo "ELIF false"; false; then
+ echo "ELIF THEN"
+else
+ echo "ELSE"
+fi
+echo "Ok:$?"
shell/hush.c+16 -8
@@ -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 <false> 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 <true> 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 <true> 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;
}
shell/hush_test/hush-misc/elif1.right+4 -0
@@ -0,0 +1,4 @@
+ELIF1
+ELIF2
+ELIF THEN
+Ok:0
shell/hush_test/hush-misc/elif1.tests+6 -0
@@ -0,0 +1,6 @@
+if false; then
+ :
+elif echo 'ELIF1'; echo 'ELIF2'; then
+ echo "ELIF THEN"
+fi
+echo "Ok:$?"
shell/hush_test/hush-misc/elif2.right+2 -0
@@ -0,0 +1,2 @@
+THEN
+Ok:0
shell/hush_test/hush-misc/elif2.tests+8 -0
@@ -0,0 +1,8 @@
+if true; then
+ echo "THEN"
+elif echo "ELIF false"; false; then
+ echo "ELIF THEN"
+else
+ echo "ELSE"
+fi
+echo "Ok:$?"