URI:
       tkeys.h - ltk - Socket-based GUI for X11 (WIP)
  HTML git clone git://lumidify.org/ltk.git (fast, but not encrypted)
  HTML git clone https://lumidify.org/git/ltk.git (encrypted, but very slow)
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tkeys.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