From cdb00a05823f69ceb9ed86f510450a5ee5cae7b9 Mon Sep 17 00:00:00 2001 From: Curtis McEnroe Date: Mon, 12 Aug 2019 16:30:43 -0400 Subject: Use a big macro switch-case This lets the compiler inline and generate jump tables however it sees fit. --- term.c | 141 +++++++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 81 insertions(+), 60 deletions(-) diff --git a/term.c b/term.c index 7bc6282..5ee88ac 100644 --- a/term.c +++ b/term.c @@ -358,68 +358,77 @@ static void add(struct Term *t, wchar_t ch) { } } -static Action *Actions[][128] = { - [Def][0] = add, - [Def][BEL] = nop, - [Def][BS] = bs, - [Def][HT] = ht, - [Def][NL] = nl, - [Def][CR] = cr, - [Def][ESC] = esc, - - [Esc][0] = escUnhandled, - [Esc]['('] = g0, - [Esc]['7'] = decsc, - [Esc]['8'] = decrc, - [Esc]['='] = nop, - [Esc]['>'] = nop, - [Esc]['M'] = ri, - [Esc]['['] = csi, - [Esc][']'] = osc, - - [G0][0] = nop, - - [CSI][0] = csiParam, - [CSI]['@'] = ich, - [CSI]['A'] = cuu, - [CSI]['B'] = cud, - [CSI]['C'] = cuf, - [CSI]['D'] = cub, - [CSI]['E'] = cnl, - [CSI]['F'] = cpl, - [CSI]['G'] = cha, - [CSI]['H'] = cup, - [CSI]['J'] = ed, - [CSI]['K'] = el, - [CSI]['L'] = il, - [CSI]['M'] = dl, - [CSI]['P'] = dch, - [CSI]['S'] = su, - [CSI]['T'] = sd, - [CSI]['X'] = ech, - [CSI]['d'] = vpa, - [CSI]['h'] = mode, - [CSI]['l'] = mode, - [CSI]['m'] = sgr, - [CSI]['r'] = decstbm, - [CSI]['t'] = nop, - - [OSC][0] = osc, - [OSC][BEL] = nop, - [OSC][ESC] = oscEsc, - - [OSCEsc][0] = osc, - [OSCEsc]['\\'] = nop, -}; - +#define S(s) break; case (s): switch (ch) +#define A(c, a) break; case (c): (a)(term, ch) +#define D(a) break; default: (a)(term, ch) void termUpdate(struct Term *term, wchar_t ch) { - assert(term->state < sizeof(Actions) / sizeof(Actions[0])); - Action *action = NULL; - if (ch < 128) action = Actions[term->state][ch]; - if (!action) action = Actions[term->state][0]; - assert(action); + uint state = term->state; term->state = Def; - action(term, ch); + switch (state) { + default: abort(); + + S(Def) { + A(BEL, nop); + A(BS, bs); + A(HT, ht); + A(NL, nl); + A(CR, cr); + A(ESC, esc); + D(add); + } + + S(Esc) { + A('(', g0); + A('7', decsc); + A('8', decrc); + A('=', nop); + A('>', nop); + A('M', ri); + A('[', csi); + A(']', osc); + D(escUnhandled); + } + S(G0) { + D(nop); + } + + S(CSI) { + A('@', ich); + A('A', cuu); + A('B', cud); + A('C', cuf); + A('D', cub); + A('E', cnl); + A('F', cpl); + A('G', cha); + A('H', cup); + A('J', ed); + A('K', el); + A('L', il); + A('M', dl); + A('P', dch); + A('S', su); + A('T', sd); + A('X', ech); + A('d', vpa); + A('h', mode); + A('l', mode); + A('m', sgr); + A('r', decstbm); + A('t', nop); + D(csiParam); + } + + S(OSC) { + A(BEL, nop); + A(ESC, oscEsc); + D(osc); + } + S(OSCEsc) { + A('\\', nop); + D(osc); + } + } } struct Term *termAlloc(uint rows, uint cols) { @@ -545,3 +554,15 @@ fail: fclose(file); return -1; } + +#ifdef TERM_MAIN + +int main(void) { + struct Term *term = termAlloc(24, 80); + wint_t ch; + while (WEOF != (ch = getwchar())) { + termUpdate(term, ch); + } +} + +#endif -- cgit 1.4.1