+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.
}
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);
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);
}
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;
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)
if (hotkey)
{
+ unsigned i;
for (i = 0; i < ARRAY_SIZE (hotkey_aliases); i++)
if (grub_strcmp (hotkey, hotkey_aliases[i].name) == 0)
{
if (! menu_args)
goto fail;
- for (i = 0; i < argc; i++)
- {
- menu_args[i] = grub_strdup (args[i]);
- if (! menu_args[i])
- goto fail;
- }
- menu_args[argc] = NULL;
+ {
+ int i;
+ for (i = 0; i < argc; 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. */
while (*last)
(*last)->argc = argc;
(*last)->args = menu_args;
(*last)->sourcecode = menu_sourcecode;
+ (*last)->submenu = submenu;
menu->size++;
return GRUB_ERR_NONE;
fail:
grub_free (menu_sourcecode);
- 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_classes && menu_classes[i].name; i++)
+ grub_free (menu_classes[i].name);
+ grub_free (menu_classes);
+ }
- for (i = 0; menu_args && menu_args[i]; i++)
- grub_free (menu_args[i]);
- grub_free (menu_args);
+ {
+ 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);
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;
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;
return r;
}
-static grub_extcmd_t cmd;
+static grub_extcmd_t cmd, cmd_sub;
void
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);
}
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;
{
grub_show_menu (menu, nested);
if (nested)
- free_menu (menu);
+ grub_normal_free_menu (menu);
}
}
}
{
grub_err_t err = GRUB_ERR_NONE;
int errs_before;
+ grub_menu_t menu;
if (entry->restricted)
err = grub_auth_check_authentication (entry->users);
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);
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
/* The flag of a completion window. */
int completion_shown;
+ int submenu;
+
struct per_term_screen *terms;
unsigned nterms;
};
if (! screen)
return 0;
+ screen->submenu = entry->submenu;
+
screen->num_lines = 1;
screen->lines = grub_malloc (sizeof (struct line));
if (! screen->lines)
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)))
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)
{
/* 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 ();
int hotkey;
+ int submenu;
+
/* The next element. */
struct grub_menu_entry *next;
};
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);