Added TERMKEY_FORMAT_LOWERSPACE for strpkey() also
This commit is contained in:
		@@ -34,7 +34,7 @@ Use spaces instead of hyphens to separate the modifier name(s) from the base key
 | 
			
		||||
Use lowercase for the modifier name.
 | 
			
		||||
.TP
 | 
			
		||||
.B TERMKEY_FORMAT_LOWERSPACE
 | 
			
		||||
Use lowercase for the key name instead of camelCase (for example "\f(CWpage down\fP" instead of "\f(CWPageDown\fP").
 | 
			
		||||
Use lowercase with spaces in for the key name instead of camelCase (for example "\f(CWpage down\fP" instead of "\f(CWPageDown\fP").
 | 
			
		||||
.TP
 | 
			
		||||
.B TERMKEY_FORMAT_MOUSE_POS
 | 
			
		||||
If the event is a mouse event, include the position rendered as "\f(CW@ (col,line)\fP".
 | 
			
		||||
 
 | 
			
		||||
@@ -29,6 +29,9 @@ Expect spaces instead of hyphens to separate the modifer name(s) from the base k
 | 
			
		||||
.TP
 | 
			
		||||
.B TERMKEY_FORMAT_LOWERMOD
 | 
			
		||||
Expect lowercase for the modifier name
 | 
			
		||||
.TP
 | 
			
		||||
.B TERMKEY_FORMAT_LOWERSPACE
 | 
			
		||||
Expect lowercase with spaces in for the key name instead of camelCase (for example "\f(CWpage down\fP" instead of "\f(CWPageDown\fP").
 | 
			
		||||
.PP
 | 
			
		||||
Before returning, this function canonicalises the \fIkey\fP structure according to the rules given for \fBtermkey_canonicalise\fP(3).
 | 
			
		||||
.PP
 | 
			
		||||
 
 | 
			
		||||
@@ -9,7 +9,7 @@ int main(int argc, char *argv[])
 | 
			
		||||
 | 
			
		||||
#define CLEAR_KEY do { key.type = -1; key.code.codepoint = -1; key.modifiers = -1; key.utf8[0] = 0; } while(0)
 | 
			
		||||
 | 
			
		||||
  plan_tests(58);
 | 
			
		||||
  plan_tests(62);
 | 
			
		||||
 | 
			
		||||
  tk = termkey_new_abstract("vt100", 0);
 | 
			
		||||
 | 
			
		||||
@@ -93,6 +93,14 @@ int main(int argc, char *argv[])
 | 
			
		||||
  is_str(key.utf8,        "c",                  "key.utf8 for unicode/c/ALT altismeta+long/space_lowermod");
 | 
			
		||||
  is_str(endp, "", "consumed entire input for unicode/c/ALT altismeta+long/space+lowermod");
 | 
			
		||||
 | 
			
		||||
  CLEAR_KEY;
 | 
			
		||||
  endp = termkey_strpkey(tk, "ctrl alt page up", &key, TERMKEY_FORMAT_LONGMOD|TERMKEY_FORMAT_SPACEMOD|TERMKEY_FORMAT_LOWERMOD|TERMKEY_FORMAT_LOWERSPACE);
 | 
			
		||||
  is_int(key.type,        TERMKEY_TYPE_KEYSYM, "key.type for sym/PageUp/CTRL+ALT long/space/lowermod+lowerspace");
 | 
			
		||||
  is_int(key.code.sym,    TERMKEY_SYM_PAGEUP,  "key.code.codepoint for sym/PageUp/CTRL+ALT long/space/lowermod+lowerspace");
 | 
			
		||||
  is_int(key.modifiers,   TERMKEY_KEYMOD_ALT | TERMKEY_KEYMOD_CTRL,
 | 
			
		||||
                                               "key.modifiers for sym/PageUp/CTRL+ALT long/space/lowermod+lowerspace");
 | 
			
		||||
  is_str(endp, "", "consumed entire input for sym/PageUp/CTRL+ALT long/space/lowermod+lowerspace");
 | 
			
		||||
 | 
			
		||||
  CLEAR_KEY;
 | 
			
		||||
  endp = termkey_strpkey(tk, "Up", &key, 0);
 | 
			
		||||
  is_int(key.type,        TERMKEY_TYPE_KEYSYM, "key.type for sym/Up/0");
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										100
									
								
								termkey.c
									
									
									
									
									
								
							
							
						
						
									
										100
									
								
								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;
 | 
			
		||||
  }
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user