vtgl

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

Commit: 4d3b84d51afc507ef8ed27180caede7a47d3d5be
Parent: d033316a3c556d06224fdaa491d4e41949d4f06d
Author: Randy Palamar
Date:   Fri, 23 Aug 2024 06:31:36 -0600

don't pass csi/osc structs on the stack

This also makes it clearer when we need more bytes.

Diffstat:
Mterminal.c | 90++++++++++++++++++++++++++++++++++++++-----------------------------------------
Mutil.h | 2+-
2 files changed, 44 insertions(+), 48 deletions(-)

diff --git a/terminal.c b/terminal.c @@ -512,48 +512,47 @@ push_tab(Term *t) cursor_step_column(t, advance); } -static CSI -parse_csi(s8 *r) +static i32 +parse_csi(s8 *r, CSI *csi) { - CSI csi = {0}; - csi.raw.data = r->data; + *csi = (CSI){0}; + csi->raw = (s8){.data = r->data}; if (peek(*r, 0) == '?') { - csi.priv = 1; - csi.raw.len++; + csi->priv = 1; + csi->raw.len++; get_ascii(r); } while (r->len) { u32 cp = get_ascii(r); - csi.raw.len++; + csi->raw.len++; if (BETWEEN(cp, '0', '9')) { - csi.argv[csi.argc] *= 10; - csi.argv[csi.argc] += cp - '0'; + csi->argv[csi->argc] *= 10; + csi->argv[csi->argc] += cp - '0'; continue; } - csi.argc++; - if (cp != ';' || csi.argc == ESC_ARG_SIZ) { + csi->argc++; + if (cp != ';' || csi->argc == ESC_ARG_SIZ) { if (cp == ';') { - csi.mode = get_ascii(r); - csi.raw.len++; + csi->mode = get_ascii(r); + csi->raw.len++; } else { - csi.mode = cp; + csi->mode = cp; } - return csi; + return 0; } } - - /* NOTE: Needs more characters! */ - csi.argc = -1; - return csi; + /* NOTE: if we fell out of the loop then we ran out of characters */ + return -1; } static void handle_csi(Term *t, s8 *raw) { - CSI csi = parse_csi(raw); - ASSERT(csi.argc != -1); + CSI csi; + i32 ret = parse_csi(raw, &csi); + ASSERT(ret != -1); #define ORONE(x) (x)? (x) : 1 @@ -591,50 +590,47 @@ handle_csi(Term *t, s8 *raw) } } -static OSC -parse_osc(s8 *raw) +static i32 +parse_osc(s8 *raw, OSC *osc) { - OSC osc = {0}; - - osc.raw.data = raw->data; + *osc = (OSC){0}; + osc->raw.data = raw->data; /* NOTE: parse command then store the rest as a string */ u32 cp; while (raw->len) { cp = get_ascii(raw); - osc.raw.len++; + osc->raw.len++; if (!BETWEEN(cp, '0', '9')) break; - osc.cmd *= 10; - osc.cmd += cp - '0'; + osc->cmd *= 10; + osc->cmd += cp - '0'; /* TODO: Performance? */ /* NOTE: The maximum OSC in xterm is 119 so if this * exceeds that the whole sequence is malformed */ - if (osc.cmd > 1000) + if (osc->cmd > 1000) break; } - if (cp != ';' || osc.cmd > 1000) + if (cp != ';' || osc->cmd > 1000) die("parse_osc: malformed\n"); - osc.arg.data = raw->data; + osc->arg.data = raw->data; while (raw->len) { cp = get_ascii(raw); - osc.raw.len++; + osc->raw.len++; if (cp == '\a') - return osc; + return 0; if (cp == 0x1B && peek(*raw, 0) == '\\') { get_ascii(raw); - osc.raw.len++; - return osc; + osc->raw.len++; + return 0; } - osc.arg.len++; + osc->arg.len++; } /* NOTE: if we fell out of the loop then we ran out of characters */ - osc.cmd = -1; - - return osc; + return -1; } static void @@ -660,13 +656,14 @@ dump_osc(OSC *osc) static void handle_osc(Term *t, s8 *raw, Arena a) { - OSC osc = parse_osc(raw); + OSC osc; + i32 ret = parse_osc(raw, &osc); + ASSERT(ret != -1); switch (osc.cmd) { case 0: set_window_title(t->gl.window, a, osc.arg); break; case 1: /* IGNORED: set icon name */ break; case 2: set_window_title(t->gl.window, a, osc.arg); break; - case -1: default: fputs("unhandled osc cmd: ", stderr); dump_osc(&osc); @@ -723,8 +720,8 @@ static enum escape_moves_cursor_result validate_osc(Term *t, s8 *raw) { enum escape_moves_cursor_result result = EMC_NORMAL_RETURN; - OSC osc = parse_osc(raw); - if (osc.cmd == -1) + OSC osc; + if (parse_osc(raw, &osc) == -1) return EMC_NEEDS_MORE_BYTES; return result; } @@ -733,9 +730,8 @@ static enum escape_moves_cursor_result check_if_csi_moves_cursor(Term *t, s8 *raw) { enum escape_moves_cursor_result result = EMC_NORMAL_RETURN; - CSI csi = parse_csi(raw); - - if (csi.argc == -1) + CSI csi; + if (parse_csi(raw, &csi) == -1) return EMC_NEEDS_MORE_BYTES; u32 term_mode = t->mode; diff --git a/util.h b/util.h @@ -13,7 +13,7 @@ #define ASSERT(c) do { if (!(c)) asm("int3; nop"); } while(0) #define DEBUG_EXPORT #else -#define ASSERT(c) +#define ASSERT(c) do { (void)(c); } while(0) #define DEBUG_EXPORT static #endif