Support for options to appear multiple times on cmdline.

* include/grub/lib/arg.h (grub_arg_list_alloc): New prototype.
	* grub-core/commands/extcmd.c: Support for repeatable option.
	* grub-core/lib/arg.c (grub_arg_list_alloc): New function for
	repeatable option support.

	Refactor menuentry into a regular command.

	* grub-core/commands/menuentry.c: New file, menuentry command
	implementation.
	* grub-core/Makefile.core.def: Rule update for normal.mod.
	* grub-core/normal/main.c: Moved menuentry creation to
	grub-core/commands/menuentry.c.
	* grub-core/normal/menu.c (grub_menu_execute_entry): Removed.
	(grub_menu_execute_entry_real): Removed.
	* grub-core/script/execute.c (grub_script_execute_sourcecode): New
	function.
	(grub_script_execute_menuentry): Removed.
	* grub-core/script/parser.y (menuentry): Removed.
	* grub-core/script/script.c (grub_script_create_cmdmenu): Removed.
	* grub-core/script/yylex.l (menuentry): Removed.
	* include/grub/menu.h (grub_menu_init): New prototype.
	(grub_menu_fini): New prototype.
	* include/grub/normal.h (grub_normal_add_menu_entry): Removed.
	* include/grub/script_sh.h (grub_script_cmd_menuentry): Removed.
	(grub_script_execute_sourcecode): New prototype.
This commit is contained in:
BVK Chaitanya 2010-09-04 21:43:54 +05:30
commit ed8c6dec96
15 changed files with 464 additions and 366 deletions

View file

@ -401,6 +401,62 @@ grub_script_function_call (grub_script_function_t func, int argc, char **args)
return ret;
}
/* Execute a source script. */
grub_err_t
grub_script_execute_sourcecode (const char *source, int argc, char **args)
{
grub_err_t ret = 0;
struct grub_script *parsed_script;
struct grub_script_scope new_scope;
struct grub_script_scope *old_scope;
auto grub_err_t getline (char **line, int cont);
grub_err_t getline (char **line, int cont __attribute__ ((unused)))
{
const char *p;
if (! source)
{
*line = 0;
return 0;
}
p = grub_strchr (source, '\n');
if (p)
*line = grub_strndup (source, p - source);
else
*line = grub_strdup (source);
source = p ? p + 1 : 0;
return 0;
}
new_scope.argv.argc = argc;
new_scope.argv.args = args;
old_scope = scope;
scope = &new_scope;
while (source)
{
char *line;
getline (&line, 0);
parsed_script = grub_script_parse (line, getline);
if (! parsed_script)
{
ret = grub_errno;
break;
}
ret = grub_script_execute (parsed_script);
grub_free (line);
}
scope = old_scope;
return ret;
}
/* Execute a single command line. */
grub_err_t
grub_script_execute_cmdline (struct grub_script_cmd *cmd)
@ -598,31 +654,6 @@ grub_script_execute_cmdwhile (struct grub_script_cmd *cmd)
return result;
}
/* Execute the menu entry generate statement. */
grub_err_t
grub_script_execute_menuentry (struct grub_script_cmd *cmd)
{
struct grub_script_cmd_menuentry *cmd_menuentry;
struct grub_script_argv argv = { 0, 0, 0 };
cmd_menuentry = (struct grub_script_cmd_menuentry *) cmd;
if (cmd_menuentry->arglist)
{
if (grub_script_arglist_to_argv (cmd_menuentry->arglist, &argv))
return grub_errno;
}
grub_normal_add_menu_entry (argv.argc, (const char **) argv.args,
cmd_menuentry->sourcecode);
grub_script_argv_free (&argv);
return grub_errno;
}
/* Execute any GRUB pre-parsed command or script. */
grub_err_t
grub_script_execute (struct grub_script *script)

View file

@ -76,7 +76,6 @@
%token <arg> GRUB_PARSER_TOKEN_WHILE "while"
%token <arg> GRUB_PARSER_TOKEN_TIME "time"
%token <arg> GRUB_PARSER_TOKEN_FUNCTION "function"
%token <arg> GRUB_PARSER_TOKEN_MENUENTRY "menuentry"
%token <arg> GRUB_PARSER_TOKEN_NAME "name"
%token <arg> GRUB_PARSER_TOKEN_WORD "word"
@ -85,7 +84,7 @@
%type <cmd> script_init script
%type <cmd> grubcmd ifclause ifcmd forcmd whilecmd untilcmd
%type <cmd> command commands1 menuentry statement
%type <cmd> command commands1 statement
%pure-parser
%lex-param { struct grub_parser_param *state };
@ -131,7 +130,6 @@ word: GRUB_PARSER_TOKEN_NAME { $$ = grub_script_add_arglist (state, 0, $1); }
statement: command { $$ = $1; }
| function { $$ = 0; }
| menuentry { $$ = $1; }
;
argument : "case" { $$ = grub_script_add_arglist (state, 0, $1); }
@ -149,7 +147,6 @@ argument : "case" { $$ = grub_script_add_arglist (state, 0, $1); }
| "until" { $$ = grub_script_add_arglist (state, 0, $1); }
| "while" { $$ = grub_script_add_arglist (state, 0, $1); }
| "function" { $$ = grub_script_add_arglist (state, 0, $1); }
| "menuentry" { $$ = grub_script_add_arglist (state, 0, $1); }
| word { $$ = $1; }
;
@ -243,12 +240,11 @@ grubcmd: word arguments0 block0
if ($3)
x = grub_script_add_arglist (state, $2, $3);
if ($1 && x)
{
$1->next = x;
$1->argcount += x->argcount;
x->argcount = 0;
}
if ($1 && x) {
$1->next = x;
$1->argcount += x->argcount;
x->argcount = 0;
}
$$ = grub_script_create_cmdline (state, $1);
}
;
@ -298,25 +294,6 @@ function: "function" "name"
}
;
menuentry: "menuentry"
{
grub_script_lexer_ref (state->lexerstate);
}
arguments1
{
$<offset>$ = grub_script_lexer_record_start (state);
}
delimiters0 "{" commands1 delimiters1 "}"
{
char *def;
def = grub_script_lexer_record_stop (state, $<offset>4);
*grub_strrchr(def, '}') = '\0';
grub_script_lexer_deref (state->lexerstate);
$$ = grub_script_create_cmdmenu (state, $3, def, 0);
}
;
ifcmd: "if"
{
grub_script_lexer_ref (state->lexerstate);

View file

@ -281,30 +281,6 @@ grub_script_create_cmdwhile (struct grub_parser_param *state,
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.
The options for this entry are passed in OPTIONS. */
struct grub_script_cmd *
grub_script_create_cmdmenu (struct grub_parser_param *state,
struct grub_script_arglist *arglist,
char *sourcecode, int options)
{
struct grub_script_cmd_menuentry *cmd;
cmd = grub_script_malloc (state, sizeof (*cmd));
if (!cmd)
return 0;
cmd->cmd.exec = grub_script_execute_menuentry;
cmd->cmd.next = 0;
cmd->sourcecode = sourcecode;
cmd->arglist = arglist;
cmd->options = options;
return (struct grub_script_cmd *) cmd;
}
/* Create a chain of commands. LAST contains the command that should
be added at the end of LIST's list. If LIST is zero, a new list
will be created. */

View file

@ -176,7 +176,6 @@ MULTILINE {WORD}?((\"{DQCHR}*)|(\'{SQCHR}*)|(\\\n))
"until" { RECORD; return GRUB_PARSER_TOKEN_UNTIL; }
"while" { RECORD; return GRUB_PARSER_TOKEN_WHILE; }
"function" { RECORD; return GRUB_PARSER_TOKEN_FUNCTION; }
"menuentry" { RECORD; return GRUB_PARSER_TOKEN_MENUENTRY; }
{MULTILINE} {
if (grub_lexer_unput (yytext, yyscanner))