From 1cd66cac903151396a7513f8e009f6f654561daf Mon Sep 17 00:00:00 2001 From: Albert Cervin Date: Tue, 31 Jan 2023 15:25:59 +0100 Subject: Fixes to copy-paste It would crash on multi-line copy. --- linux.mk | 2 +- src/buffer.c | 16 +++++------ src/reactor-epoll.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/reactor-linux.c | 76 ----------------------------------------------------- src/text.c | 36 ++++++++++++++----------- 5 files changed, 105 insertions(+), 101 deletions(-) create mode 100644 src/reactor-epoll.c delete mode 100644 src/reactor-linux.c diff --git a/linux.mk b/linux.mk index b7c193a..e6534df 100644 --- a/linux.mk +++ b/linux.mk @@ -1,4 +1,4 @@ CFLAGS += -DLINUX -D_XOPEN_SOURCE=700 -PLATFORM_SOURCES += src/reactor-linux.c +PLATFORM_SOURCES += src/reactor-epoll.c PLATFORM_OBJS = $(PLATFORM_SOURCES:.c=.o) diff --git a/src/buffer.c b/src/buffer.c index 71d486e..8a86e69 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -16,7 +16,9 @@ #include #include -static struct modeline { uint8_t *buffer; } g_modeline = {0}; +struct modeline { + uint8_t *buffer; +}; #define KILL_RING_SZ 64 static struct kill_ring { @@ -88,8 +90,9 @@ struct buffer buffer_create(char *name, bool modeline) { sizeof(bindings) / sizeof(bindings[0])); if (modeline) { - g_modeline.buffer = malloc(1024); - buffer_add_update_hook(&b, buffer_modeline_hook, &g_modeline); + struct modeline *modeline = calloc(1, sizeof(struct modeline)); + modeline->buffer = malloc(1024); + buffer_add_update_hook(&b, buffer_modeline_hook, modeline); } if (modeline) { @@ -108,10 +111,6 @@ void buffer_destroy(struct buffer *buffer) { keymap_destroy(&buffer->keymaps[keymapi]); } free(buffer->keymaps); - - if (g_modeline.buffer != NULL) { - free(g_modeline.buffer); - } } void buffer_clear(struct buffer *buffer) { @@ -194,7 +193,7 @@ struct region to_region(struct buffer_location dot, bool region_has_size(struct buffer *buffer) { return buffer->mark_set && - (labs((int64_t)buffer->mark.line - (int64_t)buffer->dot.line + 1) * + (labs((int64_t)buffer->mark.line - (int64_t)buffer->dot.line) + labs((int64_t)buffer->mark.col - (int64_t)buffer->dot.col)) > 0; } @@ -234,6 +233,7 @@ void buffer_cut(struct buffer *buffer) { text_delete(buffer->text, reg.begin.line, reg.begin.col, reg.end.line, reg.end.col); buffer_clear_mark(buffer); + buffer->dot = reg.begin; } } diff --git a/src/reactor-epoll.c b/src/reactor-epoll.c new file mode 100644 index 0000000..e488fef --- /dev/null +++ b/src/reactor-epoll.c @@ -0,0 +1,76 @@ +#include "reactor.h" + +#include +#include +#include + +struct reactor { + int epoll_fd; + void *events; +}; + +struct events { + struct epoll_event events[10]; + uint32_t nevents; +}; + +struct reactor *reactor_create() { + int epollfd = epoll_create1(0); + if (epollfd == -1) { + perror("epoll_create1"); + } + + struct reactor *r = (struct reactor *)calloc(1, sizeof(struct reactor)); + r->epoll_fd = epollfd; + r->events = calloc(1, sizeof(struct events)); + + return r; +} + +void reactor_destroy(struct reactor *reactor) { + free(reactor->events); + free(reactor); +} + +uint32_t reactor_register_interest(struct reactor *reactor, int fd, + enum interest interest) { + struct epoll_event ev; + ev.events = 0; + ev.events |= (interest & ReadInterest) != 0 ? EPOLLIN : 0; + ev.events |= (interest & WriteInterest) != 0 ? EPOLLOUT : 0; + ev.data.fd = fd; + if (epoll_ctl(reactor->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0) { + perror("epoll_ctl"); + return -1; + } + + return fd; +} + +void reactor_unregister_interest(struct reactor *reactor, uint32_t ev_id) { + epoll_ctl(reactor->epoll_fd, EPOLL_CTL_DEL, ev_id, NULL); +} + +bool reactor_poll_event(struct reactor *reactor, uint32_t ev_id) { + struct events *events = (struct events *)reactor->events; + for (uint32_t ei = 0; ei < events->nevents; ++ei) { + struct epoll_event *ev = &events->events[ei]; + + if (ev->data.fd == ev_id) { + return true; + } + } + + return false; +} + +void reactor_update(struct reactor *reactor) { + struct events *events = (struct events *)reactor->events; + int nfds = epoll_wait(reactor->epoll_fd, events->events, 10, -1); + + if (nfds == -1) { + // TODO: log failure + } + + events->nevents = nfds; +} diff --git a/src/reactor-linux.c b/src/reactor-linux.c deleted file mode 100644 index e488fef..0000000 --- a/src/reactor-linux.c +++ /dev/null @@ -1,76 +0,0 @@ -#include "reactor.h" - -#include -#include -#include - -struct reactor { - int epoll_fd; - void *events; -}; - -struct events { - struct epoll_event events[10]; - uint32_t nevents; -}; - -struct reactor *reactor_create() { - int epollfd = epoll_create1(0); - if (epollfd == -1) { - perror("epoll_create1"); - } - - struct reactor *r = (struct reactor *)calloc(1, sizeof(struct reactor)); - r->epoll_fd = epollfd; - r->events = calloc(1, sizeof(struct events)); - - return r; -} - -void reactor_destroy(struct reactor *reactor) { - free(reactor->events); - free(reactor); -} - -uint32_t reactor_register_interest(struct reactor *reactor, int fd, - enum interest interest) { - struct epoll_event ev; - ev.events = 0; - ev.events |= (interest & ReadInterest) != 0 ? EPOLLIN : 0; - ev.events |= (interest & WriteInterest) != 0 ? EPOLLOUT : 0; - ev.data.fd = fd; - if (epoll_ctl(reactor->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0) { - perror("epoll_ctl"); - return -1; - } - - return fd; -} - -void reactor_unregister_interest(struct reactor *reactor, uint32_t ev_id) { - epoll_ctl(reactor->epoll_fd, EPOLL_CTL_DEL, ev_id, NULL); -} - -bool reactor_poll_event(struct reactor *reactor, uint32_t ev_id) { - struct events *events = (struct events *)reactor->events; - for (uint32_t ei = 0; ei < events->nevents; ++ei) { - struct epoll_event *ev = &events->events[ei]; - - if (ev->data.fd == ev_id) { - return true; - } - } - - return false; -} - -void reactor_update(struct reactor *reactor) { - struct events *events = (struct events *)reactor->events; - int nfds = epoll_wait(reactor->epoll_fd, events->events, 10, -1); - - if (nfds == -1) { - // TODO: log failure - } - - events->nevents = nfds; -} diff --git a/src/text.c b/src/text.c index 6e343ae..ece4ad4 100644 --- a/src/text.c +++ b/src/text.c @@ -336,7 +336,8 @@ struct copy_cmd { struct text_chunk text_get_region(struct text *text, uint32_t start_line, uint32_t start_col, uint32_t end_line, uint32_t end_col) { - struct copy_cmd *copy_cmds = malloc(end_line - start_line + 1); + uint32_t nlines = end_line - start_line + 1; + struct copy_cmd *copy_cmds = calloc(nlines, sizeof(struct copy_cmd)); uint32_t total_chars = 0, total_bytes = 0; for (uint32_t line = start_line; line <= end_line; ++line) { @@ -348,12 +349,10 @@ struct text_chunk text_get_region(struct text *text, uint32_t start_line, cmd->line = line; cmd->byteindex = 0; cmd->nbytes = l->nbytes; - - ++line; } // correct first line - struct copy_cmd *cmd_first = ©_cmds[start_line]; + struct copy_cmd *cmd_first = ©_cmds[0]; struct line *first_line = &text->lines[start_line]; uint32_t byteoff = utf8_nbytes(first_line->data, first_line->nbytes, start_col); @@ -363,33 +362,38 @@ struct text_chunk text_get_region(struct text *text, uint32_t start_line, total_chars -= start_col; // correct last line - struct copy_cmd *cmd_last = ©_cmds[end_line]; + struct copy_cmd *cmd_last = ©_cmds[nlines - 1]; struct line *last_line = &text->lines[end_line]; uint32_t byteindex = utf8_nbytes(last_line->data, last_line->nbytes, end_col); cmd_last->nbytes -= (last_line->nchars - end_col); total_bytes -= (last_line->nbytes - byteindex); total_chars -= (last_line->nchars - end_col); - struct text_chunk txt = { - .text = (uint8_t *)malloc(total_bytes + end_line - start_line), - .line = 0, - .nbytes = total_bytes, - .nchars = total_chars, - }; + uint8_t *data = (uint8_t *)malloc(total_bytes + end_line - start_line); // copy data - for (uint32_t cmdi = 0, curr = 0; cmdi <= end_line - start_line; ++cmdi) { + for (uint32_t cmdi = 0, curr = 0; cmdi < nlines; ++cmdi) { struct copy_cmd *c = ©_cmds[cmdi]; struct line *l = &text->lines[c->line]; - memcpy(txt.text + curr, l->data + c->byteindex, c->nbytes); + memcpy(data + curr, l->data + c->byteindex, c->nbytes); curr += c->nbytes; - if (cmdi != end_line - start_line) { - txt.text[++curr] = '\n'; + if (cmdi != (nlines - 1)) { + data[curr] = '\n'; + ++curr; + ++total_bytes; + ++total_chars; } } - return txt; + free(copy_cmds); + return (struct text_chunk){ + .text = data, + .line = 0, + .nbytes = total_bytes, + .nchars = total_chars, + }; + ; } bool text_line_contains_unicode(struct text *text, uint32_t line) { -- cgit v1.2.3