3 // Copyright 2021 Bruce Hill
4 // Released under the MIT license with the Commons Clause
6 // This file contains some definitions of some utility macros and functions.
15 #define streq(a, b) (strcmp(a, b) == 0)
18 #define MAX(a, b) ((a) < (b) ? (b) : (a))
19 #define MIN(a, b) ((a) > (b) ? (b) : (a))
21 // Platform-dependent time strucutre accessors:
23 #define get_mtime(s) (s).st_mtimespec
24 #define get_atime(s) (s).st_atimespec
25 #define get_ctime(s) (s).st_ctimespec
27 #define get_mtime(s) (s).st_mtim
28 #define get_atime(s) (s).st_atim
29 #define get_ctime(s) (s).st_ctim
33 #define IS_SELECTED(e) (((e)->selected.atme) != NULL)
34 #define IS_VIEWED(e) ((e)->index >= 0)
35 #define IS_LOADED(e) ((e)->hash.atme != NULL)
37 #define E_ISDIR(e) (S_ISDIR(S_ISLNK((e)->info.st_mode) ? (e)->linkedmode : (e)->info.st_mode))
40 #define LL_PREPEND(head, node, name) \
42 ((node)->name).atme = &(head); \
43 ((node)->name).next = head; \
44 if (head) ((head)->name).atme = &(((node)->name).next); \
48 #define LL_REMOVE(node, name) \
50 if (((node)->name).next) ((__typeof__(node))(node)->name.next)->name.atme = ((node)->name).atme; \
51 if (((node)->name).atme) *(((node)->name).atme) = ((node)->name).next; \
52 ((node)->name).atme = NULL; \
53 ((node)->name).next = NULL; \
56 #define LEN(a) (sizeof(a) / sizeof(a[0]))
57 #define FOREACH(type, var, array) for (type var = array; (var) < &(array)[LEN(array)]; var++)
61 #define __LOCATION__ __FILE__ ":" S2(__LINE__)
63 // Error checking helper macros:
64 #define nonnegative(exp, ...) check_nonnegative(exp, __LOCATION__ ": `" #exp "` " __VA_ARGS__)
65 #define nonnull(exp, ...) check_nonnull(exp, __LOCATION__ ": `" #exp "` " __VA_ARGS__)
66 // Error-checking memory allocation helper macros:
67 #define new(t) check_nonnull(calloc(1, sizeof(t)), __LOCATION__ ": new(" #t ") failed")
68 #define new_bytes(n) check_nonnull(calloc(1, n), __LOCATION__ ": new_bytes(" #n ") failed")
69 #define grow(obj, new_count) \
70 check_nonnull(reallocarray(obj, (new_count), sizeof(obj[0])), \
71 __LOCATION__ ": grow(" #obj ", " #new_count ") failed")
72 #define check_strdup(s) check_nonnull(strdup(s), __LOCATION__ ": check_strdup(" #s ") failed")
74 int check_nonnegative(int negative_err, const char *err_msg, ...);
75 __attribute__((returns_nonnull)) void *check_nonnull(void *p, const char *err_msg, ...);
76 __attribute__((nonnull)) void delete(void *p);
79 // vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0