# Bazaar merge directive format 2 (Bazaar 0.90)
# revision_id: address@hidden
# target_branch: file:///home/bvk/Work/grub2/for-loop/
# testament_sha1: ab52b0aa586f2d8c04f5b84e8685bac20ce2d57c
# timestamp: 2010-01-26 12:33:11 +0530
# base_revision_id: address@hidden
# ukj4s8lpltdoslue
#
# Begin patch
=== added file 'ChangeLog.while-until-loops'
--- ChangeLog.while-until-loops 1970-01-01 00:00:00 +0000
+++ ChangeLog.while-until-loops 2010-01-26 07:02:24 +0000
@@ -0,0 +1,20 @@
+2010-01-26 BVK Chaitanya
+
+ While and until loops support to GRUB script.
+
+ * include/grub/script_sh.h (grub_script_cmdwhile): New struct.
+ (grub_script_create_cmdwhile): New function prototype.
+ (grub_script_execute_cmdwhile): New function prototype.
+ * script/execute.c (grub_script_execute_cmdwhile): New function.
+ * script/parser.y (command): New commands.
+ (whilecmd): New grammar rule.
+ (untilcmd): New grammar rule.
+ * script/script.c (grub_script_create_cmdwhile): New function.
+ * util/grub-script-check.c (grub_script_execute_cmdwhile): New
+ function.
+
+ * tests/grub_script_while1.in: New testcase.
+ * conf/tests.rmk: New testcase make rule.
+
+ * commands/true.c (grub_cmd_false): Remove printing error message.
+ * commands/test.c (grub_cmd_test): Likewise.
=== modified file 'commands/test.c'
--- commands/test.c 2010-01-03 22:05:07 +0000
+++ commands/test.c 2010-01-26 07:02:24 +0000
@@ -412,8 +412,7 @@
if (argc >= 1 && grub_strcmp (args[argc - 1], "]") == 0)
argc--;
- return test_parse (args, &argn, argc) ? GRUB_ERR_NONE
- : grub_error (GRUB_ERR_TEST_FAILURE, "false");
+ return test_parse (args, &argn, argc) ? 0 : 1;
}
static grub_command_t cmd_1, cmd_2;
=== modified file 'commands/true.c'
--- commands/true.c 2010-01-03 18:24:22 +0000
+++ commands/true.c 2010-01-26 07:02:24 +0000
@@ -34,7 +34,7 @@
int argc __attribute__ ((unused)),
char *argv[] __attribute__ ((unused)))
{
- return grub_error (GRUB_ERR_TEST_FAILURE, "false");
+ return 1;
}
static grub_command_t cmd_true, cmd_false;
=== modified file 'conf/tests.rmk'
--- conf/tests.rmk 2010-01-23 05:33:41 +0000
+++ conf/tests.rmk 2010-01-26 07:02:24 +0000
@@ -53,6 +53,9 @@
check_SCRIPTS += grub_script_for1
grub_script_for1_SOURCES = tests/grub_script_for1.in
+check_SCRIPTS += grub_script_while1
+grub_script_while1_SOURCES = tests/grub_script_while1.in
+
# List of tests to execute on "make check"
# SCRIPTED_TESTS = example_scripted_test
# SCRIPTED_TESTS += example_grub_script_test
@@ -63,6 +66,7 @@
SCRIPTED_TESTS += grub_script_echo_keywords
SCRIPTED_TESTS += grub_script_vars1
SCRIPTED_TESTS += grub_script_for1
+SCRIPTED_TESTS += grub_script_while1
# dependencies between tests and testing-tools
$(SCRIPTED_TESTS): grub-shell grub-shell-tester
=== modified file 'include/grub/script_sh.h'
--- include/grub/script_sh.h 2010-01-23 05:33:41 +0000
+++ include/grub/script_sh.h 2010-01-23 05:49:26 +0000
@@ -121,6 +121,21 @@
struct grub_script_cmd *list;
};
+/* A while/until command. */
+struct grub_script_cmdwhile
+{
+ struct grub_script_cmd cmd;
+
+ /* The command list used as condition. */
+ struct grub_script_cmd *cond;
+
+ /* The command list executed in each loop. */
+ struct grub_script_cmd *list;
+
+ /* The flag to indicate this as "until" loop. */
+ int until;
+};
+
/* A menu entry generate statement. */
struct grub_script_cmd_menuentry
{
@@ -235,6 +250,12 @@
struct grub_script_cmd *list);
struct grub_script_cmd *
+grub_script_create_cmdwhile (struct grub_parser_param *state,
+ struct grub_script_cmd *cond,
+ struct grub_script_cmd *list,
+ int is_an_until_loop);
+
+struct grub_script_cmd *
grub_script_create_cmdmenu (struct grub_parser_param *state,
struct grub_script_arglist *arglist,
char *sourcecode,
@@ -283,6 +304,7 @@
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_cmdwhile (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. */
=== modified file 'script/execute.c'
--- script/execute.c 2010-01-23 05:33:41 +0000
+++ script/execute.c 2010-01-26 07:02:24 +0000
@@ -26,13 +26,24 @@
#include
#include
+/* Max digits for a char is 3 (0xFF is 255), similarly for an int it
+ is sizeof (int) * 3, and one extra for a possible -ve sign. */
+#define ERRNO_DIGITS_MAX (sizeof (int) * 3 + 1)
+
static grub_err_t
grub_script_execute_cmd (struct grub_script_cmd *cmd)
{
+ int ret;
+ char errnobuf[ERRNO_DIGITS_MAX + 1];
+
if (cmd == 0)
return 0;
- return cmd->exec (cmd);
+ ret = cmd->exec (cmd);
+
+ grub_snprintf (errnobuf, sizeof (errnobuf), "%d", ret);
+ grub_env_set ("?", errnobuf);
+ return ret;
}
/* Expand arguments in ARGLIST into multiple arguments. */
@@ -188,7 +199,6 @@
grub_err_t ret = 0;
int argcount = 0;
grub_script_function_t func = 0;
- char errnobuf[18];
char *cmdname;
/* Lookup the command. */
@@ -222,11 +232,7 @@
grub_env_set (assign, eq);
}
grub_free (assign);
-
- grub_snprintf (errnobuf, sizeof (errnobuf), "%d", grub_errno);
- grub_env_set ("?", errnobuf);
-
- return 0;
+ return grub_errno;
}
}
@@ -241,9 +247,6 @@
grub_free (args[i]);
grub_free (args);
- grub_snprintf (errnobuf, sizeof (errnobuf), "%d", ret);
- grub_env_set ("?", errnobuf);
-
return ret;
}
@@ -251,13 +254,14 @@
grub_err_t
grub_script_execute_cmdblock (struct grub_script_cmd *cmd)
{
+ int ret = 0;
struct grub_script_cmdblock *cmdblock = (struct grub_script_cmdblock *) cmd;
/* Loop over every command and execute it. */
for (cmd = cmdblock->cmdlist; cmd; cmd = cmd->next)
- grub_script_execute_cmd (cmd);
+ ret = grub_script_execute_cmd (cmd);
- return 0;
+ return ret;
}
/* Execute an if statement. */
@@ -308,6 +312,26 @@
return result;
}
+/* Execute a "while" or "until" command. */
+grub_err_t
+grub_script_execute_cmdwhile (struct grub_script_cmd *cmd)
+{
+ int cond;
+ int result;
+ struct grub_script_cmdwhile *cmdwhile = (struct grub_script_cmdwhile *) cmd;
+
+ result = 0;
+ do {
+ cond = grub_script_execute_cmd (cmdwhile->cond);
+ if ((cmdwhile->until && !cond) || (!cmdwhile->until && cond))
+ break;
+
+ result = grub_script_execute_cmd (cmdwhile->list);
+ } while (1); /* XXX Put a check for ^C here */
+
+ return result;
+}
+
/* Execute the menu entry generate statement. */
grub_err_t
grub_script_execute_menuentry (struct grub_script_cmd *cmd)
=== modified file 'script/parser.y'
--- script/parser.y 2010-01-23 05:33:41 +0000
+++ script/parser.y 2010-01-23 05:49:26 +0000
@@ -76,8 +76,9 @@
%token GRUB_PARSER_TOKEN_WORD "word"
%type word argument arguments0 arguments1
-%type script_init script grubcmd ifcmd forcmd command
-%type commands1 menuentry statement
+%type script_init script
+%type grubcmd ifcmd forcmd whilecmd untilcmd
+%type command commands1 menuentry statement
%pure-parser
%lex-param { struct grub_parser_param *state };
@@ -173,9 +174,11 @@
;
/* A single command. */
-command: grubcmd { $$ = $1; }
- | ifcmd { $$ = $1; }
- | forcmd { $$ = $1; }
+command: grubcmd { $$ = $1; }
+ | ifcmd { $$ = $1; }
+ | forcmd { $$ = $1; }
+ | whilecmd { $$ = $1; }
+ | untilcmd { $$ = $1; }
;
/* A list of commands. */
@@ -250,3 +253,25 @@
grub_script_lexer_deref (state->lexerstate);
}
;
+
+whilecmd: "while"
+ {
+ grub_script_lexer_ref (state->lexerstate);
+ }
+ commands1 delimiters1 "do" commands1 delimiters1 "done"
+ {
+ $$ = grub_script_create_cmdwhile (state, $3, $6, 0);
+ grub_script_lexer_deref (state->lexerstate);
+ }
+;
+
+untilcmd: "until"
+ {
+ grub_script_lexer_ref (state->lexerstate);
+ }
+ commands1 delimiters1 "do" commands1 delimiters1 "done"
+ {
+ $$ = grub_script_create_cmdwhile (state, $3, $6, 1);
+ grub_script_lexer_deref (state->lexerstate);
+ }
+;
=== modified file 'script/script.c'
--- script/script.c 2010-01-23 05:33:41 +0000
+++ script/script.c 2010-01-23 05:49:26 +0000
@@ -245,6 +245,28 @@
return (struct grub_script_cmd *) cmd;
}
+/* Create a "while" or "until" command. */
+struct grub_script_cmd *
+grub_script_create_cmdwhile (struct grub_parser_param *state,
+ struct grub_script_cmd *cond,
+ struct grub_script_cmd *list,
+ int is_an_until_loop)
+{
+ struct grub_script_cmdwhile *cmd;
+
+ cmd = grub_script_malloc (state, sizeof (*cmd));
+ if (! cmd)
+ return 0;
+
+ cmd->cmd.exec = grub_script_execute_cmdwhile;
+ cmd->cmd.next = 0;
+ cmd->cond = cond;
+ cmd->list = list;
+ cmd->until = is_an_until_loop;
+
+ 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.
=== added file 'tests/grub_script_while1.in'
--- tests/grub_script_while1.in 1970-01-01 00:00:00 +0000
+++ tests/grub_script_while1.in 2010-01-26 07:02:47 +0000
@@ -0,0 +1,32 @@
+#! @builddir@/grub-shell-tester
+
+echo one
+foo=""
+while test "$foo" != "1111"; do foo="${foo}1"; echo "$foo"; done
+
+echo two
+foo=""
+while test "$foo" != "aaaa"
+do
+ foo="${foo}a"
+ echo $foo
+done
+
+foo=""
+until test "$foo" = "1111"; do foo="${foo}1"; echo $foo; done
+foo=""
+until test "$foo" = "aaaa"
+do
+ foo="${foo}a"
+ echo $foo
+done
+
+# check "$?" in condition gets its value from while body commands
+foo=""
+false
+while test "$?" != "0"
+do
+ echo $foo
+ foo="${foo}1"
+ test "$foo" = "111111"
+done
=== modified file 'util/grub-script-check.c'
--- util/grub-script-check.c 2010-01-23 05:33:41 +0000
+++ util/grub-script-check.c 2010-01-23 05:49:26 +0000
@@ -88,6 +88,12 @@
}
grub_err_t
+grub_script_execute_cmdwhile (struct grub_script_cmd *cmd __attribute__ ((unused)))
+{
+ return 0;
+}
+
+grub_err_t
grub_script_execute_menuentry (struct grub_script_cmd *cmd __attribute__ ((unused)))
{
return 0;
# Begin bundle
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