21 #ifndef P99_CHECKARGS_H_
22 # define P99_CHECKARGS_H_
34 #include P99_ADVANCE_ID
36 #define P00_CA_ASIZE(X) size_t const P99_PASTE2(p00_ca_asize_, X)
37 #define P00_CA_ASIZES(N, ...) P99_SEQ(P00_CA_ASIZE, __VA_ARGS__)
39 #define P00_CA_PSIZE(X) size_t const P99_PASTE2(p00_ca_psize_, X)
40 #define P00_CA_PSIZES(N, ...) P99_SEQ(P00_CA_PSIZE, __VA_ARGS__)
42 #define P00_CA_FSIZE(_0, X, _2) size_t P99_PASTE2(p00_ca_fsize_, X); P99_UNUSED(P99_PASTE2(p00_ca_fsize_, X))
43 #define P00_CA_FSIZES(N, ...) P99_FOR(, P99_NARG(__VA_ARGS__), P00_SEP, P00_CA_FSIZE, __VA_ARGS__)
45 #define P00_CA_TYPEDEF(X) typedef X
46 #define P00_CA_TYPEDEFS(N, ...) P99_SEP(P00_CA_TYPEDEF, P99_REVS(__VA_ARGS__))
48 #define P00_CA_FSIZEOF(_0, X, _2) P99_PASTE2(p00_ca_fsize_, X) = sizeof(X)
49 #define P00_CA_FSIZEOFS(N, ...) P99_FOR(, N, P00_SEP, P00_CA_FSIZEOF, __VA_ARGS__)
51 #define P00_CA_MANGLE_JOIN(X) _, X
52 #define P00_CA_MANGLE_LIST_(...) P99_PASTE(__VA_ARGS__)
53 #define P00_CA_MANGLE_LIST(...) P00_CA_MANGLE_LIST_(P99_SEQ(P00_CA_MANGLE_JOIN, __VA_ARGS__))
55 #define P00_CA_MANGLE(NAME, ACHECKS, PCHECKS) \
59 P00_CA_MANGLE_LIST ACHECKS, \
61 P00_CA_MANGLE_LIST PCHECKS \
66 #define P00_CA_ACHECK_(P, X) \
67 if (P99_LIKELY(X)) { \
71 (P99_PASTE2(p00_ca_fsize_, X) > P99_PASTE2(p00_ca_asize_, P)) \
74 char buf[P00_CA_CHECK_BUFFLEN]; \
75 snprintf(buf, P00_CA_CHECK_BUFFLEN - 1, \
76 "%s, call from %s, size of parameter " P99_STRINGIFY(X) " is %zu instead of %zu", \
79 P99_PASTE2(p00_ca_asize_, P), \
80 P99_PASTE2(p00_ca_fsize_, X) \
82 P99_CONSTRAINT_TRIGGER(ERANGE, buf); \
85 char buf[P00_CA_CHECK_BUFFLEN]; \
86 snprintf(buf, P00_CA_CHECK_BUFFLEN - 1, \
87 "%s, call from %s, parameter " P99_STRINGIFY(X) ", is null pointer", \
91 P99_CONSTRAINT_TRIGGER(ENOMEM, buf); \
94 #define P00_CA_ACHECK(LIST, X, _2) P00_CA_ACHECK_(X, P99_CHS(X, P00_ROBUST LIST))
96 #define P00_CA_ACHECKS(LIST, N, ...) P99_FOR(LIST, P99_NARG(__VA_ARGS__), P00_SEP, P00_CA_ACHECK, __VA_ARGS__)
98 #define P00_CA_PCHECK_(P, X, I) \
99 if (P99_LIKELY(X)) { \
100 size_t const P99_PASTE2(p00_ca_lsize_, I) = sizeof((X)[0]); \
103 (P99_PASTE2(p00_ca_lsize_, I) != P99_PASTE2(p00_ca_psize_, P)) \
106 char buf[P00_CA_CHECK_BUFFLEN]; \
107 snprintf(buf, P00_CA_CHECK_BUFFLEN - 1, \
108 "%s, call from %s, sizeof " P99_STRINGIFY(X) "[0] is %zu instead of %zu", \
111 P99_PASTE2(p00_ca_psize_, P), \
112 P99_PASTE2(p00_ca_lsize_, I) \
114 P99_CONSTRAINT_TRIGGER(ERANGE, buf); \
117 char buf[P00_CA_CHECK_BUFFLEN]; \
118 snprintf(buf, P00_CA_CHECK_BUFFLEN - 1, \
119 "%s, call from %s, parameter " P99_STRINGIFY(X) " is null pointer", \
123 P99_CONSTRAINT_TRIGGER(ENOMEM, buf); \
126 #define P00_CA_PCHECK(LIST, X, I) P00_CA_PCHECK_(X, P99_CHS(X, P00_ROBUST LIST), I)
129 #define P00_CA_PCHECKS(LIST, N, ...) P99_FOR(LIST, P99_NARG(__VA_ARGS__), P00_SEP, P00_CA_PCHECK, __VA_ARGS__)
132 #define P00_CA_WRAP_DECLARE(NAME, RET, TYPES, STYPES, VARS, ACHECKS, PCHECKS) \
134 P99_IF_COMPILER(CLANG, GCC diagnostic push) \
137 RET P00_CA_MANGLE(NAME, ACHECKS, PCHECKS) \
139 char const* p00_call, \
140 P99_IF_EMPTY ACHECKS()(P00_CA_ASIZES(P99_NARG ACHECKS, P00_ROBUST ACHECKS),) \
141 P99_IF_EMPTY PCHECKS()(P00_CA_PSIZES(P99_NARG PCHECKS, P00_ROBUST PCHECKS),) \
142 P00_ROBUST TYPES) { \
143 char const*const p00_proto = P99_STRINGIFY(NAME) STYPES; \
144 P99_UNUSED(p00_proto); \
145 P99_IF_EMPTY ACHECKS() \
147 P00_CA_FSIZES(P99_NARG VARS, P00_ROBUST VARS); \
149 P00_CA_TYPEDEFS(P99_NARG TYPES, P00_ROBUST TYPES); \
150 P00_CA_FSIZEOFS(P99_NARG VARS, P00_ROBUST VARS); \
152 P00_CA_ACHECKS(VARS, P99_NARG ACHECKS, P00_ROBUST ACHECKS); \
154 P00_CA_PCHECKS(VARS, P99_NARG PCHECKS, P00_ROBUST PCHECKS); \
156 RET (*P99_PASTE2(p00_ca_ft_, NAME)) TYPES = NAME; \
157 P99_UNUSED(P99_PASTE2(p00_ca_ft_, NAME)); \
158 P99_IF_EQ_1(P99_IS_TOK(void, RET))()(return) \
161 P99_IF_COMPILER(CLANG, GCC diagnostic pop) \
162 P99_MACRO_END(P00_CA_WRAP_RET_DECLARE)
164 #define P00_CA_WRAP_DECLARE2(NAME, RET, TYPES, STYPES, VARS, ACHECKS, PCHECKS) \
165 P00_CA_WRAP_DECLARE(NAME, RET, TYPES, STYPES, VARS, \
166 P99_IF_EMPTY ACHECKS(())(ACHECKS), \
167 P99_IF_EMPTY PCHECKS(())(PCHECKS))
170 #define P99_CA_WRAP_DECLARE(NAME, RET, TYPES, VARS, ...) \
171 P99_IF_LT(P99_NARG(__VA_ARGS__), 2) \
172 (P00_CA_WRAP_DECLARE(NAME, RET, TYPES, #TYPES, VARS, __VA_ARGS__, __VA_ARGS__)) \
173 (P00_CA_WRAP_DECLARE(NAME, RET, TYPES, #TYPES, VARS, __VA_ARGS__))
175 #define P00_CA_WRAP_DEFINE(NAME, RET, TYPES, VARS, ACHECKS, PCHECKS) \
176 P00_INSTANTIATE(RET, \
177 P00_CA_MANGLE(NAME, ACHECKS, PCHECKS), \
178 char const* p00_call, \
179 P99_IF_EMPTY ACHECKS()(P00_CA_ASIZES(P99_NARG ACHECKS, P00_ROBUST ACHECKS),) \
180 P99_IF_EMPTY PCHECKS()(P00_CA_PSIZES(P99_NARG PCHECKS, P00_ROBUST PCHECKS),) \
183 #define P00_CA_WRAP_DEFINE2(NAME, RET, TYPES, VARS, ACHECKS, PCHECKS) \
184 P00_CA_WRAP_DEFINE(NAME, RET, TYPES, VARS, \
185 P99_IF_EMPTY ACHECKS(())(ACHECKS), \
186 P99_IF_EMPTY PCHECKS(())(PCHECKS))
188 #define P99_CA_WRAP_DEFINE(NAME, RET, TYPES, VARS, ...) \
189 P99_IF_LT(P99_NARG(__VA_ARGS__), 2) \
190 (P00_CA_WRAP_DEFINE(NAME, RET, TYPES, VARS, __VA_ARGS__, __VA_ARGS__)) \
191 (P00_CA_WRAP_DEFINE(NAME, RET, TYPES, VARS, __VA_ARGS__))
193 #define P00_CA_SIZEOF(LIST, X, _2) sizeof(P99_CHS(X, P00_ROBUST LIST))
194 #define P00_CA_SIZEOFS(LIST, N, ...) P99_FOR(LIST, N, P00_SEQ, P00_CA_SIZEOF, __VA_ARGS__)
196 #define P00_CA_PSIZEOF(LIST, X, _2) sizeof(P99_CHS(X, P00_ROBUST LIST)[0])
197 #define P00_CA_PSIZEOFS(LIST, N, ...) P99_FOR(LIST, N, P00_SEQ, P00_CA_PSIZEOF, __VA_ARGS__)
200 #ifndef P99_NO_CHECKARGS
206 #define P99_CA_CALL(NAME, ACHECKS, PCHECKS, ...) \
207 P00_CA_MANGLE(NAME, ACHECKS, PCHECKS) \
209 __FILE__ ":" P99_STRINGIFY(__LINE__) ": " \
210 P99_STRINGIFY(NAME) "(" #__VA_ARGS__ ")", \
211 P99_IF_EMPTY ACHECKS()(P00_CA_SIZEOFS((__VA_ARGS__), P99_NARG ACHECKS, P00_ROBUST ACHECKS),) \
212 P99_IF_EMPTY PCHECKS()(P00_CA_PSIZEOFS((__VA_ARGS__), P99_NARG PCHECKS, P00_ROBUST PCHECKS),) \
216 #define P99_CA_CALL(NAME, ACHECKS, PCHECKS, ...) NAME(__VA_ARGS__)