Adding a testcase for while and until loops caught several GRUB script
bugs in handling return value ($?).  Attached patch has these issues
fixed along with the testcase.  Its been pushed into
branches/while-until-loops as well.



-- 
bvk.chaitanya
# Bazaar merge directive format 2 (Bazaar 0.90)
# revision_id: bvk.gro...@gmail.com-20100126070247-jav742bys6z6vz6n
# target_branch: file:///home/bvk/Work/grub2/for-loop/
# testament_sha1: ab52b0aa586f2d8c04f5b84e8685bac20ce2d57c
# timestamp: 2010-01-26 12:33:11 +0530
# base_revision_id: bvk.gro...@gmail.com-20100123053341-\
#   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  <bvk.gro...@gmail.com>
+
+       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 <grub/lib/arg.h>
 #include <grub/normal.h>
 
+/* 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 <arg> GRUB_PARSER_TOKEN_WORD      "word"
 
 %type <arglist> word argument arguments0 arguments1
-%type <cmd> script_init script grubcmd ifcmd forcmd command
-%type <cmd> commands1 menuentry statement
+%type <cmd> script_init script
+%type <cmd> grubcmd ifcmd forcmd whilecmd untilcmd
+%type <cmd> 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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
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to