/** * Copyright (c) 2026 Dominic Masters * * This software is released under the MIT License. * https://opensource.org/licenses/MIT */ #include "assert.h" #include "log/log.h" #include "util/string.h" #include "util/memory.h" #ifdef DUSK_THREAD_PTHREAD pthread_t ASSERT_MAIN_THREAD_ID = 0; #endif #ifndef DUSK_ASSERTIONS_FAKED void assertInit(void) { #ifdef DUSK_THREAD_PTHREAD ASSERT_MAIN_THREAD_ID = pthread_self(); #endif } #ifdef DUSK_TEST_ASSERT void assertTrueImpl( const char *file, const int32_t line, const bool x, const char *message ) { mock_assert( x == true, message, file, line ); } #else #ifdef DUSK_BACKTRACE #include #include static void assertLogBacktrace(void) { void *frames[64]; int count = backtrace(frames, 64); char **symbols = backtrace_symbols(frames, count); memoryTrack(symbols); logError("Stack trace:\n"); if(symbols) { for(int i = 0; i < count; i++) { logError(" %s\n", symbols[i]); } memoryFree(symbols); } } #endif void assertTrueImpl( const char *file, const int32_t line, const bool x, const char *message ) { if(x != true) { logError( "Assertion Failed in %s:%i\n\n%s\n\n", file, line, message ); #ifdef DUSK_BACKTRACE assertLogBacktrace(); #endif abort(); } } #endif void assertFalseImpl( const char *file, const int32_t line, bool x, const char *message ) { assertTrueImpl(file, line, !x, message); } void assertUnreachableImpl( const char *file, const int32_t line, const char *message ) { assertTrueImpl(file, line, false, message); } void assertNotNullImpl( const char *file, const int32_t line, const void *pointer, const char *message ) { assertTrueImpl( file, line, pointer != NULL, message ); // Ensure we can touch it volatile char temp; temp = *((char*)pointer); } void assertNullImpl( const char *file, const int32_t line, const void *pointer, const char *message ) { assertTrueImpl( file, line, pointer == NULL, message ); } void assertDeprecatedImpl( const char *file, const int32_t line, const char *message ) { assertUnreachableImpl(file, line, message); } void assertStringEqualImpl( const char *file, const int32_t line, const char *a, const char *b, const char *message ) { assertTrueImpl(file, line, stringCompare(a, b) == 0, message); } void assertIsMainThreadImpl( const char *file, const int32_t line, const char *message ) { #ifdef DUSK_THREAD_PTHREAD assertTrueImpl( file, line, pthread_self() == ASSERT_MAIN_THREAD_ID, message ); #endif } void assertNotMainThreadImpl( const char *file, const int32_t line, const char *message ) { #ifdef DUSK_THREAD_PTHREAD assertTrueImpl( file, line, pthread_self() != ASSERT_MAIN_THREAD_ID, message ); #endif } #endif