From 2498fffbbb552c6126fbf67f2e36d2b7723161d0 Mon Sep 17 00:00:00 2001 From: nick black Date: Fri, 1 Oct 2021 20:35:30 -0400 Subject: [PATCH] [automaton] unify insertion paths into insert_path() #2183 --- src/lib/automaton.c | 103 +++++++++++++++++++++----------------------- src/lib/in.c | 72 +++++++++++++++---------------- 2 files changed, 84 insertions(+), 91 deletions(-) diff --git a/src/lib/automaton.c b/src/lib/automaton.c index 2f571b149b..8fe9976a1d 100644 --- a/src/lib/automaton.c +++ b/src/lib/automaton.c @@ -141,14 +141,15 @@ esctrie_make_function(esctrie* e, triefunc fxn){ return 0; } -static int -esctrie_make_string(automaton* a, esctrie* e, triefunc fxn){ +static esctrie* +esctrie_make_string(automaton* a, esctrie* e){ if(e->ntype == NODE_STRING){ - return 0; + logerror("repeated string node\n"); + return NULL; } if(e->ntype != NODE_SPECIAL){ logerror("can't make node type %d string\n", e->ntype); - return -1; + return NULL; } for(int i = 0 ; i < 0x80 ; ++i){ if(!isprint(i)){ @@ -156,12 +157,12 @@ esctrie_make_string(automaton* a, esctrie* e, triefunc fxn){ } if(e->trie[i]){ logerror("can't make %c-followed string\n", i); - return -1; + return NULL; } } esctrie* newe = esctrie_from_idx(a, create_esctrie_node(a, 0)); if(newe == NULL){ - return -1; + return NULL; } for(int i = 0 ; i < 0x80 ; ++i){ if(!isprint(i)){ @@ -178,20 +179,17 @@ esctrie_make_string(automaton* a, esctrie* e, triefunc fxn){ e->trie[i] = esctrie_idx(a, newe); } if((e->trie[0x1b] = create_esctrie_node(a, 0)) == 0){ - return -1; + return NULL; } e = esctrie_from_idx(a, e->trie[0x1b]); if((e->trie['\\'] = create_esctrie_node(a, NCKEY_INVALID)) == 0){ - return -1; + return NULL; } e = esctrie_from_idx(a, e->trie['\\']); e->ni.id = 0; e->ntype = NODE_SPECIAL; - if(esctrie_make_function(e, fxn)){ - return -1; - } logdebug("made string: %p\n", e); - return 0; + return e; } static esctrie* @@ -277,11 +275,11 @@ link_numeric(automaton* a, esctrie* e, unsigned follow){ return efollow; } -// add a cflow path to the automaton -int inputctx_add_cflow(automaton* a, const char* seq, triefunc fxn){ +static esctrie* +insert_path(automaton* a, const char* seq){ if(a->escapes == 0){ if((a->escapes = create_esctrie_node(a, 0)) == 0){ - return -1; + return NULL; } } esctrie* eptr = esctrie_from_idx(a, a->escapes); @@ -291,7 +289,7 @@ int inputctx_add_cflow(automaton* a, const char* seq, triefunc fxn){ if(c == '\\'){ if(inescape){ logerror("illegal escape: \\\n"); - return -1; + return NULL; } inescape = true; }else if(inescape){ @@ -299,49 +297,50 @@ int inputctx_add_cflow(automaton* a, const char* seq, triefunc fxn){ // a numeric must be followed by some terminator if(!*seq){ logerror("illegal numeric terminator\n"); - return -1; + return NULL; } c = *seq++; eptr = link_numeric(a, eptr, c); if(eptr == NULL){ - return -1; + return NULL; } }else if(c == 'S'){ - if(esctrie_make_string(a, eptr, fxn)){ - return -1; + if((eptr = esctrie_make_string(a, eptr)) == NULL){ + return NULL; } - return 0; + return eptr; }else if(c == 'D'){ // drain (kleene closure) // a kleene must be followed by some terminator if(!*seq){ logerror("illegal kleene terminator\n"); - return -1; + return NULL; } c = *seq++; eptr = link_kleene(a, eptr, c); if(eptr == NULL){ - return -1; + return NULL; } }else{ logerror("illegal escape: %u\n", c); - return -1; + return NULL; } inescape = false; - }else{ + }else{ // fixed character + logtrace("adding fixed %c %u\n", c, c); if(eptr->trie[c] == 0){ if((eptr->trie[c] = create_esctrie_node(a, 0)) == 0){ - return -1; + return NULL; } }else if(eptr->trie[c] == eptr->kleene){ if((eptr->trie[c] = create_esctrie_node(a, 0)) == 0){ - return -1; + return NULL; } }else if(esctrie_from_idx(a, eptr->trie[c])->ntype == NODE_NUMERIC){ // punch a hole through the numeric loop. create a new one, and fill // it in with the existing target. struct esctrie* newe; if((newe = esctrie_from_idx(a, create_esctrie_node(a, 0))) == 0){ - return -1; + return NULL; } for(int i = 0 ; i < 0x80 ; ++i){ newe->trie[i] = esctrie_from_idx(a, eptr->trie[c])->trie[i]; @@ -353,6 +352,15 @@ int inputctx_add_cflow(automaton* a, const char* seq, triefunc fxn){ } if(inescape){ logerror("illegal escape at end of line\n"); + return NULL; + } + return eptr; +} + +// add a cflow path to the automaton +int inputctx_add_cflow(automaton* a, const char* seq, triefunc fxn){ + esctrie* eptr = insert_path(a, seq); + if(eptr == NULL){ return -1; } free(eptr->trie); @@ -367,38 +375,23 @@ int inputctx_add_input_escape(automaton* a, const char* esc, uint32_t special, logerror("not an escape (0x%x)\n", special); return -1; } - if(a->escapes == 0){ - if((a->escapes = create_esctrie_node(a, 0)) == 0){ - return -1; - } + esctrie* eptr = insert_path(a, esc + 1); + if(eptr == NULL){ + return -1; } - esctrie* cur = esctrie_from_idx(a, a->escapes); - ++esc; // don't encode initial escape as a transition - do{ - int valid = *esc; - if(valid <= 0 || valid >= 0x80 || valid == NCKEY_ESC){ - logerror("invalid character %d in escape\n", valid); - return -1; - } - if(cur->trie[valid] == 0){ - if((cur->trie[valid] = create_esctrie_node(a, 0)) == 0){ - return -1; - } - } - cur = esctrie_from_idx(a, cur->trie[valid]); - ++esc; - }while(*esc); // it appears that multiple keys can be mapped to the same escape string. as // an example, see "kend" and "kc1" in st ("simple term" from suckless) :/. - if(cur->ni.id){ // already had one here! - if(cur->ni.id != special){ - logwarn("already added escape (got 0x%x, wanted 0x%x)\n", cur->ni.id, special); + if(eptr->ni.id){ // already had one here! + if(eptr->ni.id != special){ + logwarn("already added escape (got 0x%x, wanted 0x%x)\n", eptr->ni.id, special); } }else{ - cur->ni.id = special; - cur->ni.shift = shift; - cur->ni.ctrl = ctrl; - cur->ni.alt = alt; + eptr->ni.id = special; + eptr->ni.shift = shift; + eptr->ni.ctrl = ctrl; + eptr->ni.alt = alt; + eptr->ni.y = 0; + eptr->ni.x = 0; } return 0; } diff --git a/src/lib/in.c b/src/lib/in.c index a8acf93ab6..ae535406f2 100644 --- a/src/lib/in.c +++ b/src/lib/in.c @@ -160,18 +160,18 @@ prep_special_keys(inputctx* ictx){ { .tinfo = "kf22", .key = NCKEY_F22, }, { .tinfo = "kf23", .key = NCKEY_F23, }, { .tinfo = "kf24", .key = NCKEY_F24, }, - { .tinfo = "kf25", .key = NCKEY_F01, .ctrl = 1, }, - { .tinfo = "kf26", .key = NCKEY_F02, .ctrl = 1, }, - { .tinfo = "kf27", .key = NCKEY_F03, .ctrl = 1, }, - { .tinfo = "kf28", .key = NCKEY_F04, .ctrl = 1, }, - { .tinfo = "kf29", .key = NCKEY_F05, .ctrl = 1, }, - { .tinfo = "kf30", .key = NCKEY_F06, .ctrl = 1, }, - { .tinfo = "kf31", .key = NCKEY_F07, .ctrl = 1, }, - { .tinfo = "kf32", .key = NCKEY_F08, .ctrl = 1, }, - { .tinfo = "kf33", .key = NCKEY_F09, .ctrl = 1, }, - { .tinfo = "kf34", .key = NCKEY_F10, .ctrl = 1, }, - { .tinfo = "kf35", .key = NCKEY_F11, .ctrl = 1, }, - { .tinfo = "kf36", .key = NCKEY_F12, .ctrl = 1, }, + { .tinfo = "kf25", .key = NCKEY_F25, }, + { .tinfo = "kf26", .key = NCKEY_F26, }, + { .tinfo = "kf27", .key = NCKEY_F27, }, + { .tinfo = "kf28", .key = NCKEY_F28, }, + { .tinfo = "kf29", .key = NCKEY_F29, }, + { .tinfo = "kf30", .key = NCKEY_F30, }, + { .tinfo = "kf31", .key = NCKEY_F31, }, + { .tinfo = "kf32", .key = NCKEY_F32, }, + { .tinfo = "kf33", .key = NCKEY_F33, }, + { .tinfo = "kf34", .key = NCKEY_F34, }, + { .tinfo = "kf35", .key = NCKEY_F35, }, + { .tinfo = "kf36", .key = NCKEY_F36, }, { .tinfo = "kf37", .key = NCKEY_F37, }, { .tinfo = "kf38", .key = NCKEY_F38, }, { .tinfo = "kf39", .key = NCKEY_F39, }, @@ -942,29 +942,27 @@ create_inputctx(tinfo* ti, FILE* infp, int lmargin, int tmargin, if( (i->initdata = malloc(sizeof(*i->initdata))) ){ if(getpipes(i->readypipes) == 0){ memset(&i->amata, 0, sizeof(i->amata)); - if(prep_special_keys(i) == 0){ - if(set_fd_nonblocking(i->stdinfd, 1, &ti->stdio_blocking_save) == 0){ - i->termfd = tty_check(i->stdinfd) ? -1 : get_tty_fd(infp); - memset(i->initdata, 0, sizeof(*i->initdata)); - i->iread = i->iwrite = i->ivalid = 0; - i->cread = i->cwrite = i->cvalid = 0; - i->initdata_complete = NULL; - i->stats = stats; - i->ti = ti; - i->stdineof = 0; + if(set_fd_nonblocking(i->stdinfd, 1, &ti->stdio_blocking_save) == 0){ + i->termfd = tty_check(i->stdinfd) ? -1 : get_tty_fd(infp); + memset(i->initdata, 0, sizeof(*i->initdata)); + i->iread = i->iwrite = i->ivalid = 0; + i->cread = i->cwrite = i->cvalid = 0; + i->initdata_complete = NULL; + i->stats = stats; + i->ti = ti; + i->stdineof = 0; #ifdef __MINGW64__ - i->stdinhandle = ti->inhandle; + i->stdinhandle = ti->inhandle; #endif - i->ibufvalid = 0; - i->linesigs = linesigs_enabled; - i->tbufvalid = 0; - i->midescape = 0; - i->lmargin = lmargin; - i->tmargin = tmargin; - i->drain = drain; - logdebug("input descriptors: %d/%d\n", i->stdinfd, i->termfd); - return i; - } + i->ibufvalid = 0; + i->linesigs = linesigs_enabled; + i->tbufvalid = 0; + i->midescape = 0; + i->lmargin = lmargin; + i->tmargin = tmargin; + i->drain = drain; + logdebug("input descriptors: %d/%d\n", i->stdinfd, i->termfd); + return i; } endpipes(i->readypipes); } @@ -1102,7 +1100,9 @@ prep_all_keys(inputctx* ictx){ return -1; } if(prep_kitty_special_keys(ictx)){ - input_free_esctrie(&ictx->amata); + return -1; + } + if(prep_special_keys(ictx)){ return -1; } return 0; @@ -1583,10 +1583,10 @@ static void* input_thread(void* vmarshall){ inputctx* ictx = vmarshall; if(build_cflow_automaton(ictx)){ - raise(SIGSEGV); // ? FIXME + abort(); // FIXME? } if(prep_all_keys(ictx)){ - raise(SIGSEGV); // ? FIXME + abort(); // FIXME? } for(;;){ read_inputs_nblock(ictx);