A collection of C utilities: aligned memory allocation with multiple backends, error handling, dynamic arrays, clamp functions, OpenGL helpers and more.
Portable C library for aligned memory allocation.
Supports Windows, POSIX, C11 and fallback using standard malloc.
am_aligned_realloc(pointer, 0)is not equivalent toam_aligned_free(pointer)- it returnsNULLwithout releasing the memory block.
In C11 the size passed toam_aligned_mallocmust be a multiple of alignment. The library automatically rounds up the size when using the C11 backend.
In C23 this requirement is removed. To avoid unnecessary overhead, the library does not round the size when compiled for C23 support. If your code relies on rounding, ensure the size is a multiple of alignment explicitly.
Flexible assert macros:
assert_m(condition, message)- assertion with a string message.assert_mf(condition, format, ...)- assertion with format (requires C99 or GCC/clang extensions).assert_check_m(condition, message)- evaluatesconditionlike an if check; in debug builds fails on false with an assertion message.assert_check_mf(condition, format, ...)- same asassert_check_mwith format (requires C99 or GCC/clang extensions).static_assert_m(condition, message)- compile-time checks (requires C11 with a string literal or C89 but text will not be accurate).
assert_mandassert_mfare disabled whenNDEBUGis defined.
assert_check_mandassert_check_mfare not disabled byNDEBUG; they still return condition's truth.
static_assert_mis not affected byNDEBUG.
Inline clamping functions.
Supported types: int64_t, uint64_t, size_t, float, double, long double.
For narrower integers (for example int32_t) you can safely cast to the corresponding supported type; otherwise an implicit conversion will occur, which isn't recommended.
Register a cleanup function with optional argument to be called at program exit via atexit.
- Supports one registered function with a single void * argument. Subsequent calls with a new function pointer are ignored.
- The argument pointer can be updated at any time by calling function without a function pointer.
- At least one of the pointers must be non-
NULL(enforced in debug builds). - Requires C99.
Print an error message to stderr and exit with EXIT_FAILURE.
ep_exit_print(format_pointer, ...)- prints a formatted message and exits.ep_exit_print_free(free_flag, format_pointer, ...)- prints formatted message, freesformat_pointeriffree_flagis true andformat_pointeris notNULLand then exit.
format_pointermust be non-NULL(enforced in debug builds).
Dynamic array utilities with automatic resizing and memory management.
da_dynamic_array_ensure_capacity- ensures the array has at leastneededcapacity, growing by a factor of 1.5; if that allocation fails, it attempts to allocate exactlyneededelements and if both allocations fail, returnsfalse.da_dynamic_array_ensure_capacity_list- same asda_dynamic_array_ensure_capacitybut operates on multiple dynamic arrays simultaneously (all resized to the same capacity) to simplify consistent resizing of related arrays. Requires an array ofDA_Dynamic_Array_Liststructures, each specifying the data pointer and element size for the corresponding array.da_dynamic_array_shrink- shrinks capacity to fitamountelements (ifamountsmaller thanbase_amount, capacity is set tobase_amount). If bothamountandbase_amountare0, the array is freed and capacity is zeroed.da_dynamic_array_free- frees the array and nullifies the pointer, size, and capacity.
All functions perform bounds checking and handle allocation failures gracefully.
Requires C99.
Stack-like error message storage and retrieval.
woem_push- formats and stores an error message;woem_push_raw- stores a pre-allocated error message;woem_pop- retrieves the most recent error message and removes it from storage; returns NULL if none exists and also returns flag indicating memory ownership.woem_shrink- shrinks the dynamic storage to the exact number of messages (optimises memory usage).woem_clear- frees all stored messages and resets the storage.
Memory ownership
woem_pushallocate memory internally.woem_push_rawtakes ownership of the passed pointer.woem_popreturns a flag and a pointer, if the flag istruethe caller is responsible for callingfreeon returned pointer.woem_clearfrees all remaining messages.
OpenGL error checking.
gl_errors_clean- clear all pending OpenGL errors.gl_errors_check- check for errors, returnstrueif none, otherwise stores errors viawoem_push.gl_get_error_string- returns a string description for a given OpenGL error code.
Requires OpenGL and GLEW.
Create OpenGL shader program from vertex and fragment sources.
csp_create_shader_program- create a shader program from a single fragment and single vertex shader source code string.csp_create_shader_program_many_sources- creates a program from one or more vertex and fragment source strings.
Fast and lightweight pseudo-random number generator with a minimal overhead, based on linear congruential algorithm and designed for unbiased statistical distribution.
Deterministic by default - seeds are fixed, change it via lcg_set_random64 and lcg_set_random32.
Thread-unsafe - has global seed states which are shared.
Bounded random numbers - function calls lcg_rand32_max(max) and lcg_rand64_max(max) returns values in range of [0; max - 1].
Requires C99.
Portable checked bitwise shifts with well-defined wrapping
sa_safe_shl_<type>- signed left shifts do a bitwise truncation.sa_safe_shr_<type>- signed right shifts are sign-extending.
Return
trueif shift may not be safely performed (or if pointer isNULL),falseon success.
Unsigned shifts are zero-fill. No undefined and implementation-defined behavior for signed types.
Portable overflow-checked integer arithmetic operations without undefined or implementation-defined behavior. Includes addition, subtraction, multiplication, division, mathematical modulus, negation, absolute value, exponentiation.
sa_ovf_add_<type>,sa_ovf_sub_<type>,sa_ovf_mul_<type>- compute on no overflow.sa_ovf_div_<type>- checks for division by zero and potentional overflow.sa_math_mod_<type>- compute mathematical module (negative result is impossible unlike built-in%operator).sa_ovf_neg_<type>- negate a number.sa_ovf_abs_<type>- take absolute value out.sa_ovf_pow_<type>- fast exponentiation by squaring.
Return
trueif overflow occurred,falseon success.
Use _builtin_overflow or <stdckdint.h> if available otherwise portable manual check.
Portable safe file handling operations.
hf_file_read- reads a file into a heap-allocated buffer.hf_file_write- writes data to a file replacing original.hf_file_append- append data to the end of a file.hf_file_copy- copies a file from source to destination.hf_file_rename_move- renames or moves a file (with an additional cross-device copy fallback on POSIX).hf_file_delete- deletes a file.hf_file_size_get- retrieves the size of a file.hf_file_chunk_read- read a chunk of data from a specific position.hf_file_chunk_write- writes a chunk of data at a specific position.hf_file_is_exists- check if a file exists.
Returns
0on success,-1if file closure failed and>0for other errors.
Support Windows, POSIX and standard backends. On windows safely handles UTF-8 paths, absolute path resulotion, UNC paths and long paths exceeding the standard (MAX_PATH) maximal length.
Requires C99
License: Apache 2.0