--- /dev/null
+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.
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
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
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
{
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,
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. */
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)
%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
/* A single command. */
command: grubcmd { $$ = $1; }
| ifcmd { $$ = $1; }
+ | forcmd { $$ = $1; }
;
/* A list of commands. */
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);
+ }
+;
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.
--- /dev/null
+#! @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
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)))
{