keys.h (3738B)
1 #ifndef _KEYS_H_ 2 #define _KEYS_H_ 3 4 #include "util.h" 5 6 /* FIXME: replace with proper string type */ 7 struct ltk_search_cmp_helper { 8 const char *text; 9 size_t len; 10 }; 11 12 /* FIXME: documentation */ 13 #define GEN_CB_MAP_HELPERS(name, typename, cmp_entry) \ 14 \ 15 static int name##_sorted = 0; \ 16 \ 17 /* \ 18 * IMPORTANT: The text passed to *_get_entry may not be nul-terminated, \ 19 * so ltk_search_cmp_helper has to be used for the bsearch comparison \ 20 * helper. \ 21 */ \ 22 \ 23 static int \ 24 name##_search_helper(const void *keyv, const void *entryv) { \ 25 struct ltk_search_cmp_helper *key = (struct ltk_search_cmp_helper *)keyv; \ 26 typename *entry = (typename *)entryv; \ 27 int ret = strncmp(key->text, entry->cmp_entry, key->len); \ 28 if (ret == 0) { \ 29 if (entry->cmp_entry[key->len] == '\0') \ 30 return 0; \ 31 else \ 32 return -1; \ 33 } \ 34 return ret; \ 35 } \ 36 \ 37 static int \ 38 name##_sort_helper(const void *entry1v, const void *entry2v) { \ 39 typename *entry1 = (typename *)entry1v; \ 40 typename *entry2 = (typename *)entry2v; \ 41 return strcmp(entry1->cmp_entry, entry2->cmp_entry); \ 42 } \ 43 \ 44 static typename * \ 45 name##_get_entry(const char *text, size_t len) { \ 46 /* just in case */ \ 47 if (!name##_sorted) { \ 48 qsort( \ 49 name, LENGTH(name), \ 50 sizeof(name[0]), &name##_sort_helper); \ 51 name##_sorted = 1; \ 52 } \ 53 struct ltk_search_cmp_helper tmp = {.len = len, .text = text}; \ 54 return bsearch( \ 55 &tmp, name, LENGTH(name), \ 56 sizeof(name[0]), &name##_search_helper \ 57 ); \ 58 } 59 60 #endif