diff --git a/ChangeLog b/ChangeLog index 835596322..5845bb7dc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2010-08-12 BVK Chaitanya + + "continue" command support to GRUB script. + + * script/execute.c (grub_script_execute_cmdwhile): Continue support. + (grub_script_break): Continue support. + * script/main.c (grub_script_init): Register continue command. + (grub_script_fini): Unregister continue command. + + * tests/grub_script_continue.in: New testcase. + * conf/tests.rmk: Rules for new testcase. + 2010-08-12 BVK Chaitanya "break" command support to GRUB script. diff --git a/conf/tests.rmk b/conf/tests.rmk index 8af4207b7..57cae95c5 100644 --- a/conf/tests.rmk +++ b/conf/tests.rmk @@ -77,6 +77,9 @@ grub_script_functions_SOURCES = tests/grub_script_functions.in check_SCRIPTS += grub_script_break grub_script_break_SOURCES = tests/grub_script_break.in +check_SCRIPTS += grub_script_continue +grub_script_continue_SOURCES = tests/grub_script_continue.in + # List of tests to execute on "make check" # SCRIPTED_TESTS = example_scripted_test # SCRIPTED_TESTS += example_grub_script_test @@ -95,6 +98,7 @@ SCRIPTED_TESTS += grub_script_dollar SCRIPTED_TESTS += grub_script_comments SCRIPTED_TESTS += grub_script_functions SCRIPTED_TESTS += grub_script_break +SCRIPTED_TESTS += grub_script_continue # dependencies between tests and testing-tools $(SCRIPTED_TESTS): grub-shell grub-shell-tester diff --git a/script/execute.c b/script/execute.c index bcb3d4017..a44740c30 100644 --- a/script/execute.c +++ b/script/execute.c @@ -30,6 +30,7 @@ is sizeof (int) * 3, and one extra for a possible -ve sign. */ #define ERRNO_DIGITS_MAX (sizeof (int) * 3 + 1) +static unsigned long is_continue; static unsigned long active_loops; static unsigned long active_breaks; @@ -41,8 +42,7 @@ struct grub_script_scope static struct grub_script_scope *scope = 0; grub_err_t -grub_script_break (grub_command_t cmd __attribute__((unused)), - int argc, char *argv[]) +grub_script_break (grub_command_t cmd, int argc, char *argv[]) { char *p = 0; unsigned long count; @@ -54,6 +54,7 @@ grub_script_break (grub_command_t cmd __attribute__((unused)), (*p != '\0')) return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad break"); + is_continue = grub_strcmp (cmd->name, "break") ? 1 : 0; active_breaks = grub_min (active_loops, count); return GRUB_ERR_NONE; } @@ -398,6 +399,7 @@ grub_script_execute_cmdfor (struct grub_script_cmd *cmd) unsigned i; grub_err_t result; struct grub_script_argv argv = { 0, 0 }; + struct grub_script_cmdfor *cmdfor = (struct grub_script_cmdfor *) cmd; if (grub_script_arglist_to_argv (cmdfor->words, &argv)) @@ -407,6 +409,9 @@ grub_script_execute_cmdfor (struct grub_script_cmd *cmd) result = 0; for (i = 0; i < argv.argc; i++) { + if (is_continue && active_breaks == 1) + active_breaks = 0; + if (! active_breaks) { grub_script_env_set (cmdfor->name->str, argv.args[i]); @@ -439,14 +444,17 @@ grub_script_execute_cmdwhile (struct grub_script_cmd *cmd) result = grub_script_execute_cmd (cmdwhile->list); + if (active_breaks == 1 && is_continue) + active_breaks = 0; + if (active_breaks) - { - active_breaks--; - break; - } + break; } while (1); /* XXX Put a check for ^C here */ + if (active_breaks) + active_breaks--; + active_loops--; return result; } diff --git a/script/main.c b/script/main.c index 382b35487..9354f3ed8 100644 --- a/script/main.c +++ b/script/main.c @@ -42,12 +42,15 @@ grub_normal_parse_line (char *line, grub_reader_getline_t getline) } static grub_command_t cmd_break; +static grub_command_t cmd_continue; void grub_script_init (void) { cmd_break = grub_register_command ("break", grub_script_break, N_("[n]"), N_("Exit from loops")); + cmd_continue = grub_register_command ("continue", grub_script_break, + N_("[n]"), N_("Coninue loops")); } void @@ -56,4 +59,9 @@ grub_script_fini (void) if (cmd_break) grub_unregister_command (cmd_break); cmd_break = 0; + + if (cmd_continue) + grub_unregister_command (cmd_continue); + cmd_continue = 0; + } diff --git a/tests/grub_script_continue.in b/tests/grub_script_continue.in new file mode 100644 index 000000000..4c28ce404 --- /dev/null +++ b/tests/grub_script_continue.in @@ -0,0 +1,86 @@ +#! @builddir@/grub-shell-tester +# +# Copyright (C) 2010 Free Software Foundation, Inc. +# +# GRUB is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# GRUB is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GRUB. If not, see . + +# continue without any arguments +for i in 1 2 3 4 5 6 7 8 9 10 +do + if test "$i" = 5 + then + continue + fi + echo $i +done + +# continue with one +for i in 1 2 3 4 5 6 7 8 9 10 +do + if test "$i" = 5 + then + continue 1 + fi + echo $i +done + +# continue with loop count +for i in 1 2 3 4 5 +do + for j in a b c d e f + do + if test "$i" = 3 + then + if test "$j" = d + then + continue 2 + fi + echo "$i $j" + fi + done +done + +# continue into middle loop +for i in 1 2 3 4 5 +do + for j in a b c d e f + do + if test "$i" = 3 + then + if test "$j" = d + then + continue 1 + fi + echo "$i $j" + fi + done +done + +# while and until loops +a= +while test "$a" != "aaaaaaa" +do + a="a$a" + for i in 1 2 3 4 + do + b= + until test "$b" = "bbbbb" + do + b="b$b" + if test "$i" = 3; then echo "continue 2"; continue 2; fi + echo "$a $i $b" + done + done +done +