aboutsummaryrefslogtreecommitdiff
path: root/termkey.c
diff options
context:
space:
mode:
Diffstat (limited to 'termkey.c')
-rw-r--r--termkey.c100
1 files changed, 73 insertions, 27 deletions
diff --git a/termkey.c b/termkey.c
index 0dd261f..7e39050 100644
--- a/termkey.c
+++ b/termkey.c
@@ -191,6 +191,63 @@ static const char *res2str(TermKeyResult res)
}
#endif
+/* Similar to snprintf(str, size, "%s", src) except it turns CamelCase into
+ * space separated values
+ */
+static int snprint_cameltospaces(char *str, size_t size, const char *src)
+{
+ int prev_lower = 0;
+ size_t l = 0;
+ while(*src && l < size) {
+ if(isupper(*src) && prev_lower) {
+ if(str)
+ str[l++] = ' ';
+ if(l >= size)
+ return -1;
+ }
+ prev_lower = islower(*src);
+ str[l++] = tolower(*src++);
+ }
+ if(l >= size)
+ return -1;
+ str[l] = 0;
+ return l;
+}
+
+/* Similar to strcmp(str, strcamel, n) except that:
+ * it compares CamelCase in strcamel with space separated values in str;
+ * it takes char**s and updates them
+ * n counts bytes of str, not strcamel
+ */
+static int strpncmp_camel(const char **strp, const char **strcamelp, size_t n)
+{
+ const char *str = *strp, *strcamel = *strcamelp;
+ int prev_lower = 0;
+
+ for( ; (*str || *strcamel) && n; n--) {
+ char b = tolower(*strcamel);
+ if(isupper(*strcamel) && prev_lower) {
+ if(*str != ' ')
+ break;
+ str++;
+ if(*str != b)
+ break;
+ }
+ else
+ if(*str != b)
+ break;
+
+ prev_lower = islower(*strcamel);
+
+ str++;
+ strcamel++;
+ }
+
+ *strp = str;
+ *strcamelp = strcamel;
+ return *str - *strcamel;
+}
+
static TermKey *termkey_alloc(void)
{
TermKey *tk = malloc(sizeof(TermKey));
@@ -1114,7 +1171,7 @@ const char *termkey_get_keyname(TermKey *tk, TermKeySym sym)
return "UNKNOWN";
}
-const char *termkey_lookup_keyname(TermKey *tk, const char *str, TermKeySym *sym)
+static const char *termkey_lookup_keyname_format(TermKey *tk, const char *str, TermKeySym *sym, TermKeyFormat format)
{
/* 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 */
@@ -1124,13 +1181,25 @@ const char *termkey_lookup_keyname(TermKey *tk, const char *str, TermKeySym *sym
if(!thiskey)
continue;
size_t len = strlen(thiskey);
- if(strncmp(str, thiskey, len) == 0)
- return (char *)str + len;
+ if(format & TERMKEY_FORMAT_LOWERSPACE) {
+ const char *thisstr = str;
+ if(strpncmp_camel(&thisstr, &thiskey, len) == 0)
+ return thisstr;
+ }
+ else {
+ if(strncmp(str, thiskey, len) == 0)
+ return (char *)str + len;
+ }
}
return NULL;
}
+const char *termkey_lookup_keyname(TermKey *tk, const char *str, TermKeySym *sym)
+{
+ return termkey_lookup_keyname_format(tk, str, sym, 0);
+}
+
TermKeySym termkey_keyname2sym(TermKey *tk, const char *keyname)
{
TermKeySym sym;
@@ -1171,29 +1240,6 @@ size_t termkey_snprint_key(TermKey *tk, char *buffer, size_t len, TermKeyKey *ke
return termkey_strfkey(tk, buffer, len, key, format);
}
-/* Similar to snprintf(str, size, "%s", src) except it turns CamelCase into
- * space separated values
- */
-static int snprint_cameltospaces(char *str, size_t size, const char *src)
-{
- int prev_lower = 0;
- size_t l = 0;
- while(*src && l < size) {
- if(isupper(*src) && prev_lower) {
- if(str)
- str[l++] = ' ';
- if(l >= size)
- return -1;
- }
- prev_lower = islower(*src);
- str[l++] = tolower(*src++);
- }
- if(l >= size)
- return -1;
- str[l] = 0;
- return l;
-}
-
static struct modnames {
const char *shift, *alt, *ctrl;
}
@@ -1381,7 +1427,7 @@ const char *termkey_strpkey(TermKey *tk, const char *str, TermKeyKey *key, TermK
ssize_t snbytes;
const char *endstr;
- if((endstr = termkey_lookup_keyname(tk, str, &key->code.sym))) {
+ if((endstr = termkey_lookup_keyname_format(tk, str, &key->code.sym, format))) {
key->type = TERMKEY_TYPE_KEYSYM;
str = endstr;
}