More work on menu module. Looks like the file libc isn't quite there
authorhpa <hpa>
Tue, 21 Dec 2004 01:37:43 +0000 (01:37 +0000)
committerhpa <hpa>
Tue, 21 Dec 2004 01:37:43 +0000 (01:37 +0000)
yet; however, debugging needed.

com32/lib/Makefile
com32/libutil/ansiraw.c
com32/modules/Makefile
com32/modules/menu.c
com32/modules/menu.h [new file with mode: 0644]
com32/modules/readconfig.c [new file with mode: 0644]

index 8ba4220..522761b 100644 (file)
@@ -13,7 +13,7 @@ LIBOBJS = abort.o atexit.o atoi.o atol.o atoll.o calloc.o creat.o     \
        strntoimax.o strntoumax.o strrchr.o strsep.o strspn.o strstr.o  \
        strtoimax.o strtok.o strtol.o strtoll.o strtoul.o strtoull.o    \
        strtoumax.o vfprintf.o vprintf.o vsnprintf.o vsprintf.o         \
-       asprintf.o vasprintf.o                                          \
+       asprintf.o vasprintf.o strlcpy.o strlcat.o                      \
        vsscanf.o libgcc/__ashldi3.o libgcc/__udivdi3.o                 \
        libgcc/__negdi2.o libgcc/__ashrdi3.o libgcc/__lshrdi3.o         \
        libgcc/__muldi3.o libgcc/__udivmoddi4.o libgcc/__umoddi3.o      \
index 1a0820d..8761b59 100644 (file)
@@ -86,7 +86,7 @@ void console_ansi_raw(void)
   tio.c_lflag &= ~(ISIG|ICANON|ECHO);
   tio.c_cc[VMIN]  = 0;
   tio.c_cc[VTIME] = 1;         /* Don't 100% busy-wait in Linux */
-  tcsetattr(0, TCSANOW, &tio);
+  tcsetattr(0, TCSAFLUSH, &tio);
   fputs("\033[0m\033[20h", stdout);
 }
 
index 4b6f335..570ec9c 100644 (file)
@@ -76,6 +76,12 @@ all: $(MODULES)
 %.c32: %.elf
        $(OBJCOPY) -O binary $< $@
 
+menu.elf : menu.o readconfig.o $(LIBS)
+       $(LD) $(LDFLAGS) -o $@ $^
+
+menu.lnx : menu.lo readconfig.lo $(LNXLIBS)
+       $(CC) $(LNXLDFLAGS) -o $@ $^
+
 tidy:
        rm -f *.o *.lo *.a *.lst *.elf
 
index 6757a9f..e3dace2 100644 (file)
 #include <com32.h>
 #endif
 
-struct menu_entry {
-  char *displayname;
-  char *cmdline;
-};
-
-#define MAX_CMDLINE_LEN         256
-
-#define MAX_ENTRIES    4096    /* Oughta be enough for anybody */
-struct menu_entry menu_entries[MAX_ENTRIES];
-
-int nentries  = 0;
-int defentry  = 0;
-int allowedit = 1;             /* Allow edits of the command line */
-
-char *menu_title = "This is the menu title";
+#include "menu.h"
 
 struct menu_attrib {
   const char *border;          /* Border area */
@@ -145,15 +131,6 @@ void draw_menu(int sel, int top)
   if ( allowedit )
     printf("%s\033[%d;1H%s", menu_attrib->tabmsg, TABMSG_ROW,
           pad_line("Press [Tab] to edit options", 1, WIDTH));
-
-  /* sel == -1 is a valid way of saying "draw nothing" */
-  if ( sel >= 0 ) {
-    printf("\033[%d;1H%s> %s%s\033[%d;1H",
-          CMDLINE_ROW, menu_attrib->cmdmark,
-          menu_attrib->cmdline,
-          pad_line(menu_entries[sel].cmdline, 0, 255),
-          END_ROW);
-  }
 }
 
 char *edit_cmdline(char *input)
@@ -242,7 +219,7 @@ const char *run_menu(void)
       entry = nentries-1;
 
     if ( top < 0 || top < entry-MENU_ROWS+1 )
-      top = max(0,entry-MENU_ROWS+1);
+      top = max(0, entry-MENU_ROWS+1);
     else if ( top > entry )
       top = entry;
 
@@ -284,21 +261,24 @@ const char *run_menu(void)
       top++;
       break;
     case KEY_TAB:
-      draw_menu(-1, top);      /* Disable bar */
-      cmdline = edit_cmdline(menu_entries[entry].cmdline);
-      if ( cmdline )
-       return cmdline;
+      if ( allowedit ) {
+       draw_menu(-1, top);     /* Disable bar */
+       cmdline = edit_cmdline(menu_entries[entry].cmdline);
+       if ( cmdline )
+         return cmdline;
+      }
       break;
     case KEY_CTRL('C'):                /* Ctrl-C */
     case KEY_ESC:              /* Esc */
-      exit(1);                 /* FIX THIS... do something sane here */
+      if ( allowedit )
+       return NULL;
     default:
       break;
     }
   }
 
-  printf("\033[%d;1H\033[0m", END_ROW);
-  return menu_entries[defentry].cmdline;
+  /* Return the label name so localboot and ipappend work */
+  return menu_entries[entry].displayname;
 }
 
 
@@ -320,21 +300,21 @@ void __attribute__((noreturn)) execute(const char *cmdline)
 #endif
 }
 
-int main(void)
+int main(int argc, char *argv[])
 {
   const char *cmdline;
-  int i;
 
-  console_ansi_raw();
+  (void)argc;
 
+  console_ansi_raw();
   fputs("\033%@\033(U", stdout); /* Enable CP 437 graphics on a real console */
 
-  for ( i = 1 ; i < 30 ; i++ ) {
-    asprintf(&menu_entries[nentries].displayname, "entry %2d", i);
-    asprintf(&menu_entries[nentries].cmdline, "runentry n=%d", i);
-    nentries++;
-  }
+  parse_config(argv[1]);
 
   cmdline = run_menu();
-  execute(cmdline);
+  printf("\033[%d;1H\033[0m", END_ROW);
+  if ( cmdline )
+    execute(cmdline);
+  else
+    return 0;
 }
diff --git a/com32/modules/menu.h b/com32/modules/menu.h
new file mode 100644 (file)
index 0000000..e892a12
--- /dev/null
@@ -0,0 +1,44 @@
+#ident "$Id$"
+/* ----------------------------------------------------------------------- *
+ *   
+ *   Copyright 2004 H. Peter Anvin - All Rights Reserved
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
+ *   Boston MA 02111-1307, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * menu.h
+ *
+ * Header file for the menu project
+ */
+
+#ifndef MENU_H
+#define MENU_H
+
+struct menu_entry {
+  char *displayname;
+  char *cmdline;
+};
+
+#define MAX_CMDLINE_LEN         256
+
+#define MAX_ENTRIES    4096    /* Oughta be enough for anybody */
+extern struct menu_entry menu_entries[];
+
+extern int nentries;
+extern int defentry;
+extern int allowedit;
+extern int timeout;
+
+extern char *menu_title;
+extern char *ontimeout;
+
+void parse_config(const char *filename);
+
+#endif /* MENU_H */
+
diff --git a/com32/modules/readconfig.c b/com32/modules/readconfig.c
new file mode 100644 (file)
index 0000000..dec0ae5
--- /dev/null
@@ -0,0 +1,170 @@
+#ident "$Id$"
+/* ----------------------------------------------------------------------- *
+ *   
+ *   Copyright 2004 H. Peter Anvin - All Rights Reserved
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
+ *   Boston MA 02111-1307, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+#define _GNU_SOURCE            /* Needed for asprintf() on Linux */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <alloca.h>
+#ifdef __COM32__
+# include <com32.h>
+#endif
+
+#include "menu.h"
+
+int nentries  = 0;
+int defentry  = 0;
+int allowedit = 1;             /* Allow edits of the command line */
+int timeout   = 0;
+
+char *menu_title = "";
+char *ontimeout  = NULL;
+
+struct menu_entry menu_entries[MAX_ENTRIES];
+
+#define astrdup(x) ({ char *__x = (x); \
+                      size_t __n = strlen(__x) + 1; \
+                      char *__p = alloca(__n); \
+                      if ( __p ) memcpy(__p, __x, __n); \
+                      __p; })
+                      
+
+static const char *
+get_config(void)
+{
+#ifdef __COM32__
+  static com32sys_t r;
+  
+  r.eax.w[0] = 0x000E;
+  __intcall(0x22, &r, &r);
+
+  return MK_PTR(r.es, r.ebx.w[0]);
+#else
+  return "syslinux.cfg";       /* Dummy default name */
+#endif
+}
+  
+#define MAX_LINE 512
+
+static char *
+skipspace(char *p)
+{
+  while ( *p && *p <= ' ' )
+    p++;
+  
+  return p;
+}
+
+/* Check to see if we are at a certain keyword (case insensitive) */
+static int looking_at(const char *line, const char *kwd)
+{
+  const char *p = line;
+  const char *q = kwd;
+
+  while ( *p && *q && ((*p^*q) & ~0x20) == 0 ) {
+    p++;
+    q++;
+  }
+
+  if ( *q )
+    return 0;                  /* Didn't see the keyword */
+
+  return *p <= ' ';            /* Must be EOL or whitespace */
+}
+
+static void record(char *label, char *lkernel, char *lappend, char *append)
+{
+  if ( label ) {
+    char *a, *s;
+    menu_entries[nentries].displayname = label;
+    a = lappend;
+    if ( !a ) a = append;
+    if ( !a || (a[0] == '-' && !a[1]) ) a = "";
+    s = a[0] ? " " : "";
+    asprintf(&menu_entries[nentries].cmdline, "%s%s%s", lkernel, s, a);
+
+    printf("displayname: %s\n", menu_entries[nentries].displayname);
+    printf("cmdline:     %s\n", menu_entries[nentries].cmdline);
+
+    label = NULL;
+    free(lkernel);
+    if ( lappend )
+      free(lappend);
+    nentries++;
+  }
+}
+
+void parse_config(const char *filename)
+{
+  char line[MAX_LINE], *p;
+  FILE *f;
+  char *append = NULL;
+  char *label = NULL, *lkernel = NULL, *lappend = NULL;
+
+  if ( !filename )
+    filename = get_config();
+
+  f = fopen(filename, "r");
+  if ( !f )
+    return;
+
+  while ( fgets(line, sizeof line, f) ) {
+    p = strchr(line, '\r');
+    if ( p )
+      *p = '\0';
+    p = strchr(line, '\n');
+    if ( p )
+      *p = '\0';
+
+    p = skipspace(line);
+    printf("> %s\n", p);
+
+    if ( looking_at(p, "menu") ) {
+      p = skipspace(line+4);
+
+      if ( looking_at(p, "title") ) {
+       menu_title = strdup(skipspace(p+5));
+      } else if ( looking_at(p, "default") ) {
+       defentry = atoi(skipspace(p+7));
+      } else {
+       /* Unknown, ignore for now */
+      }
+    } else if ( looking_at(p, "append") ) {
+      char *a = strdup(skipspace(p+6));
+      if ( label )
+       lappend = a;
+      else
+       append = a;
+    } else if ( looking_at(p, "label") ) {
+      p = skipspace(p+5);
+      record(label, lkernel, lappend, append);
+      label   = strdup(p);
+      lkernel = strdup(p);
+      lappend = NULL;
+    } else if ( looking_at(p, "kernel") ) {
+      if ( label ) {
+       free(lkernel);
+       lkernel = strdup(skipspace(p+6));
+      }
+    } else if ( looking_at(p, "timeout") ) {
+      timeout = atoi(skipspace(p+7));
+    } else if ( looking_at(p, "ontimeout") ) {
+      ontimeout = strdup(skipspace(p+9));
+    } else if ( looking_at(p, "allowoptions") ) {
+      allowedit = atoi(skipspace(p+12));
+    }
+  }
+  
+  record(label, lkernel, lappend, append);
+  fclose(f);
+}