Add new "UI" directive instead of abusing the DEFAULT directive
authorH. Peter Anvin <hpa@zytor.com>
Thu, 11 Dec 2008 22:59:36 +0000 (14:59 -0800)
committerH. Peter Anvin <hpa@zytor.com>
Sun, 14 Dec 2008 21:53:58 +0000 (13:53 -0800)
Add a new "UI" directive to specify a user interface module, instead
of abusing the DEFAULT directive.  This allows the DEFAULT directive
to be used for setting the default, even when the menu system is
enabled.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
NEWS
com32/menu/menu.h
com32/menu/readconfig.c
core/keywords
core/keywords.inc
core/parseconfig.inc
core/ui.inc
doc/menu.txt
doc/syslinux.txt

diff --git a/NEWS b/NEWS
index fbee594..07149d1 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -16,6 +16,10 @@ Changes in 3.73:
        * mboot.c32: add "-solaris" option to pass DHCP information to
          the Solaris kernel; required for automatic Solaris boot
          without using Solaris' pxeboot program.
+       * New UI directive, which allows a more natural way to specify
+         a menu system (or not.)  With the UI directive specifying
+         the menu system, the DEFAULT directive can be used to select
+         the default entry inside the menus.
 
 Changes in 3.72:
        * Include the pxechain.com module from Jeffery Hutzelman at
index 1fa1a24..e2ffc1b 100644 (file)
@@ -49,7 +49,7 @@ enum menu_action {
 };
 
 struct menu_entry {
-  int entry;                   /* Entry number inside menu */
+  struct menu *menu;           /* Parent menu */
   const char *displayname;
   const char *label;
   const char *passwd;
@@ -57,6 +57,7 @@ struct menu_entry {
   const char *cmdline;
   struct menu *submenu;
   struct menu_entry *next;     /* Linked list of all labels across menus */
+  int entry;                   /* Entry number inside menu */
   enum menu_action action;
   unsigned char hotkey;
 };
index 0d3093b..01dadff 100644 (file)
@@ -33,6 +33,10 @@ int shiftkey     = 0;                /* Only display menu if shift key pressed */
 int hiddenmenu   = 0;
 long long totaltimeout = 0;
 
+/* Keep track of global default */
+static int has_ui = 0;         /* DEFAULT only counts if UI is found */
+static const char *globaldefault = NULL;
+
 /* Linked list of all entires, hidden or not; used by unlabel() */
 static struct menu_entry *all_entries;
 static struct menu_entry **all_entries_end = &all_entries;
@@ -245,6 +249,7 @@ static struct menu_entry *new_entry(struct menu *m)
   }
 
   me = calloc(1, sizeof(struct menu_entry));
+  me->menu = m;
   me->entry = m->nentries;
   m->menu_entries[m->nentries++] = me;
   *all_entries_end = me;
@@ -390,6 +395,27 @@ static struct menu *end_submenu(void)
   return current_menu->parent ? current_menu->parent : current_menu;
 }
 
+static struct menu_entry *find_label(const char *str)
+{
+  const char *p;
+  struct menu_entry *me;
+  int pos;
+
+  p = str;
+  while ( *p && !my_isspace(*p) )
+    p++;
+
+  /* p now points to the first byte beyond the kernel name */
+  pos = p-str;
+
+  for (me = all_entries; me; me = me->next) {
+    if (!strncmp(str, me->label, pos) && !me->label[pos])
+      return me;
+  }
+
+  return NULL;
+}
+
 static const char *unlabel(const char *str)
 {
   /* Convert a CLI-style command line to an executable command line */
@@ -912,6 +938,11 @@ static void parse_config_file(FILE *f)
         ld.ipappend = atoi(skipspace(p+8));
       else
        ipappend = atoi(skipspace(p+8));
+    } else if ( looking_at(p, "default") ) {
+      refstr_put(globaldefault);
+      globaldefault = refstrdup(skipspace(p+7));
+    } else if ( looking_at(p, "ui") ) {
+      has_ui = 1;
     }
   }
 }
@@ -958,6 +989,7 @@ void parse_configs(char **argv)
 {
   const char *filename;
   struct menu *m;
+  struct menu_entry *me;
 
   empty_string = refstrdup("");
 
@@ -984,6 +1016,16 @@ void parse_configs(char **argv)
   /* Common postprocessing */
   resolve_gotos();
 
+  /* Handle global default */
+  if (has_ui && globaldefault) {
+    me = find_label(globaldefault);
+    if (me && me->menu != hide_menu) {
+      me->menu->defentry = me->entry;
+      start_menu = me->menu;
+    }
+  }
+
+  /* Final per-menu initialization, with all labels known */
   for (m = menu_list; m; m = m->next) {
     m->curentry = m->defentry; /* All menus start at their defaults */
 
index 7cd9ace..aeafb96 100644 (file)
@@ -5,6 +5,7 @@ append
 initrd
 config
 default
+ui
 display
 font
 implicit
index f563b9d..f2940e8 100644 (file)
@@ -50,7 +50,8 @@ keywd_table:
                keyword include,        pc_opencmd,     pc_include
                keyword append,         pc_append
                keyword initrd,         pc_filename,    InitRD
-               keyword default,        pc_default
+               keyword default,        pc_default,     1
+               keyword ui,             pc_default,     2
                keyword display,        pc_opencmd,     get_msg_file
                keyword font,           pc_opencmd,     loadfont
                keyword implicit,       pc_setint16,    AllowImplicit
index 55d6fbb..2fb26fd 100644 (file)
 
                section .text
 ;
-; "default" command
+; "default" or "ui" command, with level (1 = default, 2 = ui)
 ;
-pc_default:    mov di,default_cmd
+pc_default:    cmp ax,[DefaultLevel]
+               jb .skip
+               mov di,default_cmd
                call getline
                mov byte [di-1],0               ; null-terminate
-               ret
+.skip:         ret
 
 ;
 ; "ontimeout" command
@@ -467,6 +469,7 @@ NoComplete  dw 0                    ; No label completion on TAB key
 AllowImplicit   dw 1                    ; Allow implicit kernels
 AllowOptions   dw 1                    ; User-specified options allowed
 IncludeLevel   dw 1                    ; Nesting level
+DefaultLevel   dw 0                    ; The current level of default
 SerialPort     dw 0                    ; Serial port base (or 0 for no serial port)
 VKernel                db 0                    ; Have we seen any "label" statements?
 
index 4f5b1fd..7f88cda 100644 (file)
@@ -48,10 +48,12 @@ no_config_file:
 ; Check whether or not we are supposed to display the boot prompt.
 ;
 check_for_key:
-               cmp word [ForcePrompt],0        ; Force prompt?
-               jnz enter_command
                test byte [KbdFlags],5Bh        ; Shift Alt Caps Scroll
-               jz auto_boot                    ; If neither, default boot
+               jnz enter_command
+               cmp word [ForcePrompt],0        ; Force prompt?
+               jz auto_boot
+               cmp word [DefaultLevel],1       ; Active UI statement?
+               ja auto_boot
 
 enter_command:
                cmp word [NoEscape],0           ; If NOESCAPE, no prompt,
index a03c72a..fd5a44d 100644 (file)
@@ -28,28 +28,31 @@ configuration file for SYSLINUX, EXTLINUX and ISOLINUX, and the same
 directory as pxelinux.0 for PXELINUX), and put the following options
 in your configuration file:
 
-DEFAULT menu.c32
-PROMPT 0
+UI menu.c32
 
 
-There are a few menu additions to the command line, all starting with
-the keywords MENU or TEXT; like the rest of the Syslinux config file
-language, it is case insensitive:
+There are a few menu additions to the configuration file, all starting
+with the keywords MENU or TEXT; like the rest of the Syslinux config
+file language, it is case insensitive:
+
 
 MENU TITLE title
 
        Give the menu a title.  The title is presented at the top of
        the menu.
 
+
 MENU HIDDEN
 
        Do not display the actual menu unless the user presses a key.
        All that is displayed is a timeout message.
 
+
 MENU SEPARATOR
 
        Insert an empty line in the menu.
 
+
 MENU LABEL label
 
        (Only valid after a LABEL statement.)
@@ -85,6 +88,7 @@ MENU INDENT count
        (Only valid after a LABEL statement.)
        Will add "count" spaces in front of the displayed menu entry.
 
+
 MENU DISABLE
 
        (Only valid after a LABEL statement.)
@@ -142,8 +146,9 @@ MENU HIDE
 MENU DEFAULT
 
        (Only valid after a LABEL statement.)
-       Indicates that this entry should be the default.  If no
-       default is specified, use the first one.
+
+       Indicates that this entry should be the default for this
+       particular submenu.  See also the DEFAULT directive below.
 
 
 TEXT HELP
@@ -239,7 +244,23 @@ MENU START
        (Only valid inside MENU BEGIN ... MENU END)
 
        Indicates that the menu system should start at the menu being
-       defined instead of at the top-level menu.
+       defined instead of at the top-level menu.  See also the
+       DEFAULT directive below.
+
+
+DEFAULT label
+
+       Set the global default.  If "label" points into a submenu,
+       that menu becomes the start menu; in other words, this
+       directive has the same effect as both MENU DEFAULT and MENU
+       START.
+
+       For backwards compatibility with earlier versions of Syslinux,
+       this directive is ignored unless the configuration file also
+       contains a UI directive.
+
+       Note: the CLI accepts options after the label, or even a
+       non-label.  The menu system does not support that.
 
 
 INCLUDE filename [tagname]
index 285be8b..2d64e4b 100644 (file)
@@ -145,6 +145,11 @@ DEFAULT kernel options...
        true, as it caused problems when using a shell as a substitute
        for "init."  You may want to include this option manually.
 
+UI module options...
+       Selects a specific user interface module (typically menu.c32
+       or vesamenu.c32).  The command-line interface treats this as a
+       directive that overrides the DEFAULT and PROMPT directives.
+
 APPEND options...
         Add one or more options to the kernel command line.  These are
         added both for automatic and manual boots.  The options are