]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
for loop support to grub script
authorBVK Chaitanya <bvk.groups@gmail.com>
Sat, 23 Jan 2010 05:33:41 +0000 (11:03 +0530)
committerBVK Chaitanya <bvk.groups@gmail.com>
Sat, 23 Jan 2010 05:33:41 +0000 (11:03 +0530)
ChangeLog.for-loop [new file with mode: 0644]
conf/tests.rmk
include/grub/script_sh.h
script/execute.c
script/parser.y
script/script.c
tests/grub_script_for1.in [new file with mode: 0644]
util/grub-script-check.c

diff --git a/ChangeLog.for-loop b/ChangeLog.for-loop
new file mode 100644 (file)
index 0000000..0fbb9d0
--- /dev/null
@@ -0,0 +1,13 @@
+2010-01-12  BVK Chaitanya  <bvk.groups@gmail.com>
+
+       For loop support to GRUB script.
+
+       * include/grub/script_sh.h (grub_script_cmdfor): New struct.
+       (grub_script_create_cmdfor): New function prototype.
+       (grub_script_execute_cmdfor): New function prototype.
+       * script/execute.c (grub_script_execute_cmdfor): New function.
+       * script/parser.y (command): New for command.
+       (forcmd): New grammar rule.
+       * script/script.c (grub_script_create_cmdfor): New function.
+       * util/grub-script-check.c (grub_script_execute_cmdfor): New
+       function.
index c5080f58c7146d18930e0e7de06f6cb5b728b87b..92f14797da6f50b9d3a564d2c43ec5e6e514cfb2 100644 (file)
@@ -50,6 +50,9 @@ grub_script_echo_keywords_SOURCES = tests/grub_script_echo_keywords.in
 check_SCRIPTS += grub_script_vars1
 grub_script_vars1_SOURCES = tests/grub_script_vars1.in
 
+check_SCRIPTS += grub_script_for1
+grub_script_for1_SOURCES = tests/grub_script_for1.in
+
 # List of tests to execute on "make check"
 # SCRIPTED_TESTS    = example_scripted_test
 # SCRIPTED_TESTS   += example_grub_script_test
@@ -59,6 +62,7 @@ grub_script_vars1_SOURCES = tests/grub_script_vars1.in
 SCRIPTED_TESTS  = grub_script_echo1
 SCRIPTED_TESTS += grub_script_echo_keywords
 SCRIPTED_TESTS += grub_script_vars1
+SCRIPTED_TESTS += grub_script_for1
 
 # dependencies between tests and testing-tools
 $(SCRIPTED_TESTS): grub-shell grub-shell-tester
index c8c610d7b72e642bcc834fe7c7fde117bf5f73c2..4436afbf1f2ec54c71c23d310ac137cb15c70b2c 100644 (file)
@@ -106,6 +106,21 @@ struct grub_script_cmdif
   struct grub_script_cmd *exec_on_false;
 };
 
+/* A for statement.  */
+struct grub_script_cmdfor
+{
+  struct grub_script_cmd cmd;
+
+  /* The name used as looping variable.  */
+  struct grub_script_arg *name;
+
+  /* The words loop iterates over.  */
+  struct grub_script_arglist *words;
+
+  /* The command list executed in each loop.  */
+  struct grub_script_cmd *list;
+};
+
 /* A menu entry generate statement.  */
 struct grub_script_cmd_menuentry
 {
@@ -213,6 +228,12 @@ grub_script_create_cmdif (struct grub_parser_param *state,
                          struct grub_script_cmd *exec_on_true,
                          struct grub_script_cmd *exec_on_false);
 
+struct grub_script_cmd *
+grub_script_create_cmdfor (struct grub_parser_param *state,
+                          struct grub_script_arg *name,
+                          struct grub_script_arglist *words,
+                          struct grub_script_cmd *list);
+
 struct grub_script_cmd *
 grub_script_create_cmdmenu (struct grub_parser_param *state,
                            struct grub_script_arglist *arglist,
@@ -261,6 +282,7 @@ void grub_script_yyerror (struct grub_parser_param *, char const *);
 grub_err_t grub_script_execute_cmdline (struct grub_script_cmd *cmd);
 grub_err_t grub_script_execute_cmdblock (struct grub_script_cmd *cmd);
 grub_err_t grub_script_execute_cmdif (struct grub_script_cmd *cmd);
+grub_err_t grub_script_execute_cmdfor (struct grub_script_cmd *cmd);
 grub_err_t grub_script_execute_menuentry (struct grub_script_cmd *cmd);
 
 /* Execute any GRUB pre-parsed command or script.  */
index c956960dabd8c2d4ea0663bbd972eb578fcef3ba..aa6975fddbd092ac898ab00c5d5d46edfa59b8f0 100644 (file)
@@ -282,6 +282,32 @@ grub_script_execute_cmdif (struct grub_script_cmd *cmd)
     return grub_script_execute_cmd (cmdif->exec_on_false);
 }
 
+/* Execute a for statement.  */
+grub_err_t
+grub_script_execute_cmdfor (struct grub_script_cmd *cmd)
+{
+  int i;
+  int result;
+  char **args;
+  int argcount;
+  struct grub_script_cmdfor *cmdfor = (struct grub_script_cmdfor *) cmd;
+
+  args = grub_script_execute_arglist_to_argv (cmdfor->words, &argcount);
+  if (!args)
+    return grub_errno;
+
+  result = 0;
+  for (i = 0; i < argcount; i++)
+    {
+      grub_env_set (cmdfor->name->str, args[i]);
+      result = grub_script_execute_cmd (cmdfor->list);
+      grub_free (args[i]);
+    }
+
+  grub_free (args);
+  return result;
+}
+
 /* Execute the menu entry generate statement.  */
 grub_err_t
 grub_script_execute_menuentry (struct grub_script_cmd *cmd)
index b8d9818666f4504861f67d879251062387b4fad8..26a6e3735deb7dd3695ebd7a0bc7a675719e4816 100644 (file)
@@ -76,7 +76,7 @@
 %token <arg> GRUB_PARSER_TOKEN_WORD      "word"
 
 %type <arglist> word argument arguments0 arguments1
-%type <cmd> script_init script grubcmd ifcmd command
+%type <cmd> script_init script grubcmd ifcmd forcmd command
 %type <cmd> commands1 menuentry statement
 
 %pure-parser
@@ -175,6 +175,7 @@ grubcmd: word arguments0
 /* A single command.  */
 command: grubcmd { $$ = $1; }
        | ifcmd   { $$ = $1; }
+       | forcmd  { $$ = $1; }
 ;
 
 /* A list of commands. */
@@ -238,3 +239,14 @@ ifcmd: if commands1 delimiters1 "then" commands1 delimiters1 "fi"
          grub_script_lexer_deref (state->lexerstate);
        }
 ;
+
+forcmd: "for" "name"
+        {
+         grub_script_lexer_ref (state->lexerstate);
+        }
+        "in" arguments0 delimiters1 "do" commands1 delimiters1 "done"
+       {
+         $$ = grub_script_create_cmdfor (state, $2, $5, $8);
+         grub_script_lexer_deref (state->lexerstate);
+       }
+;
index b2d870745c5dd233ec03da10e9ece733281bb09d..9142a8245c620b8cb04f91c0582d63e3251c5cea 100644 (file)
@@ -221,6 +221,30 @@ grub_script_create_cmdif (struct grub_parser_param *state,
   return (struct grub_script_cmd *) cmd;
 }
 
+/* Create a command that functions as a for statement.  */
+struct grub_script_cmd *
+grub_script_create_cmdfor (struct grub_parser_param *state,
+                          struct grub_script_arg *name,
+                          struct grub_script_arglist *words,
+                          struct grub_script_cmd *list)
+{
+  struct grub_script_cmdfor *cmd;
+
+  grub_dprintf ("scripting", "cmdfor\n");
+
+  cmd = grub_script_malloc (state, sizeof (*cmd));
+  if (! cmd)
+    return 0;
+
+  cmd->cmd.exec = grub_script_execute_cmdfor;
+  cmd->cmd.next = 0;
+  cmd->name = name;
+  cmd->words = words;
+  cmd->list = list;
+
+  return (struct grub_script_cmd *) cmd;
+}
+
 /* Create a command that adds a menu entry to the menu.  Title is an
    argument that is parsed to generate a string that can be used as
    the title.  The sourcecode for this entry is passed in SOURCECODE.
diff --git a/tests/grub_script_for1.in b/tests/grub_script_for1.in
new file mode 100644 (file)
index 0000000..e39a766
--- /dev/null
@@ -0,0 +1,27 @@
+#! @builddir@/grub-shell-tester
+
+for x in one two 'three 3' "four 4" five six-6; do echo $x; done
+
+for x in one two 'three 3' "four 4" five six-6
+do
+       echo $x
+done
+
+foo="1 2"
+for x in ab${foo}cd; do echo $x; done
+for x in "ab${foo}cd"; do echo $x; done
+
+a="one two three"
+y=foo
+echo $y
+for y in $a; do
+    echo $y
+done
+echo $y
+
+
+b="one two three"
+for z in $b; do
+    echo $z
+done
+echo $z
index 0ad24186d02266d6ab72beba797ba668b387e9b4..3b3f5bd4701af9310ea1a6b2f9bad73ebc198292 100644 (file)
@@ -81,6 +81,12 @@ grub_script_execute_cmdif (struct grub_script_cmd *cmd __attribute__ ((unused)))
   return 0;
 }
 
+grub_err_t
+grub_script_execute_cmdfor (struct grub_script_cmd *cmd __attribute__ ((unused)))
+{
+  return 0;
+}
+
 grub_err_t
 grub_script_execute_menuentry (struct grub_script_cmd *cmd __attribute__ ((unused)))
 {