keysym: open-code bsearch
We want to optimize things here which requires messing with the binary search some. Signed-off-by: Ran Benita <ran@unusedvar.com>master
parent
c14910a0de
commit
a717549eb2
60
src/keysym.c
60
src/keysym.c
|
@ -61,42 +61,25 @@ get_name(const struct name_keysym *entry)
|
||||||
return keysym_names + entry->offset;
|
return keysym_names + entry->offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
compare_by_keysym(const void *a, const void *b)
|
|
||||||
{
|
|
||||||
const xkb_keysym_t *key = a;
|
|
||||||
const struct name_keysym *entry = b;
|
|
||||||
if (*key < entry->keysym)
|
|
||||||
return -1;
|
|
||||||
if (*key > entry->keysym)
|
|
||||||
return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
compare_by_name(const void *a, const void *b)
|
|
||||||
{
|
|
||||||
const char *key = a;
|
|
||||||
const struct name_keysym *entry = b;
|
|
||||||
return istrcmp(key, get_name(entry));
|
|
||||||
}
|
|
||||||
|
|
||||||
XKB_EXPORT int
|
XKB_EXPORT int
|
||||||
xkb_keysym_get_name(xkb_keysym_t ks, char *buffer, size_t size)
|
xkb_keysym_get_name(xkb_keysym_t ks, char *buffer, size_t size)
|
||||||
{
|
{
|
||||||
const struct name_keysym *entry;
|
|
||||||
|
|
||||||
if ((ks & ((unsigned long) ~0x1fffffff)) != 0) {
|
if ((ks & ((unsigned long) ~0x1fffffff)) != 0) {
|
||||||
snprintf(buffer, size, "Invalid");
|
snprintf(buffer, size, "Invalid");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
entry = bsearch(&ks, keysym_to_name,
|
size_t lo = 0, hi = ARRAY_SIZE(keysym_to_name) - 1;
|
||||||
ARRAY_SIZE(keysym_to_name),
|
while (hi >= lo) {
|
||||||
sizeof(*keysym_to_name),
|
size_t mid = (lo + hi) / 2;
|
||||||
compare_by_keysym);
|
if (ks > keysym_to_name[mid].keysym) {
|
||||||
if (entry)
|
lo = mid + 1;
|
||||||
return snprintf(buffer, size, "%s", get_name(entry));
|
} else if (ks < keysym_to_name[mid].keysym) {
|
||||||
|
hi = mid - 1;
|
||||||
|
} else {
|
||||||
|
return snprintf(buffer, size, "%s", get_name(&keysym_to_name[mid]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Unnamed Unicode codepoint. */
|
/* Unnamed Unicode codepoint. */
|
||||||
if (ks >= 0x01000100 && ks <= 0x0110ffff) {
|
if (ks >= 0x01000100 && ks <= 0x0110ffff) {
|
||||||
|
@ -111,7 +94,7 @@ xkb_keysym_get_name(xkb_keysym_t ks, char *buffer, size_t size)
|
||||||
/*
|
/*
|
||||||
* Find the correct keysym if one case-insensitive match is given.
|
* Find the correct keysym if one case-insensitive match is given.
|
||||||
*
|
*
|
||||||
* The name_to_keysym table is sorted by istrcmp(). So bsearch() may return
|
* The name_to_keysym table is sorted by istrcmp(). So the binary search may return
|
||||||
* _any_ of all possible case-insensitive duplicates. This function searches the
|
* _any_ of all possible case-insensitive duplicates. This function searches the
|
||||||
* returned entry @entry, all previous and all next entries that match by
|
* returned entry @entry, all previous and all next entries that match by
|
||||||
* case-insensitive comparison and returns the exact match to @name. If @icase
|
* case-insensitive comparison and returns the exact match to @name. If @icase
|
||||||
|
@ -164,7 +147,7 @@ find_sym(const struct name_keysym *entry, const char *name, bool icase)
|
||||||
XKB_EXPORT xkb_keysym_t
|
XKB_EXPORT xkb_keysym_t
|
||||||
xkb_keysym_from_name(const char *s, enum xkb_keysym_flags flags)
|
xkb_keysym_from_name(const char *s, enum xkb_keysym_flags flags)
|
||||||
{
|
{
|
||||||
const struct name_keysym *entry;
|
const struct name_keysym *entry = NULL;
|
||||||
char *tmp;
|
char *tmp;
|
||||||
xkb_keysym_t val;
|
xkb_keysym_t val;
|
||||||
bool icase = (flags & XKB_KEYSYM_CASE_INSENSITIVE);
|
bool icase = (flags & XKB_KEYSYM_CASE_INSENSITIVE);
|
||||||
|
@ -172,10 +155,19 @@ xkb_keysym_from_name(const char *s, enum xkb_keysym_flags flags)
|
||||||
if (flags & ~XKB_KEYSYM_CASE_INSENSITIVE)
|
if (flags & ~XKB_KEYSYM_CASE_INSENSITIVE)
|
||||||
return XKB_KEY_NoSymbol;
|
return XKB_KEY_NoSymbol;
|
||||||
|
|
||||||
entry = bsearch(s, name_to_keysym,
|
size_t lo = 0, hi = ARRAY_SIZE(name_to_keysym) - 1;
|
||||||
ARRAY_SIZE(name_to_keysym),
|
while (hi >= lo) {
|
||||||
sizeof(*name_to_keysym),
|
size_t mid = (lo + hi) / 2;
|
||||||
compare_by_name);
|
int cmp = istrcmp(s, get_name(&name_to_keysym[mid]));
|
||||||
|
if (cmp > 0) {
|
||||||
|
lo = mid + 1;
|
||||||
|
} else if (cmp < 0) {
|
||||||
|
hi = mid - 1;
|
||||||
|
} else {
|
||||||
|
entry = &name_to_keysym[mid];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
entry = find_sym(entry, s, icase);
|
entry = find_sym(entry, s, icase);
|
||||||
if (entry)
|
if (entry)
|
||||||
return entry->keysym;
|
return entry->keysym;
|
||||||
|
|
Loading…
Reference in New Issue