|
178 | 178 | #define _DO_N(W,C,N,V...) __DO_N(W,C,N,V)
|
179 | 179 | #define DO(W,C,V...) (_DO_N(W,C,NUM_ARGS(V),V))
|
180 | 180 |
|
181 |
| -// Macros to support option testing |
| 181 | +// Concatenate symbol names, without or with pre-expansion |
182 | 182 | #define _CAT(a,V...) a##V
|
183 | 183 | #define CAT(a,V...) _CAT(a,V)
|
184 | 184 |
|
| 185 | +// Recognize "true" values: blank, 1, 0x1, true |
185 | 186 | #define _ISENA_ ~,1
|
186 | 187 | #define _ISENA_1 ~,1
|
187 | 188 | #define _ISENA_0x1 ~,1
|
188 | 189 | #define _ISENA_true ~,1
|
189 | 190 | #define _ISENA(V...) IS_PROBE(V)
|
190 | 191 |
|
| 192 | +// Macros to evaluate simple option switches |
191 | 193 | #define _ENA_1(O) _ISENA(CAT(_IS,CAT(ENA_, O)))
|
192 | 194 | #define _DIS_1(O) NOT(_ENA_1(O))
|
193 | 195 | #define ENABLED(V...) DO(ENA,&&,V)
|
|
198 | 200 | #define COUNT_ENABLED(V...) DO(ENA,+,V)
|
199 | 201 | #define MANY(V...) (COUNT_ENABLED(V) > 1)
|
200 | 202 |
|
| 203 | +// Ternary pre-compiler macros conceal non-emitted content from the compiler |
201 | 204 | #define TERN(O,A,B) _TERN(_ENA_1(O),B,A) // OPTION ? 'A' : 'B'
|
202 | 205 | #define TERN0(O,A) _TERN(_ENA_1(O),0,A) // OPTION ? 'A' : '0'
|
203 | 206 | #define TERN1(O,A) _TERN(_ENA_1(O),1,A) // OPTION ? 'A' : '1'
|
204 | 207 | #define TERN_(O,A) _TERN(_ENA_1(O),,A) // OPTION ? 'A' : '<nul>'
|
205 | 208 | #define _TERN(E,V...) __TERN(_CAT(T_,E),V) // Prepend 'T_' to get 'T_0' or 'T_1'
|
206 | 209 | #define __TERN(T,V...) ___TERN(_CAT(_NO,T),V) // Prepend '_NO' to get '_NOT_0' or '_NOT_1'
|
207 | 210 | #define ___TERN(P,V...) THIRD(P,V) // If first argument has a comma, A. Else B.
|
| 211 | +#define IF_DISABLED(O,A) TERN(O,,A) |
208 | 212 |
|
| 213 | +// Macros to conditionally emit array items and function arguments |
209 | 214 | #define _OPTITEM(A...) A,
|
210 | 215 | #define OPTITEM(O,A...) TERN_(O,DEFER4(_OPTITEM)(A))
|
211 | 216 | #define _OPTARG(A...) , A
|
|
220 | 225 | #define SUM_TERN(O,B,A) ((B) PLUS_TERN0(O,A)) // ((B) (OPTION ? '+ (A)' : '<nul>'))
|
221 | 226 | #define DIFF_TERN(O,B,A) ((B) MINUS_TERN0(O,A)) // ((B) (OPTION ? '- (A)' : '<nul>'))
|
222 | 227 |
|
223 |
| -#define IF_DISABLED(O,A) TERN(O,,A) |
224 |
| - |
225 | 228 | // Macros to support pins/buttons exist testing
|
226 | 229 | #define PIN_EXISTS(PN) (defined(PN##_PIN) && PN##_PIN >= 0)
|
227 | 230 | #define _PINEX_1 PIN_EXISTS
|
|
233 | 236 | #define BUTTONS_EXIST(V...) DO(BTNEX,&&,V)
|
234 | 237 | #define ANY_BUTTON(V...) DO(BTNEX,||,V)
|
235 | 238 |
|
| 239 | +// Value helper macros |
236 | 240 | #define WITHIN(N,L,H) ((N) >= (L) && (N) <= (H))
|
237 | 241 | #define ISEOL(C) ((C) == '\n' || (C) == '\r')
|
238 | 242 | #define NUMERIC(a) WITHIN(a, '0', '9')
|
239 | 243 | #define DECIMAL(a) (NUMERIC(a) || a == '.')
|
240 | 244 | #define HEXCHR(a) (NUMERIC(a) ? (a) - '0' : WITHIN(a, 'a', 'f') ? ((a) - 'a' + 10) : WITHIN(a, 'A', 'F') ? ((a) - 'A' + 10) : -1)
|
241 | 245 | #define NUMERIC_SIGNED(a) (NUMERIC(a) || (a) == '-' || (a) == '+')
|
242 | 246 | #define DECIMAL_SIGNED(a) (DECIMAL(a) || (a) == '-' || (a) == '+')
|
| 247 | + |
| 248 | +// Array shorthand |
243 | 249 | #define COUNT(a) (sizeof(a)/sizeof(*a))
|
244 | 250 | #define ZERO(a) memset((void*)a,0,sizeof(a))
|
245 | 251 | #define COPY(a,b) do{ \
|
246 | 252 | static_assert(sizeof(a[0]) == sizeof(b[0]), "COPY: '" STRINGIFY(a) "' and '" STRINGIFY(b) "' types (sizes) don't match!"); \
|
247 | 253 | memcpy(&a[0],&b[0],_MIN(sizeof(a),sizeof(b))); \
|
248 | 254 | }while(0)
|
249 | 255 |
|
| 256 | +// Expansion of some code |
250 | 257 | #define CODE_16( A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,...) A; B; C; D; E; F; G; H; I; J; K; L; M; N; O; P
|
251 | 258 | #define CODE_15( A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,...) A; B; C; D; E; F; G; H; I; J; K; L; M; N; O
|
252 | 259 | #define CODE_14( A,B,C,D,E,F,G,H,I,J,K,L,M,N,...) A; B; C; D; E; F; G; H; I; J; K; L; M; N
|
|
267 | 274 | #define _CODE_N(N,V...) CODE_##N(V)
|
268 | 275 | #define CODE_N(N,V...) _CODE_N(N,V)
|
269 | 276 |
|
| 277 | +// Expansion of some non-delimited content |
270 | 278 | #define GANG_16(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,...) A B C D E F G H I J K L M N O P
|
271 | 279 | #define GANG_15(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,...) A B C D E F G H I J K L M N O
|
272 | 280 | #define GANG_14(A,B,C,D,E,F,G,H,I,J,K,L,M,N,...) A B C D E F G H I J K L M N
|
|
288 | 296 | #define GANG_N(N,V...) _GANG_N(N,V)
|
289 | 297 | #define GANG_N_1(N,K) _GANG_N(N,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K)
|
290 | 298 |
|
291 |
| -// Macros for initializing arrays |
| 299 | +// Expansion of some list items |
292 | 300 | #define LIST_26(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,...) A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z
|
293 | 301 | #define LIST_25(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,...) A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y
|
294 | 302 | #define LIST_24(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,...) A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X
|
|
0 commit comments