From e39bba1a8a2fda74bcfd06f728b7e1fddadef161 Mon Sep 17 00:00:00 2001 From: June McEnroe Date: Sun, 20 Feb 2022 15:26:23 -0500 Subject: Move mbs out of struct Edit, use a global buffer This saves 4K in the edit buffers, not to mention all the heap allocations for the separate mbs buffers! There might be a way to be more clever about capacities, but I don't think it's worth it. --- edit.c | 36 ++++++++++++++++++++---------------- edit.h | 8 ++------ input.c | 27 ++++++++++++++++----------- 3 files changed, 38 insertions(+), 33 deletions(-) diff --git a/edit.c b/edit.c index a8f5d4a..7c24865 100644 --- a/edit.c +++ b/edit.c @@ -41,32 +41,33 @@ static bool isword(wchar_t ch) { void editFree(struct Edit *e) { free(e->buf); free(e->cut.buf); - free(e->mbs.buf); e->pos = e->len = e->cap = 0; e->cut.len = 0; - e->mbs.pos = 0; } -char *editString(struct Edit *e) { - size_t cap = e->len * MB_CUR_MAX + 1; - char *buf = realloc(e->mbs.buf, cap); - if (!buf) return NULL; - e->mbs.buf = buf; +char *editString(const struct Edit *e, char **buf, size_t *cap, size_t *pos) { + size_t req = e->len * MB_CUR_MAX + 1; + if (req > *cap) { + char *new = realloc(*buf, req); + if (!new) return NULL; + *buf = new; + *cap = req; + } const wchar_t *ptr = e->buf; - size_t len = wcsnrtombs(e->mbs.buf, &ptr, e->pos, cap-1, NULL); + size_t len = wcsnrtombs(*buf, &ptr, e->pos, *cap-1, NULL); if (len == (size_t)-1) return NULL; - e->mbs.pos = len; + if (pos) *pos = len; ptr = &e->buf[e->pos]; size_t n = wcsnrtombs( - &e->mbs.buf[len], &ptr, e->len - e->pos, cap-1 - len, NULL + *buf + len, &ptr, e->len - e->pos, *cap-1 - len, NULL ); if (n == (size_t)-1) return NULL; len += n; - e->mbs.buf[len] = '\0'; - return e->mbs.buf; + (*buf)[len] = '\0'; + return *buf; } int editReserve(struct Edit *e, size_t index, size_t count) { @@ -212,11 +213,14 @@ static void fix(struct Edit *e, const char *str) { } static bool eq(struct Edit *e, const char *str1) { + size_t pos; + static size_t cap; + static char *buf; + editString(e, &buf, &cap, &pos); const char *str2 = &str1[strlen(str1) + 1]; - const char *buf = editString(e); - return e->mbs.pos == strlen(str1) - && !strncmp(buf, str1, e->mbs.pos) - && !strcmp(&buf[e->mbs.pos], str2); + return pos == strlen(str1) + && !strncmp(buf, str1, pos) + && !strcmp(&buf[pos], str2); } int main(void) { diff --git a/edit.h b/edit.h index 49adb7f..9cf814b 100644 --- a/edit.h +++ b/edit.h @@ -42,10 +42,6 @@ struct Edit { wchar_t *buf; size_t len; } cut; - struct { - char *buf; - size_t pos; - } mbs; }; enum EditFn { @@ -76,8 +72,8 @@ int editVi(struct Edit *e, wchar_t ch); // Insert a character at the cursor. int editInsert(struct Edit *e, wchar_t ch); -// Convert the buffer to a multi-byte string stored in e->mbs. -char *editString(struct Edit *e); +// Convert the buffer to a multi-byte string. +char *editString(const struct Edit *e, char **buf, size_t *cap, size_t *pos); // Free all buffers. void editFree(struct Edit *e); diff --git a/input.c b/input.c index 28349f4..a74335e 100644 --- a/input.c +++ b/input.c @@ -158,10 +158,15 @@ static char *inputStop( return stop; } +static size_t cap; +static char *buf; + void inputUpdate(void) { uint id = windowID(); - char *buf = editString(&edits[id]); - if (!buf) err(EX_OSERR, "editString"); + + size_t pos = 0; + const char *ptr = editString(&edits[id], &buf, &cap, &pos); + if (!ptr) err(EX_OSERR, "editString"); const char *prefix = ""; const char *prompt = self.nick; @@ -192,7 +197,7 @@ void inputUpdate(void) { } else { prompt = ""; } - if (skip > &buf[edits[id].mbs.pos]) { + if (skip > &buf[pos]) { prefix = prompt = suffix = ""; skip = buf; } @@ -209,14 +214,14 @@ void inputUpdate(void) { waddstr(uiInput, suffix); getyx(uiInput, y, x); - int pos; + int posx; struct Style style = styleInput; - inputStop(styleInput, &style, skip, &buf[edits[id].mbs.pos]); - getyx(uiInput, y, pos); + inputStop(styleInput, &style, skip, &buf[pos]); + getyx(uiInput, y, posx); wmove(uiInput, y, x); + ptr = skip; style = styleInput; - const char *ptr = skip; if (split) { ptr = inputStop(styleInput, &style, ptr, &buf[split]); style = styleInput; @@ -224,7 +229,7 @@ void inputUpdate(void) { } inputAdd(styleInput, &style, ptr); wclrtoeol(uiInput); - wmove(uiInput, y, pos); + wmove(uiInput, y, posx); } bool inputPending(uint id) { @@ -381,7 +386,7 @@ fail: static void inputEnter(void) { uint id = windowID(); - char *cmd = editString(&edits[id]); + char *cmd = editString(&edits[id], &buf, &cap, NULL); if (!cmd) err(EX_OSERR, "editString"); tabAccept(); @@ -459,8 +464,8 @@ static void keyCtrl(wchar_t ch) { break; case L'L': clearok(curscr, true); break; case L'N': windowShow(windowNum() + 1); break; case L'P': windowShow(windowNum() - 1); - break; case L'R': windowSearch(editString(edit), -1); - break; case L'S': windowSearch(editString(edit), +1); + break; case L'R': windowSearch(editString(edit, &buf, &cap, NULL), -1); + break; case L'S': windowSearch(editString(edit, &buf, &cap, NULL), +1); break; case L'T': error = editFn(edit, EditTranspose); break; case L'U': error = editFn(edit, EditDeleteHead); break; case L'V': windowScroll(ScrollPage, -1); -- cgit 1.4.1