Support submenus.

* grub-core/commands/menuentry.c (grub_normal_add_menu_entry): New
	parameter submenu. All users updated.
	* grub-core/normal/main.c (free_menu): Rename to ...
	(grub_normal_free_menu): ... this. Made global.
	* grub-core/normal/menu.c (grub_menu_execute_entry): Open new context
	if requested.
	* grub-core/normal/menu_entry.c (screen): New field submenu.
	(make_screen): Set submenu.
	(run): Open new context if requested.
	* include/grub/menu.h (grub_menu_entry): New field submenu.
	* include/grub/normal.h (grub_normal_free_menu): New proto.
This commit is contained in:
Vladimir 'phcoder' Serbinenko 2010-09-21 00:47:49 +02:00
parent 600cedf7f4
commit fc55cc4c27
8 changed files with 109 additions and 24 deletions

View file

@ -1,3 +1,19 @@
2010-09-20 Vladimir Serbinenko <phcoder@gmail.com>
Support submenus.
* grub-core/commands/menuentry.c (grub_normal_add_menu_entry): New
parameter submenu. All users updated.
* grub-core/normal/main.c (free_menu): Rename to ...
(grub_normal_free_menu): ... this. Made global.
* grub-core/normal/menu.c (grub_menu_execute_entry): Open new context
if requested.
* grub-core/normal/menu_entry.c (screen): New field submenu.
(make_screen): Set submenu.
(run): Open new context if requested.
* include/grub/menu.h (grub_menu_entry): New field submenu.
* include/grub/normal.h (grub_normal_free_menu): New proto.
2010-09-20 Vladimir Serbinenko <phcoder@gmail.com>
Menu entries extractor.

View file

@ -118,7 +118,7 @@ legacy_file (const char *filename)
}
args[0] = oldname;
grub_normal_add_menu_entry (1, args, NULL, NULL, NULL, NULL,
entrysrc);
entrysrc, 0);
grub_free (args);
entrysrc[0] = 0;
grub_free (oldname);
@ -168,7 +168,7 @@ legacy_file (const char *filename)
return grub_errno;
}
args[0] = entryname;
grub_normal_add_menu_entry (1, args, NULL, NULL, NULL, NULL, entrysrc);
grub_normal_add_menu_entry (1, args, NULL, NULL, NULL, NULL, entrysrc, 0);
grub_free (args);
}

View file

@ -68,9 +68,9 @@ static struct
grub_err_t
grub_normal_add_menu_entry (int argc, const char **args, char **classes,
const char *users, const char *hotkey,
const char *prefix, const char *sourcecode)
const char *prefix, const char *sourcecode,
int submenu)
{
unsigned i;
int menu_hotkey = 0;
char **menu_args = NULL;
char *menu_users = NULL;
@ -93,6 +93,7 @@ grub_normal_add_menu_entry (int argc, const char **args, char **classes,
if (classes)
{
int i;
for (i = 0; classes[i]; i++); /* count # of menuentry classes */
menu_classes = grub_zalloc (sizeof (struct grub_menu_entry_class) * i);
if (! menu_classes)
@ -116,6 +117,7 @@ grub_normal_add_menu_entry (int argc, const char **args, char **classes,
if (hotkey)
{
unsigned i;
for (i = 0; i < ARRAY_SIZE (hotkey_aliases); i++)
if (grub_strcmp (hotkey, hotkey_aliases[i].name) == 0)
{
@ -141,6 +143,8 @@ grub_normal_add_menu_entry (int argc, const char **args, char **classes,
if (! menu_args)
goto fail;
{
int i;
for (i = 0; i < argc; i++)
{
menu_args[i] = grub_strdup (args[i]);
@ -148,6 +152,7 @@ grub_normal_add_menu_entry (int argc, const char **args, char **classes,
goto fail;
}
menu_args[argc] = NULL;
}
/* Add the menu entry at the end of the list. */
while (*last)
@ -166,6 +171,7 @@ grub_normal_add_menu_entry (int argc, const char **args, char **classes,
(*last)->argc = argc;
(*last)->args = menu_args;
(*last)->sourcecode = menu_sourcecode;
(*last)->submenu = submenu;
menu->size++;
return GRUB_ERR_NONE;
@ -173,13 +179,19 @@ grub_normal_add_menu_entry (int argc, const char **args, char **classes,
fail:
grub_free (menu_sourcecode);
{
int i;
for (i = 0; menu_classes && menu_classes[i].name; i++)
grub_free (menu_classes[i].name);
grub_free (menu_classes);
}
{
int i;
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_title);
@ -259,7 +271,8 @@ grub_cmd_menuentry (grub_extcmd_context_t ctxt, int argc, char **args)
return grub_normal_add_menu_entry (argc, (const char **) args,
ctxt->state[0].args, ctxt->state[1].arg,
ctxt->state[2].arg, 0,
ctxt->state[3].arg);
ctxt->state[3].arg,
ctxt->extcmd->cmd->name[0] == 's');
src = args[argc - 1];
args[argc - 1] = NULL;
@ -274,7 +287,8 @@ grub_cmd_menuentry (grub_extcmd_context_t ctxt, int argc, char **args)
r = grub_normal_add_menu_entry (argc - 1, (const char **) args,
ctxt->state[0].args, ctxt->state[1].arg,
ctxt->state[2].arg, prefix, src + 1);
ctxt->state[2].arg, prefix, src + 1,
ctxt->extcmd->cmd->name[0] == 's');
src[len - 1] = ch;
args[argc - 1] = src;
@ -282,7 +296,7 @@ grub_cmd_menuentry (grub_extcmd_context_t ctxt, int argc, char **args)
return r;
}
static grub_extcmd_t cmd;
static grub_extcmd_t cmd, cmd_sub;
void
grub_menu_init (void)
@ -291,10 +305,16 @@ grub_menu_init (void)
GRUB_COMMAND_FLAG_BLOCKS
| GRUB_COMMAND_FLAG_EXTRACTOR,
N_("BLOCK"), N_("Define a menuentry."), options);
cmd_sub = grub_register_extcmd ("submenu", grub_cmd_menuentry,
GRUB_COMMAND_FLAG_BLOCKS
| GRUB_COMMAND_FLAG_EXTRACTOR,
N_("BLOCK"), N_("Define a submenu."),
options);
}
void
grub_menu_fini (void)
{
grub_unregister_extcmd (cmd);
grub_unregister_extcmd (cmd_sub);
}

View file

@ -123,8 +123,8 @@ grub_file_getline (grub_file_t file)
return cmdline;
}
static void
free_menu (grub_menu_t menu)
void
grub_normal_free_menu (grub_menu_t menu)
{
grub_menu_entry_t entry = menu->entry_list;
@ -289,7 +289,7 @@ grub_normal_execute (const char *config, int nested, int batch)
{
grub_show_menu (menu, nested);
if (nested)
free_menu (menu);
grub_normal_free_menu (menu);
}
}
}

View file

@ -159,6 +159,7 @@ grub_menu_execute_entry(grub_menu_entry_t entry)
{
grub_err_t err = GRUB_ERR_NONE;
int errs_before;
grub_menu_t menu;
if (entry->restricted)
err = grub_auth_check_authentication (entry->users);
@ -172,6 +173,15 @@ grub_menu_execute_entry(grub_menu_entry_t entry)
errs_before = grub_err_printed_errors;
if (entry->submenu)
{
grub_env_context_open ();
menu = grub_zalloc (sizeof (*menu));
if (! menu)
return;
grub_env_set_menu (menu);
}
grub_env_set ("chosen", entry->title);
grub_script_execute_sourcecode (entry->sourcecode, entry->argc, entry->args);
@ -181,6 +191,16 @@ grub_menu_execute_entry(grub_menu_entry_t entry)
if (grub_errno == GRUB_ERR_NONE && grub_loader_is_loaded ())
/* Implicit execution of boot, only if something is loaded. */
grub_command_execute ("boot", 0, 0);
if (entry->submenu)
{
if (menu && menu->size)
{
grub_show_menu (menu, 1);
grub_normal_free_menu (menu);
}
grub_env_context_close ();
}
}
/* Execute ENTRY from the menu MENU, falling back to entries specified

View file

@ -71,6 +71,8 @@ struct screen
/* The flag of a completion window. */
int completion_shown;
int submenu;
struct per_term_screen *terms;
unsigned nterms;
};
@ -496,6 +498,8 @@ make_screen (grub_menu_entry_t entry)
if (! screen)
return 0;
screen->submenu = entry->submenu;
screen->num_lines = 1;
screen->lines = grub_malloc (sizeof (struct line));
if (! screen->lines)
@ -1162,6 +1166,7 @@ run (struct screen *screen)
int currline = 0;
char *nextline;
int errs_before;
grub_menu_t menu;
auto grub_err_t editor_getline (char **line, int cont);
grub_err_t editor_getline (char **line, int cont __attribute__ ((unused)))
@ -1197,6 +1202,15 @@ run (struct screen *screen)
errs_before = grub_err_printed_errors;
if (screen->submenu)
{
grub_env_context_open ();
menu = grub_zalloc (sizeof (*menu));
if (! menu)
return;
grub_env_set_menu (menu);
}
/* Execute the script, line for line. */
while (currline < screen->num_lines)
{
@ -1212,6 +1226,16 @@ run (struct screen *screen)
/* Implicit execution of boot, only if something is loaded. */
grub_command_execute ("boot", 0, 0);
if (screen->submenu)
{
if (menu && menu->size)
{
grub_show_menu (menu, 1);
grub_normal_free_menu (menu);
}
grub_env_context_close ();
}
if (grub_errno != GRUB_ERR_NONE)
{
grub_print_error ();

View file

@ -53,6 +53,8 @@ struct grub_menu_entry
int hotkey;
int submenu;
/* The next element. */
struct grub_menu_entry *next;
};

View file

@ -119,11 +119,14 @@ extern int grub_extractor_level;
grub_err_t
grub_normal_add_menu_entry (int argc, const char **args, char **classes,
const char *users, const char *hotkey,
const char *prefix, const char *sourcecode);
const char *prefix, const char *sourcecode,
int submenu);
grub_err_t
grub_normal_set_password (const char *user, const char *password);
void grub_normal_free_menu (grub_menu_t menu);
void grub_normal_auth_init (void);
void grub_normal_auth_fini (void);