diff --git a/t/10keyname.c b/t/10keyname.c index 0e69122..54bc208 100644 --- a/t/10keyname.c +++ b/t/10keyname.c @@ -5,8 +5,9 @@ int main(int argc, char *argv[]) { TermKey *tk; TermKeySym sym; + char *end; - plan_tests(3); + plan_tests(10); tk = termkey_new(0, TERMKEY_FLAG_NOTERMIOS); @@ -16,6 +17,19 @@ int main(int argc, char *argv[]) sym = termkey_keyname2sym(tk, "SomeUnknownKey"); is_int(sym, TERMKEY_SYM_UNKNOWN, "keyname2sym SomeUnknownKey"); + end = termkey_lookup_keyname(tk, "Up", &sym); + ok(!!end, "termkey_get_keyname Up returns non-NULL"); + is_str(end, "", "termkey_get_keyname Up return points at endofstring"); + is_int(sym, TERMKEY_SYM_UP, "termkey_get_keyname Up yields Up symbol"); + + end = termkey_lookup_keyname(tk, "DownMore", &sym); + ok(!!end, "termkey_get_keyname DownMore returns non-NULL"); + is_str(end, "More", "termkey_get_keyname DownMore return points at More"); + is_int(sym, TERMKEY_SYM_DOWN, "termkey_get_keyname DownMore yields Down symbol"); + + end = termkey_lookup_keyname(tk, "SomeUnknownKey", &sym); + ok(!end, "termkey_get_keyname SomeUnknownKey returns NULL"); + is_str(termkey_get_keyname(tk, TERMKEY_SYM_SPACE), "Space", "get_keyname SPACE"); termkey_destroy(tk); diff --git a/termkey.c b/termkey.c index 302d81f..0503326 100644 --- a/termkey.c +++ b/termkey.c @@ -914,18 +914,30 @@ const char *termkey_get_keyname(TermKey *tk, TermKeySym sym) return "UNKNOWN"; } -TermKeySym termkey_keyname2sym(TermKey *tk, const char *keyname) +char *termkey_lookup_keyname(TermKey *tk, const char *str, TermKeySym *sym) { /* We store an array, so we can't do better than a linear search. Doesn't * matter because user won't be calling this too often */ + for(*sym = 0; *sym < tk->nkeynames; (*sym)++) { + const char *thiskey = tk->keynames[*sym]; + if(!thiskey) + continue; + size_t len = strlen(thiskey); + if(strncmp(str, thiskey, len) == 0) + return (char *)str + len; + } + + return NULL; +} + +TermKeySym termkey_keyname2sym(TermKey *tk, const char *keyname) +{ TermKeySym sym; - - for(sym = 0; sym < tk->nkeynames; sym++) - if(tk->keynames[sym] && strcmp(keyname, tk->keynames[sym]) == 0) - return sym; - - return TERMKEY_SYM_UNKNOWN; + char *endp = termkey_lookup_keyname(tk, keyname, &sym); + if(!endp || endp[0]) + return TERMKEY_SYM_UNKNOWN; + return sym; } static TermKeySym register_c0(TermKey *tk, TermKeySym sym, unsigned char ctrl, const char *name) diff --git a/termkey.h.in b/termkey.h.in index 3c0665f..f296c58 100644 --- a/termkey.h.in +++ b/termkey.h.in @@ -171,11 +171,12 @@ TermKeyResult termkey_advisereadable(TermKey *tk); TermKeySym termkey_register_keyname(TermKey *tk, TermKeySym sym, const char *name); const char *termkey_get_keyname(TermKey *tk, TermKeySym sym); - -TermKeyResult termkey_interpret_mouse(TermKey *tk, TermKeyKey *key, TermKeyMouseEvent *event, int *button, int *line, int *col); +char *termkey_lookup_keyname(TermKey *tk, const char *str, TermKeySym *sym); TermKeySym termkey_keyname2sym(TermKey *tk, const char *keyname); +TermKeyResult termkey_interpret_mouse(TermKey *tk, TermKeyKey *key, TermKeyMouseEvent *event, int *button, int *line, int *col); + typedef enum { TERMKEY_FORMAT_LONGMOD = 1 << 0, // Shift-... instead of S-... TERMKEY_FORMAT_CARETCTRL = 1 << 1, // ^X instead of C-X diff --git a/termkey_get_keyname.3 b/termkey_get_keyname.3 index 4adef73..a55d218 100644 --- a/termkey_get_keyname.3 +++ b/termkey_get_keyname.3 @@ -17,5 +17,6 @@ Link with \fI-ltermkey\fP. .BR termkey_new (3), .BR termkey_getkey (3), .BR termkey_waitkey (3), +.BR termkey_lookup_keyname (3), .BR termkey_keyname2sym (3), .BR termkey_strfkey (3) diff --git a/termkey_keyname2sym.3 b/termkey_keyname2sym.3 index 89c4c80..c9224bc 100644 --- a/termkey_keyname2sym.3 +++ b/termkey_keyname2sym.3 @@ -10,13 +10,13 @@ termkey_keyname2sym \- look up a symbolic key value for a string name .sp Link with \fI-ltermkey\fP. .SH DESCRIPTION -\fBtermkey_keyname2sym\fP looks up the symbolic key value represented by the given string name. This is a case-sensitive comparison. If the given name is not found, \fBTERMKEY_SYM_UNKNOWN\fP is returned instead. This function is the inverse of \fBtermkey_get_keyname\fP(3). +\fBtermkey_keyname2sym\fP looks up the symbolic key value represented by the given string name. This is a case-sensitive comparison. If the given name is not found, \fBTERMKEY_SYM_UNKNOWN\fP is returned instead. This function is the inverse of \fBtermkey_get_keyname\fP(3), and is a more specific form of \fBtermkey_lookup_keyname\fP(3) which only recognises names as complete strings. .PP Because the key names are stored in an array indexed by the symbol number, this function has to perform a linear search of the names. Use of this function should be restricted to converting key names into symbolic values during a program's initialisation, so that efficient comparisons can be done while it is running. .SH "RETURN VALUE" -\fBtermkey_get_key\fP() returns a pointer to a string. +\fBtermkey_keyname2sym\fP() returns a symbolic key constant, or \fBTERMKEY_SYM_UNKNOWN\fP. .SH "SEE ALSO" .BR termkey_new (3), .BR termkey_get_keyname (3), -.BR termkey_strfkey (3), +.BR termkey_lookup_keyname (3), .BR termkey_strpkey (3) diff --git a/termkey_lookup_keyname.3 b/termkey_lookup_keyname.3 new file mode 100644 index 0000000..4d763ff --- /dev/null +++ b/termkey_lookup_keyname.3 @@ -0,0 +1,23 @@ +.TH TERMKEY_LOOKUP_KEYNAME 3 +.SH NAME +termkey_lookup_keyname \- look up a symbolic key value for a string name +.SH SYNOPSIS +.nf +.B #include +.sp +.BI "char *termkey_lookup_keyname(TermKey *" tk ", const char *" keyname ", +.BI " TermKeySym *" sym "); +.fi +.sp +Link with \fI-ltermkey\fP. +.SH DESCRIPTION +\fBtermkey_lookup_keyname\fP looks up the symbolic key value represented by the given string name. This is a case-sensitive comparison. The symbolic value is written to the variable addressed by \fIsym\fP. This function is a more general form of \fBtermkey_keyname2sym\fP(3) because it can recognise a symbolic key name within a longer string, returning a pointer to the remainder of the input after the key name. +.PP +Because the key names are stored in an array indexed by the symbol number, this function has to perform a linear search of the names. Use of this function should be restricted to converting key names into symbolic values during a program's initialisation, so that efficient comparisons can be done while it is running. +.SH "RETURN VALUE" +\fBtermkey_lookup_keyname\fP() returns a pointer to the first character after a recognised name, or \fBNULL\fP if the string does not begin with the name of a recognised symbolic key. +.SH "SEE ALSO" +.BR termkey_new (3), +.BR termkey_get_keyname (3), +.BR termkey_keyname2sym (3), +.BR termkey_strpkey (3)