menuentry can pass parameters to its definition
This commit is contained in:
parent
639cc5ab44
commit
1767f7096c
6 changed files with 91 additions and 48 deletions
|
@ -51,12 +51,13 @@ static struct
|
||||||
variable data slot `menu'). As the configuration file is read, the script
|
variable data slot `menu'). As the configuration file is read, the script
|
||||||
parser calls this when a menu entry is to be created. */
|
parser calls this when a menu entry is to be created. */
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
add_menu_entry (int argc, const char **args, char **classes,
|
append_menu_entry (int argc, const char **args, char **classes,
|
||||||
const char *users, const char *hotkey,
|
const char *users, const char *hotkey,
|
||||||
const char *sourcecode)
|
const char *sourcecode)
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
int menu_hotkey = 0;
|
int menu_hotkey = 0;
|
||||||
|
char **menu_args = NULL;
|
||||||
char *menu_users = NULL;
|
char *menu_users = NULL;
|
||||||
char *menu_title = NULL;
|
char *menu_title = NULL;
|
||||||
char *menu_sourcecode = NULL;
|
char *menu_sourcecode = NULL;
|
||||||
|
@ -120,7 +121,18 @@ add_menu_entry (int argc, const char **args, char **classes,
|
||||||
if (! menu_title)
|
if (! menu_title)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
/* XXX: pass args[1..end] as parameters to block arg. */
|
/* Save argc, args to pass as parameters to block arg later. */
|
||||||
|
menu_args = grub_malloc (sizeof (char*) * (argc + 1));
|
||||||
|
if (! menu_args)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
for (i = 0; args[i]; i++)
|
||||||
|
{
|
||||||
|
menu_args[i] = grub_strdup (args[i]);
|
||||||
|
if (! menu_args[i])
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
menu_args[argc] = NULL;
|
||||||
|
|
||||||
/* Add the menu entry at the end of the list. */
|
/* Add the menu entry at the end of the list. */
|
||||||
while (*last)
|
while (*last)
|
||||||
|
@ -136,6 +148,8 @@ add_menu_entry (int argc, const char **args, char **classes,
|
||||||
if (menu_users)
|
if (menu_users)
|
||||||
(*last)->restricted = 1;
|
(*last)->restricted = 1;
|
||||||
(*last)->users = menu_users;
|
(*last)->users = menu_users;
|
||||||
|
(*last)->argc = argc;
|
||||||
|
(*last)->args = menu_args;
|
||||||
(*last)->sourcecode = menu_sourcecode;
|
(*last)->sourcecode = menu_sourcecode;
|
||||||
|
|
||||||
menu->size++;
|
menu->size++;
|
||||||
|
@ -147,6 +161,11 @@ add_menu_entry (int argc, const char **args, char **classes,
|
||||||
for (i = 0; menu_classes && menu_classes[i].name; i++)
|
for (i = 0; menu_classes && menu_classes[i].name; i++)
|
||||||
grub_free (menu_classes[i].name);
|
grub_free (menu_classes[i].name);
|
||||||
grub_free (menu_classes);
|
grub_free (menu_classes);
|
||||||
|
|
||||||
|
for (i = 0; menu_args && menu_args[i]; i++)
|
||||||
|
grub_free (menu_args[i]);
|
||||||
|
grub_free (menu_args);
|
||||||
|
|
||||||
grub_free (menu_users);
|
grub_free (menu_users);
|
||||||
grub_free (menu_title);
|
grub_free (menu_title);
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
@ -170,9 +189,9 @@ grub_cmd_menuentry (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||||
ch = src[len - 1];
|
ch = src[len - 1];
|
||||||
src[len - 1] = '\0';
|
src[len - 1] = '\0';
|
||||||
|
|
||||||
r = add_menu_entry (argc - 1, (const char **) args,
|
r = append_menu_entry (argc - 1, (const char **) args,
|
||||||
ctxt->state[0].args, ctxt->state[1].arg,
|
ctxt->state[0].args, ctxt->state[1].arg,
|
||||||
ctxt->state[2].arg, src + 1);
|
ctxt->state[2].arg, src + 1);
|
||||||
|
|
||||||
src[len - 1] = ch;
|
src[len - 1] = ch;
|
||||||
args[argc - 1] = src;
|
args[argc - 1] = src;
|
||||||
|
|
|
@ -47,6 +47,10 @@ struct grub_menu_entry
|
||||||
/* The sourcecode of the menu entry, used by the editor. */
|
/* The sourcecode of the menu entry, used by the editor. */
|
||||||
const char *sourcecode;
|
const char *sourcecode;
|
||||||
|
|
||||||
|
/* Parameters to be passed to menu definition. */
|
||||||
|
int argc;
|
||||||
|
char **args;
|
||||||
|
|
||||||
int hotkey;
|
int hotkey;
|
||||||
|
|
||||||
/* The next element. */
|
/* The next element. */
|
||||||
|
|
|
@ -303,6 +303,7 @@ grub_err_t grub_script_execute_cmdwhile (struct grub_script_cmd *cmd);
|
||||||
|
|
||||||
/* Execute any GRUB pre-parsed command or script. */
|
/* Execute any GRUB pre-parsed command or script. */
|
||||||
grub_err_t grub_script_execute (struct grub_script *script);
|
grub_err_t grub_script_execute (struct grub_script *script);
|
||||||
|
grub_err_t grub_script_execute_sourcecode (const char *source, int argc, char **args);
|
||||||
|
|
||||||
/* This variable points to the parsed command. This is used to
|
/* This variable points to the parsed command. This is used to
|
||||||
communicate with the bison code. */
|
communicate with the bison code. */
|
||||||
|
|
|
@ -142,44 +142,6 @@ get_and_remove_first_entry_number (const char *name)
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
grub_menu_execute_entry_real (grub_menu_entry_t entry)
|
|
||||||
{
|
|
||||||
const char *source;
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
source = entry->sourcecode;
|
|
||||||
|
|
||||||
while (source)
|
|
||||||
{
|
|
||||||
char *line;
|
|
||||||
|
|
||||||
getline (&line, 0);
|
|
||||||
grub_normal_parse_line (line, getline);
|
|
||||||
grub_free (line);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Run a menu entry. */
|
/* Run a menu entry. */
|
||||||
void
|
void
|
||||||
grub_menu_execute_entry(grub_menu_entry_t entry)
|
grub_menu_execute_entry(grub_menu_entry_t entry)
|
||||||
|
@ -197,8 +159,7 @@ grub_menu_execute_entry(grub_menu_entry_t entry)
|
||||||
}
|
}
|
||||||
|
|
||||||
grub_env_set ("chosen", entry->title);
|
grub_env_set ("chosen", entry->title);
|
||||||
|
grub_script_execute_sourcecode (entry->sourcecode, entry->argc, entry->args);
|
||||||
grub_menu_execute_entry_real (entry);
|
|
||||||
|
|
||||||
if (grub_errno == GRUB_ERR_NONE && grub_loader_is_loaded ())
|
if (grub_errno == GRUB_ERR_NONE && grub_loader_is_loaded ())
|
||||||
/* Implicit execution of boot, only if something is loaded. */
|
/* Implicit execution of boot, only if something is loaded. */
|
||||||
|
|
|
@ -268,6 +268,62 @@ grub_script_function_call (grub_script_function_t func, int argc, char **args)
|
||||||
return ret;
|
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. */
|
/* Execute a single command line. */
|
||||||
grub_err_t
|
grub_err_t
|
||||||
grub_script_execute_cmdline (struct grub_script_cmd *cmd)
|
grub_script_execute_cmdline (struct grub_script_cmd *cmd)
|
||||||
|
|
|
@ -95,6 +95,7 @@ void
|
||||||
grub_script_free (struct grub_script *script)
|
grub_script_free (struct grub_script *script)
|
||||||
{
|
{
|
||||||
struct grub_script *s;
|
struct grub_script *s;
|
||||||
|
struct grub_script *t;
|
||||||
|
|
||||||
if (!script)
|
if (!script)
|
||||||
return;
|
return;
|
||||||
|
@ -104,8 +105,9 @@ grub_script_free (struct grub_script *script)
|
||||||
|
|
||||||
s = script->children;
|
s = script->children;
|
||||||
while (s) {
|
while (s) {
|
||||||
s = s->siblings;
|
t = s->siblings;
|
||||||
grub_script_put (s);
|
grub_script_put (s);
|
||||||
|
s = t;
|
||||||
}
|
}
|
||||||
grub_free (script);
|
grub_free (script);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue