commit b1ce7c090d461f5c4e2dbc8970ab641df3a68366 Author: SoraKatadzuma Date: Tue Aug 25 06:38:37 2026 -0500 Initial Commit diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..95788f7 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,14 @@ +root = true + +[*] +indent_size = 2 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.py] +indent_style = tab + +[chinookfile] +indent_style = space diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2744b01 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.chinook/ +.environ/ +.vscode/ diff --git a/chinookfile b/chinookfile new file mode 100644 index 0000000..5b6f6a9 --- /dev/null +++ b/chinookfile @@ -0,0 +1,16 @@ +name: assert +gpid: malunal +semv: 1.0.0 + +requires: +- remote: git@git.erasit.com:malunal/types + branch: v1.0.0 + +targets: +- name: malunal.assert + type: archive + deps: [malunal.types] + srcs: [./sources/assert.c] + +exports: +- malunal.assert diff --git a/include/malunal/assert.h b/include/malunal/assert.h new file mode 100644 index 0000000..82f4076 --- /dev/null +++ b/include/malunal/assert.h @@ -0,0 +1,111 @@ +/** + * @file assert.h + * @brief Contains the definitions for various types of the library and + * declarations for functions that make the library work. + * @author John Christman (sorakatadzuma@gmail.com) + * @copyright Malunal Studios, LLC. + */ +#include "malunal/types/bool.h" +#include "malunal/types/integer.h" +#include "malunal/types/string.h" + +#ifndef MALUNAL_ASSERT_HEADER +#define MALUNAL_ASSERT_HEADER + +/** + * @def assert + * @brief A preprocessor macro which can test and throw an assertion. + * @details This will eventually call @c assert_test which will test the + * assertion formally and throw the assertion if necessary. + * @param cond The condition that should be tested. + */ +#ifdef MALUNAL_ENABLE_ASSERTIONS +#define assert(cond) \ + assertmsg(cond, (malunal_cstr_t)0) +#else /* Do not enable assertions. */ +#define assert(cond) +#endif /* MALUNAL_ENABLE_ASSERTIONS */ + +/** + * @def assertmsg + * @brief A preprocessor macro which can test and throw an assertion. + * @details This is the same as @c assert but with the added benefit that it + * can provide an additional developer message. + * @param cond The condition that should be tested. + * @param msg The developer message to add to error message. + */ +#ifdef MALUNAL_ENABLE_ASSERTIONS +#define assertmsg(cond, msg) \ + assert_test(cond, #cond, msg, __FILE__, __LINE__) +#else /* Do not enable assertions. */ +#define assertmsg(cond, msg) +#endif /* MALUNAL_ENABLE_ASSERTIONS */ + + +/** + * @brief A function pointer type declaration. + * @details Allows the ability to handle an assertion failure manually instead + * of the application automatically dumping and exiting. + * @param expr Why the assertion failed. + * @param msg Why the assertion failed, extra. + * @param file The file in which the assertion failed. + * @param line the line in which the assertion failed. + */ +typedef malunal_void_t +(*assertion_handler_pfn_t)( + malunal_cstr_t expr, + malunal_cstr_t msg, + malunal_cstr_t file, + malunal_int32_t line +); + +/** + * @brief Sets the global assertion handler. + * @details Provides the capability for developers to catch an assertion and + * handle it manually instead of the application automatically dumping + * and exiting. + * @param handler The pointer to the function which will handle the assertion. + */ +malunal_void_t +assertion_handler( + assertion_handler_pfn_t handler +); + +/** + * @brief Tests the given condition. + * @details When the condition fails, this will pass the information to the + * failure function which is responsible for handling the failure. + * @param cond The condition being asserted. + * @param expr The expression being asserted. + * @param msg The developer message about the assertion. + * @param file The file in which the assertion is taking place. + * @param line The line in which the assertion is taking place. + */ +malunal_void_t +assert_test( + malunal_bool_t cond, + malunal_cstr_t expr, + malunal_cstr_t msg, + malunal_cstr_t file, + malunal_int32_t line +); + +/** + * @brief Reports that an assertion has failed. + * @details This will pass the information to the global assertion handler if + * one is set, otherwise it will print the error message and abort the + * application. + * @param expr The expression that failed. + * @param msg The developer message about the assertion. + * @param file The file in which the assertion failed. + * @param line The line in which the assertion failed. + */ +malunal_void_t +assert_failed( + malunal_cstr_t expr, + malunal_cstr_t msg, + malunal_cstr_t file, + malunal_int32_t line +); + +#endif /* MALUNAL_ASSERT_HEADER */ diff --git a/sources/assert.c b/sources/assert.c new file mode 100644 index 0000000..c8be834 --- /dev/null +++ b/sources/assert.c @@ -0,0 +1,42 @@ +// TODO: Replace standard headers when possible. +#include +#include "malunal/assert.h" + +static +assertion_handler_pfn_t +g_handler; + +malunal_void_t +assertion_handler( + assertion_handler_pfn_t handler +) { + g_handler = handler; +} + +malunal_void_t +assertion_test( + malunal_bool_t cond, + malunal_cstr_t expr, + malunal_cstr_t msg, + malunal_cstr_t file, + malunal_int32_t line +) { + if (!cond) assertion_failed(expr, msg, file, line); +} + +malunal_void_t +assertion_failed( + malunal_cstr_t expr, + malunal_cstr_t msg, + malunal_cstr_t file, + malunal_int32_t line +) { + if (g_handler != null) + return (*g_handler)(expr, msg, file, line); + + malunal_cstr_t format = msg != null + ? "%s:%d '%s' Assertion Failed!\n ↳ %s\n" + : "%s:%d '%s' Assertion Failed!\n"; + fprintf(stderr, format, file, line, expr, msg); + abort(); +}