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:
Vladimir 'phcoder' Serbinenko 2011-01-10 23:27:58 +01:00
parent 6fef99b4e4
commit dcb883b162
7 changed files with 137 additions and 24 deletions

View file

@ -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> 2011-01-10 Vladimir Serbinenko <phcoder@gmail.com>
* util/grub-mklayout.c (usage): Update help text. * util/grub-mklayout.c (usage): Update help text.

View file

@ -213,7 +213,7 @@ grub_cmd_legacy_source (struct grub_command *cmd,
grub_menu_t menu; grub_menu_t menu;
menu = grub_env_get_menu (); menu = grub_env_get_menu ();
if (menu && menu->size) if (menu && menu->size)
grub_show_menu (menu, 1); grub_show_menu (menu, 1, 0);
if (!extractor) if (!extractor)
grub_env_context_close (); grub_env_context_close ();
} }

View file

@ -287,7 +287,7 @@ grub_normal_execute (const char *config, int nested, int batch)
{ {
if (menu && menu->size) if (menu && menu->size)
{ {
grub_show_menu (menu, nested); grub_show_menu (menu, nested, 0);
if (nested) if (nested)
grub_normal_free_menu (menu); grub_normal_free_menu (menu);
} }

View file

@ -154,12 +154,15 @@ get_and_remove_first_entry_number (const char *name)
} }
/* Run a menu entry. */ /* Run a menu entry. */
void static void
grub_menu_execute_entry(grub_menu_entry_t entry) grub_menu_execute_entry(grub_menu_entry_t entry, int auto_boot)
{ {
grub_err_t err = GRUB_ERR_NONE; grub_err_t err = GRUB_ERR_NONE;
int errs_before; int errs_before;
grub_menu_t menu; grub_menu_t menu;
char *optr, *buf, *oldchosen = NULL, *olddefault = NULL;
const char *ptr, *chosen, *def;
grub_size_t sz = 0;
if (entry->restricted) if (entry->restricted)
err = grub_auth_check_authentication (entry->users); 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; errs_before = grub_err_printed_errors;
chosen = grub_env_get ("chosen");
def = grub_env_get ("default");
if (entry->submenu) if (entry->submenu)
{ {
grub_env_context_open (); grub_env_context_open ();
@ -180,9 +186,64 @@ grub_menu_execute_entry(grub_menu_entry_t entry)
if (! menu) if (! menu)
return; return;
grub_env_set_menu (menu); 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); grub_script_execute_sourcecode (entry->sourcecode, entry->argc, entry->args);
if (errs_before != grub_err_printed_errors) if (errs_before != grub_err_printed_errors)
@ -196,20 +257,30 @@ grub_menu_execute_entry(grub_menu_entry_t entry)
{ {
if (menu && menu->size) if (menu && menu->size)
{ {
grub_show_menu (menu, 1); grub_show_menu (menu, 1, auto_boot);
grub_normal_free_menu (menu); grub_normal_free_menu (menu);
} }
grub_env_context_close (); 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 /* Execute ENTRY from the menu MENU, falling back to entries specified
in the environment variable "fallback" if it fails. CALLBACK is a in the environment variable "fallback" if it fails. CALLBACK is a
pointer to a struct of function pointers which are used to allow the pointer to a struct of function pointers which are used to allow the
caller provide feedback to the user. */ caller provide feedback to the user. */
void static void
grub_menu_execute_with_fallback (grub_menu_t menu, grub_menu_execute_with_fallback (grub_menu_t menu,
grub_menu_entry_t entry, grub_menu_entry_t entry,
int autobooted,
grub_menu_execute_callback_t callback, grub_menu_execute_callback_t callback,
void *callback_data) void *callback_data)
{ {
@ -217,7 +288,7 @@ grub_menu_execute_with_fallback (grub_menu_t menu,
callback->notify_booting (entry, callback_data); callback->notify_booting (entry, callback_data);
grub_menu_execute_entry (entry); grub_menu_execute_entry (entry, 1);
/* Deal with fallback entries. */ /* Deal with fallback entries. */
while ((fallback_entry = get_and_remove_first_entry_number ("fallback")) 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); entry = grub_menu_get_entry (menu, fallback_entry);
callback->notify_fallback (entry, callback_data); 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 /* 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 taken to indicate a boot failure. For menu entries that do something
other than actually boot an operating system, this could assume other than actually boot an operating system, this could assume
incorrectly that something failed. */ incorrectly that something failed. */
} }
callback->notify_failure (callback_data); if (!autobooted)
callback->notify_failure (callback_data);
} }
static struct grub_menu_viewer *viewers; static struct grub_menu_viewer *viewers;
@ -309,11 +381,35 @@ grub_menu_register_viewer (struct grub_menu_viewer *viewer)
viewers = 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. */ /* Get the entry number from the variable NAME. */
static int static int
get_entry_number (grub_menu_t menu, const char *name) get_entry_number (grub_menu_t menu, const char *name)
{ {
char *val; const char *val;
int entry; int entry;
val = grub_env_get (name); val = grub_env_get (name);
@ -334,7 +430,7 @@ get_entry_number (grub_menu_t menu, const char *name)
for (i = 0; e; i++) for (i = 0; e; i++)
{ {
if (grub_strcmp (e->title, val) == 0) if (menuentry_eq (e->title, val))
{ {
entry = i; entry = i;
break; break;
@ -590,7 +686,7 @@ static struct grub_menu_execute_callback execution_callback =
}; };
static grub_err_t static grub_err_t
show_menu (grub_menu_t menu, int nested) show_menu (grub_menu_t menu, int nested, int autobooted)
{ {
while (1) while (1)
{ {
@ -609,22 +705,26 @@ show_menu (grub_menu_t menu, int nested)
grub_cls (); grub_cls ();
if (auto_boot) 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 else
grub_menu_execute_entry (e); grub_menu_execute_entry (e, 0);
if (autobooted)
break;
} }
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
} }
grub_err_t 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; grub_err_t err1, err2;
while (1) while (1)
{ {
err1 = show_menu (menu, nested); err1 = show_menu (menu, nested, autoboot);
autoboot = 0;
grub_print_error (); grub_print_error ();
if (grub_normal_exit_level) if (grub_normal_exit_level)

View file

@ -1227,7 +1227,7 @@ run (struct screen *screen)
{ {
if (menu && menu->size) if (menu && menu->size)
{ {
grub_show_menu (menu, 1); grub_show_menu (menu, 1, 0);
grub_normal_free_menu (menu); grub_normal_free_menu (menu);
} }
grub_env_context_close (); grub_env_context_close ();

View file

@ -94,11 +94,6 @@ typedef struct grub_menu_execute_callback
grub_menu_entry_t grub_menu_get_entry (grub_menu_t menu, int no); grub_menu_entry_t grub_menu_get_entry (grub_menu_t menu, int no);
int grub_menu_get_timeout (void); int grub_menu_get_timeout (void);
void grub_menu_set_timeout (int timeout); 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); void grub_menu_entry_run (grub_menu_entry_t entry);
int grub_menu_get_default_entry_index (grub_menu_t menu); int grub_menu_get_default_entry_index (grub_menu_t menu);

View file

@ -89,7 +89,7 @@ void grub_print_message_indented (const char *msg, int margin_left,
void void
grub_menu_text_register_instances (int entry, grub_menu_t menu, int nested); grub_menu_text_register_instances (int entry, grub_menu_t menu, int nested);
grub_err_t 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'. */ /* Defined in `handler.c'. */
void read_handler_list (void); void read_handler_list (void);