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.
weechat-hashes
June McEnroe 2022-02-20 15:26:23 -05:00
parent cca9688cca
commit e39bba1a8a
3 changed files with 38 additions and 33 deletions

36
edit.c
View File

@ -41,32 +41,33 @@ static bool isword(wchar_t ch) {
void editFree(struct Edit *e) { void editFree(struct Edit *e) {
free(e->buf); free(e->buf);
free(e->cut.buf); free(e->cut.buf);
free(e->mbs.buf);
e->pos = e->len = e->cap = 0; e->pos = e->len = e->cap = 0;
e->cut.len = 0; e->cut.len = 0;
e->mbs.pos = 0;
} }
char *editString(struct Edit *e) { char *editString(const struct Edit *e, char **buf, size_t *cap, size_t *pos) {
size_t cap = e->len * MB_CUR_MAX + 1; size_t req = e->len * MB_CUR_MAX + 1;
char *buf = realloc(e->mbs.buf, cap); if (req > *cap) {
if (!buf) return NULL; char *new = realloc(*buf, req);
e->mbs.buf = buf; if (!new) return NULL;
*buf = new;
*cap = req;
}
const wchar_t *ptr = e->buf; 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; if (len == (size_t)-1) return NULL;
e->mbs.pos = len; if (pos) *pos = len;
ptr = &e->buf[e->pos]; ptr = &e->buf[e->pos];
size_t n = wcsnrtombs( 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; if (n == (size_t)-1) return NULL;
len += n; len += n;
e->mbs.buf[len] = '\0'; (*buf)[len] = '\0';
return e->mbs.buf; return *buf;
} }
int editReserve(struct Edit *e, size_t index, size_t count) { 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) { 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 *str2 = &str1[strlen(str1) + 1];
const char *buf = editString(e); return pos == strlen(str1)
return e->mbs.pos == strlen(str1) && !strncmp(buf, str1, pos)
&& !strncmp(buf, str1, e->mbs.pos) && !strcmp(&buf[pos], str2);
&& !strcmp(&buf[e->mbs.pos], str2);
} }
int main(void) { int main(void) {

8
edit.h
View File

@ -42,10 +42,6 @@ struct Edit {
wchar_t *buf; wchar_t *buf;
size_t len; size_t len;
} cut; } cut;
struct {
char *buf;
size_t pos;
} mbs;
}; };
enum EditFn { enum EditFn {
@ -76,8 +72,8 @@ int editVi(struct Edit *e, wchar_t ch);
// Insert a character at the cursor. // Insert a character at the cursor.
int editInsert(struct Edit *e, wchar_t ch); int editInsert(struct Edit *e, wchar_t ch);
// Convert the buffer to a multi-byte string stored in e->mbs. // Convert the buffer to a multi-byte string.
char *editString(struct Edit *e); char *editString(const struct Edit *e, char **buf, size_t *cap, size_t *pos);
// Free all buffers. // Free all buffers.
void editFree(struct Edit *e); void editFree(struct Edit *e);

27
input.c
View File

@ -158,10 +158,15 @@ static char *inputStop(
return stop; return stop;
} }
static size_t cap;
static char *buf;
void inputUpdate(void) { void inputUpdate(void) {
uint id = windowID(); 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 *prefix = "";
const char *prompt = self.nick; const char *prompt = self.nick;
@ -192,7 +197,7 @@ void inputUpdate(void) {
} else { } else {
prompt = ""; prompt = "";
} }
if (skip > &buf[edits[id].mbs.pos]) { if (skip > &buf[pos]) {
prefix = prompt = suffix = ""; prefix = prompt = suffix = "";
skip = buf; skip = buf;
} }
@ -209,14 +214,14 @@ void inputUpdate(void) {
waddstr(uiInput, suffix); waddstr(uiInput, suffix);
getyx(uiInput, y, x); getyx(uiInput, y, x);
int pos; int posx;
struct Style style = styleInput; struct Style style = styleInput;
inputStop(styleInput, &style, skip, &buf[edits[id].mbs.pos]); inputStop(styleInput, &style, skip, &buf[pos]);
getyx(uiInput, y, pos); getyx(uiInput, y, posx);
wmove(uiInput, y, x); wmove(uiInput, y, x);
ptr = skip;
style = styleInput; style = styleInput;
const char *ptr = skip;
if (split) { if (split) {
ptr = inputStop(styleInput, &style, ptr, &buf[split]); ptr = inputStop(styleInput, &style, ptr, &buf[split]);
style = styleInput; style = styleInput;
@ -224,7 +229,7 @@ void inputUpdate(void) {
} }
inputAdd(styleInput, &style, ptr); inputAdd(styleInput, &style, ptr);
wclrtoeol(uiInput); wclrtoeol(uiInput);
wmove(uiInput, y, pos); wmove(uiInput, y, posx);
} }
bool inputPending(uint id) { bool inputPending(uint id) {
@ -381,7 +386,7 @@ fail:
static void inputEnter(void) { static void inputEnter(void) {
uint id = windowID(); uint id = windowID();
char *cmd = editString(&edits[id]); char *cmd = editString(&edits[id], &buf, &cap, NULL);
if (!cmd) err(EX_OSERR, "editString"); if (!cmd) err(EX_OSERR, "editString");
tabAccept(); tabAccept();
@ -459,8 +464,8 @@ static void keyCtrl(wchar_t ch) {
break; case L'L': clearok(curscr, true); break; case L'L': clearok(curscr, true);
break; case L'N': windowShow(windowNum() + 1); break; case L'N': windowShow(windowNum() + 1);
break; case L'P': windowShow(windowNum() - 1); break; case L'P': windowShow(windowNum() - 1);
break; case L'R': windowSearch(editString(edit), -1); break; case L'R': windowSearch(editString(edit, &buf, &cap, NULL), -1);
break; case L'S': windowSearch(editString(edit), +1); break; case L'S': windowSearch(editString(edit, &buf, &cap, NULL), +1);
break; case L'T': error = editFn(edit, EditTranspose); break; case L'T': error = editFn(edit, EditTranspose);
break; case L'U': error = editFn(edit, EditDeleteHead); break; case L'U': error = editFn(edit, EditDeleteHead);
break; case L'V': windowScroll(ScrollPage, -1); break; case L'V': windowScroll(ScrollPage, -1);