[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;
}
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;
}

@ -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);

Loading…
Cancel
Save