diff options
-rw-r--r-- | lib/draw/curses.c | 2 | ||||
-rw-r--r-- | lib/internal.h | 12 | ||||
-rw-r--r-- | lib/menu.c | 40 | ||||
-rw-r--r-- | lib/util.c | 41 |
4 files changed, 56 insertions, 39 deletions
diff --git a/lib/draw/curses.c b/lib/draw/curses.c index 946275e..3d7871e 100644 --- a/lib/draw/curses.c +++ b/lib/draw/curses.c @@ -182,7 +182,7 @@ static void _bmDrawCursesRender(const bmMenu *menu) curses.erase(); int titleLen = (menu->title ? strlen(menu->title) + 1 : 0); - _bmDrawCursesDrawLine(0, 0, "%*s%s", titleLen, "", menu->filter); + _bmDrawCursesDrawLine(0, 0, "%*s%s", titleLen, "", (menu->filter ? menu->filter : "")); if (menu->title) { curses.attron(COLOR_PAIR(1)); diff --git a/lib/internal.h b/lib/internal.h index 6d116a0..4f6afbe 100644 --- a/lib/internal.h +++ b/lib/internal.h @@ -103,9 +103,8 @@ struct _bmMenu { /** * Text used to filter matches. - * XXX: Change this to a pointer? */ - char filter[1024]; + char *filter; /** * Used as optimization. @@ -113,6 +112,11 @@ struct _bmMenu { char *oldFilter; /** + * Size of filter buffer + */ + size_t filterSize; + + /** * Current byte offset on filter text. */ unsigned int cursor; @@ -173,7 +177,7 @@ size_t _bmUtf8RuneNext(const char *string, size_t start); size_t _bmUtf8RunePrev(const char *string, size_t start); size_t _bmUtf8RuneWidth(const char *rune, unsigned int u8len); size_t _bmUtf8RuneRemove(char *string, size_t start, size_t *outRuneWidth); -size_t _bmUtf8RuneInsert(char *string, size_t bufSize, size_t start, const char *rune, unsigned int u8len, size_t *outRuneWidth); -size_t _bmUnicodeInsert(char *string, size_t bufSize, size_t start, unsigned int unicode, size_t *outRuneWidth); +size_t _bmUtf8RuneInsert(char **string, size_t *bufSize, size_t start, const char *rune, unsigned int u8len, size_t *outRuneWidth); +size_t _bmUnicodeInsert(char **string, size_t *bufSize, size_t start, unsigned int unicode, size_t *outRuneWidth); /* vim: set ts=8 sw=4 tw=0 :*/ @@ -71,6 +71,9 @@ void bmMenuFree(bmMenu *menu) if (menu->title) free(menu->title); + if (menu->filter) + free(menu->filter); + if (menu->oldFilter) free(menu->oldFilter); @@ -126,12 +129,11 @@ void bmMenuSetFilter(bmMenu *menu, const char *filter) { assert(menu); - if (!filter) { - memset(menu->filter, 0, sizeof(menu->filter)); - return; - } + if (menu->filter) + free(menu->filter); - strncpy(menu->filter, filter, sizeof(menu->filter)); + menu->filter = (filter ? _bmStrdup(filter) : NULL); + menu->filterSize = (filter ? strlen(filter) : 0); } /** @@ -426,7 +428,7 @@ bmItem** bmMenuGetFilteredItems(const bmMenu *menu, unsigned int *outNmemb) { assert(menu); - if (strlen(menu->filter)) + if (menu->filter && strlen(menu->filter)) return _bmItemListGetItems(&menu->filtered, outNmemb); return _bmItemListGetItems(&menu->items, outNmemb); @@ -459,7 +461,7 @@ void bmMenuFilter(bmMenu *menu) assert(menu); char addition = 0; - size_t len = strlen(menu->filter); + size_t len = (menu->filter ? strlen(menu->filter) : 0); if (!len || !menu->items.list || menu->items.count <= 0) { _bmItemListFreeList(&menu->filtered); @@ -561,7 +563,7 @@ bmRunResult bmMenuRunWithKey(bmMenu *menu, bmKey key, unsigned int unicode) break; case BM_KEY_END: - menu->cursor = strlen(menu->filter); + menu->cursor = (menu->filter ? strlen(menu->filter) : 0); menu->cursesCursor = _bmUtf8StringScreenWidth(menu->filter); break; @@ -619,17 +621,17 @@ bmRunResult bmMenuRunWithKey(bmMenu *menu, bmKey key, unsigned int unicode) case BM_KEY_WORD_DELETE: { - while (menu->cursor < strlen(menu->filter) && !isspace(menu->filter[menu->cursor])) { + while (menu->cursor < (menu->filter ? strlen(menu->filter) : 0) && !isspace(menu->filter[menu->cursor])) { unsigned int oldCursor = menu->cursor; menu->cursor += _bmUtf8RuneNext(menu->filter, menu->cursor); menu->cursesCursor += _bmUtf8RuneWidth(menu->filter + oldCursor, menu->cursor - oldCursor); } - while (menu->cursor > 0 && isspace(menu->filter[menu->cursor - 1])) { + while (menu->cursor > 0 && menu->filter && isspace(menu->filter[menu->cursor - 1])) { unsigned int oldCursor = menu->cursor; menu->cursor -= _bmUtf8RunePrev(menu->filter, menu->cursor); menu->cursesCursor -= _bmUtf8RuneWidth(menu->filter + menu->cursor, oldCursor - menu->cursor); } - while (menu->cursor > 0 && !isspace(menu->filter[menu->cursor - 1])) { + while (menu->cursor > 0 && menu->filter && !isspace(menu->filter[menu->cursor - 1])) { size_t width; menu->cursor -= _bmUtf8RuneRemove(menu->filter, menu->cursor, &width); menu->cursesCursor -= width; @@ -640,24 +642,18 @@ bmRunResult bmMenuRunWithKey(bmMenu *menu, bmKey key, unsigned int unicode) case BM_KEY_UNICODE: { size_t width; - menu->cursor += _bmUnicodeInsert(menu->filter, sizeof(menu->filter) - 1, menu->cursor, unicode, &width); + menu->cursor += _bmUnicodeInsert(&menu->filter, &menu->filterSize, menu->cursor, unicode, &width); menu->cursesCursor += width; } break; case BM_KEY_TAB: { + const char *text; bmItem *highlighted = bmMenuGetHighlightedItem(menu); - if (highlighted && bmItemGetText(highlighted)) { - const char *text = bmItemGetText(highlighted); - size_t len = strlen(text); - - if (len > sizeof(menu->filter) - 1) - len = sizeof(menu->filter) - 1; - - memset(menu->filter, 0, strlen(menu->filter)); - memcpy(menu->filter, text, len); - menu->cursor = strlen(menu->filter); + if (highlighted && (text = bmItemGetText(highlighted))) { + bmMenuSetFilter(menu, text); + menu->cursor = (menu->filter ? strlen(menu->filter) : 0); menu->cursesCursor = _bmUtf8StringScreenWidth(menu->filter); } } @@ -228,29 +228,45 @@ size_t _bmUtf8RuneRemove(char *string, size_t start, size_t *outRuneWidth) /** * Insert UTF8 rune to buffer. * - * @param string Null terminated C "string". - * @param bufSize Size of the buffer. + * @param inOutString Reference to buffer. + * @param inOutBufSize Reference to size of the buffer. * @param start Start offset where to insert to. (cursor) * @param rune Buffer to insert to string. * @param u8len Byte length of the rune. * @param outRuneWidth Reference to size_t, return number of columns for inserted rune, or -1 on failure. * @return Number of bytes inserted to buffer. */ -size_t _bmUtf8RuneInsert(char *string, size_t bufSize, size_t start, const char *rune, unsigned int u8len, size_t *outRuneWidth) +size_t _bmUtf8RuneInsert(char **inOutString, size_t *inOutBufSize, size_t start, const char *rune, unsigned int u8len, size_t *outRuneWidth) { - assert(string); + assert(inOutString); + assert(inOutBufSize); if (outRuneWidth) *outRuneWidth = 0; - size_t len = strlen(string); - if (len + u8len >= bufSize) + size_t len = (*inOutString ? strlen(*inOutString) : 0); + if (!*inOutString && !(*inOutString = calloc(1, (*inOutBufSize = u8len + 1)))) return 0; + if (len + u8len >= *inOutBufSize) { + void *tmp; + if (!(tmp = realloc(*inOutString, (*inOutBufSize * 2)))) { + if (!(tmp = malloc((*inOutBufSize * 2)))) + return 0; + + memcpy(tmp, *inOutString, *inOutBufSize); + free(*inOutString); + } + + memset(tmp + *inOutBufSize, 0, *inOutBufSize); + *inOutString = tmp; + *inOutBufSize *= 2; + } + if (u8len == 1 && !isprint(*rune)) return 0; - char *str = string + start; + char *str = *inOutString + start; memmove(str + u8len, str, len - start); memcpy(str, rune, u8len); @@ -262,16 +278,17 @@ size_t _bmUtf8RuneInsert(char *string, size_t bufSize, size_t start, const char /** * Insert unicode character to UTF8 buffer. * - * @param string Null terminated C "string". - * @param bufSize Size of the buffer. + * @param inOutString Reference to buffer. + * @param inOutBufSize Reference to size of the buffer. * @param start Start offset where to insert to. (cursor) * @param unicode Unicode character to insert. * @param outRuneWidth Reference to size_t, return number of columns for inserted rune, or -1 on failure. * @return Number of bytes inserted to buffer. */ -size_t _bmUnicodeInsert(char *string, size_t bufSize, size_t start, unsigned int unicode, size_t *outRuneWidth) +size_t _bmUnicodeInsert(char **inOutString, size_t *inOutBufSize, size_t start, unsigned int unicode, size_t *outRuneWidth) { - assert(string); + assert(inOutString); + assert(inOutBufSize); char u8len = ((unicode < 0x80) ? 1 : ((unicode < 0x800) ? 2 : ((unicode < 0x10000) ? 3 : 4))); char mb[5] = { 0, 0, 0, 0 }; @@ -285,7 +302,7 @@ size_t _bmUnicodeInsert(char *string, size_t bufSize, size_t start, unsigned int mb[0] |= (unicode >> (i * 6 - 6)); } - return _bmUtf8RuneInsert(string, bufSize, start, mb, u8len, outRuneWidth); + return _bmUtf8RuneInsert(inOutString, inOutBufSize, start, mb, u8len, outRuneWidth); } /* vim: set ts=8 sw=4 tw=0 :*/ |