From: hpa Date: Tue, 21 Dec 2004 01:37:43 +0000 (+0000) Subject: More work on menu module. Looks like the file libc isn't quite there X-Git-Tag: syslinux-3.11~256 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=8d6c07657b1bb3c990a38af4132a424e5033d5f2;p=profile%2Fivi%2Fsyslinux.git More work on menu module. Looks like the file libc isn't quite there yet; however, debugging needed. --- diff --git a/com32/lib/Makefile b/com32/lib/Makefile index 8ba4220..522761b 100644 --- a/com32/lib/Makefile +++ b/com32/lib/Makefile @@ -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 \ diff --git a/com32/libutil/ansiraw.c b/com32/libutil/ansiraw.c index 1a0820d..8761b59 100644 --- a/com32/libutil/ansiraw.c +++ b/com32/libutil/ansiraw.c @@ -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); } diff --git a/com32/modules/Makefile b/com32/modules/Makefile index 4b6f335..570ec9c 100644 --- a/com32/modules/Makefile +++ b/com32/modules/Makefile @@ -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 diff --git a/com32/modules/menu.c b/com32/modules/menu.c index 6757a9f..e3dace2 100644 --- a/com32/modules/menu.c +++ b/com32/modules/menu.c @@ -29,21 +29,7 @@ #include #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 index 0000000..e892a12 --- /dev/null +++ b/com32/modules/menu.h @@ -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 index 0000000..dec0ae5 --- /dev/null +++ b/com32/modules/readconfig.c @@ -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 +#include +#include +#include +#ifdef __COM32__ +# include +#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); +}