summaryrefslogtreecommitdiffstats
path: root/util.h
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2020-09-18 16:39:40 -0400
committerTavian Barnes <tavianator@tavianator.com>2020-10-13 13:42:11 -0400
commitc565e665781f39cf31c64d85c76224c2fffa9f7d (patch)
treeed8d167bd38d2d23f39875ffe25793de3416948a /util.h
parentfd0b968b5afe28d9adcfbc9aef17bc83d6eaf84b (diff)
downloadbfs-c565e665781f39cf31c64d85c76224c2fffa9f7d.tar.xz
util: New BFS_FLEX_SIZEOF() macro for more precise flexible array allocations
See http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_282.htm for all the fun behind this.
Diffstat (limited to 'util.h')
-rw-r--r--util.h23
1 files changed, 23 insertions, 0 deletions
diff --git a/util.h b/util.h
index a9bdecf..15e983f 100644
--- a/util.h
+++ b/util.h
@@ -26,6 +26,7 @@
#include <fnmatch.h>
#include <regex.h>
#include <stdbool.h>
+#include <stddef.h>
#include <sys/types.h>
// Some portability concerns
@@ -91,6 +92,28 @@
# define BFS_FORMATTER(fmt, args)
#endif
+// Lower bound on BFS_FLEX_SIZEOF()
+#define BFS_FLEX_LB(type, member, length) (offsetof(type, member) + sizeof(((type *)NULL)->member[0]) * (length))
+
+// Maximum macro for BFS_FLEX_SIZE()
+#define BFS_FLEX_MAX(a, b) ((a) > (b) ? (a) : (b))
+
+/**
+ * Computes the size of a struct containing a flexible array member of the given
+ * length.
+ *
+ * @param type
+ * The type of the struct containing the flexible array.
+ * @param member
+ * The name of the flexible array member.
+ * @param length
+ * The length of the flexible array.
+ */
+#define BFS_FLEX_SIZEOF(type, member, length) \
+ (sizeof(type) <= BFS_FLEX_LB(type, member, 0) \
+ ? BFS_FLEX_LB(type, member, length) \
+ : BFS_FLEX_MAX(sizeof(type), BFS_FLEX_LB(type, member, length)))
+
/**
* readdir() wrapper that makes error handling cleaner.
*/