svn commit: trunk/busybox/shell: hush_test/hush-misc

vda at busybox.net vda at busybox.net
Tue Jul 29 11:37:16 UTC 2008


Author: vda
Date: 2008-07-29 04:37:15 -0700 (Tue, 29 Jul 2008)
New Revision: 22981

Log:
hush: fix break'ing out of {} and () groups; with testcase

function                                             old     new   delta
builtin_break                                         93     129     +36
builtin_continue                                      21      47     +26
run_list                                            1973    1976      +3



Added:
   trunk/busybox/shell/hush_test/hush-misc/break5.right
   trunk/busybox/shell/hush_test/hush-misc/break5.tests

Modified:
   trunk/busybox/shell/hush.c


Changeset:
Modified: trunk/busybox/shell/hush.c
===================================================================
--- trunk/busybox/shell/hush.c	2008-07-29 11:10:01 UTC (rev 22980)
+++ trunk/busybox/shell/hush.c	2008-07-29 11:37:15 UTC (rev 22981)
@@ -446,6 +446,7 @@
 	int global_argc;
 #if ENABLE_HUSH_LOOPS
 	unsigned depth_break_continue;
+	unsigned depth_of_loop;
 #endif
 	pid_t last_bg_pid;
 	const char *ifs;
@@ -496,6 +497,7 @@
 #define ifs              (G.ifs             )
 #define flag_break_continue  (G.flag_break_continue )
 #define depth_break_continue (G.depth_break_continue)
+#define depth_of_loop    (G.depth_of_loop   )
 #define fake_mode        (G.fake_mode       )
 #define cwd              (G.cwd             )
 #define last_bg_pid      (G.last_bg_pid     )
@@ -2153,13 +2155,14 @@
 		if (rword == RES_WHILE || rword == RES_UNTIL || rword == RES_FOR) {
 			/* start of a loop: remember where loop starts */
 			loop_top = pi;
+			depth_of_loop++;
 		}
 #endif
 		if (rword == skip_more_for_this_rword && flag_skip) {
+			if (pi->followup == PIPE_SEQ)
+				flag_skip = 0;
 			/* it is "<false> && CMD" or "<true> || CMD"
 			 * and we should not execute CMD */
-			if (pi->followup == PIPE_SEQ)
-				flag_skip = 0;
 			continue;
 		}
 		flag_skip = 1;
@@ -2277,15 +2280,13 @@
 						depth_break_continue--;
 						if (depth_break_continue == 0)
 							flag_break_continue = 0;
-						if (depth_break_continue != 0 || fbc == BC_BREAK)
-							goto check_jobs_and_break;
-						/* "continue": simulate end of loop */
-						rword = RES_DONE;
-						continue;
-					}		
-					flag_break_continue = 0;
-					bb_error_msg("break/continue: only meaningful in a loop");
-					/* bash compat: exit code is still 0 */
+						/* else: e.g. "continue 2" should *break* once, *then* continue */
+					} /* else: "while... do... { we are here (innermost list is not a loop!) };...done" */
+					if (depth_break_continue != 0 || fbc == BC_BREAK)
+						goto check_jobs_and_break;
+					/* "continue": simulate end of loop */
+					rword = RES_DONE;
+					continue;
 				}
 #endif
 			} else if (pi->followup == PIPE_BG) {
@@ -2358,6 +2359,8 @@
 #endif
 	debug_printf_exec("run_list lvl %d return %d\n", run_list_level + 1, rcode);
 #if ENABLE_HUSH_LOOPS
+	if (loop_top)
+		depth_of_loop--;
 	free(for_list);
 #endif
 #if ENABLE_HUSH_CASE
@@ -4554,6 +4557,10 @@
 #if ENABLE_HUSH_LOOPS
 static int builtin_break(char **argv)
 {
+	if (depth_of_loop == 0) {
+		bb_error_msg("%s: only meaningful in a loop", "break");
+		return EXIT_SUCCESS; /* bash compat */
+	}
 	flag_break_continue++; /* BC_BREAK = 1 */
 	depth_break_continue = 1;
 	if (argv[1]) {
@@ -4564,12 +4571,18 @@
 			depth_break_continue = UINT_MAX;
 		}
 	}
+	if (depth_of_loop > depth_break_continue)
+		depth_break_continue = depth_of_loop;
 	return EXIT_SUCCESS;
 }
 
 static int builtin_continue(char **argv)
 {
-	flag_break_continue++; /* BC_CONTINUE = 2 = 1+1 */
-	return builtin_break(argv);
+	if (depth_of_loop) {
+		flag_break_continue++; /* BC_CONTINUE = 2 = 1+1 */
+		return builtin_break(argv);
+	}
+	bb_error_msg("%s: only meaningful in a loop", "continue");
+	return EXIT_SUCCESS; /* bash compat */
 }
 #endif

Added: trunk/busybox/shell/hush_test/hush-misc/break5.right
===================================================================
--- trunk/busybox/shell/hush_test/hush-misc/break5.right	                        (rev 0)
+++ trunk/busybox/shell/hush_test/hush-misc/break5.right	2008-07-29 11:37:15 UTC (rev 22981)
@@ -0,0 +1,13 @@
+A
+B
+0
+A:a
+B
+D
+A:b
+B
+D
+A:c
+B
+D
+0

Added: trunk/busybox/shell/hush_test/hush-misc/break5.tests
===================================================================
--- trunk/busybox/shell/hush_test/hush-misc/break5.tests	                        (rev 0)
+++ trunk/busybox/shell/hush_test/hush-misc/break5.tests	2008-07-29 11:37:15 UTC (rev 22981)
@@ -0,0 +1,4 @@
+while true; do echo A; { echo B; break; echo C; }; echo D; done
+echo $?
+for v in a b c; do echo A:$v; (echo B; break; echo C); echo D; done
+echo $?


Property changes on: trunk/busybox/shell/hush_test/hush-misc/break5.tests
___________________________________________________________________
Name: svn:executable
   + *




More information about the busybox-cvs mailing list