vtgl

terminal emulator implemented in OpenGL
git clone anongit@rnpnr.xyz:vtgl.git
Log | Files | Refs | Feed | LICENSE

Commit: 7b2a7bda201ec0b716f53108d9c2abff434c95bc
Parent: 50dbb69776976cf9b043a9c1187c0e0e5971b850
Author: Randy Palamar
Date:   Mon, 17 Feb 2025 11:54:32 -0700

remove duplicate integer conversion code

Diffstat:
Mbuild.sh | 2+-
Mplatform_linux_x11.c | 20+++++++++++++-------
Mterminal.c | 39+++++++++++++++++++--------------------
Mutil.c | 65+++++++++++++++++++----------------------------------------------
Mutil.h | 2+-
Mvtgl.c | 2+-
6 files changed, 54 insertions(+), 76 deletions(-)

diff --git a/build.sh b/build.sh @@ -66,7 +66,7 @@ fuzz_llvm) fuzz_results) ${cc} ${testcflags} -DFUZZ_RESULTS -O0 tests/test-fuzz.c -o tests/test-fuzz-results set -e - for file in fuzz_out/default/crashes/id*; do + for file in tests/fuzz_out/default/crashes/id*; do echo ${file} ./tests/test-fuzz-results "${file}" done diff --git a/platform_linux_x11.c b/platform_linux_x11.c @@ -373,7 +373,6 @@ main(i32 argc, char *argv[], char *envp[]) char *argv0 = *argv++; argc--; - struct conversion_result cres; for (i32 i = 0; i < argc; i++) { char *arg = argv[i]; if (!arg || !arg[0]) @@ -382,15 +381,22 @@ main(i32 argc, char *argv[], char *envp[]) break; arg++; switch (arg[0]) { - case 'g': + case 'g': { if (!argv[i + 1]) usage(argv0, &linux_ctx.error_stream); - cres = i32_from_cstr(argv[i + 1], 'x'); + s8 g_arg = c_str_to_s8(argv[i + 1]); + struct conversion_result cres = s8_parse_i32_until(g_arg, 'x'); if (cres.status == CR_SUCCESS) cells.w = cres.i; - cres = i32_from_cstr(cres.unparsed.c_str, 0); - if (cres.status == CR_SUCCESS) - cells.h = cres.i; + + if (cres.unparsed.len > 0 && cres.unparsed.data[0] == 'x') { + s8 remainder = {.len = cres.unparsed.len - 1, + .data = cres.unparsed.data + 1}; + cres = s8_parse_i32(remainder); + if (cres.status == CR_SUCCESS) + cells.h = cres.i; + } + if (cells.w <= 0 || cells.h <= 0) { stream_push_s8(&linux_ctx.error_stream, s8("ignoring malformed geometry: ")); stream_push_s8(&linux_ctx.error_stream, c_str_to_s8(argv[i + 1])); @@ -398,7 +404,7 @@ main(i32 argc, char *argv[], char *envp[]) } argv++; argc--; - break; + } break; case 'v': stream_push_s8s(&linux_ctx.error_stream, 2, (s8 []){c_str_to_s8(argv0), s8(" " VERSION "\n")}); diff --git a/terminal.c b/terminal.c @@ -369,6 +369,8 @@ cursor_step_raw(Term *t, i32 step, i32 rows, i32 cols) { rows *= step; cols *= step; + rows = MIN(rows, I32_MAX - t->cursor.pos.y); + cols = MIN(cols, I32_MAX - t->cursor.pos.x); cursor_move_to(t, t->cursor.pos.y + rows, t->cursor.pos.x + cols); } @@ -907,27 +909,24 @@ parse_csi(s8 *r, CSI *csi) get_ascii(r); } - i32 accum = 0; + struct conversion_result arg = {0}; while (r->len) { - u32 cp = get_ascii(r); - if (ISCONTROL(cp)) { - continue; - } else if (BETWEEN(cp, '0', '9')) { - i32 digit = cp - '0'; - if (accum <= (I32_MAX - digit) / 10) { - accum = 10 * accum + digit; - } else { - /* TODO(rnp): report error/out of range? */ - } - continue; - } - csi->argv[csi->argc++] = accum; - accum = 0; + s8_parse_i32_accum(&arg, *r); + *r = arg.unparsed; + if (r->len) { + u32 cp = get_ascii(r); + + if (ISCONTROL(cp)) + continue; + + csi->argv[csi->argc++] = arg.i; + zero_struct(&arg); - if (cp != ';' || csi->argc == ESC_ARG_SIZ) { - if (cp == ';') csi->mode = get_ascii(r); - else csi->mode = cp; - goto end; + if (cp != ';' || csi->argc == ESC_ARG_SIZ) { + if (cp == ';') csi->mode = get_ascii(r); + else csi->mode = cp; + goto end; + } } } /* NOTE: if we fell out of the loop then we ran out of characters */ @@ -1034,7 +1033,7 @@ parse_osc(s8 *raw, OSC *osc) struct conversion_result cmd = s8_parse_i32_until(*raw, ';'); if (cmd.status != CR_FAILURE) { osc->cmd = cmd.i; - osc->arg = cmd.unparsed.s8; + osc->arg = cmd.unparsed; osc->raw.len = osc->arg.data - raw->data; *raw = consume(*raw, osc->raw.len); } else { diff --git a/util.c b/util.c @@ -309,13 +309,13 @@ s8_chop_at(s8 raw, u8 delim) return result; } -static struct conversion_result -s8_parse_i32(s8 raw) +static void +s8_parse_i32_accum(struct conversion_result *result, s8 raw) { - struct conversion_result result = {.status = CR_SUCCESS}; - i32 scale = 1; + result->status = CR_SUCCESS; - size i = 0; + size i = 0; + i32 scale = 1; if (raw.len && raw.data[0] == '-') { scale = -1; i = 1; @@ -324,11 +324,11 @@ s8_parse_i32(s8 raw) for (; i < raw.len; i++) { i32 digit = (i32)raw.data[i] - '0'; if (BETWEEN(digit, 0, 9)) { - if (result.i > (I32_MAX - digit) / 10) { - result.status = CR_OUT_OF_RANGE; - result.i = I32_MAX; + if (result->i > (I32_MAX - digit) / 10) { + result->status = CR_OUT_OF_RANGE; + result->i = I32_MAX; } else { - result.i = 10 * result.i + digit; + result->i = 10 * result->i + digit; } } else { break; @@ -336,11 +336,17 @@ s8_parse_i32(s8 raw) } if (i == 0 || (i == 1 && raw.data[0] == '-')) - result.status = CR_FAILURE; + result->status = CR_FAILURE; - result.unparsed.s8 = (s8){.len = raw.len - i, .data = raw.data + i}; - result.i *= scale; + result->unparsed = (s8){.len = raw.len - i, .data = raw.data + i}; + result->i *= scale; +} +static struct conversion_result +s8_parse_i32(s8 raw) +{ + struct conversion_result result = {0}; + s8_parse_i32_accum(&result, raw); return result; } @@ -349,43 +355,10 @@ s8_parse_i32_until(s8 raw, u8 delim) { s8 chopped = s8_chop_at(raw, delim); struct conversion_result result = s8_parse_i32(chopped); - result.unparsed.s8 = (s8){.data = raw.data + chopped.len, .len = raw.len - chopped.len}; + result.unparsed = (s8){.data = raw.data + chopped.len, .len = raw.len - chopped.len}; return result; } -static struct conversion_result -i32_from_cstr(char *s, char delim) -{ - struct conversion_result ret = {.status = CR_FAILURE}; - i32 scale = 1; - - if (!s || !s[0]) - return ret; - - if (s[0] == '-') { - s++; - scale = -1; - } - - for (; *s && *s != delim; s++) { - i32 digit = s[0] - '0'; - if (!BETWEEN(digit, 0, 9)) - return ret; - - if (ret.i > (I32_MAX - digit) / 10) { - ret.status = CR_OUT_OF_RANGE; - return ret; - } - ret.i = 10 * ret.i + digit; - } - - ret.i *= scale; - ret.status = CR_SUCCESS; - ret.unparsed.c_str = (*s == delim) ? s + 1 : s; - - return ret; -} - static Stream arena_stream(Arena a) { diff --git a/util.h b/util.h @@ -279,7 +279,7 @@ typedef __attribute__((aligned(64))) struct { typedef enum { CR_FAILURE, CR_SUCCESS, CR_OUT_OF_RANGE } conversion_status; struct conversion_result { conversion_status status; - union { char *c_str; s8 s8; } unparsed; + s8 unparsed; union { i32 i; f32 f; Colour colour;}; }; diff --git a/vtgl.c b/vtgl.c @@ -1080,7 +1080,7 @@ DEBUG_EXPORT VTGL_INITIALIZE_FN(vtgl_initialize) .x = cs.x * requested_cells.x + 2 * g_term_margin.x, .y = cs.y * requested_cells.y + 2 * g_term_margin.y, }; - if (requested_cells.x < 0 || requested_cells.y) + if (requested_cells.x < 0 || requested_cells.y < 0) requested_size = (iv2){.x = -1, .y = -1}; t->size = (iv2){.x = 1, .y = 1};