Submenu default support.
* grub-core/normal/menu.c (grub_menu_execute_entry): New parameter auto_boot. All users updated. Declared static. Handle chosen and default with submenus. (grub_menu_execute_with_fallback): Declared static. Don't notify failure if autobooted. Upper level does it. (menuentry_eq): New function. (get_entry_number): Use menuentry_eq. (show_menu): New parameter "autobooted". All users updated. (grub_show_menu): Likewise. * include/grub/normal.h (grub_show_menu): Likewise. * include/grub/menu.h (grub_menu_execute_entry): Removed. (grub_menu_execute_with_fallback): Likewise.
This commit is contained in:
parent
6fef99b4e4
commit
dcb883b162
7 changed files with 137 additions and 24 deletions
18
ChangeLog
18
ChangeLog
|
@ -1,3 +1,21 @@
|
|||
2011-01-10 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
Submenu default support.
|
||||
|
||||
* grub-core/normal/menu.c (grub_menu_execute_entry): New parameter
|
||||
auto_boot. All users updated.
|
||||
Declared static.
|
||||
Handle chosen and default with submenus.
|
||||
(grub_menu_execute_with_fallback): Declared static.
|
||||
Don't notify failure if autobooted. Upper level does it.
|
||||
(menuentry_eq): New function.
|
||||
(get_entry_number): Use menuentry_eq.
|
||||
(show_menu): New parameter "autobooted". All users updated.
|
||||
(grub_show_menu): Likewise.
|
||||
* include/grub/normal.h (grub_show_menu): Likewise.
|
||||
* include/grub/menu.h (grub_menu_execute_entry): Removed.
|
||||
(grub_menu_execute_with_fallback): Likewise.
|
||||
|
||||
2011-01-10 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
* util/grub-mklayout.c (usage): Update help text.
|
||||
|
|
|
@ -213,7 +213,7 @@ grub_cmd_legacy_source (struct grub_command *cmd,
|
|||
grub_menu_t menu;
|
||||
menu = grub_env_get_menu ();
|
||||
if (menu && menu->size)
|
||||
grub_show_menu (menu, 1);
|
||||
grub_show_menu (menu, 1, 0);
|
||||
if (!extractor)
|
||||
grub_env_context_close ();
|
||||
}
|
||||
|
|
|
@ -287,7 +287,7 @@ grub_normal_execute (const char *config, int nested, int batch)
|
|||
{
|
||||
if (menu && menu->size)
|
||||
{
|
||||
grub_show_menu (menu, nested);
|
||||
grub_show_menu (menu, nested, 0);
|
||||
if (nested)
|
||||
grub_normal_free_menu (menu);
|
||||
}
|
||||
|
|
|
@ -154,12 +154,15 @@ get_and_remove_first_entry_number (const char *name)
|
|||
}
|
||||
|
||||
/* Run a menu entry. */
|
||||
void
|
||||
grub_menu_execute_entry(grub_menu_entry_t entry)
|
||||
static void
|
||||
grub_menu_execute_entry(grub_menu_entry_t entry, int auto_boot)
|
||||
{
|
||||
grub_err_t err = GRUB_ERR_NONE;
|
||||
int errs_before;
|
||||
grub_menu_t menu;
|
||||
char *optr, *buf, *oldchosen = NULL, *olddefault = NULL;
|
||||
const char *ptr, *chosen, *def;
|
||||
grub_size_t sz = 0;
|
||||
|
||||
if (entry->restricted)
|
||||
err = grub_auth_check_authentication (entry->users);
|
||||
|
@ -173,6 +176,9 @@ grub_menu_execute_entry(grub_menu_entry_t entry)
|
|||
|
||||
errs_before = grub_err_printed_errors;
|
||||
|
||||
chosen = grub_env_get ("chosen");
|
||||
def = grub_env_get ("default");
|
||||
|
||||
if (entry->submenu)
|
||||
{
|
||||
grub_env_context_open ();
|
||||
|
@ -180,9 +186,64 @@ grub_menu_execute_entry(grub_menu_entry_t entry)
|
|||
if (! menu)
|
||||
return;
|
||||
grub_env_set_menu (menu);
|
||||
if (auto_boot)
|
||||
grub_env_set ("timeout", "0");
|
||||
}
|
||||
|
||||
grub_env_set ("chosen", entry->title);
|
||||
for (ptr = entry->title; *ptr; ptr++)
|
||||
sz += (*ptr == '>') ? 2 : 1;
|
||||
if (chosen)
|
||||
{
|
||||
oldchosen = grub_strdup (chosen);
|
||||
if (!oldchosen)
|
||||
grub_print_error ();
|
||||
}
|
||||
if (def)
|
||||
{
|
||||
olddefault = grub_strdup (def);
|
||||
if (!olddefault)
|
||||
grub_print_error ();
|
||||
}
|
||||
sz++;
|
||||
if (chosen)
|
||||
sz += grub_strlen (chosen);
|
||||
sz++;
|
||||
buf = grub_malloc (sz);
|
||||
if (!buf)
|
||||
grub_print_error ();
|
||||
else
|
||||
{
|
||||
optr = buf;
|
||||
if (chosen)
|
||||
{
|
||||
optr = grub_stpcpy (optr, chosen);
|
||||
*optr++ = '>';
|
||||
}
|
||||
for (ptr = entry->title; *ptr; ptr++)
|
||||
{
|
||||
if (*ptr == '>')
|
||||
*optr++ = '>';
|
||||
*optr++ = *ptr;
|
||||
}
|
||||
*optr = 0;
|
||||
grub_env_set ("chosen", buf);
|
||||
grub_env_export ("chosen");
|
||||
grub_free (buf);
|
||||
}
|
||||
for (ptr = def; *ptr; ptr++)
|
||||
{
|
||||
if (ptr[0] == '>' && ptr[1] == '>')
|
||||
{
|
||||
ptr++;
|
||||
continue;
|
||||
}
|
||||
if (ptr[0] == '>')
|
||||
break;
|
||||
}
|
||||
if (ptr[0] && ptr[1])
|
||||
grub_env_set ("default", ptr + 1);
|
||||
else
|
||||
grub_env_unset ("default");
|
||||
grub_script_execute_sourcecode (entry->sourcecode, entry->argc, entry->args);
|
||||
|
||||
if (errs_before != grub_err_printed_errors)
|
||||
|
@ -196,20 +257,30 @@ grub_menu_execute_entry(grub_menu_entry_t entry)
|
|||
{
|
||||
if (menu && menu->size)
|
||||
{
|
||||
grub_show_menu (menu, 1);
|
||||
grub_show_menu (menu, 1, auto_boot);
|
||||
grub_normal_free_menu (menu);
|
||||
}
|
||||
grub_env_context_close ();
|
||||
}
|
||||
if (oldchosen)
|
||||
grub_env_set ("chosen", oldchosen);
|
||||
else
|
||||
grub_env_unset ("chosen");
|
||||
if (olddefault)
|
||||
grub_env_set ("default", olddefault);
|
||||
else
|
||||
grub_env_unset ("default");
|
||||
grub_env_unset ("timeout");
|
||||
}
|
||||
|
||||
/* Execute ENTRY from the menu MENU, falling back to entries specified
|
||||
in the environment variable "fallback" if it fails. CALLBACK is a
|
||||
pointer to a struct of function pointers which are used to allow the
|
||||
caller provide feedback to the user. */
|
||||
void
|
||||
static void
|
||||
grub_menu_execute_with_fallback (grub_menu_t menu,
|
||||
grub_menu_entry_t entry,
|
||||
int autobooted,
|
||||
grub_menu_execute_callback_t callback,
|
||||
void *callback_data)
|
||||
{
|
||||
|
@ -217,7 +288,7 @@ grub_menu_execute_with_fallback (grub_menu_t menu,
|
|||
|
||||
callback->notify_booting (entry, callback_data);
|
||||
|
||||
grub_menu_execute_entry (entry);
|
||||
grub_menu_execute_entry (entry, 1);
|
||||
|
||||
/* Deal with fallback entries. */
|
||||
while ((fallback_entry = get_and_remove_first_entry_number ("fallback"))
|
||||
|
@ -228,14 +299,15 @@ grub_menu_execute_with_fallback (grub_menu_t menu,
|
|||
|
||||
entry = grub_menu_get_entry (menu, fallback_entry);
|
||||
callback->notify_fallback (entry, callback_data);
|
||||
grub_menu_execute_entry (entry);
|
||||
grub_menu_execute_entry (entry, 1);
|
||||
/* If the function call to execute the entry returns at all, then this is
|
||||
taken to indicate a boot failure. For menu entries that do something
|
||||
other than actually boot an operating system, this could assume
|
||||
incorrectly that something failed. */
|
||||
}
|
||||
|
||||
callback->notify_failure (callback_data);
|
||||
if (!autobooted)
|
||||
callback->notify_failure (callback_data);
|
||||
}
|
||||
|
||||
static struct grub_menu_viewer *viewers;
|
||||
|
@ -309,11 +381,35 @@ grub_menu_register_viewer (struct grub_menu_viewer *viewer)
|
|||
viewers = viewer;
|
||||
}
|
||||
|
||||
static int
|
||||
menuentry_eq (const char *title, const char *spec)
|
||||
{
|
||||
const char *ptr1, *ptr2;
|
||||
ptr1 = title;
|
||||
ptr2 = spec;
|
||||
while (1)
|
||||
{
|
||||
if (*ptr2 == '>' && ptr2[1] != '>' && *ptr1 == 0)
|
||||
return 1;
|
||||
if (*ptr2 == '>' && ptr2[1] != '>')
|
||||
return 0;
|
||||
if (*ptr2 == '>')
|
||||
ptr2++;
|
||||
if (*ptr1 != *ptr2)
|
||||
return 0;
|
||||
if (*ptr1 == 0)
|
||||
return 1;
|
||||
ptr1++;
|
||||
ptr2++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Get the entry number from the variable NAME. */
|
||||
static int
|
||||
get_entry_number (grub_menu_t menu, const char *name)
|
||||
{
|
||||
char *val;
|
||||
const char *val;
|
||||
int entry;
|
||||
|
||||
val = grub_env_get (name);
|
||||
|
@ -334,7 +430,7 @@ get_entry_number (grub_menu_t menu, const char *name)
|
|||
|
||||
for (i = 0; e; i++)
|
||||
{
|
||||
if (grub_strcmp (e->title, val) == 0)
|
||||
if (menuentry_eq (e->title, val))
|
||||
{
|
||||
entry = i;
|
||||
break;
|
||||
|
@ -590,7 +686,7 @@ static struct grub_menu_execute_callback execution_callback =
|
|||
};
|
||||
|
||||
static grub_err_t
|
||||
show_menu (grub_menu_t menu, int nested)
|
||||
show_menu (grub_menu_t menu, int nested, int autobooted)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
|
@ -609,22 +705,26 @@ show_menu (grub_menu_t menu, int nested)
|
|||
grub_cls ();
|
||||
|
||||
if (auto_boot)
|
||||
grub_menu_execute_with_fallback (menu, e, &execution_callback, 0);
|
||||
grub_menu_execute_with_fallback (menu, e, autobooted,
|
||||
&execution_callback, 0);
|
||||
else
|
||||
grub_menu_execute_entry (e);
|
||||
grub_menu_execute_entry (e, 0);
|
||||
if (autobooted)
|
||||
break;
|
||||
}
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
grub_err_t
|
||||
grub_show_menu (grub_menu_t menu, int nested)
|
||||
grub_show_menu (grub_menu_t menu, int nested, int autoboot)
|
||||
{
|
||||
grub_err_t err1, err2;
|
||||
|
||||
while (1)
|
||||
{
|
||||
err1 = show_menu (menu, nested);
|
||||
err1 = show_menu (menu, nested, autoboot);
|
||||
autoboot = 0;
|
||||
grub_print_error ();
|
||||
|
||||
if (grub_normal_exit_level)
|
||||
|
|
|
@ -1227,7 +1227,7 @@ run (struct screen *screen)
|
|||
{
|
||||
if (menu && menu->size)
|
||||
{
|
||||
grub_show_menu (menu, 1);
|
||||
grub_show_menu (menu, 1, 0);
|
||||
grub_normal_free_menu (menu);
|
||||
}
|
||||
grub_env_context_close ();
|
||||
|
|
|
@ -94,11 +94,6 @@ typedef struct grub_menu_execute_callback
|
|||
grub_menu_entry_t grub_menu_get_entry (grub_menu_t menu, int no);
|
||||
int grub_menu_get_timeout (void);
|
||||
void grub_menu_set_timeout (int timeout);
|
||||
void grub_menu_execute_entry (grub_menu_entry_t entry);
|
||||
void grub_menu_execute_with_fallback (grub_menu_t menu,
|
||||
grub_menu_entry_t entry,
|
||||
grub_menu_execute_callback_t callback,
|
||||
void *callback_data);
|
||||
void grub_menu_entry_run (grub_menu_entry_t entry);
|
||||
int grub_menu_get_default_entry_index (grub_menu_t menu);
|
||||
|
||||
|
|
|
@ -89,7 +89,7 @@ void grub_print_message_indented (const char *msg, int margin_left,
|
|||
void
|
||||
grub_menu_text_register_instances (int entry, grub_menu_t menu, int nested);
|
||||
grub_err_t
|
||||
grub_show_menu (grub_menu_t menu, int nested);
|
||||
grub_show_menu (grub_menu_t menu, int nested, int autobooted);
|
||||
|
||||
/* Defined in `handler.c'. */
|
||||
void read_handler_list (void);
|
||||
|
|
Loading…
Reference in a new issue