commit: c9df00005a6068d2ae5a756ab9feaed4f0e48e30
parent 8ae6625b98a78dc2af0a1189f3d0353affaf0a28
Author: Michael Forney <mforney@mforney.org>
Date: Fri, 31 Jan 2020 23:37:26 -0800
vis: Avoid VLAs and wide string literals for now
Diffstat:
3 files changed, 284 insertions(+), 1 deletion(-)
diff --git a/pkg/vis/patch/0001-Avoid-use-of-VLAs.patch b/pkg/vis/patch/0001-Avoid-use-of-VLAs.patch
@@ -0,0 +1,256 @@
+From f436524892def7a6d07c5bfeec22422f35496054 Mon Sep 17 00:00:00 2001
+From: Michael Forney <mforney@mforney.org>
+Date: Fri, 31 Jan 2020 23:33:28 -0800
+Subject: [PATCH] Avoid use of VLAs
+
+---
+ sam.c | 6 +++---
+ text-regex-tre.c | 2 +-
+ text-regex.c | 4 ++--
+ text-regex.h | 2 ++
+ ui-terminal.c | 32 +++++++++++++++++---------------
+ view.c | 13 +++++++++++--
+ vis-digraph.c | 8 ++++++--
+ 7 files changed, 42 insertions(+), 25 deletions(-)
+
+diff --git a/sam.c b/sam.c
+index 11d245b..4d3c49b 100644
+--- a/sam.c
++++ b/sam.c
+@@ -1380,9 +1380,9 @@ static int extract(Vis *vis, Win *win, Command *cmd, const char *argv[], Selecti
+ bool trailing_match = false;
+ size_t start = range->start, end = range->end, last_start = EPOS;
+ size_t nsub = 1 + text_regex_nsub(cmd->regex);
+- if (nsub > 10)
+- nsub = 10;
+- RegexMatch match[nsub];
++ if (nsub > MAX_REGEX_SUB)
++ nsub = MAX_REGEX_SUB;
++ RegexMatch match[MAX_REGEX_SUB];
+ while (start < end || trailing_match) {
+ trailing_match = false;
+ char c;
+diff --git a/text-regex-tre.c b/text-regex-tre.c
+index da377b4..eccbafb 100644
+--- a/text-regex-tre.c
++++ b/text-regex-tre.c
+@@ -136,7 +136,7 @@ int text_search_range_forward(Text *txt, size_t pos, size_t len, Regex *r, size_
+ r->it = text_iterator_get(txt, pos);
+ r->end = pos+len;
+
+- regmatch_t match[nmatch];
++ regmatch_t match[MAX_REGEX_SUB];
+ int ret = tre_reguexec(&r->regex, &r->str_source, nmatch, match, eflags);
+ if (!ret) {
+ for (size_t i = 0; i < nmatch; i++) {
+diff --git a/text-regex.c b/text-regex.c
+index 56ecafc..7c6812e 100644
+--- a/text-regex.c
++++ b/text-regex.c
+@@ -45,7 +45,7 @@ int text_search_range_forward(Text *txt, size_t pos, size_t len, Regex *r, size_
+ return REG_NOMATCH;
+ char *cur = buf, *end = buf + len;
+ int ret = REG_NOMATCH;
+- regmatch_t match[nmatch];
++ regmatch_t match[MAX_REGEX_SUB];
+ for (size_t junk = len; len > 0; len -= junk, pos += junk) {
+ ret = regexec(&r->regex, cur, nmatch, match, eflags);
+ if (!ret) {
+@@ -73,7 +73,7 @@ int text_search_range_backward(Text *txt, size_t pos, size_t len, Regex *r, size
+ return REG_NOMATCH;
+ char *cur = buf, *end = buf + len;
+ int ret = REG_NOMATCH;
+- regmatch_t match[nmatch];
++ regmatch_t match[MAX_REGEX_SUB];
+ for (size_t junk = len; len > 0; len -= junk, pos += junk) {
+ char *next;
+ if (!regexec(&r->regex, cur, nmatch, match, eflags)) {
+diff --git a/text-regex.h b/text-regex.h
+index 45054c8..dd87c1c 100644
+--- a/text-regex.h
++++ b/text-regex.h
+@@ -9,6 +9,8 @@
+ #endif
+ #include "text.h"
+
++#define MAX_REGEX_SUB 10
++
+ typedef struct Regex Regex;
+ typedef Filerange RegexMatch;
+
+diff --git a/ui-terminal.c b/ui-terminal.c
+index bcf4f48..b939947 100644
+--- a/ui-terminal.c
++++ b/ui-terminal.c
+@@ -198,11 +198,11 @@ static void ui_draw_line(UiTerm *tui, int x, int y, char c, enum UiStyle style_i
+ if (x < 0 || x >= tui->width || y < 0 || y >= tui->height)
+ return;
+ CellStyle style = tui->styles[style_id];
+- Cell (*cells)[tui->width] = (void*)tui->cells;
++ Cell *cells = tui->cells + y * tui->width;
+ while (x < tui->width) {
+- cells[y][x].data[0] = c;
+- cells[y][x].data[1] = '\0';
+- cells[y][x].style = style;
++ cells[x].data[0] = c;
++ cells[x].data[1] = '\0';
++ cells[x].style = style;
+ x++;
+ }
+ }
+@@ -213,17 +213,17 @@ static void ui_draw_string(UiTerm *tui, int x, int y, const char *str, UiTermWin
+ return;
+ CellStyle style = tui->styles[(win ? win->id : 0)*UI_STYLE_MAX + style_id];
+ // FIXME: does not handle double width characters etc, share code with view.c?
+- Cell (*cells)[tui->width] = (void*)tui->cells;
+- const size_t cell_size = sizeof(cells[0][0].data)-1;
++ Cell *cells = tui->cells + y * tui->width;
++ const size_t cell_size = sizeof(cells[0].data)-1;
+ for (const char *next = str; *str && x < tui->width; str = next) {
+ do next++; while (!ISUTF8(*next));
+ size_t len = next - str;
+ if (!len)
+ break;
+ len = MIN(len, cell_size);
+- strncpy(cells[y][x].data, str, len);
+- cells[y][x].data[len] = '\0';
+- cells[y][x].style = style;
++ strncpy(cells[x].data, str, len);
++ cells[x].data[len] = '\0';
++ cells[x].style = style;
+ x++;
+ }
+ }
+@@ -232,7 +232,6 @@ static void ui_window_draw(UiWin *w) {
+ UiTermWin *win = (UiTermWin*)w;
+ UiTerm *ui = win->ui;
+ View *view = win->win->view;
+- Cell (*cells)[ui->width] = (void*)ui->cells;
+ int width = win->width, height = win->height;
+ const Line *line = view_lines_first(view);
+ bool status = win->options & UI_OPTION_STATUSBAR;
+@@ -250,9 +249,10 @@ static void ui_window_draw(UiWin *w) {
+ Selection *sel = view_selections_primary_get(view);
+ const Line *cursor_line = view_cursors_line_get(sel);
+ size_t cursor_lineno = cursor_line->lineno;
+- char buf[sidebar_width+1];
++ char buf[(sizeof(size_t) * CHAR_BIT + 2) / 3 + 1];
+ int x = win->x, y = win->y;
+ int view_width = view_width_get(view);
++ Cell *cells = ui->cells + y * ui->width;
+ if (x + sidebar_width + view_width > ui->width)
+ view_width = ui->width - x - sidebar_width;
+ for (const Line *l = line; l; l = l->next) {
+@@ -276,7 +276,8 @@ static void ui_window_draw(UiWin *w) {
+ prev_lineno = l->lineno;
+ }
+ debug("draw-window: [%d][%d] ... cells[%d][%d]\n", y, x+sidebar_width, y, view_width);
+- memcpy(&cells[y++][x+sidebar_width], l->cells, sizeof(Cell) * view_width);
++ memcpy(&cells[x+sidebar_width], l->cells, sizeof(Cell) * view_width);
++ cells += ui->width;
+ }
+ }
+
+@@ -299,7 +300,6 @@ static void ui_arrange(Ui *ui, enum UiLayout layout) {
+ debug("ui-arrange\n");
+ UiTerm *tui = (UiTerm*)ui;
+ tui->layout = layout;
+- Cell (*cells)[tui->width] = (void*)tui->cells;
+ int n = 0, m = !!tui->info[0], x = 0, y = 0;
+ for (UiTermWin *win = tui->windows; win; win = win->next) {
+ if (win->options & UI_OPTION_ONELINE)
+@@ -325,9 +325,11 @@ static void ui_arrange(Ui *ui, enum UiLayout layout) {
+ ui_window_move(win, x, y);
+ x += w;
+ if (n) {
++ Cell *cells = tui->cells;
+ for (int i = 0; i < max_height; i++) {
+- strcpy(cells[i][x].data,"│");
+- cells[i][x].style = tui->styles[UI_STYLE_SEPARATOR];
++ strcpy(cells[x].data,"│");
++ cells[x].style = tui->styles[UI_STYLE_SEPARATOR];
++ cells += tui->width;
+ }
+ x++;
+ }
+diff --git a/view.c b/view.c
+index 1bffb4f..d69f488 100644
+--- a/view.c
++++ b/view.c
+@@ -55,6 +55,7 @@ struct Selection {
+
+ struct View {
+ Text *text; /* underlying text management */
++ char *textbuf; /* scratch buffer used for drawing */
+ UiWin *ui; /* corresponding ui window */
+ Cell cell_blank; /* used for empty/blank cells */
+ int width, height; /* size of display area */
+@@ -328,7 +329,7 @@ void view_draw(View *view) {
+ /* read a screenful of text considering each character as 4-byte UTF character*/
+ const size_t size = view->width * view->height * 4;
+ /* current buffer to work with */
+- char text[size+1];
++ char *text = view->textbuf;
+ /* remaining bytes to process in buffer */
+ size_t rem = text_bytes_get(view->text, view->start, size, text);
+ /* NUL terminate text section */
+@@ -454,14 +455,21 @@ bool view_resize(View *view, int width, int height) {
+ view->need_update = true;
+ return true;
+ }
++ char *textbuf = malloc(width * height * 4 + 1);
++ if (!textbuf)
++ return false;
+ size_t lines_size = height*(sizeof(Line) + width*sizeof(Cell));
+ if (lines_size > view->lines_size) {
+ Line *lines = realloc(view->lines, lines_size);
+- if (!lines)
++ if (!lines) {
++ free(textbuf);
+ return false;
++ }
+ view->lines = lines;
+ view->lines_size = lines_size;
+ }
++ free(view->textbuf);
++ view->textbuf = textbuf;
+ view->width = width;
+ view->height = height;
+ memset(view->lines, 0, view->lines_size);
+@@ -482,6 +490,7 @@ void view_free(View *view) {
+ return;
+ while (view->selections)
+ selection_free(view->selections);
++ free(view->textbuf);
+ free(view->lines);
+ free(view);
+ }
+diff --git a/vis-digraph.c b/vis-digraph.c
+index 452ede3..35a5a17 100644
+--- a/vis-digraph.c
++++ b/vis-digraph.c
+@@ -2,6 +2,7 @@
+ #include <termios.h>
+ #include <locale.h>
+ #include <stdio.h>
++#include <stdlib.h>
+ #include <string.h>
+ #include <unistd.h>
+ #include <wchar.h>
+@@ -1993,8 +1994,11 @@ int main(int argc, char *argv[]) {
+ return 1;
+ }
+
+- wchar_t runes[argc-1];
+- memset(runes, 0, sizeof(runes));
++ wchar_t *runes = calloc(argc-1, sizeof(runes[0]));
++ if (!runes) {
++ perror(NULL);
++ return 1;
++ }
+
+ for (int i = 1; i < argc; i++) {
+ int l = lookup(argv[i], &runes[i-1]);
+--
+2.25.0
+
diff --git a/pkg/vis/patch/0002-HACK-Avoid-wide-string-literals-for-now.patch b/pkg/vis/patch/0002-HACK-Avoid-wide-string-literals-for-now.patch
@@ -0,0 +1,27 @@
+From 358e4526a4ed8c5780d4fa43403c5c6e3d92f8bb Mon Sep 17 00:00:00 2001
+From: Michael Forney <mforney@mforney.org>
+Date: Fri, 31 Jan 2020 23:34:52 -0800
+Subject: [PATCH] [HACK] Avoid wide string literals for now
+
+---
+ vis-digraph.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/vis-digraph.c b/vis-digraph.c
+index 35a5a17..0c23387 100644
+--- a/vis-digraph.c
++++ b/vis-digraph.c
+@@ -1962,8 +1962,9 @@ int main(int argc, char *argv[]) {
+ setlocale(LC_ALL, "");
+
+ if (argc == 1) {
++ static const wchar_t fmt[] = {'%', 's', ' ', '%', 'l', 'c', ' ', '%', 's', '\n', '\0'};
+ for (const Digraph *d = digraphs; d->name[0]; d++)
+- wprintf(L"%s %lc %s\n", d->name, d->rune, d->description);
++ wprintf(fmt, d->name, d->rune, d->description);
+ return 0;
+ }
+
+--
+2.25.0
+
diff --git a/pkg/vis/ver b/pkg/vis/ver
@@ -1 +1 @@
-0.5-120-g24630d2 r0
+0.5-120-g24630d2 r1