summary refs log tree commit diff
path: root/edit.c
diff options
context:
space:
mode:
authorJune McEnroe2022-02-20 15:26:23 -0500
committerJune McEnroe2022-02-20 15:42:24 -0500
commite39bba1a8a2fda74bcfd06f728b7e1fddadef161 (patch)
tree2add7aeaba4d0c69116c2f672d05e407fbffcdb3 /edit.c
parentcca9688cca171dc3ee6ac24822bdd8c315997759 (diff)
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.
Diffstat (limited to 'edit.c')
-rw-r--r--edit.c36
1 files changed, 20 insertions, 16 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) {