sort_search.h (4535B)
1 /* 2 * Copyright (c) 2024 lumidify <nobody@lumidify.org> 3 * 4 * Permission to use, copy, modify, and/or distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17 #ifndef LTK_SORT_SEARCH_H 18 #define LTK_SORT_SEARCH_H 19 20 #include <stdlib.h> 21 #include <stddef.h> 22 #include <string.h> 23 24 struct ltk_search_cmp_helper { 25 const char *text; 26 size_t len; 27 }; 28 29 /* FIXME: documentation */ 30 #define GEN_SORT_SEARCH_HELPERS(name, typename, cmp_entry) \ 31 \ 32 /* \ 33 * IMPORTANT: The text passed to *_get_entry may not be nul-terminated, \ 34 * so ltk_search_cmp_helper has to be used for the bsearch comparison \ 35 * helper. \ 36 */ \ 37 \ 38 static int \ 39 name##_search_helper(const void *keyv, const void *entryv) { \ 40 struct ltk_search_cmp_helper *key = (struct ltk_search_cmp_helper *)keyv; \ 41 typename *entry = (typename *)entryv; \ 42 int ret = strncmp(key->text, entry->cmp_entry, key->len); \ 43 if (ret == 0) { \ 44 if (entry->cmp_entry[key->len] == '\0') \ 45 return 0; \ 46 else \ 47 return -1; \ 48 } \ 49 return ret; \ 50 } \ 51 \ 52 static int \ 53 name##_sort_helper(const void *entry1v, const void *entry2v) { \ 54 typename *entry1 = (typename *)entry1v; \ 55 typename *entry2 = (typename *)entry2v; \ 56 return strcmp(entry1->cmp_entry, entry2->cmp_entry); \ 57 } \ 58 \ 59 static void \ 60 name##_sort(typename *arr, size_t arrlen) { \ 61 qsort( \ 62 arr, arrlen, \ 63 sizeof(typename), &name##_sort_helper \ 64 ); \ 65 } \ 66 \ 67 static typename * \ 68 name##_get_entry(typename *arr, size_t arrlen, const char *text, size_t len) { \ 69 struct ltk_search_cmp_helper tmp = {.text = text, .len = len}; \ 70 return bsearch( \ 71 &tmp, arr, arrlen, \ 72 sizeof(typename), &name##_search_helper \ 73 ); \ 74 } 75 76 #endif /* LTK_SORT_SEARCH_H */