]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
setparams command to set positional parameters
authorBVK Chaitanya <bvk@dbook>
Sun, 15 Aug 2010 06:32:33 +0000 (12:02 +0530)
committerBVK Chaitanya <bvk@dbook>
Sun, 15 Aug 2010 06:32:33 +0000 (12:02 +0530)
conf/tests.rmk
include/grub/script_sh.h
script/argv.c
script/execute.c
script/main.c
tests/grub_script_setparams.in [new file with mode: 0644]
util/grub-script-check.c

index c14fe0fdaf9dc6485efc136e1522be4d9ce2ac8a..0d41a711bff9d2775afe8936388dd0c5a0c8d302 100644 (file)
@@ -83,6 +83,9 @@ grub_script_continue_SOURCES = tests/grub_script_continue.in
 check_SCRIPTS += grub_script_shift
 grub_script_shift_SOURCES = tests/grub_script_shift.in
 
+check_SCRIPTS += grub_script_setparams
+grub_script_setparams_SOURCES = tests/grub_script_setparams.in
+
 # List of tests to execute on "make check"
 # SCRIPTED_TESTS    = example_scripted_test
 # SCRIPTED_TESTS   += example_grub_script_test
@@ -103,6 +106,7 @@ SCRIPTED_TESTS += grub_script_functions
 SCRIPTED_TESTS += grub_script_break
 SCRIPTED_TESTS += grub_script_continue
 SCRIPTED_TESTS += grub_script_shift
+SCRIPTED_TESTS += grub_script_setparams
 
 # dependencies between tests and testing-tools
 $(SCRIPTED_TESTS): grub-shell grub-shell-tester
index 77e8073600ca70a303131d13e8e026738f6511a8..e0ed5c005cc1bcad05f2b1409990ac9c11772c8f 100644 (file)
@@ -227,6 +227,7 @@ void grub_script_init (void);
 void grub_script_fini (void);
 
 void grub_script_argv_free    (struct grub_script_argv *argv);
+int grub_script_argv_make     (struct grub_script_argv *argv, int argc, char **args);
 int grub_script_argv_next     (struct grub_script_argv *argv);
 int grub_script_argv_append   (struct grub_script_argv *argv, const char *s);
 int grub_script_argv_split_append (struct grub_script_argv *argv, char *s);
@@ -321,6 +322,9 @@ 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[]);
 
+/* SETPARAMS command for GRUB script functions.  */
+grub_err_t grub_script_setparams (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;
index b69ee39c57be092dbbe358cf9879a0fc16bf98fe..c642ea9c59594fa7d59eb1a153dccf78a77c6865 100644 (file)
@@ -57,6 +57,23 @@ grub_script_argv_free (struct grub_script_argv *argv)
   argv->args = 0;
 }
 
+/* Make argv from argc, args pair.  */
+int
+grub_script_argv_make (struct grub_script_argv *argv, int argc, char **args)
+{
+  int i;
+  struct grub_script_argv r = { 0, 0};
+
+  for (i = 0; i < argc; i++)
+    if (grub_script_argv_next (&r) || grub_script_argv_append (&r, args[i]))
+      {
+       grub_script_argv_free (&r);
+       return 1;
+      }
+  *argv = r;
+  return 0;
+}
+
 /* Prepare for next argc.  */
 int
 grub_script_argv_next (struct grub_script_argv *argv)
index 26a46b12b0d48d94dffa41f233fac7387b23e519..b911163f7bd67f4f38e1b0b828f5eaea89dffbdb 100644 (file)
@@ -34,13 +34,35 @@ static unsigned long is_continue;
 static unsigned long active_loops;
 static unsigned long active_breaks;
 
+#define GRUB_SCRIPT_SCOPE_MALLOCED      1
+#define GRUB_SCRIPT_SCOPE_ARGS_MALLOCED 2
+
 /* Scope for grub script functions.  */
 struct grub_script_scope
 {
+  unsigned flags;
+  unsigned shifts;
   struct grub_script_argv argv;
 };
 static struct grub_script_scope *scope = 0;
 
+static void
+replace_scope (struct grub_script_scope *new_scope)
+{
+  if (scope)
+    {
+      scope->argv.argc += scope->shifts;
+      scope->argv.args -= scope->shifts;
+
+      if (scope->flags & GRUB_SCRIPT_SCOPE_ARGS_MALLOCED)
+       grub_script_argv_free (&scope->argv);
+
+      if (scope->flags & GRUB_SCRIPT_SCOPE_MALLOCED)
+       grub_free (scope);
+    }
+  scope = new_scope;
+}
+
 grub_err_t
 grub_script_break (grub_command_t cmd, int argc, char *argv[])
 {
@@ -85,11 +107,41 @@ grub_script_shift (grub_command_t cmd __attribute__((unused)),
   if (n > scope->argv.argc)
     return GRUB_ERR_BAD_ARGUMENT;
 
+  scope->shifts += n;
   scope->argv.argc -= n;
   scope->argv.args += n;
   return GRUB_ERR_NONE;
 }
 
+grub_err_t
+grub_script_setparams (grub_command_t cmd __attribute__((unused)),
+                      int argc, char **args)
+{
+  struct grub_script_scope *new_scope;
+  struct grub_script_argv argv = { 0, 0 };
+
+  if (! scope)
+    return GRUB_ERR_INVALID_COMMAND;
+
+  new_scope = grub_malloc (sizeof (*new_scope));
+  if (! new_scope)
+    return grub_errno;
+
+  if (grub_script_argv_make (&argv, argc, args))
+    {
+      grub_free (new_scope);
+      return grub_errno;
+    }
+
+  new_scope->shifts = 0;
+  new_scope->argv = argv;
+  new_scope->flags = GRUB_SCRIPT_SCOPE_MALLOCED |
+    GRUB_SCRIPT_SCOPE_ARGS_MALLOCED;
+
+  replace_scope (new_scope);
+  return GRUB_ERR_NONE;
+}
+
 static int
 grub_env_special (const char *name)
 {
@@ -104,6 +156,7 @@ grub_env_special (const char *name)
 static char **
 grub_script_env_get (const char *name, grub_script_arg_type_t type)
 {
+  unsigned i;
   struct grub_script_argv result = { 0, 0 };
 
   if (grub_script_argv_next (&result))
@@ -138,8 +191,6 @@ grub_script_env_get (const char *name, grub_script_arg_type_t type)
     }
   else if (grub_strcmp (name, "*") == 0)
     {
-      unsigned i;
-
       for (i = 0; i < scope->argv.argc; i++)
        if (type == GRUB_SCRIPT_ARG_TYPE_VAR)
          {
@@ -160,8 +211,6 @@ grub_script_env_get (const char *name, grub_script_arg_type_t type)
     }
   else if (grub_strcmp (name, "@") == 0)
     {
-      unsigned i;
-
       for (i = 0; i < scope->argv.argc; i++)
        {
          if (i != 0 && grub_script_argv_next (&result))
@@ -302,6 +351,8 @@ grub_script_function_call (grub_script_function_t func, int argc, char **args)
   struct grub_script_scope new_scope;
 
   active_loops = 0;
+  new_scope.flags = 0;
+  new_scope.shifts = 0;
   new_scope.argv.argc = argc;
   new_scope.argv.args = args;
 
@@ -311,7 +362,7 @@ grub_script_function_call (grub_script_function_t func, int argc, char **args)
   ret = grub_script_execute (func->func);
 
   active_loops = loops;
-  scope = old_scope;
+  replace_scope (old_scope); /* free any scopes by setparams */
   return ret;
 }
 
index ff714d060f28567a17a4492807a3240237b9d3c9..a16a65c13c47fd298e7990e724fea1d60f2f270c 100644 (file)
@@ -44,6 +44,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;
+static grub_command_t cmd_setparams;
 
 void
 grub_script_init (void)
@@ -54,6 +55,9 @@ grub_script_init (void)
                                        N_("[n]"), N_("Continue loops"));
   cmd_shift = grub_register_command ("shift", grub_script_shift,
                                     N_("[n]"), N_("Shift positional parameters."));
+  cmd_setparams = grub_register_command ("setparams", grub_script_setparams,
+                                        N_("[VALUE]..."),
+                                        N_("Set positional parameters."));
 }
 
 void
@@ -70,4 +74,8 @@ grub_script_fini (void)
   if (cmd_shift)
     grub_unregister_command (cmd_shift);
   cmd_shift = 0;
+
+  if (cmd_setparams)
+    grub_unregister_command (cmd_setparams);
+  cmd_setparams = 0;
 }
diff --git a/tests/grub_script_setparams.in b/tests/grub_script_setparams.in
new file mode 100644 (file)
index 0000000..82d3168
--- /dev/null
@@ -0,0 +1,59 @@
+#! @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 <http://www.gnu.org/licenses/>.
+
+if test x$grubshell = xyes; then cmd=setparams; else cmd=set; fi
+
+function f1 {
+    echo $#
+    echo "$#"
+
+    echo $@
+    echo "$@"
+
+    echo $*
+    echo "$*"
+
+    echo $1 $2
+    for v in "$@"; do echo $v; done
+    shift
+    echo $1 $2
+    for v in "$@"; do echo $v; done
+
+    $cmd 1 2 3 4
+
+    echo $#
+    echo "$#"
+
+    echo $@
+    echo "$@"
+
+    echo $*
+    echo "$*"
+
+    echo $1 $2
+    for v in "$@"; do echo $v; done
+    shift
+    echo $1 $2
+    for v in "$@"; do echo $v; done
+}
+# f1
+# f1 a
+f1 a b
+f1 a b c
+f1 a b c d
+f1 a b c d e
index 4ca85c4bdad3f6d3e77dc49b471b9a80c55458f4..375d064d437aec98b0f827cf624576ae54d35134 100644 (file)
@@ -73,6 +73,14 @@ grub_script_shift (grub_command_t cmd __attribute__((unused)),
   return 0;
 }
 
+grub_err_t
+grub_script_setparams (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)))
 {