aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMosder <xmosder12@gmail.com>2026-08-21 11:50:51 +0200
committerMosder <xmosder12@gmail.com>2026-08-21 11:50:51 +0200
commitb6b7a01987dca604a161c8c73a240ec4430baed0 (patch)
treeb9fdeb674ad767ccb16d1a3cdc2c6c975ea11737
parent890a52b9af6e24015048eb2754552b9613484b3f (diff)
refactor: renamed mem/alloc.h to safe.h and made it be a collection of "safe" wrappers for "unsafe" functions
-rw-r--r--Makefile8
-rw-r--r--README.md4
-rw-r--r--include/moslib.h2
-rw-r--r--include/moslib/ds/array.h2
-rw-r--r--include/moslib/mem/alloc.h50
-rw-r--r--include/moslib/safe.h37
-rw-r--r--include/moslib/string.h2
-rw-r--r--src/ds/array.c2
-rw-r--r--src/mem/alloc.c45
-rw-r--r--src/safe.c42
-rw-r--r--tests/mem/alloc_tests.h3
-rw-r--r--tests/safe_tests.c (renamed from tests/mem/alloc_tests.c)27
-rw-r--r--tests/safe_tests.h3
-rw-r--r--tests/tests.c4
14 files changed, 113 insertions, 118 deletions
diff --git a/Makefile b/Makefile
index 0c4622b..6fc62cd 100644
--- a/Makefile
+++ b/Makefile
@@ -16,19 +16,17 @@ static: compile headers
headers:
sudo cp -r include/* /usr/local/include
-compile: memory structures
+compile: structures
$(CC) $(CFLAGS) -c src/tester.c
+ $(CC) $(CFLAGS) -c src/safe.c
$(CC) $(CFLAGS) -c src/string.c
-memory:
- $(CC) $(CFLAGS) -c src/mem/alloc.c
-
structures:
$(CC) $(CFLAGS) -c src/ds/array.c
$(CC) $(CFLAGS) -c src/ds/hashmap.c
test:
- $(CC) $(CFLAGS_TEST) -c tests/mem/alloc_tests.c
+ $(CC) $(CFLAGS_TEST) -c tests/safe_tests.c
$(CC) $(CFLAGS_TEST) -c tests/ds/array_tests.c
$(CC) $(CFLAGS_TEST) -c tests/string_tests.c
$(CC) $(CFLAGS_TEST) -c tests/ds/hashmap_tests.c
diff --git a/README.md b/README.md
index 9c83639..660a8e7 100644
--- a/README.md
+++ b/README.md
@@ -4,11 +4,11 @@ Just a bunch of useful code for me put into a single lib, so I don't have to imp
Defnitely not the best implementations ever made, but they're mine, so idc.
## Contains:
-- memory management helpers
+- "safe" wrappers for "unsafe" functions
- testing framework
- dynamic array implementation
## Planned:
-- string slices
+- length aware string slices
- hashmap implementation
- a bunch of other stuff most certainly
diff --git a/include/moslib.h b/include/moslib.h
index 777d951..fa549da 100644
--- a/include/moslib.h
+++ b/include/moslib.h
@@ -10,6 +10,6 @@
// This way you can, for example, avoid collisions
#include "moslib/ds/array.h"
-#include "moslib/mem/alloc.h"
+#include "moslib/safe.h"
#include "moslib/string.h"
#include "moslib/tester.h"
diff --git a/include/moslib/ds/array.h b/include/moslib/ds/array.h
index 8f76901..b4c80f5 100644
--- a/include/moslib/ds/array.h
+++ b/include/moslib/ds/array.h
@@ -148,7 +148,7 @@
// ----------------------------------------------------------------------------------------------------
// ===================================== END OF QUICK USAGE GUIDE =====================================
-#include "moslib/mem/alloc.h"
+#include "moslib/safe.h"
#ifndef MOSLIB_DS_ARRAY_H
#define MOSLIB_DS_ARRAY_H
diff --git a/include/moslib/mem/alloc.h b/include/moslib/mem/alloc.h
deleted file mode 100644
index 564c70f..0000000
--- a/include/moslib/mem/alloc.h
+++ /dev/null
@@ -1,50 +0,0 @@
-// moslib/mem/alloc.h
-// Helper functions for general memory management
-
-#include <stddef.h>
-
-#ifndef MOSLIB_MEM_ALLOC_H
-#define MOSLIB_MEM_ALLOC_H
-
-// Attempt count for alloc functions
-#ifndef MOS_MAX_ALLOC_ATTEMPTS
-#define MOS_MAX_ALLOC_ATTEMPTS 3
-#endif // MOS_MAX_ALLOC_ATTEMPTS
-
-#ifndef MOS_FORCE_PREFIXES
-
-#define safe_malloc mos_safe_malloc
-#define safe_realloc mos_safe_realloc
-
-#endif // MOS_FORCE_PREFIXES
-
-// Tries to malloc MOS_MAX_ALLOC_ATTEMPTS times
-// If all attempts fail - exits with EXIT_FAILURE code
-//
-// Arguments:
-// size
-// count of bytes to malloc
-//
-// Returns:
-// pointer to the allocated memory
-#define mos_safe_malloc(size) mos_safe_malloc_fn(size, MOS_MAX_ALLOC_ATTEMPTS, __FILE__, __LINE__, __func__)
-
-// Tries to realloc MOS_MAX_ALLOC_ATTEMPTS times
-// If all attempts fail - exits with EXIT_FAILURE code
-//
-// Arguments:
-// ptr
-// pointer to the memory to realloc
-//
-// size
-// new desired count of bytes of memory
-//
-// Returns:
-// pointer to the reallocated memory
-#define mos_safe_realloc(ptr, size) mos_safe_realloc_fn(ptr, size, MOS_MAX_ALLOC_ATTEMPTS, __FILE__, __LINE__, __func__)
-
-// Function prototypes for macros
-extern void *mos_safe_malloc_fn(size_t size, size_t att, const char *file, int line, const char *func);
-extern void *mos_safe_realloc_fn(void *ptr, size_t size, size_t att, const char *file, int line, const char *func);
-
-#endif // MOSLIB_MEM_ALLOC_H
diff --git a/include/moslib/safe.h b/include/moslib/safe.h
new file mode 100644
index 0000000..8074c31
--- /dev/null
+++ b/include/moslib/safe.h
@@ -0,0 +1,37 @@
+// moslib/safe.h
+// "Safe" wrappers for some "unsafe" functions
+// aka "I don't want to check for NULL every single time" header
+
+#include <stddef.h>
+
+#ifndef MOSLIB_SAFE_H
+#define MOSLIB_SAFE_H
+
+#ifndef MOS_FORCE_PREFIXES
+
+#define safe_malloc mos_safe_malloc
+#define safe_calloc mos_safe_calloc
+#define safe_realloc mos_safe_realloc
+
+#endif // MOS_FORCE_PREFIXES
+
+typedef struct {
+ const char *file;
+ int line;
+ const char *func;
+} MosSafeErrInfo;
+
+#define mos_err_info ((MosSafeErrInfo){.file = __FILE__, .line = __LINE__, .func = __func__})
+
+// All of the below function-like macros do the same thing the original functions do
+// They check whether the operation suceeded and if not - they exit with an error message
+#define mos_safe_malloc(size) mos_safe_malloc_fn(size, mos_err_info)
+#define mos_safe_calloc(count, size) mos_safe_calloc_fn(count, size, mos_err_info)
+#define mos_safe_realloc(ptr, size) mos_safe_realloc_fn(ptr, size, mos_err_info)
+
+// Function prototypes for macros
+extern void *mos_safe_malloc_fn(size_t size, MosSafeErrInfo info);
+extern void *mos_safe_calloc_fn(size_t count, size_t size, MosSafeErrInfo info);
+extern void *mos_safe_realloc_fn(void *ptr, size_t size, MosSafeErrInfo info);
+
+#endif // MOSLIB_SAFE_H
diff --git a/include/moslib/string.h b/include/moslib/string.h
index e01c975..bc9efff 100644
--- a/include/moslib/string.h
+++ b/include/moslib/string.h
@@ -549,4 +549,4 @@ extern MosStringSlice mos_ss_find_str(MosStringSlice ss, const char *target);
// utf-8 length
extern size_t mos_ss_utf8_len(MosStringSlice ss);
-#endif // MOSLIB_MEM_ALLOC_H
+#endif // MOSLIB_STRING_H
diff --git a/src/ds/array.c b/src/ds/array.c
index cdaf152..2b28a21 100644
--- a/src/ds/array.c
+++ b/src/ds/array.c
@@ -5,7 +5,7 @@
#include <stdlib.h>
#include <string.h>
-#include "moslib/mem/alloc.h"
+#include "moslib/safe.h"
MosArrHeader *arr2hdr(void *arr) {
return (MosArrHeader *)arr - 1;
diff --git a/src/mem/alloc.c b/src/mem/alloc.c
deleted file mode 100644
index 60da131..0000000
--- a/src/mem/alloc.c
+++ /dev/null
@@ -1,45 +0,0 @@
-#define MOS_FORCE_PREFIXES
-#include "moslib/mem/alloc.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#define ERR_MESS(fl, ln, fn, msg) "%s:%d - error in function %s:\n%s\n", fl, ln, fn, msg
-
-void *mos_safe_malloc_fn(size_t size, size_t att, const char *file, int line, const char *func) {
- for (size_t i = 0; i < att; i++) {
- void *p = malloc(size);
- if (p)
- return p;
- if (i < att - 1) {
- fprintf(stderr, ERR_MESS(file, line, func, "malloc failed - retrying in 1s..."));
- sleep(1);
- }
- }
-
- char errmes[64];
- sprintf(errmes, "FATAL: malloc failed %zu times - exiting...", att);
- fprintf(stderr, ERR_MESS(file, line, func, errmes));
- exit(EXIT_FAILURE);
-}
-
-void *mos_safe_realloc_fn(void *ptr, size_t size, size_t att, const char *file, int line, const char *func) {
- if (!ptr)
- return mos_safe_malloc_fn(size, att, file, line, func);
-
- for (size_t i = 0; i < att; i++) {
- void *p = realloc(ptr, size);
- if (p)
- return p;
- if (i < att - 1) {
- fprintf(stderr, ERR_MESS(file, line, func, "realloc failed - retrying in 1s..."));
- sleep(1);
- }
- }
-
- char errmes[64];
- sprintf(errmes, "FATAL: realloc failed %zu times - exiting...", att);
- fprintf(stderr, ERR_MESS(file, line, func, errmes));
- exit(EXIT_FAILURE);
-}
diff --git a/src/safe.c b/src/safe.c
new file mode 100644
index 0000000..7c7627e
--- /dev/null
+++ b/src/safe.c
@@ -0,0 +1,42 @@
+#define MOS_FORCE_PREFIXES
+#include "moslib/safe.h"
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#define ERR_MESS(msg, ...) err_mess(info, msg, __VA_ARGS__)
+
+void err_mess(MosSafeErrInfo info, const char *msg, ...) {
+ va_list args;
+ va_start(args, msg);
+ fprintf(stderr, "%s:%d - fatal error in function %s:\n", info.file, info.line, info.func);
+ vfprintf(stderr, msg, args);
+ fprintf(stderr, "\n");
+ va_end(args);
+}
+
+void *mos_safe_malloc_fn(size_t size, MosSafeErrInfo info) {
+ void *p = malloc(size);
+ if (p)
+ return p;
+ ERR_MESS("failed to malloc %zu bytes", size);
+ exit(EXIT_FAILURE);
+}
+
+void *mos_safe_calloc_fn(size_t count, size_t size, MosSafeErrInfo info) {
+ void *p = calloc(count, size);
+ if (p)
+ return p;
+ ERR_MESS("failed to calloc %zu items of %zu size", count, size);
+ exit(EXIT_FAILURE);
+}
+
+void *mos_safe_realloc_fn(void *ptr, size_t size, MosSafeErrInfo info) {
+ void *p = realloc(ptr, size);
+ if (p)
+ return p;
+ ERR_MESS("failed to realloc %p to %zu bytes", ptr, size);
+ exit(EXIT_FAILURE);
+}
diff --git a/tests/mem/alloc_tests.h b/tests/mem/alloc_tests.h
deleted file mode 100644
index aaf70a4..0000000
--- a/tests/mem/alloc_tests.h
+++ /dev/null
@@ -1,3 +0,0 @@
-#include <moslib/tester.h>
-
-extern void mem_alloc_tests(Tester *tester);
diff --git a/tests/mem/alloc_tests.c b/tests/safe_tests.c
index 5b71887..1d48a48 100644
--- a/tests/mem/alloc_tests.c
+++ b/tests/safe_tests.c
@@ -1,6 +1,5 @@
-#include "alloc_tests.h"
-#define MOS_MAX_ALLOC_ATTEMPTS 1
-#include "moslib/mem/alloc.h"
+#include "safe_tests.h"
+#include "moslib/safe.h"
#include <limits.h>
#include <stdlib.h>
@@ -13,7 +12,7 @@ Test test_safe_malloc() {
void *p = safe_malloc(1024);
test_assert(p != NULL, "Failed to malloc 1KiB");
- suppress_output(&stderr);
+ suppress_output(stderr);
test_assert_exit(malloc_exit, EXIT_FAILURE);
unsuppress_outputs();
}
@@ -23,6 +22,19 @@ Test realloc_exit() {
safe_realloc(p, ULLONG_MAX);
}
+Test calloc_exit() {
+ safe_calloc(ULLONG_MAX, ULLONG_MAX);
+}
+
+Test test_safe_calloc() {
+ void *p = safe_calloc(16, 16);
+ test_assert(p != NULL, "Failed to calloc 16 items of 16 bytes");
+
+ suppress_output(stderr);
+ test_assert_exit(calloc_exit, EXIT_FAILURE);
+ unsuppress_outputs();
+}
+
Test test_safe_realloc() {
void *p = NULL;
p = safe_realloc(p, 1024);
@@ -31,13 +43,14 @@ Test test_safe_realloc() {
p = safe_realloc(p, 4096);
test_assert(p != NULL, "Failed to realloc 1KiB to 4KiB");
- suppress_output(&stderr);
+ suppress_output(stderr);
test_assert_exit(realloc_exit, EXIT_FAILURE);
unsuppress_outputs();
}
-void mem_alloc_tests(Tester *tester) {
- TestGroup *group = add_test_group(tester, "moslib/mem/alloc.h");
+void safe_tests(Tester *tester) {
+ TestGroup *group = add_test_group(tester, "moslib/safe.h");
add_test(group, test_safe_malloc);
+ add_test(group, test_safe_calloc);
add_test(group, test_safe_realloc);
}
diff --git a/tests/safe_tests.h b/tests/safe_tests.h
new file mode 100644
index 0000000..8127b4c
--- /dev/null
+++ b/tests/safe_tests.h
@@ -0,0 +1,3 @@
+#include <moslib/tester.h>
+
+extern void safe_tests(Tester *tester);
diff --git a/tests/tests.c b/tests/tests.c
index d7ce15b..648ab4c 100644
--- a/tests/tests.c
+++ b/tests/tests.c
@@ -2,13 +2,13 @@
#include "ds/array_tests.h"
#include "ds/hashmap_tests.h"
-#include "mem/alloc_tests.h"
+#include "safe_tests.h"
#include "string_tests.h"
int main(void) {
Tester *tester = new_tester();
- mem_alloc_tests(tester);
+ safe_tests(tester);
ds_array_tests(tester);
string_tests(tester);
ds_hashmap_tests(tester);