[automaton] unify insertion paths into insert_path() #2183

pull/2224/head
nick black 3 years ago
parent ce931a1bd5
commit 2498fffbbb
No known key found for this signature in database
GPG Key ID: 5F43400C21CBFACC

@ -141,14 +141,15 @@ esctrie_make_function(esctrie* e, triefunc fxn){
return 0; return 0;
} }
static int static esctrie*
esctrie_make_string(automaton* a, esctrie* e, triefunc fxn){ esctrie_make_string(automaton* a, esctrie* e){
if(e->ntype == NODE_STRING){ if(e->ntype == NODE_STRING){
return 0; logerror("repeated string node\n");
return NULL;
} }
if(e->ntype != NODE_SPECIAL){ if(e->ntype != NODE_SPECIAL){
logerror("can't make node type %d string\n", e->ntype); logerror("can't make node type %d string\n", e->ntype);
return -1; return NULL;
} }
for(int i = 0 ; i < 0x80 ; ++i){ for(int i = 0 ; i < 0x80 ; ++i){
if(!isprint(i)){ if(!isprint(i)){
@ -156,12 +157,12 @@ esctrie_make_string(automaton* a, esctrie* e, triefunc fxn){
} }
if(e->trie[i]){ if(e->trie[i]){
logerror("can't make %c-followed string\n", 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)); esctrie* newe = esctrie_from_idx(a, create_esctrie_node(a, 0));
if(newe == NULL){ if(newe == NULL){
return -1; return NULL;
} }
for(int i = 0 ; i < 0x80 ; ++i){ for(int i = 0 ; i < 0x80 ; ++i){
if(!isprint(i)){ if(!isprint(i)){
@ -178,20 +179,17 @@ esctrie_make_string(automaton* a, esctrie* e, triefunc fxn){
e->trie[i] = esctrie_idx(a, newe); e->trie[i] = esctrie_idx(a, newe);
} }
if((e->trie[0x1b] = create_esctrie_node(a, 0)) == 0){ if((e->trie[0x1b] = create_esctrie_node(a, 0)) == 0){
return -1; return NULL;
} }
e = esctrie_from_idx(a, e->trie[0x1b]); e = esctrie_from_idx(a, e->trie[0x1b]);
if((e->trie['\\'] = create_esctrie_node(a, NCKEY_INVALID)) == 0){ if((e->trie['\\'] = create_esctrie_node(a, NCKEY_INVALID)) == 0){
return -1; return NULL;
} }
e = esctrie_from_idx(a, e->trie['\\']); e = esctrie_from_idx(a, e->trie['\\']);
e->ni.id = 0; e->ni.id = 0;
e->ntype = NODE_SPECIAL; e->ntype = NODE_SPECIAL;
if(esctrie_make_function(e, fxn)){
return -1;
}
logdebug("made string: %p\n", e); logdebug("made string: %p\n", e);
return 0; return e;
} }
static esctrie* static esctrie*
@ -277,11 +275,11 @@ link_numeric(automaton* a, esctrie* e, unsigned follow){
return efollow; return efollow;
} }
// add a cflow path to the automaton static esctrie*
int inputctx_add_cflow(automaton* a, const char* seq, triefunc fxn){ insert_path(automaton* a, const char* seq){
if(a->escapes == 0){ if(a->escapes == 0){
if((a->escapes = create_esctrie_node(a, 0)) == 0){ if((a->escapes = create_esctrie_node(a, 0)) == 0){
return -1; return NULL;
} }
} }
esctrie* eptr = esctrie_from_idx(a, a->escapes); 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(c == '\\'){
if(inescape){ if(inescape){
logerror("illegal escape: \\\n"); logerror("illegal escape: \\\n");
return -1; return NULL;
} }
inescape = true; inescape = true;
}else if(inescape){ }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 // a numeric must be followed by some terminator
if(!*seq){ if(!*seq){
logerror("illegal numeric terminator\n"); logerror("illegal numeric terminator\n");
return -1; return NULL;
} }
c = *seq++; c = *seq++;
eptr = link_numeric(a, eptr, c); eptr = link_numeric(a, eptr, c);
if(eptr == NULL){ if(eptr == NULL){
return -1; return NULL;
} }
}else if(c == 'S'){ }else if(c == 'S'){
if(esctrie_make_string(a, eptr, fxn)){ if((eptr = esctrie_make_string(a, eptr)) == NULL){
return -1; return NULL;
} }
return 0; return eptr;
}else if(c == 'D'){ // drain (kleene closure) }else if(c == 'D'){ // drain (kleene closure)
// a kleene must be followed by some terminator // a kleene must be followed by some terminator
if(!*seq){ if(!*seq){
logerror("illegal kleene terminator\n"); logerror("illegal kleene terminator\n");
return -1; return NULL;
} }
c = *seq++; c = *seq++;
eptr = link_kleene(a, eptr, c); eptr = link_kleene(a, eptr, c);
if(eptr == NULL){ if(eptr == NULL){
return -1; return NULL;
} }
}else{ }else{
logerror("illegal escape: %u\n", c); logerror("illegal escape: %u\n", c);
return -1; return NULL;
} }
inescape = false; inescape = false;
}else{ }else{ // fixed character
logtrace("adding fixed %c %u\n", c, c);
if(eptr->trie[c] == 0){ if(eptr->trie[c] == 0){
if((eptr->trie[c] = create_esctrie_node(a, 0)) == 0){ if((eptr->trie[c] = create_esctrie_node(a, 0)) == 0){
return -1; return NULL;
} }
}else if(eptr->trie[c] == eptr->kleene){ }else if(eptr->trie[c] == eptr->kleene){
if((eptr->trie[c] = create_esctrie_node(a, 0)) == 0){ 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){ }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 // punch a hole through the numeric loop. create a new one, and fill
// it in with the existing target. // it in with the existing target.
struct esctrie* newe; struct esctrie* newe;
if((newe = esctrie_from_idx(a, create_esctrie_node(a, 0))) == 0){ if((newe = esctrie_from_idx(a, create_esctrie_node(a, 0))) == 0){
return -1; return NULL;
} }
for(int i = 0 ; i < 0x80 ; ++i){ for(int i = 0 ; i < 0x80 ; ++i){
newe->trie[i] = esctrie_from_idx(a, eptr->trie[c])->trie[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){ if(inescape){
logerror("illegal escape at end of line\n"); 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; return -1;
} }
free(eptr->trie); 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); logerror("not an escape (0x%x)\n", special);
return -1; return -1;
} }
if(a->escapes == 0){ esctrie* eptr = insert_path(a, esc + 1);
if((a->escapes = create_esctrie_node(a, 0)) == 0){ if(eptr == NULL){
return -1; 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 // 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) :/. // an example, see "kend" and "kc1" in st ("simple term" from suckless) :/.
if(cur->ni.id){ // already had one here! if(eptr->ni.id){ // already had one here!
if(cur->ni.id != special){ if(eptr->ni.id != special){
logwarn("already added escape (got 0x%x, wanted 0x%x)\n", cur->ni.id, special); logwarn("already added escape (got 0x%x, wanted 0x%x)\n", eptr->ni.id, special);
} }
}else{ }else{
cur->ni.id = special; eptr->ni.id = special;
cur->ni.shift = shift; eptr->ni.shift = shift;
cur->ni.ctrl = ctrl; eptr->ni.ctrl = ctrl;
cur->ni.alt = alt; eptr->ni.alt = alt;
eptr->ni.y = 0;
eptr->ni.x = 0;
} }
return 0; return 0;
} }

@ -160,18 +160,18 @@ prep_special_keys(inputctx* ictx){
{ .tinfo = "kf22", .key = NCKEY_F22, }, { .tinfo = "kf22", .key = NCKEY_F22, },
{ .tinfo = "kf23", .key = NCKEY_F23, }, { .tinfo = "kf23", .key = NCKEY_F23, },
{ .tinfo = "kf24", .key = NCKEY_F24, }, { .tinfo = "kf24", .key = NCKEY_F24, },
{ .tinfo = "kf25", .key = NCKEY_F01, .ctrl = 1, }, { .tinfo = "kf25", .key = NCKEY_F25, },
{ .tinfo = "kf26", .key = NCKEY_F02, .ctrl = 1, }, { .tinfo = "kf26", .key = NCKEY_F26, },
{ .tinfo = "kf27", .key = NCKEY_F03, .ctrl = 1, }, { .tinfo = "kf27", .key = NCKEY_F27, },
{ .tinfo = "kf28", .key = NCKEY_F04, .ctrl = 1, }, { .tinfo = "kf28", .key = NCKEY_F28, },
{ .tinfo = "kf29", .key = NCKEY_F05, .ctrl = 1, }, { .tinfo = "kf29", .key = NCKEY_F29, },
{ .tinfo = "kf30", .key = NCKEY_F06, .ctrl = 1, }, { .tinfo = "kf30", .key = NCKEY_F30, },
{ .tinfo = "kf31", .key = NCKEY_F07, .ctrl = 1, }, { .tinfo = "kf31", .key = NCKEY_F31, },
{ .tinfo = "kf32", .key = NCKEY_F08, .ctrl = 1, }, { .tinfo = "kf32", .key = NCKEY_F32, },
{ .tinfo = "kf33", .key = NCKEY_F09, .ctrl = 1, }, { .tinfo = "kf33", .key = NCKEY_F33, },
{ .tinfo = "kf34", .key = NCKEY_F10, .ctrl = 1, }, { .tinfo = "kf34", .key = NCKEY_F34, },
{ .tinfo = "kf35", .key = NCKEY_F11, .ctrl = 1, }, { .tinfo = "kf35", .key = NCKEY_F35, },
{ .tinfo = "kf36", .key = NCKEY_F12, .ctrl = 1, }, { .tinfo = "kf36", .key = NCKEY_F36, },
{ .tinfo = "kf37", .key = NCKEY_F37, }, { .tinfo = "kf37", .key = NCKEY_F37, },
{ .tinfo = "kf38", .key = NCKEY_F38, }, { .tinfo = "kf38", .key = NCKEY_F38, },
{ .tinfo = "kf39", .key = NCKEY_F39, }, { .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( (i->initdata = malloc(sizeof(*i->initdata))) ){
if(getpipes(i->readypipes) == 0){ if(getpipes(i->readypipes) == 0){
memset(&i->amata, 0, sizeof(i->amata)); 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){
if(set_fd_nonblocking(i->stdinfd, 1, &ti->stdio_blocking_save) == 0){ i->termfd = tty_check(i->stdinfd) ? -1 : get_tty_fd(infp);
i->termfd = tty_check(i->stdinfd) ? -1 : get_tty_fd(infp); memset(i->initdata, 0, sizeof(*i->initdata));
memset(i->initdata, 0, sizeof(*i->initdata)); i->iread = i->iwrite = i->ivalid = 0;
i->iread = i->iwrite = i->ivalid = 0; i->cread = i->cwrite = i->cvalid = 0;
i->cread = i->cwrite = i->cvalid = 0; i->initdata_complete = NULL;
i->initdata_complete = NULL; i->stats = stats;
i->stats = stats; i->ti = ti;
i->ti = ti; i->stdineof = 0;
i->stdineof = 0;
#ifdef __MINGW64__ #ifdef __MINGW64__
i->stdinhandle = ti->inhandle; i->stdinhandle = ti->inhandle;
#endif #endif
i->ibufvalid = 0; i->ibufvalid = 0;
i->linesigs = linesigs_enabled; i->linesigs = linesigs_enabled;
i->tbufvalid = 0; i->tbufvalid = 0;
i->midescape = 0; i->midescape = 0;
i->lmargin = lmargin; i->lmargin = lmargin;
i->tmargin = tmargin; i->tmargin = tmargin;
i->drain = drain; i->drain = drain;
logdebug("input descriptors: %d/%d\n", i->stdinfd, i->termfd); logdebug("input descriptors: %d/%d\n", i->stdinfd, i->termfd);
return i; return i;
}
} }
endpipes(i->readypipes); endpipes(i->readypipes);
} }
@ -1102,7 +1100,9 @@ prep_all_keys(inputctx* ictx){
return -1; return -1;
} }
if(prep_kitty_special_keys(ictx)){ if(prep_kitty_special_keys(ictx)){
input_free_esctrie(&ictx->amata); return -1;
}
if(prep_special_keys(ictx)){
return -1; return -1;
} }
return 0; return 0;
@ -1583,10 +1583,10 @@ static void*
input_thread(void* vmarshall){ input_thread(void* vmarshall){
inputctx* ictx = vmarshall; inputctx* ictx = vmarshall;
if(build_cflow_automaton(ictx)){ if(build_cflow_automaton(ictx)){
raise(SIGSEGV); // ? FIXME abort(); // FIXME?
} }
if(prep_all_keys(ictx)){ if(prep_all_keys(ictx)){
raise(SIGSEGV); // ? FIXME abort(); // FIXME?
} }
for(;;){ for(;;){
read_inputs_nblock(ictx); read_inputs_nblock(ictx);

Loading…
Cancel
Save