diff options
author | Nicholas Noll <nbnoll@eml.cc> | 2020-06-18 19:45:40 -0700 |
---|---|---|
committer | Nicholas Noll <nbnoll@eml.cc> | 2020-06-18 19:45:40 -0700 |
commit | 425ef692da7e74112f88f0b368f3286dba84f846 (patch) | |
tree | d45729e90010e8d8c539031c3b72165f6884575d /sys/cmd/dvtm/term.c | |
parent | 0522b4bf4e125b7ceb67f7177db692aed3a0ebf9 (diff) |
feat: working parser for rc shell language
Diffstat (limited to 'sys/cmd/dvtm/term.c')
-rw-r--r-- | sys/cmd/dvtm/term.c | 395 |
1 files changed, 0 insertions, 395 deletions
diff --git a/sys/cmd/dvtm/term.c b/sys/cmd/dvtm/term.c deleted file mode 100644 index cda2bbe..0000000 --- a/sys/cmd/dvtm/term.c +++ /dev/null @@ -1,395 +0,0 @@ -#include "term.h" - -struct ExtraInfo -{ - char *enteralt; - char *exitalt; - - char *entermouse; - char *exitmouse; -}; - -static -struct ExtraInfo vt200 = -{ - .enteralt = "\e[?1049h", - .exitalt = "\e[?1049l", - - .entermouse = "\e[?1049h\e[?1006l", - .exitmouse = "\e[?1002l\e[?1006l", -}; - -// ----------------------------------------------------------------------- -// database lookup - -static -char* -tryinfostr(Term *t, enum unibi_string s) -{ - char *val = (char*)unibi_get_str(t->info, s); - /* TODO: provide fallbacks */ - return val; -} - -static -char* -guessinfostr(Term *t, enum unibi_string s, char *guess) -{ - char *val = (char*)unibi_get_str(t->info, s); - if (!val) - return guess; - return val; -} - -static -char* -getinfostr(Term *t, enum unibi_string s) -{ - char *val = tryinfostr(t, s); - if (!val) - panicf("required term info string '%s' missing", unibi_name_str(s)); - - return val; -} - -static -char * -tryextrastr(Term *t, char *name) -{ - const char *nm; - size_t max = unibi_count_ext_str(t->info); - for (size_t i = 0; i < max; i++) { - nm = unibi_get_ext_str_name(t->info, i); - if (nm && !strcmp(nm, name)) { - return (char *)nm; - } - } - return nil; -} - -static -char * -guessextrastr(Term *t, char *name, char *guess) -{ - char *s; - if ((s = tryextrastr(t, name))) - return s; - - return guess; -} - -static -int -tryextrabool(Term *t, char *name) -{ - const char *nm; - size_t max = unibi_count_ext_bool(t->info); - for (size_t i = 0; i < max; i++) { - nm = unibi_get_ext_bool_name(t->info, i); - if (nm && !strcmp(nm, name)) { - return (int)i; - } - } - return -1; -} - -/* formats escape strings and writes to output */ -static void tfmt(Term *t, char *esc, int n, ...); - -// ----------------------------------------------------------------------- -// exported pen methods - -// ----------------------------------------------------------------------- -// exported term methods - -static -char * -ttmpbuf(Term *t, int len) -{ - if (t->tmp.len >= len) - return t->tmp.b; - - /* TODO: error handling */ - return (t->tmp.b = realloc(t->tmp.b, len)); -} - -void -tinit(Term *t) -{ - t->name = getenv("TERM"); - t->info = unibi_from_term(t->name); - if (!t->info) - panicf("could not identify terminal"); - - t->mode.mouse = 0; - t->mode.cursorvis = 1; - t->mode.altscreen = 0; - - t->cap.colors = unibi_get_num(t->info, unibi_max_colors); - t->cap.bce = unibi_get_bool(t->info, unibi_back_color_erase); - - /* TODO */ - t->input = nil; - t->root = nil; - t->pen = (Pen){0}; - - /* fill in buffers */ - t->buf.c = t->buf.b; - t->tmp.b = nil; - t->tmp.len = 0; - - /* get all term info format strings */ - t->esc.cup = getinfostr(t, unibi_cursor_address); - t->esc.vpa = tryinfostr(t, unibi_row_address); - t->esc.hpa = tryinfostr(t, unibi_column_address); - t->esc.cuu = getinfostr(t, unibi_parm_up_cursor); - t->esc.cuu1 = tryinfostr(t, unibi_cursor_up); - t->esc.cud = getinfostr(t, unibi_parm_down_cursor); - t->esc.cud1 = tryinfostr(t, unibi_cursor_down); - t->esc.cuf = getinfostr(t, unibi_parm_right_cursor); - t->esc.cuf1 = tryinfostr(t, unibi_cursor_right); - t->esc.cub = getinfostr(t, unibi_parm_left_cursor); - t->esc.cub1 = tryinfostr(t, unibi_cursor_left); - t->esc.ich = getinfostr(t, unibi_parm_ich); - t->esc.ich1 = tryinfostr(t, unibi_insert_character); - t->esc.dch = getinfostr(t, unibi_parm_dch); - t->esc.dch1 = tryinfostr(t, unibi_delete_character); - t->esc.il = getinfostr(t, unibi_parm_insert_line); - t->esc.il1 = tryinfostr(t, unibi_insert_line); - t->esc.dl = getinfostr(t, unibi_parm_delete_line); - t->esc.dl1 = tryinfostr(t, unibi_delete_line); - t->esc.ech = getinfostr(t, unibi_erase_chars); - t->esc.ed2 = getinfostr(t, unibi_clear_screen); - t->esc.stbm = getinfostr(t, unibi_change_scroll_region); - t->esc.sgr = getinfostr(t, unibi_set_attributes); - t->esc.sgr0 = getinfostr(t, unibi_exit_attribute_mode); - t->esc.sgr_i0 = tryinfostr(t, unibi_exit_italics_mode); - t->esc.sgr_i1 = tryinfostr(t, unibi_enter_italics_mode); - t->esc.sgr_fg = getinfostr(t, unibi_set_a_foreground); - t->esc.sgr_bg = getinfostr(t, unibi_set_a_background); - t->esc.sm_csr = getinfostr(t, unibi_cursor_normal); - t->esc.rm_csr = getinfostr(t, unibi_cursor_invisible); - - /* extensions to terminfo */ - t->esc.ext.rgbf = guessextrastr(t, "setrgbf", "\x1b[38;2;%p1%d;%p2%d;%p3%dm"); - t->esc.ext.rgbb = guessextrastr(t, "setrgbb", "\x1b[48;2;%p1%d;%p2%d;%p3%dm"); - - /* acs characters */ - t->acs.vline = tryinfostr(t, unibi_acs_vline); - t->acs.hline = tryinfostr(t, unibi_acs_hline); - t->acs.plus = tryinfostr(t, unibi_acs_plus); - t->acs.ltee = tryinfostr(t, unibi_acs_ltee); - t->acs.rtee = tryinfostr(t, unibi_acs_rtee); - t->acs.ttee = tryinfostr(t, unibi_acs_ttee); - t->acs.btee = tryinfostr(t, unibi_acs_btee); - t->acs.ulcorner = tryinfostr(t, unibi_acs_ulcorner); - t->acs.urcorner = tryinfostr(t, unibi_acs_urcorner); - t->acs.llcorner = tryinfostr(t, unibi_acs_llcorner); - t->acs.lrcorner = tryinfostr(t, unibi_acs_lrcorner); -} - -void -tfini(Term *t) -{ - if (t->mode.mouse) - twrite(t, 0, vt200.exitmouse); - if (!t->mode.cursorvis) - tfmt(t, t->esc.rm_csr, 0); - if (t->mode.altscreen) - twrite(t, 0, vt200.exitalt); - - tfmt(t, t->esc.sgr0, 0); -} - -void -tflush(Term *t) -{ - if (t->fd != -1) - write(t->fd, t->buf.b, t->buf.c - t->buf.b); - - t->buf.c = t->buf.b; -} - -void -twrite(Term *t, long len, char *s) -{ - int n; - if (!len) - len = strlen(s); - - while (len > 0) { - n = MIN(len, arrend(t->buf.b) - t->buf.c); - memcpy(t->buf.c, s, n); - t->buf.c += n; - len -= n; - tflush(t); - } -} - -void -tsetpen(Term *t, Pen new) -{ - int c; - ushort ic, in; - Pen cur = t->pen; - if (!memcmp(&new, &cur, sizeof(new))) - return; - - /* attributes */ - tfmt(t, t->esc.sgr, 9, - 0, /* standout */ - new.state & PenUnderline, - new.state & PenReverse, - new.state & PenBlink, - new.state & PenDim, - new.state & PenBold, - new.state & PenInvis, - 0, /* protect */ - 0); /* alt */ - - ic = cur.state & PenItalic; - in = new.state & PenItalic; - if (ic & ~in) - tfmt(t, t->esc.sgr_i0, 0); - else if (~ic & in) - tfmt(t, t->esc.sgr_i1, 0); - - /* fg/bg color */ - /* TODO: add a check for if the terminal supports true color */ - /* TODO: add a check for negative indices */ - if (new.state & PenTrueClr) { - tfmt(t, t->esc.ext.rgbf, 3, new.rgb.fg.r, new.rgb.fg.g, new.rgb.fg.b); - tfmt(t, t->esc.ext.rgbb, 3, new.rgb.bg.r, new.rgb.bg.g, new.rgb.bg.b); - } else { - tfmt(t, t->esc.sgr_fg, 1, new.col.fg); - tfmt(t, t->esc.sgr_bg, 1, new.col.bg); - } - - t->pen = new; -} - -static -void -tfmt(Term *t, char *esc, int n, ...) -{ - int i; - long len; - va_list args; - unibi_var_t param[9]; - char buf[64], *c = buf; - - if (!esc) - panicf("no terminfo escape string given"); - - va_start(args, n); - for (i = 0; i < arrlen(param) && i < n; i++) - param[i] = unibi_var_from_num(va_arg(args, int)); - va_end(args); - - len = unibi_run(esc, param, c, sizeof(buf)); - if (len < arrlen(buf)) { - c = ttmpbuf(t, len); - unibi_run(esc, param, c, len); - } - - twrite(t, len, c); -} - -/* absolute move */ -int -tgoto(Term *t, int row, int col) -{ - if (row != -1 && col != -1) - tfmt(t, t->esc.cup, 2, row, col); - else if (row != -1) { - if (!t->esc.vpa) - return 0; - tfmt(t, t->esc.vpa, 1, row); - } else if (col != -1) { - if (col == 0) { - twrite(t, 1, "\r"); - return 1; - } - if (t->esc.hpa) - tfmt(t, t->esc.hpa, 1, col); - else if (t->esc.cuf) { - twrite(t, 1, "\r"); - tfmt(t, t->esc.cuf, 1, col); - } else - return 0; - } else - return 0; /* unreachable */ - - return 1; -} - -/* relative move */ -void -tjump(Term *t, int down, int right) -{ - if (down == 1 && t->esc.cud1) - tfmt(t, t->esc.cud1, 0); - else if (down == -1 && t->esc.cuu1) - tfmt(t, t->esc.cuu1, 0); - else if (down > 0) - tfmt(t, t->esc.cud, 1, down); - else if (down < 0) - tfmt(t, t->esc.cuu, 1, -down); - - if (right == 1 && t->esc.cuf1) - tfmt(t, t->esc.cuf1, 0); - else if (right == -1 && t->esc.cub1) - tfmt (t, t->esc.cub1, 0); - else if (right > 0) - tfmt(t, t->esc.cuf, 1, right); - else if( right < 0) - tfmt(t, t->esc.cub, 1, -right); -} - -void -tdel(Term *t, int num) -{ - char *c, buf[64]; - if (num < 1) - return; - - /* TODO: allow for not moving */ - if (t->cap.bce) { - tfmt(t, t->esc.ech, 1, num); - tjump(t, 0, num); - } else { - c = buf; - memset(c, ' ', arrlen(buf)); - while(num > 64) { - twrite(t, arrlen(buf), c); - num -= arrlen(buf); - } - twrite(t, num, c); - } -} - -void -tclear(Term *t) -{ - tfmt(t, t->esc.ed2, 0); -} - -// ----------------------------------------------------------------------- -// testing entry - -int -main() -{ - Term t; - tinit(&t); - - printf("%s: %s\n", unibi_short_name_str(unibi_set_a_foreground), t.esc.sgr_fg); - printf("%s: %s\n", unibi_short_name_str(unibi_set_a_background), t.esc.sgr_bg); - tfmt(&t, t.esc.ext.rgbf, 3, 10, 10, 100); - tfmt(&t, t.esc.ext.rgbb, 3, 100, 0, 100); - twrite(&t, 0, "hello world\n"); - twrite(&t, 0, "hello world\n"); - twrite(&t, 0, t.acs.hline); - - tfini(&t); -} |