From: H. Peter Anvin Date: Fri, 22 Feb 2008 19:03:34 +0000 (-0800) Subject: Fix the handling of hotkeys in MENU LABEL on submenus X-Git-Tag: syslinux-3.62-pre14^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=44e9cab0e6bc5a7a75d8470e7a4ba41d739f4a37;p=profile%2Fivi%2Fsyslinux.git Fix the handling of hotkeys in MENU LABEL on submenus Two bugs: - We didn't strip ^ symbols inheriting from MENU LABEL to MENU TITLE - We did consider_for_hotkey() with the wrong menu (the submenu itself, as opposed to the parent menu.) As part of these changes, make a function available to create an uninitialized, mutable refstring (that can be constructed and then used as a refstring, that is.) --- diff --git a/com32/menu/readconfig.c b/com32/menu/readconfig.c index a17beb2..65e230d 100644 --- a/com32/menu/readconfig.c +++ b/com32/menu/readconfig.c @@ -93,6 +93,36 @@ skipspace(char *p) return p; } +/* Strip ^ from a string, returning a new reference to the same refstring + if none present */ +static const char *strip_caret(const char *str) +{ + const char *p, *r; + char *q; + int carets = 0; + + p = str; + for (;;) { + p = strchr(p, '^'); + if (!p) + break; + carets++; + p++; + } + + if (!carets) + return refstr_get(str); + + r = q = refstr_alloc(strlen(str)-carets); + for (p = str; *p; p++) + if (*p != '^') + *q++ = *p; + + *q = '\0'; /* refstr_alloc() already did this... */ + + return r; +} + /* Check to see if we are at a certain keyword (case insensitive) */ /* Returns a pointer to the first character past the keyword */ static char * @@ -223,12 +253,11 @@ static struct menu_entry *new_entry(struct menu *m) static void consider_for_hotkey(struct menu *m, struct menu_entry *me) { - unsigned char *p = - (unsigned char *)strchr(me->displayname, '^'); + const char *p = strchr(me->displayname, '^'); if (me->action != MA_DISABLED) { if ( p && p[1] ) { - int hotkey = p[1] & ~0x20; + unsigned char hotkey = p[1] & ~0x20; if ( !m->menu_hotkeys[hotkey] ) { me->hotkey = hotkey; m->menu_hotkeys[hotkey] = me; @@ -571,11 +600,11 @@ static void parse_config_file(FILE *f) } else if ( m->parent_entry ) { refstr_put(m->parent_entry->displayname); m->parent_entry->displayname = refstrdup(skipspace(p+5)); - consider_for_hotkey(m, m->parent_entry); + consider_for_hotkey(m->parent, m->parent_entry); if (!m->title[0]) { /* MENU LABEL -> MENU TITLE on submenu */ refstr_put(m->title); - m->title = refstr_get(m->parent_entry->displayname); + m->title = strip_caret(m->parent_entry->displayname); } } } else if ( looking_at(p, "title") ) { diff --git a/com32/menu/refstr.c b/com32/menu/refstr.c index 868a8ac..f727abc 100644 --- a/com32/menu/refstr.c +++ b/com32/menu/refstr.c @@ -21,6 +21,19 @@ #include #include "refstr.h" +/* Allocate space for a refstring of len bytes, plus final null */ +/* The final null is inserted in the string; the rest is uninitialized. */ +char *refstr_alloc(size_t len) +{ + char *r = malloc(sizeof(unsigned int)+len+1); + if (!r) + return NULL; + *(unsigned int *)r = 1; + r += sizeof(unsigned int); + r[len] = '\0'; + return r; +} + const char *refstrndup(const char *str, size_t len) { char *r; @@ -29,11 +42,9 @@ const char *refstrndup(const char *str, size_t len) return NULL; len = strnlen(str, len); - r = malloc(sizeof(unsigned int)+len+1); - *(unsigned int *)r = 1; - r += sizeof(unsigned int); - memcpy(r, str, len); - r[len] = '\0'; + r = refstr_alloc(len); + if (r) + memcpy(r, str, len); return r; } @@ -46,35 +57,27 @@ const char *refstrdup(const char *str) return NULL; len = strlen(str); - r = malloc(sizeof(unsigned int)+len+1); - *(unsigned int *)r = 1; - r += sizeof(unsigned int); - memcpy(r, str, len); - r[len] = '\0'; + r = refstr_alloc(len); + if (r) + memcpy(r, str, len); return r; } int vrsprintf(const char **bufp, const char *fmt, va_list ap) { va_list ap1; - int bytes; + int len; char *p; va_copy(ap1, ap); - bytes = vsnprintf(NULL, 0, fmt, ap1)+1; + len = vsnprintf(NULL, 0, fmt, ap1); va_end(ap1); - p = malloc(bytes+sizeof(unsigned int)); - if ( !p ) { - *bufp = NULL; + *bufp = p = refstr_alloc(len); + if ( !p ) return -1; - } - - *(unsigned int *)p = 1; - p += sizeof(unsigned int); - *bufp = p; - return vsnprintf(p, bytes, fmt, ap); + return vsnprintf(p, len+1, fmt, ap); } int rsprintf(const char **bufp, const char *fmt, ...) diff --git a/com32/menu/refstr.h b/com32/menu/refstr.h index 8bec018..f51777d 100644 --- a/com32/menu/refstr.h +++ b/com32/menu/refstr.h @@ -31,6 +31,7 @@ const char *refstr_get(const char *r) } void refstr_put(const char *); +char *refstr_alloc(size_t); const char *refstrdup(const char *); const char *refstrndup(const char *, size_t); int rsprintf(const char **, const char *, ...);