summaryrefslogtreecommitdiff
path: root/src/shared.h
diff options
context:
space:
mode:
author@syxhe <https://t.me/syxhe>2025-06-09 17:43:50 -0500
committer@syxhe <https://t.me/syxhe>2025-06-09 17:51:14 -0500
commit1444c72db8505340c0988ea286a29bc261297933 (patch)
tree22d52285ab36b440d02b20aa5f680c75c0c0dbaf /src/shared.h
parent682c6e29e5b2546ff586a55cea8b81a8c072d3ee (diff)
We do a little documentation
Diffstat (limited to 'src/shared.h')
-rw-r--r--src/shared.h143
1 files changed, 125 insertions, 18 deletions
diff --git a/src/shared.h b/src/shared.h
index 3ff7b2d..6276281 100644
--- a/src/shared.h
+++ b/src/shared.h
@@ -1,28 +1,41 @@
1/**
2 * @file shared.h
3 * @author syxhe (https://t.me/syxhe)
4 * @brief A collection of functions and macros shared between files, or without a better place
5 * @version 0.1
6 * @date 2025-06-09
7 *
8 * @copyright Copyright (c) 2025
9 *
10 */
11
1#ifndef __VXGG_REWRITE___SHARED_H___3880294315821___ 12#ifndef __VXGG_REWRITE___SHARED_H___3880294315821___
2#define __VXGG_REWRITE___SHARED_H___3880294315821___ 1 13#define __VXGG_REWRITE___SHARED_H___3880294315821___ 1
3 14
4#include <stddef.h> 15#include <stddef.h>
5 16
6typedef int (*gcallback)(void*); // Generic callback signature 17typedef int (*gcallback)(void*); //!< Generic callback signature
7typedef void (*fcallback)(void*); // free()-like callback signature 18typedef void (*fcallback)(void*); //!< free()-like callback signature
8 19
20//! Get the size of a statically/vla defined array. Doesn't work on arrays allocated via `malloc()`
9#define STATIC_ARRAY_LEN(arr) (sizeof((arr))/sizeof((arr)[0])) 21#define STATIC_ARRAY_LEN(arr) (sizeof((arr))/sizeof((arr)[0]))
10 22
23//! Sets errno to `errval`, then returns `retval`. Defined as a macro because it is meant for use inside functions, not as a function itself
11#define ERRRET(errval, retval) do {\ 24#define ERRRET(errval, retval) do {\
12 errno = (errval);\ 25 errno = (errval);\
13 return (retval);\ 26 return (retval);\
14} while (0) 27} while (0)
15 28
16// Defines how `x___alloc()` functions should exit. `___VXGG___XALLOC_EXIT_ON_ERROR___ > 0` calls `error()`, and thus functions 29/// Defines how `x___alloc()` functions should exit. `___VXGG___XALLOC_EXIT_ON_ERROR___ > 0` calls `error()`, and thus functions
17// registered with `atexit()` and `on_exit()`. `___VXGG___XALLOC_EXIT_ON_ERROR___ <= 0` calls `abort()` on error. `x___alloc()` 30/// registered with `atexit()` and `on_exit()`. `___VXGG___XALLOC_EXIT_ON_ERROR___ <= 0` calls `abort()` on error. `x___alloc()`
18// type functions will ALWAYS 'abort', doing otherwise defeats the purpose of the function type 31/// type functions will ALWAYS 'abort', doing otherwise defeats the purpose of the function type
19#define ___VXGG___XALLOC_EXIT_ON_ERROR___ 1 32#define ___VXGG___XALLOC_EXIT_ON_ERROR___ 1
20 33
21// Defines whether vxgg functions that can error print out a short warning of the error when one is encountered. 34/// Defines whether vxgg functions that can error print out a short warning of the error when one is encountered.
22// `___VXGG___VERBOSE_ERRORS___ > 0` will print diagnostic error messages, and will do nothing otherwise 35/// `___VXGG___VERBOSE_ERRORS___ > 0` will print diagnostic error messages, and will do nothing otherwise
23#define ___VXGG___VERBOSE_ERRORS___ 1 36#define ___VXGG___VERBOSE_ERRORS___ 1
24 37
25// Macro to exit on an alloc error instead of doing the terrible nested if statement that was being used previously 38//! Macro to exit on an alloc error instead of doing the terrible nested if statement that was being used previously
26#define XALLOC_EXIT(msg, ...) do {\ 39#define XALLOC_EXIT(msg, ...) do {\
27 if(!___VXGG___XALLOC_EXIT_ON_ERROR___)\ 40 if(!___VXGG___XALLOC_EXIT_ON_ERROR___)\
28 abort();\ 41 abort();\
@@ -33,37 +46,122 @@ typedef void (*fcallback)(void*); // free()-like callback signature
33} while (0) 46} while (0)
34 47
35 48
49//! Holdover macro because I'm lazy. Used to call either malloc or xmalloc, but the xalloc functions were a bad idea, so I removed them
36#define VALLOC(nmemb, size) malloc((nmemb) * (size)) 50#define VALLOC(nmemb, size) malloc((nmemb) * (size))
37 51
38// Error macro that gcc will not complain about 52//! Error macro that gcc will not complain about
39#define ERROR(status, errnum, format, ...) do {error((status), (errnum), (format)__VA_ARGS__); exit((status));} while (0) 53#define ERROR(status, errnum, format, ...) do {error((status), (errnum), (format)__VA_ARGS__); exit((status));} while (0)
40// Spit out a warning using `error` 54//! Spit out a warning using `error`
41#define WARN(errnum, format, ...) do {error(0, (errnum), (format)__VA_ARGS__);} while (0) 55#define WARN(errnum, format, ...) do {error(0, (errnum), (format)__VA_ARGS__);} while (0)
42 56
43// Read the entire contents of a file descriptor into a malloc()'ed buffer 57
58
59/**
60 * @brief Read the entire contents of a file descriptor into a malloc()'ed buffer
61 *
62 * @param str Pointer to a string. Will be replaced with the malloc()'ed string
63 * @param initsize The initial size of the malloc()'ed string
64 * @param fd A file descriptor to read from
65 * @return int Returns the size of the array on success, or -1 on error
66 * @note The allocated buffer will expand and contract as necessary, but it's recommended to set `initsize` to some value close to or equal to the size of the file being read to reduce the number of resizes
67 */
44int rwbuf(char **str, unsigned long int initsize, int fd); 68int rwbuf(char **str, unsigned long int initsize, int fd);
45// Write the entire contents of a buffer into a file descriptor 69
70/**
71 * @brief Write the entire contents of a buffer into a file descriptor
72 *
73 * @param fd The file descriptor to write to
74 * @param buf The buffer to write from
75 * @param len The length of the buffer
76 * @return int Returns 0 on success, -1 on error
77 */
46int wwbuf(int fd, const unsigned char *buf, int len); 78int wwbuf(int fd, const unsigned char *buf, int len);
47// `dirname()` reimplementation that returns a malloc()'ed string 79
80
81
82/**
83 * @brief `dirname()` reimplementation that returns a malloc()'ed string
84 *
85 * @param path The filepath to be inspected
86 * @return char* Returns a null-terminated string on success, or `null` on error
87 */
48char * vxdirname(const char * const path); 88char * vxdirname(const char * const path);
49 89
50 90
51 91
52// A locally defined structure designed for easier function cleanup 92/**
93 * @brief A locally defined structure designed for easier function cleanup
94 *
95 */
53typedef struct cl { 96typedef struct cl {
54 fcallback *callbacks; // Actual Type: fcallback callbacks[] 97 fcallback *callbacks; //!< An array of free()-like callbacks. Actual Type: fcallback callbacks[]
55 void * *arguments; // Actual Type: void *arguments[] 98 void * *arguments; //!< An array of void pointers. Actual Type: void *arguments[]
56 int size; 99 int size; //!< The size of each array
57 int used; 100 int used; //!< The current number of used elements in each array
58} cleanup; 101} cleanup;
59 102
103/**
104 * @brief Initialize a cleanup object
105 *
106 * @param loc The cleanup object to be initialized
107 * @param callbacks An array of free()-like callbacks. Must be `size` elements long
108 * @param arguments An array of void pointers. Must be `size` elements long
109 * @param size The number of elements the callbacks and arguments array are long
110 * @return int Returns 0 on success, -1 on error
111 */
60int cleanup_init(cleanup *loc, fcallback callbacks[], void *arguments[], int size); 112int cleanup_init(cleanup *loc, fcallback callbacks[], void *arguments[], int size);
113
114/**
115 * @brief Register a new callback and argument onto a cleanup stack
116 *
117 * @param loc The cleanup object to modify
118 * @param cb A free()-like callback to run
119 * @param arg A piece of data for the callback to run
120 * @return int Returns 0 on success, -1 on error
121 */
61int cleanup_register(cleanup *loc, fcallback cb, void *arg); 122int cleanup_register(cleanup *loc, fcallback cb, void *arg);
123
124/**
125 * @brief Conditionally register a callback and argument
126 *
127 * @param loc The cleanup object to modify
128 * @param cb A free()-like callback to run
129 * @param arg A piece of data for the callback to run
130 * @param flag Whether or not the register should take place. Will not run if `flag` is non-zero
131 * @return int Returns 0 on success or skip, -1 on error
132 */
62int cleanup_cndregister(cleanup *loc, fcallback cb, void *arg, unsigned char flag); 133int cleanup_cndregister(cleanup *loc, fcallback cb, void *arg, unsigned char flag);
134
135/**
136 * @brief Clear a cleanup object
137 * @attention Does not free any registered callbacks or arguments, just marks them as available space
138 *
139 * @param loc The cleanup object to modify
140 * @return int Returns 0 on success, -1 on error
141 */
63int cleanup_clear(cleanup *loc); 142int cleanup_clear(cleanup *loc);
143
144/**
145 * @brief Fires all the registered callbacks and arguments in a cleanup object in FIFO (stack) order
146 *
147 * @param loc The cleanup object to fire
148 * @return int Returns 0 on success, -1 on error
149 */
64int cleanup_fire(cleanup *loc); 150int cleanup_fire(cleanup *loc);
151
152/**
153 * @brief Conditionally fires a cleanup object
154 *
155 * @param loc The cleanup object in question
156 * @param flag Whether the object should be fired. Will skip firing if non-zero
157 * @return int Returns 0 on success, -1 on error
158 */
65int cleanup_cndfire(cleanup *loc, unsigned char flag); 159int cleanup_cndfire(cleanup *loc, unsigned char flag);
66 160
161/**
162 * @brief Initializes a set of variables suitable for use in the cleanup macros
163 * @param size The number of elements long each array should be
164 */
67#define cleanup_CREATE(size) \ 165#define cleanup_CREATE(size) \
68cleanup __CLEANUP; \ 166cleanup __CLEANUP; \
69fcallback __CLEANUP_FUNCS[(size)]; \ 167fcallback __CLEANUP_FUNCS[(size)]; \
@@ -71,14 +169,23 @@ void *__CLEANUP_ARGS[(size)]; \
71unsigned char __FLAG = 0; \ 169unsigned char __FLAG = 0; \
72cleanup_init(&__CLEANUP, __CLEANUP_FUNCS, __CLEANUP_ARGS, (size)) 170cleanup_init(&__CLEANUP, __CLEANUP_FUNCS, __CLEANUP_ARGS, (size))
73 171
172//! Register a callback-argument pair using the local cleanup object
74#define cleanup_REGISTER(cb, arg) cleanup_register(&__CLEANUP, (cb), (arg)) 173#define cleanup_REGISTER(cb, arg) cleanup_register(&__CLEANUP, (cb), (arg))
174//! Conditionally register a callback-argument pair using the local cleanup object
75#define cleanup_CNDREGISTER(cb, arg) cleanup_cndregister(&__CLEANUP, (cb), (arg), __FLAG) 175#define cleanup_CNDREGISTER(cb, arg) cleanup_cndregister(&__CLEANUP, (cb), (arg), __FLAG)
176//! Clean the local cleanup object
76#define cleanup_CLEAR() cleanup_clear(&__CLEANUP) 177#define cleanup_CLEAR() cleanup_clear(&__CLEANUP)
178//! Fire the local cleanup object
77#define cleanup_FIRE() cleanup_fire(&__CLEANUP) 179#define cleanup_FIRE() cleanup_fire(&__CLEANUP)
180//! Conditionally fire the local cleanup object
78#define cleanup_CNDFIRE() cleanup_cndfire(&__CLEANUP, __FLAG) 181#define cleanup_CNDFIRE() cleanup_cndfire(&__CLEANUP, __FLAG)
182//! Set the local cleanup flag to a non-zero number
79#define cleanup_MARK() (__FLAG = 1) 183#define cleanup_MARK() (__FLAG = 1)
184//! Set the local cleanup flag to zero
80#define cleanup_UNMARK() (__FLAG = 0) 185#define cleanup_UNMARK() (__FLAG = 0)
186//! Check if the local cleanup flag is non-zero
81#define cleanup_ERRORFLAGGED (__FLAG != 0) 187#define cleanup_ERRORFLAGGED (__FLAG != 0)
188//! Conditionally execute some `code` if the local cleanup flag has not been marked
82#define cleanup_CNDEXEC(code) while(!cleanup_ERRORFLAGGED) {code; break;} 189#define cleanup_CNDEXEC(code) while(!cleanup_ERRORFLAGGED) {code; break;}
83 190
84#endif \ No newline at end of file 191#endif \ No newline at end of file