1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright 2016, Olivier MATZ <zer0@droids-corp.org>
6 * @defgroup alloc Allocation
9 * @brief Helpers to allocate and free memory
11 * Interface to configure the allocator used by libecoli.
12 * By default, the standard allocation functions from libc are used.
18 #include <sys/types.h>
23 * Function type of malloc, passed to ec_malloc_register().
25 * The API is the same than malloc(), excepted the file and line
29 * The size of the memory area to allocate.
31 * The path to the file that invoked the malloc.
33 * The line in the file that invoked the malloc.
35 * A pointer to the allocated memory area, or NULL on error (errno
38 typedef void *(*ec_malloc_t)(size_t size, const char *file, unsigned int line);
41 * Function type of free, passed to ec_malloc_register().
43 * The API is the same than free(), excepted the file and line
47 * The pointer to the memory area to be freed.
49 * The path to the file that invoked the malloc.
51 * The line in the file that invoked the malloc.
53 typedef void (*ec_free_t)(void *ptr, const char *file, unsigned int line);
56 * Function type of realloc, passed to ec_malloc_register().
58 * The API is the same than realloc(), excepted the file and line
62 * The pointer to the memory area to be reallocated.
64 * The path to the file that invoked the malloc.
66 * The line in the file that invoked the malloc.
68 * A pointer to the allocated memory area, or NULL on error (errno
71 typedef void *(*ec_realloc_t)(void *ptr, size_t size, const char *file,
75 * Register allocation functions.
77 * This function can be use to register another allocator
78 * to be used by libecoli. By default, ec_malloc(), ec_free() and
79 * ec_realloc() use the standard libc allocator. Another handler
80 * can be used for debug purposes or when running in a specific
83 * This function must be called before ec_init().
86 * A user-defined malloc function.
88 * A user-defined free function.
90 * A user-defined realloc function.
92 * 0 on success, or -1 on error (errno is set).
94 int ec_malloc_register(ec_malloc_t usr_malloc, ec_free_t usr_free,
95 ec_realloc_t usr_realloc);
97 struct ec_malloc_handler {
100 ec_realloc_t realloc;
103 extern struct ec_malloc_handler ec_malloc_handler;
106 * Allocate a memory area.
108 * Like malloc(), ec_malloc() allocates size bytes and returns a pointer
109 * to the allocated memory. The memory is not initialized. The memory is
110 * freed with ec_free().
113 * The size of the area to allocate in bytes.
115 * The pointer to the allocated memory, or NULL on error (errno is set).
117 #define ec_malloc(size) ({ \
119 if (ec_malloc_handler.malloc == NULL) \
120 ret_ = malloc(size); \
122 ret_ = __ec_malloc(size, __FILE__, __LINE__); \
127 * Ecoli malloc function.
129 * Use this function when the macro ec_malloc() cannot be used,
130 * for instance when it is passed as a callback pointer.
132 void *ec_malloc_func(size_t size);
135 * Free a memory area.
137 * Like free(), ec_free() frees the area pointed by ptr, which must have
138 * been returned by a previous call to ec_malloc() or any other
139 * allocation function of this file.
142 * The pointer to the memory area.
144 #define ec_free(ptr) ({ \
145 if (ec_malloc_handler.free == NULL) \
148 __ec_free(ptr, __FILE__, __LINE__); \
152 * Ecoli free function.
154 * Use this function when the macro ec_free() cannot be used,
155 * for instance when it is passed as a callback pointer.
157 void ec_free_func(void *ptr);
160 * Resize an allocated memory area.
163 * The pointer to the previously allocated memory area, or NULL.
165 * The new size of the memory area.
167 * A pointer to the newly allocated memory, or NULL if the request
168 * fails. In that case, the original area is left untouched.
170 #define ec_realloc(ptr, size) ({ \
172 if (ec_malloc_handler.realloc == NULL) \
173 ret_ = realloc(ptr, size); \
175 ret_ = __ec_realloc(ptr, size, __FILE__, __LINE__); \
180 * Ecoli realloc function.
182 * Use this function when the macro ec_realloc() cannot be used,
183 * for instance when it is passed as a callback pointer.
185 void ec_realloc_func(void *ptr, size_t size);
188 * Allocate and initialize an array of elements.
191 * The number of elements.
193 * The size of each element.
195 * The pointer to the allocated memory, or NULL on error (errno is set).
197 #define ec_calloc(n, size) ({ \
199 if (ec_malloc_handler.malloc == NULL) \
200 ret_ = calloc(n, size); \
202 ret_ = __ec_calloc(n, size, __FILE__, __LINE__); \
207 * Duplicate a string.
209 * Memory for the new string is obtained with ec_malloc(), and can be
210 * freed with ec_free().
213 * The string to be duplicated.
215 * The pointer to the duplicated string, or NULL on error (errno is set).
217 #define ec_strdup(s) ({ \
219 if (ec_malloc_handler.malloc == NULL) \
222 ret_ = __ec_strdup(s, __FILE__, __LINE__); \
227 * Duplicate at most n bytes of a string.
229 * This function is similar to ec_strdup(), except that it copies at
230 * most n bytes. If s is longer than n, only n bytes are copied, and a
231 * terminating null byte ('\0') is added.
234 * The string to be duplicated.
236 * The maximum length of the new string.
238 * The pointer to the duplicated string, or NULL on error (errno is set).
240 #define ec_strndup(s, n) ({ \
242 if (ec_malloc_handler.malloc == NULL) \
243 ret_ = strndup(s, n); \
245 ret_ = __ec_strndup(s, n, __FILE__, __LINE__); \
250 void *__ec_malloc(size_t size, const char *file, unsigned int line);
251 void __ec_free(void *ptr, const char *file, unsigned int line);
252 void *__ec_calloc(size_t nmemb, size_t size, const char *file,
254 void *__ec_realloc(void *ptr, size_t size, const char *file, unsigned int line);
255 char *__ec_strdup(const char *s, const char *file, unsigned int line);
256 char *__ec_strndup(const char *s, size_t n, const char *file,