eĿlipsis
a language independent preprocessor
 
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Loading...
Searching...
No Matches
ellipsis-special.h
Go to the documentation of this file.
1
8#ifndef ELLIPSIS_SPECIAL_H
9#define ELLIPSIS_SPECIAL_H 1
10
11#include <stddef.h>
12#include "ellipsis-category.h"
14#include "utils/ellipsis-str8.h"
15
16extern thread_local bool volatile ellipsis‿contracts‿ignore‿dynamic;
17extern thread_local bool volatile ellipsis‿contracts‿proceed‿dynamic;
18extern thread_local bool volatile ellipsis‿contracts‿verbose‿dynamic;
19
21
22#include <stdio.h>
23#include <stdlib.h>
24#include <stdint.h>
25
26#define STRINGIFY(...) STRINGIFY_(__VA_ARGS__)
27#define STRINGIFY_(...) #__VA_ARGS__
28
29#define ELLIPSIS_CONTRACT_VIOLATION(COUNT, VERB, CTYPE, CSTR, ...) \
30({\
31 static char const contract_format_ ## COUNT[] = \
32 __FILE__ ":" STRINGIFY(__LINE__) ": violation of " CTYPE " `" CSTR "`" __VA_OPT__(", ") __VA_ARGS__ "\n";\
33 (VERB \
34 ? fputs(contract_format_ ## COUNT, stderr) \
35 : 0);\
36 })
37
38#define ELLIPSIS_CONTRACT_IMPL(COUNT, COND, ACTION, VERB, CSTR, CTYPE, ...) \
39(((false) || (COND)) \
40 ? (void)0 \
41 : (ELLIPSIS_CONTRACT_VIOLATION(COUNT, VERB, CTYPE, CSTR __VA_OPT__(,) __VA_ARGS__) \
42 , ((false) \
43 ? (void)0 \
44 : ACTION())))
45
46#define ELLIPSIS_TO_VOIDS(...) ((void*)((uintptr_t)((__VA_ARGS__)-(__VA_ARGS__))))
47
48#define ELLIPSIS_TEST_ICE(...) (false ? ELLIPSIS_TO_VOIDS(__VA_ARGS__) : (ellipsis‿contracts‿is_ice*)nullptr)
49
50#define ELLIPSIS_CONTRACT_ICE_OR_TRUE(...) \
51 _Generic( \
52 ELLIPSIS_TEST_ICE(__VA_ARGS__), \
53 ellipsis‿contracts‿is_ice*: (__VA_ARGS__), \
54 default: true)
55
56#define ELLIPSIS_CONTRACT_CHECK_STATIC(CTYPE, COND, CSTR, ...) \
57 ({\
58 static_assert(ELLIPSIS_CONTRACT_ICE_OR_TRUE(COND), \
59 "compile time violation of " CTYPE " " CSTR \
60 __VA_OPT__(", ") __VA_ARGS__ );\
61 })
62
63#define ELLIPSIS_CONTRACT(COUNT, COND, ACTION, VERB, CSTR, CTYPE, ...) \
64 \
65 do { \
66 _Generic( \
67 ELLIPSIS_TEST_ICE(COND), \
68 ellipsis‿contracts‿is_ice*: ELLIPSIS_CONTRACT_CHECK_STATIC(CTYPE, COND, CSTR __VA_OPT__(,) __VA_ARGS__), \
69 default: ELLIPSIS_CONTRACT_IMPL(COUNT, COND, ACTION, VERB, CSTR, CTYPE __VA_OPT__(,) __VA_ARGS__));\
70 } while(false)
71
73
89#undef ELLIPSIS_STR8_LITERAL
90#define ELLIPSIS_STR8_LITERAL ELLIPSIS_STR8_LITERAL_GLOBAL
91
92#undef ELLIPSIS_STR32_LITERAL
93#define ELLIPSIS_STR32_LITERAL ELLIPSIS_STR32_LITERAL_GLOBAL
94
101
102typedef ellipsis‿special const* ellipsis‿special‿find(size_t len, char const buf[len]);
104
105inline
107 size_t len[static 1], char const*restrict buf[static 1],
108 bool terminated[static 1], bool without, bool unescaped) {
109 typeof(ellipsis‿str32*) DEFER_LOC_ID_0_1;
110 if (__func__[0] == 'm' && __func__[1] == 'a' && __func__[2] == 'i' && __func__[3] == 'n' && !__func__[4]) {
111 DEFER_LOC_ID_0_1 = (typeof(ellipsis‿str32*)) {};
112 }
113 [[__maybe_unused__]] register unsigned DEFER_LOC_ID_0_2 = 1U;
114 [[__maybe_unused__]] register bool defer_return_flag = false;
115 if (false) {
116 DEFER_ID_1_1:
117 goto DEFER_END_ID_1_2;
118 } else {
119 (void)0 ;
120 do {ELLIPSIS_CONTRACT(1, sp, abort, true, "sp", "assertion", "pointer to special needed in scan");} while (false);
121 do {ELLIPSIS_CONTRACT(2, len, abort, true, "len", "assertion", "pointer to length needed in scan");} while (false);
122 do {ELLIPSIS_CONTRACT(3, buf, abort, true, "buf", "assertion", "pointer to buffer pointer needed in scan");} while (false);
123 do {ELLIPSIS_CONTRACT(4, *buf, abort, true, "*buf", "assertion", "pointer to buffer needed in scan");} while (false);
124 do {ELLIPSIS_CONTRACT(5, terminated, abort, true, "terminated", "assertion", "pointer to return state needed in scan");} while (false);
125 /* defer */
126 [[__maybe_unused__, __deprecated__("dummy variable for better diagnostics")]]
127 unsigned (*DEFER_LOC_ID_1_1)[DEFER_LOC_ID_0_2] = {};
128 if (false) {
129 DEFER_ID_1_2: {
130 [[__maybe_unused__, __deprecated__("invalid termination of a deferred block")]]
131 register bool const defer_return_flag = false, defer_break_flag = false, defer_continue_flag = false;
132 {ELLIPSIS_CONTRACT(6, ((typeof(DEFER_LOC_ID_0_1))DEFER_LOC_ID_0_1), unreachable, false, "((typeof(DEFER_LOC_ID_0_1))DEFER_LOC_ID_0_1)", "assumption", "scan did not return a value");}
133 }
134 goto DEFER_ID_1_1;
135 } else
136 (void)0 ;
138 do {
139 /* return mode 2 */
140 defer_return_flag = true;
141 DEFER_LOC_ID_0_1 = ellipsis‿special‿scan‿str32‿_Insta(sp, len, buf, terminated, without, unescaped);
142 goto DEFER_ID_1_2;
143 } while(false);
144
145 goto DEFER_ID_1_2;
146 }
147[[__maybe_unused__]] DEFER_END_ID_1_2:;
148 return DEFER_LOC_ID_0_1;
149}
150
151inline
153 size_t len[static 1], char const*restrict buf[static 1],
154 bool terminated[static 1], bool without, bool unescaped) {
155 typeof(ellipsis‿str32*) DEFER_LOC_ID_0_1;
156 if (__func__[0] == 'm' && __func__[1] == 'a' && __func__[2] == 'i' && __func__[3] == 'n' && !__func__[4]) {
157 DEFER_LOC_ID_0_1 = (typeof(ellipsis‿str32*)) {};
158 }
159 [[__maybe_unused__]] register unsigned DEFER_LOC_ID_0_2 = 1U;
160 [[__maybe_unused__]] register bool defer_return_flag = false;
161 if (false) {
162 DEFER_ID_1_3:
163 goto DEFER_END_ID_1_4;
164 } else {
165 (void)0 ;
166 do {ELLIPSIS_CONTRACT(7, sp, unreachable, false, "sp", "assumption", "pointer to special needed in scan");} while (false);
167 do {ELLIPSIS_CONTRACT(8, len, unreachable, false, "len", "assumption", "pointer to length needed in scan");} while (false);
168 do {ELLIPSIS_CONTRACT(9, buf, unreachable, false, "buf", "assumption", "pointer to buffer pointer needed in scan");} while (false);
169 do {ELLIPSIS_CONTRACT(10, *buf, unreachable, false, "*buf", "assumption", "pointer to buffer needed in scan");} while (false);
170 do {ELLIPSIS_CONTRACT(11, terminated, unreachable, false, "terminated", "assumption", "pointer to return state needed in scan");} while (false);
171 /* defer */
172 [[__maybe_unused__, __deprecated__("dummy variable for better diagnostics")]]
173 unsigned (*DEFER_LOC_ID_1_2)[DEFER_LOC_ID_0_2] = {};
174 if (false) {
175 DEFER_ID_1_4: {
176 [[__maybe_unused__, __deprecated__("invalid termination of a deferred block")]]
177 register bool const defer_return_flag = false, defer_break_flag = false, defer_continue_flag = false;
178 {ELLIPSIS_CONTRACT(12, ((typeof(DEFER_LOC_ID_0_1))DEFER_LOC_ID_0_1), abort, true, "((typeof(DEFER_LOC_ID_0_1))DEFER_LOC_ID_0_1)", "assertion", "scan did not return a value");}
179 }
180 goto DEFER_ID_1_3;
181 } else
182 (void)0 ;
184 do {
185 /* return mode 2 */
186 defer_return_flag = true;
187 DEFER_LOC_ID_0_1 = ellipsis‿special‿scan‿str32‿_Inner(sp, len, buf, terminated, without, unescaped);
188 goto DEFER_ID_1_4;
189 } while(false);
190
191 goto DEFER_ID_1_4;
192 }
193[[__maybe_unused__]] DEFER_END_ID_1_4:;
194 return DEFER_LOC_ID_0_1;
195}
196
197inline
199 size_t len[static 1], char const*restrict buf[static 1],
200 bool terminated[static 1], bool without, bool unescaped) {
201 typeof(ellipsis‿str8*) DEFER_LOC_ID_0_1;
202 if (__func__[0] == 'm' && __func__[1] == 'a' && __func__[2] == 'i' && __func__[3] == 'n' && !__func__[4]) {
203 DEFER_LOC_ID_0_1 = (typeof(ellipsis‿str8*)) {};
204 }
205 [[__maybe_unused__]] register unsigned DEFER_LOC_ID_0_2 = 1U;
206 [[__maybe_unused__]] register bool defer_return_flag = false;
207 if (false) {
208 DEFER_ID_1_5:
209 goto DEFER_END_ID_1_6;
210 } else {
211 (void)0 ;
212 do {ELLIPSIS_CONTRACT(13, sp, abort, true, "sp", "assertion", "pointer to special needed in scan");} while (false);
213 do {ELLIPSIS_CONTRACT(14, len, abort, true, "len", "assertion", "pointer to length needed in scan");} while (false);
214 do {ELLIPSIS_CONTRACT(15, buf, abort, true, "buf", "assertion", "pointer to buffer pointer needed in scan");} while (false);
215 do {ELLIPSIS_CONTRACT(16, *buf, abort, true, "*buf", "assertion", "pointer to buffer needed in scan");} while (false);
216 do {ELLIPSIS_CONTRACT(17, terminated, abort, true, "terminated", "assertion", "pointer to return state needed in scan");} while (false);
217 /* defer */
218 [[__maybe_unused__, __deprecated__("dummy variable for better diagnostics")]]
219 unsigned (*DEFER_LOC_ID_1_3)[DEFER_LOC_ID_0_2] = {};
220 if (false) {
221 DEFER_ID_1_6: {
222 [[__maybe_unused__, __deprecated__("invalid termination of a deferred block")]]
223 register bool const defer_return_flag = false, defer_break_flag = false, defer_continue_flag = false;
224 {ELLIPSIS_CONTRACT(18, ((typeof(DEFER_LOC_ID_0_1))DEFER_LOC_ID_0_1), unreachable, false, "((typeof(DEFER_LOC_ID_0_1))DEFER_LOC_ID_0_1)", "assumption", "scan did not return a value");}
225 }
226 goto DEFER_ID_1_5;
227 } else
228 (void)0 ;
230 do {
231 /* return mode 2 */
232 defer_return_flag = true;
233 DEFER_LOC_ID_0_1 = ellipsis‿special‿scan‿str8‿_Insta(sp, len, buf, terminated, without, unescaped);
234 goto DEFER_ID_1_6;
235 } while(false);
236
237 goto DEFER_ID_1_6;
238 }
239[[__maybe_unused__]] DEFER_END_ID_1_6:;
240 return DEFER_LOC_ID_0_1;
241}
242
243inline
245 size_t len[static 1], char const*restrict buf[static 1],
246 bool terminated[static 1], bool without, bool unescaped) {
247 typeof(ellipsis‿str8*) DEFER_LOC_ID_0_1;
248 if (__func__[0] == 'm' && __func__[1] == 'a' && __func__[2] == 'i' && __func__[3] == 'n' && !__func__[4]) {
249 DEFER_LOC_ID_0_1 = (typeof(ellipsis‿str8*)) {};
250 }
251 [[__maybe_unused__]] register unsigned DEFER_LOC_ID_0_2 = 1U;
252 [[__maybe_unused__]] register bool defer_return_flag = false;
253 if (false) {
254 DEFER_ID_1_7:
255 goto DEFER_END_ID_1_8;
256 } else {
257 (void)0 ;
258 do {ELLIPSIS_CONTRACT(19, sp, unreachable, false, "sp", "assumption", "pointer to special needed in scan");} while (false);
259 do {ELLIPSIS_CONTRACT(20, len, unreachable, false, "len", "assumption", "pointer to length needed in scan");} while (false);
260 do {ELLIPSIS_CONTRACT(21, buf, unreachable, false, "buf", "assumption", "pointer to buffer pointer needed in scan");} while (false);
261 do {ELLIPSIS_CONTRACT(22, *buf, unreachable, false, "*buf", "assumption", "pointer to buffer needed in scan");} while (false);
262 do {ELLIPSIS_CONTRACT(23, terminated, unreachable, false, "terminated", "assumption", "pointer to return state needed in scan");} while (false);
263 /* defer */
264 [[__maybe_unused__, __deprecated__("dummy variable for better diagnostics")]]
265 unsigned (*DEFER_LOC_ID_1_4)[DEFER_LOC_ID_0_2] = {};
266 if (false) {
267 DEFER_ID_1_8: {
268 [[__maybe_unused__, __deprecated__("invalid termination of a deferred block")]]
269 register bool const defer_return_flag = false, defer_break_flag = false, defer_continue_flag = false;
270 {ELLIPSIS_CONTRACT(24, ((typeof(DEFER_LOC_ID_0_1))DEFER_LOC_ID_0_1), abort, true, "((typeof(DEFER_LOC_ID_0_1))DEFER_LOC_ID_0_1)", "assertion", "scan did not return a value");}
271 }
272 goto DEFER_ID_1_7;
273 } else
274 (void)0 ;
276 do {
277 /* return mode 2 */
278 defer_return_flag = true;
279 DEFER_LOC_ID_0_1 = ellipsis‿special‿scan‿str8‿_Inner(sp, len, buf, terminated, without, unescaped);
280 goto DEFER_ID_1_8;
281 } while(false);
282
283 goto DEFER_ID_1_8;
284 }
285[[__maybe_unused__]] DEFER_END_ID_1_8:;
286 return DEFER_LOC_ID_0_1;
287}
288
289void ellipsis‿special‿cpy(size_t len, ellipsis‿special target[static restrict len], ellipsis‿special const source[static restrict len]);
290void ellipsis‿special‿delete(size_t len, ellipsis‿special const target[static restrict len]);
291
293#define SPECIAL_ADD_IIII(STARTER, CLOSER, CAT, REPL) \
294 {\
295 .cat = CAT, \
296 .starter8 = &ELLIPSIS_STR8_STRING_LITERAL(STARTER), \
297 .closer8 = &ELLIPSIS_STR8_STRING_LITERAL(CLOSER), \
298 .repl32 = &ELLIPSIS_STR32_STRING_LITERAL(REPL), \
299 }
300
309#define SPECIAL_ADD(STARTER, ...) SPECIAL_ADD_I ## __VA_OPT__(Iplus) (STARTER __VA_OPT__(,) __VA_ARGS__)
310
316#define SPECIAL_ADD_I(STARTER) SPECIAL_ADD_III(STARTER, "", punctuator)
317
323#define SPECIAL_ADD_II(STARTER, CLOSER) SPECIAL_ADD_III(STARTER, CLOSER, special)
324
330#define SPECIAL_ADD_III(STARTER, CLOSER, CAT) SPECIAL_ADD_IIII(STARTER, CLOSER, CAT, "")
331
337#define SPECIAL_ADD_IIplus(STARTER, CLOSER, ...) SPECIAL_ADD_II ## __VA_OPT__(Iplus) (STARTER, CLOSER __VA_OPT__(,) __VA_ARGS__)
338
344#define SPECIAL_ADD_IIIplus(STARTER, CLOSER, CAT, ...) SPECIAL_ADD_III ## __VA_OPT__(I) (STARTER, CLOSER, CAT __VA_OPT__(,) __VA_ARGS__)
345
354#define PUNCTUATOR_ADD(STARTER, ...) PUNCTUATOR_ADD_I ## __VA_OPT__(I) (STARTER __VA_OPT__(,) __VA_ARGS__)
355
361#define PUNCTUATOR_ADD_I(STARTER) PUNCTUATOR_ADD_II(STARTER, STARTER)
362
368#define PUNCTUATOR_ADD_II(STARTER, REPL) SPECIAL_ADD(STARTER, "", punctuator, REPL)
369
370#define PUNCTUATOR_ADDON(STARTER, ...) PUNCTUATOR_ADDON_I ## __VA_OPT__(I) (STARTER __VA_OPT__(,) __VA_ARGS__)
371 #define PUNCTUATOR_ADDON_I(STARTER) PUNCTUATOR_ADD(STARTER),
372 #define PUNCTUATOR_ADDON_II(STARTER, REPL, ...) PUNCTUATOR_ADD(STARTER, REPL),
373
374#define PUNCTUATOR_TEXT0(...)
375#define PUNCTUATOR_TEXT1(...)
376#define PUNCTUATOR_TEXT2(...)
377#define PUNCTUATOR_TEXT3(...)
378
379#define SPECIAL_ADDON(STARTER, CLOSER, CAT, ...) SPECIAL_ADDON_III ## __VA_OPT__(I) (STARTER, CLOSER, CAT __VA_OPT__(,) __VA_ARGS__)
380 #define SPECIAL_ADDON_III(STARTER, CLOSER, CAT) SPECIAL_ADD(STARTER, CLOSER, CAT),
381 #define SPECIAL_ADDON_IIII(STARTER, CLOSER, CAT, REPL, ...) SPECIAL_ADD(STARTER, CLOSER, CAT, REPL),
382
383#define SPECIAL_TEXT0(...)
384#define SPECIAL_TEXT1(...)
385#define SPECIAL_TEXT2(...)
386#define SPECIAL_TEXT3(...)
387
396#define KEYWORD_ADD(STARTER, ...) KEYWORD_ADD_I ## __VA_OPT__(I) (STARTER __VA_OPT__(,) __VA_ARGS__)
397
398 #define KEYWORD_ADD_ID(X, ...) KEYWORD_ADD(#X __VA_OPT__(, #__VA_ARGS__)),
399
400#define KEYWORD_HEADING(...)
401#define KEYWORD_TEXT(...)
402
408#define KEYWORD_ADD_I(STARTER) KEYWORD_ADD_II(STARTER, STARTER)
409
415#define KEYWORD_ADD_II(STARTER, REPL) SPECIAL_ADD(STARTER, "", keyword, REPL)
416
428#define NOMINAL_ADD(...) NOMINAL_ADD_2(__VA_ARGS__)
429#define NOMINAL_ADD_2(X, R, ...) NOMINAL_ADD_1(X, R)
430#define NOMINAL_ADD_1(X, ...) NOMINAL_ADD_I ## __VA_OPT__(I)(X __VA_OPT__(,) __VA_ARGS__)
431
432 #define NOMINAL_ADD_I(X) SPECIAL_ADD(X, "", nominal, ""),
433 #define NOMINAL_ADD_II(X, R) SPECIAL_ADD(X, "", nominal, R),
434
435#endif
ellipsis‿category
An enumeration type ellipsis‿category with the underlying integer type ellipsis‿category‿base.
Definition ellipsis-category.h:32
struct ellipsis‿contracts‿is_ice ellipsis‿contracts‿is_ice
Definition ellipsis-expression.c:24
ellipsis‿str8 * ellipsis‿special‿scan‿str8‿_Insta(ellipsis‿special const sp[static 1], size_t len[static 1], char const *restrict buf[static 1], bool terminated[static 1], bool without, bool unescaped)
Definition ellipsis-special.c:223
ellipsis‿str32 * ellipsis‿special‿scan‿str32‿_Inner(ellipsis‿special const sp[static 1], size_t len[static 1], char const *restrict buf[static 1], bool terminated[static 1], bool without, bool unescaped)
Definition ellipsis-special.c:67
ellipsis‿str32 * ellipsis‿special‿scan‿str32‿_Insta(ellipsis‿special const sp[static 1], size_t len[static 1], char const *restrict buf[static 1], bool terminated[static 1], bool without, bool unescaped)
Definition ellipsis-special.c:128
ellipsis‿str8 * ellipsis‿special‿scan‿str8‿_Inner(ellipsis‿special const sp[static 1], size_t len[static 1], char const *restrict buf[static 1], bool terminated[static 1], bool without, bool unescaped)
Definition ellipsis-special.c:162
ellipsis‿str8 * ellipsis‿special‿scan‿str8‿_Ctra(ellipsis‿special const sp[static 1], size_t len[static 1], char const *restrict buf[static 1], bool terminated[static 1], bool without, bool unescaped)
Definition ellipsis-special.h:244
thread_local bool volatile ellipsis‿contracts‿verbose‿dynamic
#define ELLIPSIS_CONTRACT(COUNT, COND, ACTION, VERB, CSTR, CTYPE,...)
Definition ellipsis-special.h:63
thread_local bool volatile ellipsis‿contracts‿proceed‿dynamic
void ellipsis‿special‿cpy(size_t len, ellipsis‿special target[static restrict len], ellipsis‿special const source[static restrict len])
Definition ellipsis-special.c:257
ellipsis‿str32 * ellipsis‿special‿scan‿str32‿_Ctra(ellipsis‿special const sp[static 1], size_t len[static 1], char const *restrict buf[static 1], bool terminated[static 1], bool without, bool unescaped)
Definition ellipsis-special.h:152
ellipsis‿str32 * ellipsis‿special‿scan‿str32(ellipsis‿special const sp[static 1], size_t len[static 1], char const *restrict buf[static 1], bool terminated[static 1], bool without, bool unescaped)
Definition ellipsis-special.h:106
thread_local bool volatile ellipsis‿contracts‿ignore‿dynamic
ellipsis‿special const * ellipsis‿special‿find(size_t len, char const buf[len])
Definition ellipsis-special.h:102
void ellipsis‿special‿delete(size_t len, ellipsis‿special const target[static restrict len])
Definition ellipsis-special.c:266
void ellipsis‿special‿append(size_t len, ellipsis‿special *p)
Definition ellipsis-special.h:103
ellipsis‿str8 * ellipsis‿special‿scan‿str8(ellipsis‿special const sp[static 1], size_t len[static 1], char const *restrict buf[static 1], bool terminated[static 1], bool without, bool unescaped)
Definition ellipsis-special.h:198
Definition ellipsis-special.h:95
ellipsis‿str8 const * starter8
Definition ellipsis-special.h:97
ellipsis‿str8 const * closer8
Definition ellipsis-special.h:98
ellipsis‿str32 const * repl32
Definition ellipsis-special.h:99
ellipsis‿category cat
Definition ellipsis-special.h:96
A structure with a flexible array member of base type ellipsis‿str32‿base.
Definition ellipsis-str32.h:156
A structure with a flexible array member of base type ellipsis‿str8‿base.
Definition ellipsis-str8.h:150