]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
while and until loops support
authorBVK Chaitanya <bvk.groups@gmail.com>
Sat, 23 Jan 2010 05:49:26 +0000 (11:19 +0530)
committerBVK Chaitanya <bvk.groups@gmail.com>
Sat, 23 Jan 2010 05:49:26 +0000 (11:19 +0530)
include/grub/script_sh.h
script/execute.c
script/parser.y
script/script.c
util/grub-script-check.c

index 4436afbf1f2ec54c71c23d310ac137cb15c70b2c..207b5fcbcccaf0d04376a55fb367c76b55482718 100644 (file)
@@ -121,6 +121,21 @@ struct grub_script_cmdfor
   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
 {
@@ -234,6 +249,12 @@ grub_script_create_cmdfor (struct grub_parser_param *state,
                           struct grub_script_arglist *words,
                           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,
@@ -283,6 +304,7 @@ 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_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.  */
index aa6975fddbd092ac898ab00c5d5d46edfa59b8f0..b905de46f55a3a32fe0ee0c0449a095bb07030bd 100644 (file)
@@ -308,6 +308,26 @@ grub_script_execute_cmdfor (struct grub_script_cmd *cmd)
   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)
index 26a6e3735deb7dd3695ebd7a0bc7a675719e4816..4d22ae400dfb426ab594f23cce571eda770f4334 100644 (file)
@@ -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 @@ grubcmd: word arguments0
 ;
 
 /* 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 @@ forcmd: "for" "name"
          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);
+         }
+;
index 9142a8245c620b8cb04f91c0582d63e3251c5cea..4c87d94911a1e7eb35ed7d4f4f56bfdc10c0d142 100644 (file)
@@ -245,6 +245,28 @@ grub_script_create_cmdfor (struct grub_parser_param *state,
   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.
index 3b3f5bd4701af9310ea1a6b2f9bad73ebc198292..eb11988e379290692b998867c1ca6bb00d0bdc41 100644 (file)
@@ -87,6 +87,12 @@ grub_script_execute_cmdfor (struct grub_script_cmd *cmd __attribute__ ((unused))
   return 0;
 }
 
+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)))
 {