Ask your program to read the name-code mapping from the configuration file (s), for example /usr/share/yourprogram/keycodes and / or $HOME/.yourprogram/keycodes .
The document that anyone can restore this file from their /usr/include/linux/input.h - and restore the original file themselves, using, for example,
awk '$2 ~ /^KEY_/ { code[$2] = $3 } END { for (name in code) if (code[name] ~ /^KEY_/) code[name] = code[code[name]]; for (name in code) if (code[name] !~ /KEY_/) printf "%-24s %s\n", name, code[name] }' /usr/include/linux/input.h | sort
You may need to add KEY_CNT youself (this value is greater than KEY_MAX ), since the above script does not perform math, but only direct aliases.
To describe comparisons between names, I would use
struct keycode { struct keycode *next; unsigned int code; unsigned int hash; unsigned char namelen; char name[]; };
where the hash is a simple hash of, say, djb2,
unsigned int djb2(const char *const str, const size_t len) { unsigned int result = 5831U; size_t i; for (i = 0; i < len; i++) result = result * 33U ^ (unsigned int)str[i]; return result; }
Currently certain key codes, only KEY_CUT and KEY_F15 mapped to the same djb2 hash, 1857856141. (If you used 31U instead of 33U , the current set will not have collisions, but it will not be proof against future collisions. It is better to have one collision so that you can verify that it is being processed correctly.)
A function that reads the configuration file may simply return codes by adding new ones to the list with one link, perhaps
int read_keycodes(const char *const filename, struct keycode **list);
If you added to the list, you should later ignore the override with the same name. Thus, if you first read the system-wide configuration, then the user-specific, depending on the user, can override the system-wide.
After all the code key mappings have been read, you will create a hash table, something like
struct keytab { unsigned int size; struct keycode **slot; };
(When constructing a hash table, discard the key codes whose exact names are already in keytab. Thus, later definitions override the earlier ones.)
Thus, you only need to calculate the hash of the name you want to find, and then check the linked list in your keytab structure. Compare hashes first, then lengths; if both matches finally execute strcmp() . Thus, the search will be very fast and relatively easy to implement. When using current key codes, you will execute slow strcmp() twice for KEY_F15 and KEY_CUT ; for all the rest, one strcmp() enough.
Questions?