171 lines
3.3 KiB
C
171 lines
3.3 KiB
C
/**
|
|
* 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 <execinfo.h>
|
|
#include <stdlib.h>
|
|
|
|
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
|
|
|