]> git.draconx.ca Git - dxcommon.git/blob - src/xtra.h
DX_C_ALIGNAS: Work around bash-5 parsing bug.
[dxcommon.git] / src / xtra.h
1 /*
2  * Copyright © 2023 Nick Bowler
3  *
4  * License WTFPL2: Do What The Fuck You Want To Public License, version 2.
5  * This is free software: you are free to do what the fuck you want to.
6  * There is NO WARRANTY, to the extent permitted by law.
7  */
8
9 #ifndef DX_XTRA_H_
10 #define DX_XTRA_H_
11
12 #define XTRA_PASTE(a, b) a ## b
13 #define XTRA_PASTE2(a, b) XTRA_PASTE(a, b)
14
15 #define XTRA_ARRAYSIZE(a) (sizeof (a) / sizeof (a)[0])
16
17 /*
18  * This macro may be used to simplify construction of a 'struct option'
19  * array from the packed format produced by gen-options.awk.
20  *
21  * Expanding this in a function will
22  *
23  *   (1) declare a constant array with static storage duration that
24  *       contains the packed representation, and
25  *   (2) declare an array of struct option of suitable length, with
26  *       the given name, and
27  *   (3) emit code to fill the struct option array from the packed
28  *       representation.
29  *
30  * The uint_leastXX_t typedefs must be in scope in order to use this macro.
31  */
32 #define XTRA_PACKED_LOPTS(name) \
33         static const XTRA_PASTE2(XTRA_PASTE2(uint_least, LOPT_PACK_BITS2), _t) \
34                 name##_packed[] = { LOPTS_PACKED_INITIALIZER }; \
35         struct option name[XTRA_ARRAYSIZE(name##_packed) + 1] = {0}; \
36         do { \
37                 unsigned i; \
38                 for (i = 0; i < XTRA_ARRAYSIZE(name##_packed); i++) \
39                         LOPT_UNPACK(name[i], name##_packed[i]); \
40         } while (0)
41
42 #endif