44 { \
45 GBL_ASSERT(pStackFrame->sourceCurrentCaptureDepth); \
46 --pStackFrame->sourceCurrentCaptureDepth; \
47 } GBL_STMT_END
48
49#define GBL_CTX_SOURCE_LOC_PUSH(srcLoc) \
50 GBL_CTX_STACK_FRAME_SOURCE_PUSH(GBL_CTX_FRAME_NAME, srcLoc)
51
52#define GBL_CTX_SOURCE_PUSH(FILE, FUNCTION, LINE) \
53 GBL_CTX_SOURCE_LOC_PUSH(GBL_SOURCE_LOCATION(FILE, FUNCTION, LINE))
54
55#define GBL_CTX_SOURCE_POP() \
56 GBL_CTX_STACK_FRAME_SOURCE_POP(GBL_CTX_FRAME_NAME)
57
58#define GBL_CTX_SOURCE_SCOPED(CALL, loc, ...) \
59 GBL_STMT_START { \
60 GBL_CTX_SOURCE_LOC_PUSH((loc)); \
61 GBL_IDENTITY(CALL)(__VA_ARGS__); \
62 GBL_CTX_SOURCE_POP(); \
63 } GBL_STMT_END
64
65
66
67#define GBL_CTX_RECORD_SET_JMP_CND_(expr, result, label, srcLoc, ...) \
68 GBL_STMT_START { \
69 GBL_CTX_SOURCE_LOC_PUSH(srcLoc); \
70 if(!(expr)) GBL_UNLIKELY { \
71 GBL_CTX_RECORD_SET(result, __VA_ARGS__); \
72 GBL_CTX_SOURCE_POP(); \
73 label; \
74 } else GBL_LIKELY { \
75 GBL_CTX_SOURCE_POP(); \
76 } \
77 } GBL_STMT_END
78
79#define GBL_CTX_RECORD_SET_JMP_CND(expr, result, label, ...) \
80 GBL_CTX_RECORD_SET_JMP_CND_(expr, result, goto label, GBL_SRC_LOC(GBL_SRC_FILE, GBL_SRC_FN, GBL_SRC_LN), __VA_ARGS__);
81
82
83
84#define GBL_CTX_VERIFY_(expr, result, srcLoc, ...) \
85 GBL_CTX_RECORD_SET_JMP_CND_((expr), \
86 result, \
87 goto GBL_CTX_END_LABEL, \
88 srcLoc, __VA_ARGS__)
89
90#define GBL_CTX_VERIFY_N(srcLoc, expr, result, ...) \
91 GBL_CTX_VERIFY_(expr, result, srcLoc, __VA_ARGS__)
92
93#define GBL_CTX_VERIFY_3(srcLoc, expr, result) \
94 GBL_CTX_VERIFY_N(srcLoc, expr, result, gblResultString(result))
95
96#define GBL_CTX_VERIFY(...) \
97 GBL_STMT_START { \
98 const GblSrcLoc src_ = GBL_SRC_LOC(GBL_SRC_FILE, GBL_SRC_FN, GBL_SRC_LN); \
99 GBL_VA_OVERLOAD_SELECT(GBL_CTX_VERIFY, GBL_VA_OVERLOAD_SUFFIXER_3_N, src_, __VA_ARGS__)(src_, __VA_ARGS__); \
100 } GBL_STMT_END
101
102
103
104#define GBL_CTX_VERIFY_EXPRESSION_N(srcLoc, expr, ...) \
105 GBL_CTX_VERIFY_(expr, GBL_RESULT_ERROR_INVALID_EXPRESSION, srcLoc, __VA_ARGS__)
106
107#define GBL_CTX_VERIFY_EXPRESSION_2(src, expr) \
108 GBL_CTX_VERIFY_EXPRESSION_N(src, expr, "Invalid Expression: "#expr)
109
110#define GBL_CTX_VERIFY_EXPRESSION(...) \
111 GBL_STMT_START { \
112 const GblSrcLoc src_ = GBL_SRC_LOC(GBL_SRC_FILE, GBL_SRC_FN, GBL_SRC_LN); \
113 GBL_VA_OVERLOAD_SELECT(GBL_CTX_VERIFY_EXPRESSION, GBL_VA_OVERLOAD_SUFFIXER_2_N, src_, __VA_ARGS__)(src_, __VA_ARGS__); \
114 } GBL_STMT_END
115
116
117#define GBL_CTX_VERIFY_POINTER_N(srcLoc, expr, ...) \
118 GBL_CTX_VERIFY_(expr, GBL_RESULT_ERROR_INVALID_POINTER, srcLoc, __VA_ARGS__)
119
120#define GBL_CTX_VERIFY_POINTER_2(src, expr) \
121 GBL_CTX_VERIFY_POINTER_N(src, expr, "Invalid Pointer")
122
123#define GBL_CTX_VERIFY_POINTER(...) \
124 GBL_STMT_START { \
125 const GblSrcLoc src_ = GBL_SRC_LOC(GBL_SRC_FILE, GBL_SRC_FN, GBL_SRC_LN); \
126 GBL_VA_OVERLOAD_SELECT(GBL_CTX_VERIFY_POINTER, GBL_VA_OVERLOAD_SUFFIXER_2_N, src_, __VA_ARGS__)(src_, __VA_ARGS__); \
127 } GBL_STMT_END
128
129
130#define GBL_CTX_VERIFY_ARG_N(srcLoc, expr, ...) \
131 GBL_CTX_VERIFY_(expr, GBL_RESULT_ERROR_INVALID_ARG, srcLoc, __VA_ARGS__)
132
133#define GBL_CTX_VERIFY_ARG_2(src, expr) \
134 GBL_CTX_VERIFY_ARG_N(src, expr, "Invalid Arg: "#expr);
135
136#define GBL_CTX_VERIFY_ARG(...) \
137 GBL_STMT_START { \
138 const GblSrcLoc src_ = GBL_SRC_LOC(GBL_SRC_FILE, GBL_SRC_FN, GBL_SRC_LN); \
139 GBL_VA_OVERLOAD_SELECT(GBL_CTX_VERIFY_ARG, GBL_VA_OVERLOAD_SUFFIXER_2_N, src_, __VA_ARGS__)(src_, __VA_ARGS__); \
140 } GBL_STMT_END
141
142
143#define GBL_CTX_VERIFY_TYPE_N(srcLoc, actualType, expectedType, ...) \
144 GBL_CTX_VERIFY_(GblType_check(actualType, expectedType), GBL_RESULT_ERROR_TYPE_MISMATCH, srcLoc, __VA_ARGS__)
145
146#define GBL_CTX_VERIFY_TYPE_3(srcLoc, actualType, expectedType) \
147 GBL_CTX_VERIFY_TYPE_N(srcLoc, actualType, expectedType, "Type mismatch [Actual: %s, Expected: %s]", GblType_name(actualType), GblType_name(expectedType))
148
149#define GBL_CTX_VERIFY_TYPE_2(srcLoc, actualType) \
150 GBL_CTX_VERIFY_(actualType != GBL_INVALID_TYPE, GBL_RESULT_ERROR_INVALID_TYPE, srcLoc, "Invalid Type");
151
152#define GBL_CTX_VERIFY_TYPE(...) \
153 GBL_STMT_START { \
154 const GblSrcLoc src_ = GBL_SRC_LOC(GBL_SRC_FILE, GBL_SRC_FN, GBL_SRC_LN); \
155 GBL_VA_OVERLOAD_SELECT(GBL_CTX_VERIFY_TYPE, GBL_VA_OVERLOAD_SUFFIXER_3_N, src_, __VA_ARGS__)(src_, __VA_ARGS__); \
156 } GBL_STMT_END
157
158
159#define GBL_CTX_VERIFY_LAST_RECORD() \
160 GBL_STMT_START { \
161 const GblCallRecord* pRecord = \
162 GblThd_callRecord(NULL); \
163 if(pRecord && GBL_RESULT_ERROR(pRecord->result)) { \
164 GBL_CTX_RESULT() = pRecord->result; \
165 GBL_CTX_DONE(); \
166 } \
167 } GBL_STMT_END
168
169#define GBL_CTX_CLEAR_LAST_RECORD() \
170 GblThd_setCallRecord(NULL, NULL)
171
172
173
174#ifdef GBL_CONFIG_ERRNO_CHECKS
175#define GBL_CTX_ERRNO_CLEAR() errno = 0
176#else
177#define GBL_CTX_ERRNO_CLEAR()
178#endif
179
180#ifdef GBL_CONFIG_ERRNO_CHECKS
181# define GBL_CTX_PERROR(...) \
182 GBL_STMT_START { \
183 if(errno) GBL_UNLIKELY { \
184 const GBL_RESULT code = \
185 GBL_ERRNO_RESULT(errno); \
186 GBL_CTX_VERIFY( \
187 GBL_RESULT_SUCCESS(code), \
188 code, \
189 "ERRNO: %s", strerror(errno)); \
190 } \
191 } GBL_STMT_END
192#else
193# define GBL_CTX_PERROR(...)
194#endif
195
196GBL_MAYBE_UNUSED GBL_INLINE
GBL_RESULT GBL_ERRNO_RESULT(
int ernum) {
197 switch(ernum) {
198 case 0: return GBL_RESULT_SUCCESS;
199 default: return GBL_RESULT_ERROR;
200 }
201}
202
203
204#define GBL_CTX_INLINE_RETVAL() GBL_CTX_INLINE_RETURN_VALUE_NAME
205
206#define GBL_CTX_INLINE(MethodPrefix, ReturnType, ...) \
207 GBL_INLINE ReturnType GBL_CTX_INLINE_##MethodPrefix##_(GBL_CTX_FRAME_DECLARE, ##__VA_ARGS__) { \
208 ReturnType GBL_CTX_INLINE_RETURN_VALUE_NAME;
209
210#define GBL_CTX_INLINE_BEGIN(InitialRetValue) \
211 GBL_CTX_INLINE_RETVAL() = InitialRetValue;
212
213
214#define GBL_CTX_INLINE_END() \
215 goto GBL_CTX_END_LABEL; \
216 GBL_CTX_END_LABEL: GBL_STMT_START {;} GBL_STMT_END; \
217 }
218
219#define GBL_CTX_INLINE_RETURN() \
220 return GBL_CTX_INLINE_RETVAL()
221
222
223#define GBL_CTX_INLINE_CALL_(MethodPrefix, srcLoc, ...) \
224 GBL_CTX_INLINE_##MethodPrefix##_(GBL_CTX_FRAME() GBL_VA_ARGS(__VA_ARGS__))
225
226#define GBL_CTX_INLINE_CALL(MethodPrefix, ...) \
227 GBL_CTX_INLINE_CALL_(MethodPrefix, GBL_SRC_LOC(GBL_SRC_FILE, GBL_SRC_FN, GBL_SRC_LN) GBL_VA_ARG)
228
229
230
231#define GBL_CTX_EXT(prefix, ...) \
232 GBL_STMT_START { \
233 const GBL_RESULT localResult = GblContext_##prefix(GBL_CTX_CONTEXT(), \
234 GBL_CTX_FRAME_NAME, \
235 ##__VA_ARGS__); \
236 GBL_ASSERT(!(GBL_CONFIG_ASSERT_ERROR_ENABLED && \
237 GBL_RESULT_ERROR(localResult)), \
238 "Ext["#prefix"]: ERROR"); \
239 GBL_ASSERT(!(GBL_CONFIG_ASSERT_PARTIAL_ENABLED && \
240 GBL_RESULT_PARTIAL(localResult)), \
241 "Ext["#prefix"]: ERROR"); \
242 GBL_UNUSED(localResult); \
243 } GBL_STMT_END
244
245
246GBL_MAYBE_UNUSED GBL_CTX_INLINE(MALLOC, void*, size_t size, size_t align, const char* pDebugStr) {
247 GBL_CTX_INLINE_BEGIN(GBL_NULL);
248 if(align == 0) {
249 align = GBL_ALIGNOF(GBL_MAX_ALIGN_T);
250 size = gblAlignedAllocSizeDefault(size);
251 }
252 GBL_ASSERT(size % align == 0);
253 GBL_CTX_EXT(memAlloc_, size, align, pDebugStr, &GBL_CTX_INLINE_RETVAL());
254 GBL_CTX_INLINE_END();
255
256 GBL_CTX_INLINE_RETURN();
257}
258
259#define GBL_CTX_MALLOC_4(src, size, align, dbgStr) \
260 GBL_CTX_INLINE_CALL_(MALLOC, src, size, align, dbgStr)
261
262#define GBL_CTX_MALLOC_3(src, size, align) \
263 GBL_CTX_MALLOC_4(src, size, align, GBL_NULL)
264
265#define GBL_CTX_MALLOC_2(src, size) \
266 GBL_CTX_MALLOC_3(src, gblAlignedAllocSizeDefault(size), GBL_ALIGNOF(GBL_MAX_ALIGN_T))
267
268#define GBL_CTX_MALLOC(...) \
269 GBL_VA_OVERLOAD_SELECT(GBL_CTX_MALLOC, GBL_VA_OVERLOAD_SUFFIXER_ARGC, 1, __VA_ARGS__)(GBL_SRC_LOC(GBL_SRC_FILE, GBL_SRC_FN, GBL_SRC_LN), __VA_ARGS__)
270
271#define GBL_CTX_NEW_4(src, type, count, dbgStr) \
272 (type*)GBL_CTX_INLINE_CALL_(MALLOC, src, gblAlignedAllocSizeDefault(sizeof(type)*count), 0, dbgStr)
273
274#define GBL_CTX_NEW_3(src, type, count) \
275 GBL_CTX_NEW_4(src, type, count, GBL_NULL)
276
277#define GBL_CTX_NEW_2(src, type) \
278 GBL_CTX_NEW_3(src, type, 1)
279
280#define GBL_CTX_NEW(...) \
281 GBL_VA_OVERLOAD_SELECT(GBL_CTX_NEW, GBL_VA_OVERLOAD_SUFFIXER_ARGC, 1, __VA_ARGS__)(GBL_SRC_LOC(GBL_SRC_FILE, GBL_SRC_FN, GBL_SRC_LN), __VA_ARGS__)
282
283GBL_MAYBE_UNUSED GBL_CTX_INLINE(REALLOC, void*, void* pData, size_t newSize, size_t newAlign) {
284 GBL_CTX_INLINE_BEGIN(NULL);
285
286 GBL_CTX_EXT(memRealloc_, pData, newSize, newAlign, &GBL_CTX_INLINE_RETVAL());
287 GBL_CTX_INLINE_END();
288
289 GBL_CTX_INLINE_RETURN();
290}
291
292#define GBL_CTX_REALLOC_4(src, pData, newSize, newAlign) \
293 GBL_CTX_INLINE_CALL_(REALLOC, src, pData, newSize, newAlign)
294
295#define GBL_CTX_REALLOC_3(src, pData, newSize) \
296 GBL_CTX_REALLOC_4(src, pData, newSize, 1)
297
298#define GBL_CTX_REALLOC(...) \
299 GBL_VA_OVERLOAD_SELECT(GBL_CTX_REALLOC, GBL_VA_OVERLOAD_SUFFIXER_ARGC, 1, __VA_ARGS__)(GBL_SRC_LOC(GBL_SRC_FILE, GBL_SRC_FN, GBL_SRC_LN), __VA_ARGS__)
300
301#define GBL_CTX_RENEW_5(src, ptr, type, count, dbgStr) \
302 GBL_CTX_INLINE_CALL(REALLOC, src, ptr, sizeof(type)*count, dbgStr)
303
304#define GBL_CTX_RENEW_4(src, ptr, type, count) \
305 GBL_CTX_RENEW_5(src, ptr, type, count, GBL_NULL)
306
307#define GBL_CTX_RENEW_3(src, ptr, type) \
308 GBL_CTX_RENEW_4(src, ptr, type, 1)
309
310#define GBL_CTX_RENEW(...) \
311 GBL_VA_OVERLOAD_SELECT(GBL_CTX_REALLOC, GBL_VA_OVERLOAD_SUFFIXER_ARGC, 1, __VA_ARGS__)(GBL_SRC_LOC(GBL_SRC_FILE, GBL_SRC_FN, GBL_SRC_LN), __VA_ARGS__)
312
313#define GBL_CTX_FREE(pData) \
314 GBL_CTX_SOURCE_SCOPED(GBL_CTX_EXT, (GBL_SRC_LOC(GBL_SRC_FILE, GBL_SRC_FN, GBL_SRC_LN)), memFree_, pData)
315
316#define GBL_CTX_PUSH_(srcLoc, ...) \
317 GBL_STMT_START { \
318 GBL_CTX_SOURCE_LOC_PUSH(srcLoc); \
319 GblThd_logPush(NULL); \
320 GBL_CTX_EXT(logPush_); \
321 GBL_CTX_SOURCE_POP(); \
322 ++GBL_CTX_FRAME()->stackDepth; \
323 } GBL_STMT_END
324
325#define GBL_CTX_PUSH() \
326 GBL_STMT_START { \
327 const GblSrcLoc src_ = GBL_SRC_LOC(GBL_SRC_FILE, GBL_SRC_FN, GBL_SRC_LN); \
328 GBL_CTX_PUSH_(src_); \
329 } GBL_STMT_END
330
331#define GBL_CTX_PUSH_VERBOSE_N(srcLoc, pFmt, ...) \
332 GBL_STMT_START { \
333 GBL_CTX_SOURCE_SCOPED(GBL_CTX_VERBOSE, srcLoc, pFmt, ##__VA_ARGS__); \
334 GBL_CTX_PUSH_(srcLoc); \
335 } GBL_STMT_END
336
337#define GBL_CTX_PUSH_VERBOSE(...) \
338 GBL_STMT_START { \
339 const GblSrcLoc src_ = GBL_SRC_LOC(GBL_SRC_FILE, GBL_SRC_FN, GBL_SRC_LN); \
340 GBL_VA_OVERLOAD_SELECT(GBL_CTX_PUSH_VERBOSE, GBL_VA_OVERLOAD_SUFFIXER_1_N, src_, ##__VA_ARGS__)(src_, ##__VA_ARGS__); \
341 } GBL_STMT_END
342
343#define GBL_CTX_POP_2(srcLoc, count) \
344 GblThd_logPop(NULL, count); \
345 GBL_CTX_SOURCE_SCOPED(GBL_CTX_EXT, srcLoc, logPop_, count); \
346 GBL_CTX_FRAME()->stackDepth -= count;
347
348#define GBL_CTX_POP_1(srcLoc) \
349 GBL_CTX_POP_2(srcLoc, 1)
350
351#define GBL_CTX_POP(...) \
352 GBL_STMT_START { \
353 const GblSrcLoc loc = GBL_SRC_LOC(GBL_SRC_FILE, GBL_SRC_FN, GBL_SRC_LN); \
354 GBL_VA_OVERLOAD_CALL(GBL_CTX_POP, GBL_VA_OVERLOAD_SUFFIXER_ARGC, loc, __VA_ARGS__); \
355 } GBL_STMT_END
356
357GBL_MAYBE_UNUSED GBL_CTX_INLINE(LOG,
GBL_RESULT,
GblFlags level,
const char* pFmt, ...) {
358 GBL_CTX_INLINE_BEGIN(GBL_RESULT_SUCCESS);
359 va_list varArgs;
360 va_start(varArgs, pFmt);
361
362 GBL_CTX_EXT(logWrite_, level, pFmt, varArgs);
363 va_end(varArgs);
364 GBL_CTX_INLINE_END();
365 GBL_CTX_INLINE_RETURN();
366}
367
368#define GBL_CTX_LOG_(src, level, pFmt, ...) \
369 GBL_CTX_INLINE_CALL_(LOG, src, level, pFmt, ##__VA_ARGS__)
370#define GBL_CTX_LOG(level, pFmt, ...) \
371 GBL_CTX_LOG_(GBL_SRC_LOC(GBL_SRC_FILE, GBL_SRC_FN, GBL_SRC_LN), level, pFmt, ##__VA_ARGS__)
372
373#define GBL_CTX_DEBUG(pFmt, ...) \
374 GBL_CTX_LOG_(GBL_SRC_LOC(GBL_SRC_FILE, GBL_SRC_FN, GBL_SRC_LN), GBL_LOG_LEVEL_DEBUG, pFmt, ##__VA_ARGS__)
375
376#define GBL_CTX_VERBOSE(pFmt, ...) \
377 GBL_CTX_LOG_(GBL_SRC_LOC(GBL_SRC_FILE, GBL_SRC_FN, GBL_SRC_LN), GBL_LOG_LEVEL_VERBOSE, pFmt, ##__VA_ARGS__)
378
379#define GBL_CTX_INFO(pFmt, ...) \
380 GBL_CTX_LOG_(GBL_SRC_LOC(GBL_SRC_FILE, GBL_SRC_FN, GBL_SRC_LN), GBL_LOG_LEVEL_INFO, pFmt, ##__VA_ARGS__)
381
382#define GBL_CTX_WARN(pFmt, ...) \
383 GBL_CTX_LOG_(GBL_SRC_LOC(GBL_SRC_FILE, GBL_SRC_FN, GBL_SRC_LN), GBL_LOG_LEVEL_WARNING, pFmt, ##__VA_ARGS__)
384
385#define GBL_CTX_ERROR(pFmt, ...) \
386 GBL_CTX_LOG_(GBL_SRC_LOC(GBL_SRC_FILE, GBL_SRC_FN, GBL_SRC_LN), GBL_LOG_LEVEL_ERROR, pFmt, ##__VA_ARGS__)
387
388#define GBL_CTX_EVENT(event) \
389 GBL_STMT_START { \
390 const GblSrcLoc src_ = GBL_SRC_LOC(GBL_SRC_FILE, GBL_SRC_FN, GBL_SRC_LN); \
391 GBL_UNUSED(src_); \
392 GblObject_sendEvent(GBL_CTX_OBJECT(), (GblEvent*)event); \
393 } GBL_STMT_END
394
395
396
397
398
399#define GBL_CTX_RECORD_ASSERT_(record, test) \
400 GBL_STMT_START { \
401 GBL_ASSERT(!test(record->result), record->message); \
402 } GBL_STMT_END
403
404
405#define GBL_CTX_RECORD_ASSERT_CONDITIONAL_(enabled, record, test) \
406 GBL_MACRO_CONDITIONAL_CALL(enabled, GBL_CTX_RECORD_ASSERT_, record, test)
407
408
409#define GBL_CTX_RECORD_ASSERT_PARTIAL(record) \
410 GBL_CTX_RECORD_ASSERT_CONDITIONAL_(GBL_CONFIG_ASSERT_PARTIAL_ENABLED, \
411 record, GBL_RESULT_PARTIAL)
412
413#define GBL_CTX_RECORD_ASSERT_ERROR(record) \
414 GBL_CTX_RECORD_ASSERT_CONDITIONAL_(GBL_CONFIG_ASSERT_ERROR_ENABLED, \
415 record, GBL_RESULT_ERROR)
416
417
418#define GBL_CTX_RECORD_ASSERT_UNKNOWN(record) \
419 GBL_CTX_RECORD_ASSERT_CONDITIONAL_(GBL_CONFIG_ASSERT_UNKNOWN_ENABLED, \
420 record, GBL_RESULT_UNKNOWN)
421
422#define GBL_CTX_RECORD_ASSERT(record) \
423 GBL_STMT_START { \
424 GBL_CTX_RECORD_ASSERT_ERROR(record); \
425 GBL_CTX_RECORD_ASSERT_PARTIAL(record); \
426 GBL_CTX_RECORD_ASSERT_UNKNOWN(record); \
427 } GBL_STMT_END
428
429
430
431
432
433#define GBL_CTX_RECORD_LOG_(prefix, record) \
434 GBL_STMT_START { \
435 if(GBL_RESULT_##prefix(record->result)) GBL_UNLIKELY { \
436 GBL_CTX_LOG(GBL_CONFIG_LOG_##prefix##_LEVEL, \
437 "%s: %s", \
438 gblResultString(record->result), record->message); \
439 } \
440 } GBL_STMT_END
441
442
443
444#define GBL_CTX_RECORD_LOG_CONDITIONAL_(prefix, record) \
445 GBL_MACRO_CONDITIONAL_CALL(GBL_CONFIG_LOG_##prefix##_ENABLED, \
446 GBL_CTX_RECORD_LOG_, prefix, record)
447
448
449#define GBL_CTX_RECORD_LOG_PARTIAL(record) \
450 GBL_CTX_RECORD_LOG_CONDITIONAL_(PARTIAL, record)
451
452
453#define GBL_CTX_RECORD_LOG_ERROR(record) \
454 GBL_CTX_RECORD_LOG_CONDITIONAL_(ERROR, record)
455
456
457#define GBL_CTX_RECORD_LOG_UNKNOWN(record) \
458 GBL_CTX_RECORD_LOG_CONDITIONAL_(UNKNOWN, record)
459
460
461#define GBL_CTX_RECORD_LOG(record) \
462 GBL_STMT_START { \
463 GBL_CTX_RECORD_LOG_ERROR(record); \
464 GBL_CTX_RECORD_LOG_PARTIAL(record); \
465 GBL_CTX_RECORD_LOG_UNKNOWN(record); \
466 } GBL_STMT_END
467
468
469
470#define GBL_CTX_RECORD_LAST_RECORD_(prefix, record) \
471 GBL_STMT_START { \
472 if(GBL_RESULT_##prefix(record->result)) { \
473 GblContext_callRecordSet_(GBL_CTX_CONTEXT(), GBL_CTX_FRAME_NAME, record); \
474 GblThd_setCallRecord(NULL, record); \
475 } \
476 } GBL_STMT_END
477
478#define GBL_CTX_RECORD_LAST_RECORD_PARTIAL(record) \
479 GBL_CTX_RECORD_LAST_RECORD_(PARTIAL, record)
480
481#define GBL_CTX_RECORD_LAST_RECORD_ERROR(record) \
482 GBL_CTX_RECORD_LAST_RECORD_(ERROR, record)
483
484#define GBL_CTX_RECORD_LAST_RECORD_UNKNOWN(record) \
485 GBL_CTX_RECORD_LAST_RECORD_(UNKNOWN, record)
486
487#define GBL_CTX_RECORD_LAST_RECORD(record) \
488 GBL_STMT_START { \
489 GBL_CTX_RECORD_LAST_RECORD_ERROR(record); \
490 GBL_CTX_RECORD_LAST_RECORD_PARTIAL(record); \
491 GBL_CTX_RECORD_LAST_RECORD_UNKNOWN(record); \
492 } GBL_STMT_END
493
494
495#define GBL_CTX_RECORD_HANDLER(record) \
496 GBL_STMT_START { \
497 GBL_CTX_RECORD_LOG((record)); \
498 GBL_CTX_RECORD_LAST_RECORD((record)); \
499 GBL_CTX_RECORD_ASSERT((record)); \
500 } GBL_STMT_END
501
502#define GBL_CTX_RECORD_SET_N(file, func, line, result, ...) \
503 GBL_STMT_START { \
504 GBL_CTX_SOURCE_LOC_PUSH(GBL_SRC_LOC(GBL_SRC_FILE, GBL_SRC_FN, GBL_SRC_LN)); \
505 GblCallRecord_construct(&GBL_CTX_RECORD(), result, GBL_CTX_SOURCE(), __VA_ARGS__); \
506 GBL_CTX_RECORD_HANDLER(&GBL_CTX_RECORD()); \
507 GBL_CTX_SOURCE_POP(); \
508 } GBL_STMT_END
509
510#define GBL_CTX_RECORD_SET_5(file, func, line, result, pFmt) \
511 GBL_CTX_RECORD_SET_N(file, func, line, result, "%s", pFmt)
512
513#define GBL_CTX_RECORD_SET_4(file, func, line, result) \
514 GBL_CTX_RECORD_SET_5(file, func, line, result, gblResultString(result))
515
516#define GBL_CTX_RECORD_SET(...) \
517 GBL_VA_OVERLOAD_CALL(GBL_CTX_RECORD_SET, GBL_VA_OVERLOAD_SUFFIXER_5_N, GBL_SRC_FILE, GBL_SRC_FN, GBL_SRC_LN, __VA_ARGS__)
518
519#define GBL_CTX_CALL_N(src, funcCall, ...) \
520 GBL_STMT_START { \
521 GBL_CTX_SOURCE_LOC_PUSH(src); \
522 GBL_MAYBE_UNUSED const GBL_RESULT localResult = (funcCall); \
523 if(!GBL_RESULT_SUCCESS(localResult)) GBL_UNLIKELY { \
524 GBL_CTX_RESULT() = localResult; \
525 } \
526 GBL_CTX_SOURCE_POP(); \
527 } GBL_STMT_END
528
529#define GBL_CTX_CALL_2(src, funcCall) \
530 GBL_CTX_CALL_N(src, funcCall, #funcCall);
531
532#define GBL_CTX_CALL(...) \
533 GBL_STMT_START { \
534 const GblSrcLoc src_ = GBL_SRC_LOC(GBL_SRC_FILE, GBL_SRC_FN, GBL_SRC_LN); \
535 GBL_VA_OVERLOAD_SELECT(GBL_CTX_CALL, GBL_VA_OVERLOAD_SUFFIXER_2_N, src_, __VA_ARGS__)(src_, __VA_ARGS__); \
536 } GBL_STMT_END
537
538#define GBL_CTX_VERIFY_CALL(...) \
539 GBL_STMT_START { \
540 const GblSrcLoc src_ = GBL_SRC_LOC(GBL_SRC_FILE, GBL_SRC_FN, GBL_SRC_LN); \
541 GBL_VA_OVERLOAD_SELECT(GBL_CTX_CALL, GBL_VA_OVERLOAD_SUFFIXER_2_N, src_, __VA_ARGS__)(src_, __VA_ARGS__); \
542 if(!GBL_RESULT_SUCCESS(GBL_CTX_RESULT())) goto GBL_CTX_END_LABEL; \
543 } GBL_STMT_END
544
545
546
547
548#define GBL_CTX_BEGIN_FRAME(file, func, line, pObject, frame) \
549 GBL_CTX_FRAME_DECLARE = frame; \
550 GblStackFrame_construct(GBL_CTX_FRAME_NAME, (GblObject*)pObject, GBL_RESULT_SUCCESS); \
551 GblThd_stackFramePush(NULL, GBL_CTX_FRAME_NAME)
552
553#define GBL_CTX_BEGIN_LOG_4(file, func, line, hHandle) \
554 GBL_CTX_BEGIN_FRAME(file, func, line, hHandle, ((GblStackFrame*)GBL_ALLOCA(sizeof(GblStackFrame))))
555
556#define GBL_CTX_BEGIN_LOG_N(file, func, line, hHandle, ...) \
557 GBL_CTX_BEGIN_LOG_5(file, func, line, hHandle); \
558 GBL_CTX_PUSH_VERBOSE(__VA_ARGS__);
559
560#define GBL_CTX_BEGIN(...) \
561 GBL_VA_OVERLOAD_CALL(GBL_CTX_BEGIN_LOG, GBL_VA_OVERLOAD_SUFFIXER_4_N, GBL_SRC_FILE, GBL_SRC_FN, GBL_SRC_LN, __VA_ARGS__)
562
563#define GBL_CTX_DONE() \
564 goto GBL_CTX_END_LABEL
565
566#define GBL_CTX_END_BLOCK() \
567 goto GBL_CTX_END_LABEL; \
568 GBL_LABEL_EMPTY(GBL_CTX_END_LABEL); \
569 if(GBL_CTX_FRAME_NAME->stackDepth) \
570 GBL_CTX_POP(GBL_CTX_FRAME_NAME->stackDepth); \
571 GblThd_stackFramePop(NULL)
572
573#define GBL_CTX_END() \
574 GBL_CTX_END_BLOCK(); \
575 return GBL_CTX_FRAME_NAME->record.result
576
577#define GBL_CTX_END_EMPTY() \
578 GBL_LABEL_EMPTY(GBL_CTX_END_LABEL)
579
580#define GBL_CTX_BLOCK_6(file, func, line, hHandle, frame, block) \
581 GBL_CTX_BEGIN_FRAME(file, func, line, hHandle, frame); \
582 block; \
583 GBL_CTX_END_BLOCK()
584
585#define GBL_CTX_BLOCK_5(file, func, line, hHandle, block) \
586 GBL_CTX_BLOCK_7(file, func, line, hHandle, ((GblStackFrame*)GBL_ALLOCA(sizeof(GblStackFrame))), block)
587
588#define GBL_CTX_BLOCK_4(file, func, line, block) \
589 GBL_CTX_BLOCK_6(file, func, line, NULL, block)
590
591#define GBL_CTX_BLOCK(...) \
592 GBL_VA_OVERLOAD_SELECT(GBL_CTX_BLOCK, GBL_VA_OVERLOAD_SUFFIXER_ARGC, GBL_SRC_FILE, GBL_SRC_FN, GBL_SRC_LN, __VA_ARGS__)(GBL_SRC_FILE, GBL_SRC_FN, GBL_SRC_LN, __VA_ARGS__)
593
594GBL_DECLS_END
595
596#endif
uint32_t GblFlags
Standard-sized flags type, 32-bits across platforms.