5#ifndef GIMBAL_API_FRAME_H
6#define GIMBAL_API_FRAME_H
9#include "../algorithms/gimbal_numeric.h"
23#define GBL_API_FRAME_DECLARE GblStackFrame* GBL_API_FRAME_NAME
24#define GBL_API_FRAME() (GBL_API_FRAME_NAME)
25#define GBL_API_CONTEXT() GBL_API_FRAME()->pContext
26#define GBL_API_OBJECT() GBL_API_FRAME()->pObject
27#define GBL_API_RECORD() GBL_API_FRAME()->record
28#define GBL_API_RESULT() GBL_API_RECORD().result
29#define GBL_API_SOURCE() GBL_API_FRAME()->sourceCurrent
30#define GBL_API_LAST_RECORD() GblThread_callRecord(NULL)
31#define GBL_API_LAST_RESULT() GblThread_callRecord(NULL)->result
35#define GBL_SRC_FILE GBL_SOURCE_FILE
36#define GBL_SRC_FN GBL_SOURCE_FUNCTION
37#define GBL_SRC_LN GBL_SOURCE_LINE
38#define GBL_SRC_COL GBL_SOURCE_COLUMN
39#define GBL_SRC_LOC GBL_SOURCE_LOCATION
40#define GblSrcLoc GblSourceLocation
42#define GBL_SOURCE_LOCATION(FILE, FUNCTION, LINE, COL) ((GblSourceLocation){FILE, FUNCTION, LINE, COL})
44#define GBL_API_STACK_FRAME_SOURCE_PUSH(pStackFrame, current) \
45 if(++pStackFrame->sourceCurrentCaptureDepth == 1) pStackFrame->sourceCurrent = current;
47#define GBL_API_STACK_FRAME_SOURCE_POP(pStackFrame) \
49 GBL_ASSERT(pStackFrame->sourceCurrentCaptureDepth); \
50 if(--pStackFrame->sourceCurrentCaptureDepth == 0) \
51 pStackFrame->sourceCurrent = pStackFrame->sourceEntry; \
55#define GBL_API_SOURCE_LOC_PUSH(srcLoc) \
56 GBL_API_STACK_FRAME_SOURCE_PUSH(GBL_API_FRAME(), srcLoc)
58#define GBL_API_SOURCE_PUSH(FILE, FUNCTION, LINE, COLUMN) \
59 GBL_API_SOURCE_LOC_PUSH(GBL_SOURCE_LOCATION(FILE, FUNCTION, LINE, COLUMN))
61#define GBL_API_SOURCE_POP() \
62 GBL_API_STACK_FRAME_SOURCE_POP(GBL_API_FRAME())
64#define GBL_API_SOURCE_SCOPED(CALL, loc, ...) \
66 GBL_API_SOURCE_LOC_PUSH((loc)); \
67 GBL_IDENTITY(CALL)(__VA_ARGS__); \
68 GBL_API_SOURCE_POP(); \
73#define GBL_API_RECORD_SET_JMP_CND_(expr, result, label, srcLoc, ...) \
75 GBL_API_SOURCE_LOC_PUSH(srcLoc); \
76 if(!(expr)) GBL_UNLIKELY { \
77 GBL_API_RECORD_SET(result, __VA_ARGS__); \
78 GBL_API_SOURCE_POP(); \
81 GBL_API_SOURCE_POP(); \
85#define GBL_API_RECORD_SET_JMP_CND(expr, result, label, ...) \
86 GBL_API_RECORD_SET_JMP_CND_(expr, result, goto label, GBL_SRC_LOC(GBL_SRC_FILE, GBL_SRC_FN, GBL_SRC_LN, GBL_SRC_COL), __VA_ARGS__);
90#define GBL_API_VERIFY_(expr, result, srcLoc, ...) \
91 GBL_API_RECORD_SET_JMP_CND_((expr), \
93 goto GBL_API_END_LABEL, \
98#define GBL_API_VERIFY_N(srcLoc, expr, result, ...) \
99 GBL_API_VERIFY_(expr, result, srcLoc, __VA_ARGS__)
101#define GBL_API_VERIFY_3(srcLoc, expr, result) \
102 GBL_API_VERIFY_N(srcLoc, expr, result, gblResultString(result))
104#define GBL_API_VERIFY(...) \
106 const GblSrcLoc src_ = GBL_SRC_LOC(GBL_SRC_FILE, GBL_SRC_FN, GBL_SRC_LN, GBL_SRC_COL); \
107 GBL_VA_OVERLOAD_SELECT(GBL_API_VERIFY, GBL_VA_OVERLOAD_SUFFIXER_3_N, src_, __VA_ARGS__)(src_, __VA_ARGS__); \
112#define GBL_API_VERIFY_EXPRESSION_N(srcLoc, expr, ...) \
113 GBL_API_VERIFY_(expr, GBL_RESULT_ERROR_INVALID_EXPRESSION, srcLoc, __VA_ARGS__)
115#define GBL_API_VERIFY_EXPRESSION_2(src, expr) \
116 GBL_API_VERIFY_EXPRESSION_N(src, expr, "Invalid Expression: "#expr)
118#define GBL_API_VERIFY_EXPRESSION(...) \
120 const GblSrcLoc src_ = GBL_SRC_LOC(GBL_SRC_FILE, GBL_SRC_FN, GBL_SRC_LN, GBL_SRC_COL); \
121 GBL_VA_OVERLOAD_SELECT(GBL_API_VERIFY_EXPRESSION, GBL_VA_OVERLOAD_SUFFIXER_2_N, src_, __VA_ARGS__)(src_, __VA_ARGS__); \
125#define GBL_API_VERIFY_POINTER_N(srcLoc, expr, ...) \
126 GBL_API_VERIFY_(expr, GBL_RESULT_ERROR_INVALID_POINTER, srcLoc, __VA_ARGS__)
128#define GBL_API_VERIFY_POINTER_2(src, expr) \
129 GBL_API_VERIFY_POINTER_N(src, expr, "Invalid Pointer")
131#define GBL_API_VERIFY_POINTER(...) \
133 const GblSrcLoc src_ = GBL_SRC_LOC(GBL_SRC_FILE, GBL_SRC_FN, GBL_SRC_LN, GBL_SRC_COL); \
134 GBL_VA_OVERLOAD_SELECT(GBL_API_VERIFY_POINTER, GBL_VA_OVERLOAD_SUFFIXER_2_N, src_, __VA_ARGS__)(src_, __VA_ARGS__); \
138#define GBL_API_VERIFY_ARG_N(srcLoc, expr, ...) \
139 GBL_API_VERIFY_(expr, GBL_RESULT_ERROR_INVALID_ARG, srcLoc, __VA_ARGS__)
141#define GBL_API_VERIFY_ARG_2(src, expr) \
142 GBL_API_VERIFY_ARG_N(src, expr, "Invalid Arg: "#expr);
144#define GBL_API_VERIFY_ARG(...) \
146 const GblSrcLoc src_ = GBL_SRC_LOC(GBL_SRC_FILE, GBL_SRC_FN, GBL_SRC_LN, GBL_SRC_COL); \
147 GBL_VA_OVERLOAD_SELECT(GBL_API_VERIFY_ARG, GBL_VA_OVERLOAD_SUFFIXER_2_N, src_, __VA_ARGS__)(src_, __VA_ARGS__); \
151#define GBL_API_VERIFY_TYPE_N(srcLoc, actualType, expectedType, ...) \
152 GBL_API_VERIFY_(GblType_check(actualType, expectedType), GBL_RESULT_ERROR_TYPE_MISMATCH, srcLoc, __VA_ARGS__)
154#define GBL_API_VERIFY_TYPE_3(srcLoc, actualType, expectedType) \
155 GBL_API_VERIFY_TYPE_N(srcLoc, actualType, expectedType, "Type mismatch [Actual: %s, Expected: %s]", GblType_name(actualType), GblType_name(expectedType))
157#define GBL_API_VERIFY_TYPE_2(srcLoc, actualType) \
158 GBL_API_VERIFY_(actualType != GBL_INVALID_TYPE, GBL_RESULT_ERROR_INVALID_TYPE, srcLoc, "Invalid Type");
160#define GBL_API_VERIFY_TYPE(...) \
162 const GblSrcLoc src_ = GBL_SRC_LOC(GBL_SRC_FILE, GBL_SRC_FN, GBL_SRC_LN, GBL_SRC_COL); \
163 GBL_VA_OVERLOAD_SELECT(GBL_API_VERIFY_TYPE, GBL_VA_OVERLOAD_SUFFIXER_3_N, src_, __VA_ARGS__)(src_, __VA_ARGS__); \
167#define GBL_API_VERIFY_LAST_RECORD() \
169 const GblCallRecord* pRecord = \
170 GblThread_callRecord(NULL); \
171 if(pRecord && GBL_RESULT_ERROR(pRecord->result)) { \
172 GBL_API_RESULT() = pRecord->result; \
177#define GBL_API_CLEAR_LAST_RECORD() \
178 GblThread_setCallRecord(NULL, NULL)
182#ifdef GBL_CONFIG_ERRNO_CHECKS
183#define GBL_API_ERRNO_CLEAR() errno = 0
185#define GBL_API_ERRNO_CLEAR()
188#ifdef GBL_CONFIG_ERRNO_CHECKS
189# define GBL_API_PERROR(...) \
191 if(errno) GBL_UNLIKELY { \
192 const GBL_RESULT code = \
193 GBL_ERRNO_RESULT(errno); \
195 GBL_RESULT_SUCCESS(code), \
197 "ERRNO: %x", errno); \
201# define GBL_API_PERROR(...)
204GBL_MAYBE_UNUSED GBL_INLINE GBL_RESULT GBL_ERRNO_RESULT(
int ernum) {
206 case 0:
return GBL_RESULT_SUCCESS;
207 default:
return GBL_RESULT_ERROR;
212#define GBL_API_INLINE_RETVAL() GBL_API_INLINE_RETURN_VALUE_NAME
214#define GBL_API_INLINE(MethodPrefix, ReturnType, ...) \
215 GBL_INLINE ReturnType GBL_API_INLINE_##MethodPrefix##_(GBL_API_FRAME_DECLARE, GblSrcLoc srcLoc, ##__VA_ARGS__) { \
216 ReturnType GBL_API_INLINE_RETURN_VALUE_NAME;
218#define GBL_API_INLINE_BEGIN(InitialRetValue) \
219 GBL_API_INLINE_RETVAL() = InitialRetValue; \
220 GBL_API_SOURCE_LOC_PUSH(srcLoc);
223#define GBL_API_INLINE_END() \
224 goto GBL_API_END_LABEL; \
225 GBL_API_END_LABEL: GBL_STMT_START {;} GBL_STMT_END; \
228#define GBL_API_INLINE_RETURN() \
229 GBL_API_SOURCE_POP(); \
230 return GBL_API_INLINE_RETVAL()
233#define GBL_API_INLINE_CALL_(MethodPrefix, srcLoc, ...) \
234 GBL_API_INLINE_##MethodPrefix##_(GBL_API_FRAME(), srcLoc GBL_VA_ARGS(__VA_ARGS__))
236#define GBL_API_INLINE_CALL(MethodPrefix, ...) \
237 GBL_API_INLINE_CALL_(MethodPrefix, GBL_SRC_LOC(GBL_SRC_FILE, GBL_SRC_FN, GBL_SRC_LN, GBL_SRC_COL) GBL_VA_ARG)
241#define GBL_API_EXT(prefix, ...) \
243 GBL_API_SOURCE_PUSH(GBL_SRC_FILE, GBL_SRC_FN, GBL_SRC_LN, GBL_SRC_COL); \
244 GBL_MAYBE_UNUSED const GBL_RESULT localResult = GBL_EXT_##prefix(GBL_API_FRAME(), ##__VA_ARGS__); \
245 GBL_ASSERT(!(GBL_CONFIG_ASSERT_ERROR_ENABLED && GBL_RESULT_ERROR(localResult)), "Ext["#prefix"]: ERROR"); \
246 GBL_ASSERT(!(GBL_CONFIG_ASSERT_PARTIAL_ENABLED && GBL_RESULT_PARTIAL(localResult)), "Ext["#prefix"]: ERROR"); \
247 GBL_UNUSED(localResult); \
248 GBL_API_SOURCE_POP(); \
252GBL_MAYBE_UNUSED GBL_API_INLINE(MALLOC,
void*, GblSize size, GblSize align,
const char* pDebugStr) {
253 GBL_API_INLINE_BEGIN(GBL_NULL);
255 align = GBL_ALIGNOF(GBL_MAX_ALIGN_T);
256 size = gblAlignedAllocSizeDefault(size);
258 GBL_ASSERT(size % align == 0);
259 GBL_API_EXT(MALLOC, size, align, pDebugStr, &GBL_API_INLINE_RETVAL());
260 GBL_API_INLINE_END();
262 GBL_API_INLINE_RETURN();
265#define GBL_API_MALLOC_4(src, size, align, dbgStr) \
266 GBL_API_INLINE_CALL_(MALLOC, src, size, align, dbgStr)
268#define GBL_API_MALLOC_3(src, size, align) \
269 GBL_API_MALLOC_4(src, size, align, GBL_NULL)
271#define GBL_API_MALLOC_2(src, size) \
272 GBL_API_MALLOC_3(src, gblAlignedAllocSizeDefault(size), GBL_ALIGNOF(GBL_MAX_ALIGN_T))
274#define GBL_API_MALLOC(...) \
275 GBL_VA_OVERLOAD_SELECT(GBL_API_MALLOC, GBL_VA_OVERLOAD_SUFFIXER_ARGC, 1, __VA_ARGS__)(GBL_SRC_LOC(GBL_SRC_FILE, GBL_SRC_FN, GBL_SRC_LN, GBL_SRC_COL), __VA_ARGS__)
277#define GBL_API_NEW_4(src, type, count, dbgStr) \
278 (type*)GBL_API_INLINE_CALL_(MALLOC, src, gblAlignedAllocSizeDefault(sizeof(type)*count), 0, dbgStr)
280#define GBL_API_NEW_3(src, type, count) \
281 GBL_API_NEW_4(src, type, count, GBL_NULL)
283#define GBL_API_NEW_2(src, type) \
284 GBL_API_NEW_3(src, type, 1)
286#define GBL_API_NEW(...) \
287 GBL_VA_OVERLOAD_SELECT(GBL_API_NEW, GBL_VA_OVERLOAD_SUFFIXER_ARGC, 1, __VA_ARGS__)(GBL_SRC_LOC(GBL_SRC_FILE, GBL_SRC_FN, GBL_SRC_LN, GBL_SRC_COL), __VA_ARGS__)
289GBL_MAYBE_UNUSED GBL_API_INLINE(REALLOC,
void*,
void* pData, GblSize newSize, GblSize newAlign) {
290 GBL_API_INLINE_BEGIN(NULL);
292 GBL_API_EXT(REALLOC, pData, newSize, newAlign, &GBL_API_INLINE_RETVAL());
293 GBL_API_INLINE_END();
295 GBL_API_INLINE_RETURN();
298#define GBL_API_REALLOC_4(src, pData, newSize, newAlign) \
299 GBL_API_INLINE_CALL_(REALLOC, src, pData, newSize, newAlign)
301#define GBL_API_REALLOC_3(src, pData, newSize) \
302 GBL_API_REALLOC_4(src, pData, newSize, 1)
304#define GBL_API_REALLOC(...) \
305 GBL_VA_OVERLOAD_SELECT(GBL_API_REALLOC, GBL_VA_OVERLOAD_SUFFIXER_ARGC, 1, __VA_ARGS__)(GBL_SRC_LOC(GBL_SRC_FILE, GBL_SRC_FN, GBL_SRC_LN, GBL_SRC_COL), __VA_ARGS__)
307#define GBL_API_RENEW_5(src, ptr, type, count, dbgStr) \
308 GBL_API_INLINE_CALL(REALLOC, src, ptr, sizeof(type)*count, dbgStr)
310#define GBL_API_RENEW_4(src, ptr, type, count) \
311 GBL_API_RENEW_5(src, ptr, type, count, GBL_NULL)
313#define GBL_API_RENEW_3(src, ptr, type) \
314 GBL_API_RENEW_4(src, ptr, type, 1)
316#define GBL_API_RENEW(...) \
317 GBL_VA_OVERLOAD_SELECT(GBL_API_REALLOC, GBL_VA_OVERLOAD_SUFFIXER_ARGC, 1, __VA_ARGS__)(GBL_SRC_LOC(GBL_SRC_FILE, GBL_SRC_FN, GBL_SRC_LN, GBL_SRC_COL), __VA_ARGS__)
319#define GBL_API_FREE(pData) \
320 GBL_API_SOURCE_SCOPED(GBL_API_EXT, (GBL_SRC_LOC(GBL_SRC_FILE, GBL_SRC_FN, GBL_SRC_LN, GBL_SRC_COL)), FREE, pData)
322#define GBL_API_PUSH_(srcLoc, ...) \
324 GBL_API_SOURCE_LOC_PUSH(srcLoc); \
325 GBL_RESULT_SUCCESS(GblThread_logPush(NULL)); \
326 GBL_API_EXT(LOG_PUSH); \
327 GBL_API_SOURCE_POP(); \
328 ++GBL_API_FRAME()->stackDepth; \
331#define GBL_API_PUSH() \
333 const GblSrcLoc src_ = GBL_SRC_LOC(GBL_SRC_FILE, GBL_SRC_FN, GBL_SRC_LN, GBL_SRC_COL); \
334 GBL_API_PUSH_(src_); \
337#define GBL_API_PUSH_VERBOSE_N(srcLoc, pFmt, ...) \
339 GBL_API_SOURCE_SCOPED(GBL_API_VERBOSE, srcLoc, pFmt, ##__VA_ARGS__); \
340 GBL_API_PUSH_(srcLoc); \
343#define GBL_API_PUSH_VERBOSE(...) \
345 const GblSrcLoc src_ = GBL_SRC_LOC(GBL_SRC_FILE, GBL_SRC_FN, GBL_SRC_LN, GBL_SRC_COL); \
346 GBL_VA_OVERLOAD_SELECT(GBL_API_PUSH_VERBOSE, GBL_VA_OVERLOAD_SUFFIXER_1_N, src_, ##__VA_ARGS__)(src_, ##__VA_ARGS__); \
349#define GBL_API_POP_2(srcLoc, count) \
350 GblThread_logPop(NULL, count); \
351 GBL_API_SOURCE_SCOPED(GBL_API_EXT, srcLoc, LOG_POP, count); \
352 GBL_API_FRAME()->stackDepth -= count;
354#define GBL_API_POP_1(srcLoc) \
355 GBL_API_POP_2(srcLoc, 1)
357#define GBL_API_POP(...) \
359 const GblSrcLoc loc = GBL_SRC_LOC(GBL_SRC_FILE, GBL_SRC_FN, GBL_SRC_LN, GBL_SRC_COL); \
360 GBL_VA_OVERLOAD_CALL(GBL_API_POP, GBL_VA_OVERLOAD_SUFFIXER_ARGC, loc, __VA_ARGS__); \
363GBL_MAYBE_UNUSED GBL_API_INLINE(LOG, GBL_RESULT, GBL_LOG_LEVEL level,
const char* pFmt, ...) {
364 GBL_API_INLINE_BEGIN(GBL_RESULT_SUCCESS);
366 va_start(varArgs, pFmt);
368 GBL_API_EXT(LOG_WRITE, level, pFmt, varArgs);
370 GBL_API_INLINE_END();
371 GBL_API_INLINE_RETURN();
374#define GBL_API_LOG_(src, level, pFmt, ...) \
375 GBL_API_INLINE_CALL_(LOG, src, level, pFmt, ##__VA_ARGS__);
376#define GBL_API_LOG(level, pFmt, ...) \
377 GBL_API_LOG_(GBL_SRC_LOC(GBL_SRC_FILE, GBL_SRC_FN, GBL_SRC_LN, GBL_SRC_COL), level, pFmt, ##__VA_ARGS__)
379#define GBL_API_DEBUG(pFmt, ...) \
381 const GblSrcLoc src = GBL_SRC_LOC(GBL_SRC_FILE, GBL_SRC_FN, GBL_SRC_LN, GBL_SRC_COL); \
382 GBL_API_LOG_(src, GBL_LOG_LEVEL_DEBUG, pFmt, ##__VA_ARGS__); \
385#define GBL_API_VERBOSE(pFmt, ...) \
387 const GblSrcLoc src = GBL_SRC_LOC(GBL_SRC_FILE, GBL_SRC_FN, GBL_SRC_LN, GBL_SRC_COL); \
388 GBL_API_LOG_(src, GBL_LOG_LEVEL_VERBOSE, pFmt, ##__VA_ARGS__); \
391#define GBL_API_INFO(pFmt, ...) \
393 const GblSrcLoc src = GBL_SRC_LOC(GBL_SRC_FILE, GBL_SRC_FN, GBL_SRC_LN, GBL_SRC_COL); \
394 GBL_API_LOG_(src, GBL_LOG_LEVEL_INFO, pFmt, ##__VA_ARGS__); \
397#define GBL_API_WARN(pFmt, ...) \
399 const GblSrcLoc src = GBL_SRC_LOC(GBL_SRC_FILE, GBL_SRC_FN, GBL_SRC_LN, GBL_SRC_COL); \
400 GBL_API_LOG_(src, GBL_LOG_LEVEL_WARNING, pFmt, ##__VA_ARGS__); \
403#define GBL_API_ERROR(pFmt, ...) \
405 const GblSrcLoc src = GBL_SRC_LOC(GBL_SRC_FILE, GBL_SRC_FN, GBL_SRC_LN, GBL_SRC_COL); \
406 GBL_API_LOG_(src, GBL_LOG_LEVEL_ERROR, pFmt, ##__VA_ARGS__); \
410#define GBL_API_EVENT_2(srcLoc, event) \
411 GBL_API_SOURCE_SCOPED(GBL_API_EXT, srcLoc, EVENT, type, NULL, 0)
413#define GBL_API_EVENT(event) \
415 const GblSrcLoc src_ = GBL_SRC_LOC(GBL_SRC_FILE, GBL_SRC_FN, GBL_SRC_LN, GBL_SRC_COL); \
417 GblObject_sendEvent(GBL_API_OBJECT(), (GblEvent*)event); \
424#define GBL_API_RECORD_ASSERT_(record, test) \
426 GBL_ASSERT(!test(record->result), record->message); \
430#define GBL_API_RECORD_ASSERT_CONDITIONAL_(enabled, record, test) \
431 GBL_MACRO_CONDITIONAL_CALL(enabled, GBL_API_RECORD_ASSERT_, record, test)
434#define GBL_API_RECORD_ASSERT_PARTIAL(record) \
435 GBL_API_RECORD_ASSERT_CONDITIONAL_(GBL_CONFIG_ASSERT_PARTIAL_ENABLED, \
436 record, GBL_RESULT_PARTIAL)
438#define GBL_API_RECORD_ASSERT_ERROR(record) \
439 GBL_API_RECORD_ASSERT_CONDITIONAL_(GBL_CONFIG_ASSERT_ERROR_ENABLED, \
440 record, GBL_RESULT_ERROR)
443#define GBL_API_RECORD_ASSERT_UNKNOWN(record) \
444 GBL_API_RECORD_ASSERT_CONDITIONAL_(GBL_CONFIG_ASSERT_UNKNOWN_ENABLED, \
445 record, GBL_RESULT_UNKNOWN)
447#define GBL_API_RECORD_ASSERT(record) \
449 GBL_API_RECORD_ASSERT_ERROR(record); \
450 GBL_API_RECORD_ASSERT_PARTIAL(record); \
451 GBL_API_RECORD_ASSERT_UNKNOWN(record); \
458#define GBL_API_RECORD_LOG_(prefix, record) \
460 if(GBL_RESULT_##prefix(record->result)) GBL_UNLIKELY { \
461 GBL_API_LOG(GBL_CONFIG_LOG_##prefix##_LEVEL, \
463 gblResultString(record->result), record->message); \
469#define GBL_API_RECORD_LOG_CONDITIONAL_(prefix, record) \
470 GBL_MACRO_CONDITIONAL_CALL(GBL_CONFIG_LOG_##prefix##_ENABLED, \
471 GBL_API_RECORD_LOG_, prefix, record)
474#define GBL_API_RECORD_LOG_PARTIAL(record) \
475 GBL_API_RECORD_LOG_CONDITIONAL_(PARTIAL, record)
478#define GBL_API_RECORD_LOG_ERROR(record) \
479 GBL_API_RECORD_LOG_CONDITIONAL_(ERROR, record)
482#define GBL_API_RECORD_LOG_UNKNOWN(record) \
483 GBL_API_RECORD_LOG_CONDITIONAL_(UNKNOWN, record)
486#define GBL_API_RECORD_LOG(record) \
488 GBL_API_RECORD_LOG_ERROR(record); \
489 GBL_API_RECORD_LOG_PARTIAL(record); \
490 GBL_API_RECORD_LOG_UNKNOWN(record); \
495#define GBL_API_RECORD_LAST_RECORD_(prefix, record) \
497 if(GBL_RESULT_##prefix(record->result)) { \
498 gblExtCallRecordSet(GBL_API_FRAME(), record); \
499 GblThread_setCallRecord(NULL, record); \
504#define GBL_API_RECORD_LAST_RECORD_CONDITIONAL_(prefix, record) \
505 GBL_MACRO_CONDITIONAL_CALL(GBL_CONFIG_LAST_CALL_RECORD_##prefix##_ENABLED, \
506 GBL_API_RECORD_LAST_RECORD_, prefix, record)
508#define GBL_API_RECORD_LAST_RECORD_PARTIAL(record) \
509 GBL_API_RECORD_LAST_RECORD_CONDITIONAL_(PARTIAL, record)
511#define GBL_API_RECORD_LAST_RECORD_ERROR(record) \
512 GBL_API_RECORD_LAST_RECORD_CONDITIONAL_(ERROR, record)
514#define GBL_API_RECORD_LAST_RECORD_UNKNOWN(record) \
515 GBL_API_RECORD_LAST_RECORD_CONDITIONAL_(UNKNOWN, record)
517#define GBL_API_RECORD_LAST_RECORD(record) \
519 GBL_API_RECORD_LAST_RECORD_ERROR(record); \
520 GBL_API_RECORD_LAST_RECORD_PARTIAL(record); \
521 GBL_API_RECORD_LAST_RECORD_UNKNOWN(record); \
526#define GBL_API_RECORD_HANDLER(record) \
528 GBL_API_RECORD_LOG((record)); \
529 GBL_API_RECORD_LAST_RECORD((record)); \
530 GBL_API_RECORD_ASSERT((record)); \
533#define GBL_API_RECORD_SET_N(file, func, line, col, result, ...) \
535 GBL_API_SOURCE_LOC_PUSH(GBL_SRC_LOC(GBL_SRC_FILE, GBL_SRC_FN, GBL_SRC_LN, GBL_SRC_COL)); \
536 GBL_CALL_RECORD_CONSTRUCT(&GBL_API_RECORD(), GBL_API_OBJECT(), result, GBL_API_SOURCE(), __VA_ARGS__); \
537 GBL_API_RECORD_HANDLER(&GBL_API_RECORD()); \
538 GBL_API_SOURCE_POP(); \
541#define GBL_API_RECORD_SET_6(file, func, line, col, result, pFmt) \
542 GBL_API_RECORD_SET_N(file, func, line, col, result, "%s", pFmt)
544#define GBL_API_RECORD_SET_5(file, func, line, col, result) \
545 GBL_API_RECORD_SET_6(file, func, line, col, result, gblResultString(result))
547#define GBL_API_RECORD_SET(...) \
548 GBL_VA_OVERLOAD_CALL(GBL_API_RECORD_SET, GBL_VA_OVERLOAD_SUFFIXER_6_N, GBL_SRC_FILE, GBL_SRC_FN, GBL_SRC_LN, GBL_SRC_COL, __VA_ARGS__)
551#define GBL_API_CALL_N(src, funcCall, ...) \
553 GBL_API_SOURCE_LOC_PUSH(src); \
554 GBL_MAYBE_UNUSED const GBL_RESULT localResult = (funcCall); \
555 if(!GBL_RESULT_SUCCESS(localResult)) GBL_UNLIKELY { \
556 GBL_API_RESULT() = localResult; \
558 GBL_API_SOURCE_POP(); \
561#define GBL_API_CALL_2(src, funcCall) \
562 GBL_API_CALL_N(src, funcCall, #funcCall);
564#define GBL_API_CALL(...) \
566 const GblSrcLoc src_ = GBL_SRC_LOC(GBL_SRC_FILE, GBL_SRC_FN, GBL_SRC_LN, GBL_SRC_COL); \
567 GBL_VA_OVERLOAD_SELECT(GBL_API_CALL, GBL_VA_OVERLOAD_SUFFIXER_2_N, src_, __VA_ARGS__)(src_, __VA_ARGS__); \
570#define GBL_API_VERIFY_CALL(...) \
572 const GblSrcLoc src_ = GBL_SRC_LOC(GBL_SRC_FILE, GBL_SRC_FN, GBL_SRC_LN, GBL_SRC_COL); \
573 GBL_VA_OVERLOAD_SELECT(GBL_API_CALL, GBL_VA_OVERLOAD_SUFFIXER_2_N, src_, __VA_ARGS__)(src_, __VA_ARGS__); \
574 if(!GBL_RESULT_SUCCESS(GBL_API_RESULT())) goto GBL_API_END_LABEL; \
580#define GBL_API_BEGIN_FRAME(file, func, line, col, pObject, frame) \
581 const GblSrcLoc gblApiEntrySrcLoc_ = GBL_SRC_LOC(file, func, line, col); \
582 GBL_API_FRAME_DECLARE = frame; \
583 GBL_API_STACK_FRAME_CONSTRUCT(GBL_API_FRAME(), (GblObject*)pObject, GBL_RESULT_SUCCESS, gblApiEntrySrcLoc_); \
584 GBL_RESULT_SUCCESS(GblThread_stackFramePush(NULL, GBL_API_FRAME()))
586#define GBL_API_BEGIN_LOG_5(file, func, line, col, hHandle) \
587 GBL_API_BEGIN_FRAME(file, func, line, col, hHandle, ((GblStackFrame*)GBL_ALLOCA(sizeof(GblStackFrame))))
589#define GBL_API_BEGIN_LOG_N(file, func, line, col, hHandle, ...) \
590 GBL_API_BEGIN_LOG_5(file, func, line, col, hHandle); \
591 GBL_API_PUSH_VERBOSE(__VA_ARGS__);
593#define GBL_API_BEGIN(...) \
594 GBL_VA_OVERLOAD_CALL(GBL_API_BEGIN_LOG, GBL_VA_OVERLOAD_SUFFIXER_5_N, GBL_SRC_FILE, GBL_SRC_FN, GBL_SRC_LN, GBL_SRC_COL, __VA_ARGS__)
596#define GBL_API_DONE() \
597 goto GBL_API_END_LABEL
599#define GBL_API_END_BLOCK() \
600 goto GBL_API_END_LABEL; \
601 GBL_LABEL_EMPTY(GBL_API_END_LABEL); \
602 if(GBL_API_FRAME()->stackDepth) \
603 GBL_API_POP(GBL_API_FRAME()->stackDepth); \
604 GBL_RESULT_SUCCESS(GblThread_stackFramePop(NULL))
606#define GBL_API_END() \
607 GBL_API_END_BLOCK(); \
608 return GBL_API_RESULT()
610#define GBL_API_END_EMPTY() \
611 GBL_LABEL_EMPTY(GBL_API_END_LABEL)
613#define GBL_API_BLOCK_7(file, func, line, col, hHandle, frame, block) \
614 GBL_API_BEGIN_FRAME(file, func, line, col, hHandle, frame); \
618#define GBL_API_BLOCK_6(file, func, line, col, hHandle, block) \
619 GBL_API_BLOCK_7(file, func, line, col, hHandle, ((GblStackFrame*)GBL_ALLOCA(sizeof(GblStackFrame))), block)
621#define GBL_API_BLOCK_5(file, func, line, col, block) \
622 GBL_API_BLOCK_6(file, func, line, col, NULL, block)
624#define GBL_API_BLOCK(...) \
625 GBL_VA_OVERLOAD_SELECT(GBL_API_BLOCK, GBL_VA_OVERLOAD_SUFFIXER_ARGC, GBL_SRC_FILE, GBL_SRC_FN, GBL_SRC_LN, GBL_SRC_COL, __VA_ARGS__)(GBL_SRC_FILE, GBL_SRC_FN, GBL_SRC_LN, GBL_SRC_COL, __VA_ARGS__)
Helper defines for struct, enum, flags, handle delcarations.
Stack frame, call record, source capture debug utilities.
Optional Compile-time polymorphic context overrides.
GblThread, per-thread state and context management.