aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2008-02-19 16:16:03 -0800
committerH. Peter Anvin <hpa@zytor.com>2008-02-19 16:51:24 -0800
commite2bfd46bfc6372501d9379f5251bd97cce04ff3c (patch)
treeaa33fcf2f689262b715dbc9dbf08c015cf2fa681
parent87e51b1848c449827e1a5a6438a19d2047021816 (diff)
downloadsyslinux.git-e2bfd46bfc6372501d9379f5251bd97cce04ff3c.tar.gz
syslinux.git-e2bfd46bfc6372501d9379f5251bd97cce04ff3c.tar.xz
syslinux.git-e2bfd46bfc6372501d9379f5251bd97cce04ff3c.zip
simple menu: The use of realloc() requires indirect pointers
Since we store pointers to struct menu_entry, we can't put it in storage that is subject to realloc(). Accordingly, make menu_entries an indirect array instead.
-rw-r--r--com32/menu/menu.h3
-rw-r--r--com32/menu/menumain.c51
-rw-r--r--com32/menu/readconfig.c12
3 files changed, 37 insertions, 29 deletions
diff --git a/com32/menu/menu.h b/com32/menu/menu.h
index 62b2f46a..99d378e5 100644
--- a/com32/menu/menu.h
+++ b/com32/menu/menu.h
@@ -45,6 +45,7 @@ enum menu_action {
};
struct menu_entry {
+ int entry; /* Entry number inside menu */
const char *displayname;
const char *label;
const char *passwd;
@@ -134,7 +135,7 @@ struct menu {
struct menu *parent;
struct menu_entry *parent_entry; /* Entry for self in parent */
- struct menu_entry *menu_entries;
+ struct menu_entry **menu_entries;
struct menu_entry *menu_hotkeys[256];
const char *messages[MSG_COUNT];
diff --git a/com32/menu/menumain.c b/com32/menu/menumain.c
index 84fe2b0e..fb6a99f9 100644
--- a/com32/menu/menumain.c
+++ b/com32/menu/menumain.c
@@ -131,7 +131,7 @@ static void
draw_row(int y, int sel, int top, int sbtop, int sbbot)
{
int i = (y-4-VSHIFT)+top;
- int dis = (i < cm->nentries) && is_disabled(&cm->menu_entries[i]);
+ int dis = (i < cm->nentries) && is_disabled(cm->menu_entries[i]);
printf("\033[%d;%dH\1#1\016x\017%s ",
y, MARGIN+1+HSHIFT,
@@ -140,7 +140,7 @@ draw_row(int y, int sel, int top, int sbtop, int sbbot)
if ( i >= cm->nentries ) {
fputs(pad_line("", 0, WIDTH-2*MARGIN-4), stdout);
} else {
- display_entry(&cm->menu_entries[i],
+ display_entry(cm->menu_entries[i],
(i == sel) ? "\1#5" : dis ? "\2#17" : "\1#3",
(i == sel) ? "\1#6" : dis ? "\2#17" : "\1#4",
WIDTH-2*MARGIN-4);
@@ -676,7 +676,7 @@ do_hidden_menu(void)
}
}
- return cm->menu_entries[cm->defentry].cmdline; /* Default entry */
+ return cm->menu_entries[cm->defentry]->cmdline; /* Default entry */
}
static const char *
@@ -689,6 +689,7 @@ run_menu(void)
int clear = 1, to_clear;
const char *cmdline = NULL;
volatile clock_t key_timeout, timeout_left, this_timeout;
+ const struct menu_entry *me;
/* Note: for both key_timeout and timeout == 0 means no limit */
timeout_left = key_timeout = cm->timeout;
@@ -696,7 +697,7 @@ run_menu(void)
/* If we're in shiftkey mode, exit immediately unless a shift key
is pressed */
if ( shiftkey && !shift_is_held() ) {
- return cm->menu_entries[cm->defentry].cmdline;
+ return cm->menu_entries[cm->defentry]->cmdline;
} else {
shiftkey = 0;
}
@@ -726,23 +727,25 @@ run_menu(void)
top = min(entry, max(0, cm->nentries-MENU_ROWS));
draw_menu(cm->ontimeout ? -1 : entry, top, 1);
- cmdline = cm->ontimeout ? cm->ontimeout : cm->menu_entries[entry].cmdline;
+ cmdline = cm->ontimeout ? cm->ontimeout : cm->menu_entries[entry]->cmdline;
done = 1;
}
while ( !done ) {
if ( entry <= 0 ) {
entry = 0;
- while (entry < cm->nentries && is_disabled(&cm->menu_entries[entry]))
+ while (entry < cm->nentries && is_disabled(cm->menu_entries[entry]))
entry++;
}
if ( entry >= cm->nentries ) {
entry = cm->nentries-1;
- while (entry > 0 && is_disabled(&cm->menu_entries[entry]))
+ while (entry > 0 && is_disabled(cm->menu_entries[entry]))
entry--;
}
+ me = cm->menu_entries[entry];
+
if ( top < 0 || top < entry-MENU_ROWS+1 )
top = max(0, entry-MENU_ROWS+1);
else if ( top > entry || top > max(0, cm->nentries-MENU_ROWS) )
@@ -762,11 +765,11 @@ run_menu(void)
if ( top != prev_top ) {
draw_menu(entry, top, 1);
- display_help(cm->menu_entries[entry].helptext);
+ display_help(me->helptext);
} else if ( entry != prev_entry ) {
draw_row(prev_entry-top+4+VSHIFT, entry, top, 0, 0);
draw_row(entry-top+4+VSHIFT, entry, top, 0, 0);
- display_help(cm->menu_entries[entry].helptext);
+ display_help(me->helptext);
}
prev_entry = entry; prev_top = top;
@@ -815,23 +818,23 @@ run_menu(void)
case KEY_ENTER:
case KEY_CTRL('J'):
key_timeout = 0; /* Cancels timeout */
- if ( cm->menu_entries[entry].passwd ) {
+ if ( me->passwd ) {
clear = 1;
- done = ask_passwd(cm->menu_entries[entry].passwd);
+ done = ask_passwd(me->passwd);
} else {
done = 1;
}
cmdline = NULL;
if (done) {
- switch (cm->menu_entries[entry].action) {
+ switch (me->action) {
case MA_CMD:
- cmdline = cm->menu_entries[entry].cmdline;
+ cmdline = me->cmdline;
break;
case MA_SUBMENU:
case MA_GOTO:
done = 0;
clear = 2;
- cm = cm->menu_entries[entry].submenu;
+ cm = me->submenu;
entry = top = 0;
break;
case MA_QUIT:
@@ -849,13 +852,13 @@ run_menu(void)
case KEY_UP:
case KEY_CTRL('P'):
- while (entry > 0 && entry-- && is_disabled(&cm->menu_entries[entry])) {
+ while (entry > 0 && entry-- && is_disabled(cm->menu_entries[entry])) {
if ( entry < top )
top -= MENU_ROWS;
}
if ( entry == 0 ) {
- while (is_disabled(&cm->menu_entries[entry]))
+ while (is_disabled(cm->menu_entries[entry]))
entry++;
}
break;
@@ -863,13 +866,13 @@ run_menu(void)
case KEY_DOWN:
case KEY_CTRL('N'):
while (entry < cm->nentries-1 && entry++ &&
- is_disabled(&cm->menu_entries[entry])) {
+ is_disabled(cm->menu_entries[entry])) {
if ( entry >= top+MENU_ROWS )
top += MENU_ROWS;
}
if ( entry >= cm->nentries-1 ) {
- while (is_disabled(&cm->menu_entries[entry]))
+ while (is_disabled(cm->menu_entries[entry]))
entry--;
}
break;
@@ -929,7 +932,7 @@ run_menu(void)
break;
case KEY_TAB:
- if ( cm->allowedit ) {
+ if ( cm->allowedit && me->action == MA_CMD ) {
int ok = 1;
key_timeout = 0; /* Cancels timeout */
@@ -946,7 +949,7 @@ run_menu(void)
}
if ( ok ) {
- cmdline = edit_cmdline(cm->menu_entries[entry].cmdline, top);
+ cmdline = edit_cmdline(me->cmdline, top);
done = !!cmdline;
clear = 1; /* In case we hit [Esc] and done is null */
} else {
@@ -956,7 +959,11 @@ run_menu(void)
break;
case KEY_CTRL('C'): /* Ctrl-C */
case KEY_ESC: /* Esc */
- if ( cm->allowedit ) {
+ if ( cm->parent ) {
+ cm = cm->parent;
+ clear = 2;
+ entry = top = 0;
+ } else if ( cm->allowedit ) {
done = 1;
clear = 1;
key_timeout = 0;
@@ -972,7 +979,7 @@ run_menu(void)
key &= ~0x20; /* Upper case */
if ( cm->menu_hotkeys[key] ) {
key_timeout = 0;
- entry = cm->menu_hotkeys[key] - cm->menu_entries;
+ entry = cm->menu_hotkeys[key]->entry;
/* Should we commit at this point? */
}
}
diff --git a/com32/menu/readconfig.c b/com32/menu/readconfig.c
index 4c2ecbd4..c3f2da4b 100644
--- a/com32/menu/readconfig.c
+++ b/com32/menu/readconfig.c
@@ -211,12 +211,12 @@ static struct menu_entry *new_entry(struct menu *m)
m->nentries_space <<= 1;
m->menu_entries = realloc(m->menu_entries, m->nentries_space*
- sizeof(struct menu_entry));
+ sizeof(struct menu_entry *));
}
- me = &m->menu_entries[m->nentries++];
- memset(me, 0, sizeof *me);
-
+ me = calloc(1, sizeof(struct menu_entry));
+ me->entry = m->nentries;
+ m->menu_entries[m->nentries++] = me;
*all_entries_end = me;
all_entries_end = &me->next;
@@ -367,8 +367,8 @@ static const char *unlabel(const char *str)
/* 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] ) {
+ for (me = all_entries; me; me = me->next) {
+ if (!strncmp(str, me->label, pos) && !me->label[pos]) {
/* Found matching label */
rsprintf(&q, "%s%s", me->cmdline, p);
refstr_put(str);