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
{
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,
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. */
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)
%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 };
;
/* 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. */
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);
+ }
+;
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.
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)))
{