diff --git a/ChangeLog b/ChangeLog index 5845bb7dc..a8cb8f6e6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2010-08-12 BVK Chaitanya + + "shift" command support to GRUB script. + + * include/grub/script_sh.h (grub_script_shift): New prototype. + * script/execute.c (grub_script_shift): New function. + * script/main.c (grub_script_init): Register shift command. + (grub_script_fini): Unregister shift command. + * util/grub-script-check.c (grub_script_cmd_shift): New function. + + * tests/grub_script_shift.in: New testcase. + * conf/tests.rmk: Rules for new testcase. + 2010-08-12 BVK Chaitanya "continue" command support to GRUB script. diff --git a/conf/tests.rmk b/conf/tests.rmk index 57cae95c5..c14fe0fda 100644 --- a/conf/tests.rmk +++ b/conf/tests.rmk @@ -80,6 +80,9 @@ grub_script_break_SOURCES = tests/grub_script_break.in check_SCRIPTS += grub_script_continue grub_script_continue_SOURCES = tests/grub_script_continue.in +check_SCRIPTS += grub_script_shift +grub_script_shift_SOURCES = tests/grub_script_shift.in + # List of tests to execute on "make check" # SCRIPTED_TESTS = example_scripted_test # SCRIPTED_TESTS += example_grub_script_test @@ -99,6 +102,7 @@ SCRIPTED_TESTS += grub_script_comments SCRIPTED_TESTS += grub_script_functions SCRIPTED_TESTS += grub_script_break SCRIPTED_TESTS += grub_script_continue +SCRIPTED_TESTS += grub_script_shift # dependencies between tests and testing-tools $(SCRIPTED_TESTS): grub-shell grub-shell-tester diff --git a/include/grub/script_sh.h b/include/grub/script_sh.h index 512498a59..77e807360 100644 --- a/include/grub/script_sh.h +++ b/include/grub/script_sh.h @@ -318,6 +318,9 @@ grub_err_t grub_script_execute (struct grub_script *script); /* Break command for loops. */ grub_err_t grub_script_break (grub_command_t cmd, int argc, char *argv[]); +/* SHIFT command for GRUB script. */ +grub_err_t grub_script_shift (grub_command_t cmd, int argc, char *argv[]); + /* This variable points to the parsed command. This is used to communicate with the bison code. */ extern struct grub_script_cmd *grub_script_parsed; diff --git a/script/execute.c b/script/execute.c index a44740c30..26a46b12b 100644 --- a/script/execute.c +++ b/script/execute.c @@ -59,6 +59,37 @@ grub_script_break (grub_command_t cmd, int argc, char *argv[]) return GRUB_ERR_NONE; } +grub_err_t +grub_script_shift (grub_command_t cmd __attribute__((unused)), + int argc, char *argv[]) +{ + char *p = 0; + unsigned long n = 0; + + if (! scope) + return GRUB_ERR_NONE; + + if (argc == 0) + n = 1; + + else if (argc > 1) + return GRUB_ERR_BAD_ARGUMENT; + + else + { + n = grub_strtoul (argv[0], &p, 10); + if (*p != '\0') + return GRUB_ERR_BAD_ARGUMENT; + } + + if (n > scope->argv.argc) + return GRUB_ERR_BAD_ARGUMENT; + + scope->argv.argc -= n; + scope->argv.args += n; + return GRUB_ERR_NONE; +} + static int grub_env_special (const char *name) { @@ -327,7 +358,7 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd) grub_free (assign); grub_snprintf (errnobuf, sizeof (errnobuf), "%d", grub_errno); - grub_env_set ("?", errnobuf); + grub_script_env_set ("?", errnobuf); grub_script_argv_free (&argv); grub_print_error (); diff --git a/script/main.c b/script/main.c index 9354f3ed8..ff714d060 100644 --- a/script/main.c +++ b/script/main.c @@ -43,6 +43,7 @@ grub_normal_parse_line (char *line, grub_reader_getline_t getline) static grub_command_t cmd_break; static grub_command_t cmd_continue; +static grub_command_t cmd_shift; void grub_script_init (void) @@ -50,7 +51,9 @@ 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")); + N_("[n]"), N_("Continue loops")); + cmd_shift = grub_register_command ("shift", grub_script_shift, + N_("[n]"), N_("Shift positional parameters.")); } void @@ -64,4 +67,7 @@ grub_script_fini (void) grub_unregister_command (cmd_continue); cmd_continue = 0; + if (cmd_shift) + grub_unregister_command (cmd_shift); + cmd_shift = 0; } diff --git a/tests/grub_script_shift.in b/tests/grub_script_shift.in new file mode 100644 index 000000000..785b9c396 --- /dev/null +++ b/tests/grub_script_shift.in @@ -0,0 +1,85 @@ +#! @builddir@/grub-shell-tester + +# Run GRUB script in a Qemu instance +# 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 . + +function f1 { + echo f1 '$@' $@ + echo f1 '$*' $* + echo f1 $# $1 $2 $3 + shift + echo f1 '$@' $@ + echo f1 '$*' $* + echo f1 $# $1 $2 $3 +} + +f1 +f1 a +f1 a b +f1 a b c +f1 a b c d +f1 a b c d e + +function f2 { + echo f1 '$@' $@ + echo f1 '$*' $* + echo f2 $# $1 $2 $3 + shift 1 + echo f1 '$@' $@ + echo f1 '$*' $* + echo f2 $# $1 $2 $3 +} + +f2 +f2 a +f2 a b +f2 a b c +f2 a b c d +f2 a b c d e + +function f3 { + echo f1 '$@' $@ + echo f1 '$*' $* + echo f3 $# $1 $2 $3 + shift 3 + echo f1 '$@' $@ + echo f1 '$*' $* + echo f3 $# $1 $2 $3 +} + +f3 +f3 a +f3 a b +f3 a b c +f3 a b c d +f3 a b c d e + +function f4 { + echo f1 '$@' $@ + echo f1 '$*' $* + echo f4 $# $1 $2 $3 + shift 100 + echo f1 '$@' $@ + echo f1 '$*' $* + echo f4 $# $1 $2 $3 +} + +f4 +f4 a +f4 a b +f4 a b c +f4 a b c d +f4 a b c d e diff --git a/util/grub-script-check.c b/util/grub-script-check.c index ac59d5fcc..4ca85c4bd 100644 --- a/util/grub-script-check.c +++ b/util/grub-script-check.c @@ -65,6 +65,14 @@ grub_script_break (grub_command_t cmd __attribute__((unused)), return 0; } +grub_err_t +grub_script_shift (grub_command_t cmd __attribute__((unused)), + int argc __attribute__((unused)), + char *argv[] __attribute__((unused))) +{ + return 0; +} + char * grub_script_execute_argument_to_string (struct grub_script_arg *arg __attribute__ ((unused))) {