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> 2010-09-20 Vladimir Serbinenko <phcoder@gmail.com>
Menu entries extractor. Menu entries extractor.

View file

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

View file

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

View file

@ -123,8 +123,8 @@ grub_file_getline (grub_file_t file)
return cmdline; return cmdline;
} }
static void void
free_menu (grub_menu_t menu) grub_normal_free_menu (grub_menu_t menu)
{ {
grub_menu_entry_t entry = menu->entry_list; 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); grub_show_menu (menu, nested);
if (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; grub_err_t err = GRUB_ERR_NONE;
int errs_before; int errs_before;
grub_menu_t menu;
if (entry->restricted) if (entry->restricted)
err = grub_auth_check_authentication (entry->users); 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; 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_env_set ("chosen", entry->title);
grub_script_execute_sourcecode (entry->sourcecode, entry->argc, entry->args); 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 ()) 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. */
grub_command_execute ("boot", 0, 0); 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 /* 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. */ /* The flag of a completion window. */
int completion_shown; int completion_shown;
int submenu;
struct per_term_screen *terms; struct per_term_screen *terms;
unsigned nterms; unsigned nterms;
}; };
@ -496,6 +498,8 @@ make_screen (grub_menu_entry_t entry)
if (! screen) if (! screen)
return 0; return 0;
screen->submenu = entry->submenu;
screen->num_lines = 1; screen->num_lines = 1;
screen->lines = grub_malloc (sizeof (struct line)); screen->lines = grub_malloc (sizeof (struct line));
if (! screen->lines) if (! screen->lines)
@ -1162,6 +1166,7 @@ run (struct screen *screen)
int currline = 0; int currline = 0;
char *nextline; char *nextline;
int errs_before; int errs_before;
grub_menu_t menu;
auto grub_err_t editor_getline (char **line, int cont); auto grub_err_t editor_getline (char **line, int cont);
grub_err_t editor_getline (char **line, int cont __attribute__ ((unused))) 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; 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. */ /* Execute the script, line for line. */
while (currline < screen->num_lines) while (currline < screen->num_lines)
{ {
@ -1212,6 +1226,16 @@ run (struct screen *screen)
/* Implicit execution of boot, only if something is loaded. */ /* Implicit execution of boot, only if something is loaded. */
grub_command_execute ("boot", 0, 0); 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) if (grub_errno != GRUB_ERR_NONE)
{ {
grub_print_error (); grub_print_error ();

View file

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

View file

@ -119,11 +119,14 @@ extern int grub_extractor_level;
grub_err_t grub_err_t
grub_normal_add_menu_entry (int argc, const char **args, char **classes, grub_normal_add_menu_entry (int argc, const char **args, char **classes,
const char *users, const char *hotkey, const char *users, const char *hotkey,
const char *prefix, const char *sourcecode); const char *prefix, const char *sourcecode,
int submenu);
grub_err_t grub_err_t
grub_normal_set_password (const char *user, const char *password); 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_init (void);
void grub_normal_auth_fini (void); void grub_normal_auth_fini (void);