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
parent
cca9688cca
commit
e39bba1a8a
36
edit.c
36
edit.c
|
@ -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
8
edit.h
|
@ -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
27
input.c
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue