=== modified file 'ChangeLog.scripting' --- ChangeLog.scripting 2009-12-26 04:07:41 +0000 +++ ChangeLog.scripting 2009-12-26 05:05:37 +0000 @@ -1,3 +1,17 @@ +2009-12-26 BVK Chaitanya + + * include/grub/script_sh.h: New function prototypes for + grub_script_create_cmdwhile and grub_script_execute_cmdwhile. + * script/parser.y ("whilecmd"): New grammar rule for while + command. + ("untilcmd"): New grammar rule for until command. + * script/script.c (grub_script_create_cmdwhile): Creates a + while/until command object. + * script/execute.c (grub_script_execute_cmdwhile): Executes a + while/until command object. + * util/grub-script-check.c (grub_script_execute_cmdwhile): Dummy + stub for syntax checking while/until statements. + 2009-12-25 BVK Chaitanya * include/grub/script_sh.h (grub_script_arg_type_t): New types === modified file 'include/grub/script_sh.h' --- include/grub/script_sh.h 2009-12-26 04:07:41 +0000 +++ include/grub/script_sh.h 2009-12-26 04:51:55 +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 { @@ -236,6 +251,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, @@ -284,6 +305,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 2009-12-26 04:07:41 +0000 +++ script/execute.c 2009-12-26 04:45:21 +0000 @@ -296,6 +296,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 2009-12-26 03:51:24 +0000 +++ script/parser.y 2009-12-26 04:26:28 +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 %error-verbose @@ -179,9 +180,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. */ @@ -261,3 +264,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 2009-12-26 03:51:24 +0000 +++ script/script.c 2009-12-26 04:31:30 +0000 @@ -230,6 +230,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. === modified file 'util/grub-script-check.c' --- util/grub-script-check.c 2009-12-26 03:51:24 +0000 +++ util/grub-script-check.c 2009-12-26 04:54:43 +0000 @@ -84,6 +84,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) { struct grub_script_cmd_menuentry *menu;