1 /** These routines represent handling of struct memory_list.
13 #include "util/error.h"
14 #include "util/memlist.h"
15 #include "util/memory.h"
20 * memory_list is used to track information about all allocated memory
21 * belonging to something. Then we can free it when we won't need it
22 * anymore, but the one who allocated it won't be able to get control
23 * back in order to free it himself.
26 #define ML_SIZE(n) (sizeof(struct memory_list) + (n) * sizeof(void *))
28 /** Create a memory list. If @a p is NULL or allocation fails, it will
30 * It always stops at first NULL element.
31 * @relates memory_list */
32 #if defined(DEBUG_MEMLIST) && defined(HAVE_VARIADIC_MACROS)
34 debug_getml(unsigned char *file
, int line
, void *p
, ...)
40 struct memory_list
*ml
;
45 /* If first element is NULL, there's no need to allocate memory, so
49 /* How many elements ? */
51 while ((q
= va_arg(ap
, void *))) n
++;
54 /* Allocate space for memory list. */
55 ml
= mem_alloc(ML_SIZE(n
));
64 while ((q
= va_arg(ap
, void *))) ml
->p
[ml
->n
++] = q
;
71 /** Add elements to a memory list.
72 * If memory list exists, it enlarges it, else it creates it.
73 * if there's no elements or first element is NULL, it does nothing.
74 * It always stops at first NULL element.
75 * @relates memory_list */
76 #if defined(DEBUG_MEMLIST) && defined(HAVE_VARIADIC_MACROS)
78 debug_add_to_ml(unsigned char *file
, int line
, struct memory_list
**ml
, ...)
81 add_to_ml(struct memory_list
**ml
, ...)
88 /* How many new elements ? */
90 while ((q
= va_arg(ap
, void *))) n
++;
93 /* None, so just return. */
96 #ifdef HAVE_VARIADIC_MACROS
97 errline
= line
, errfile
= file
;
99 errline
= 0, errfile
= "?";
101 elinks_error("add_to_ml(%p, NULL, ...)", ml
);
107 /* If getml() wasn't called before or returned NULL,
108 * then we create it. */
109 *ml
= mem_alloc(ML_SIZE(n
));
114 /* Enlarge existing ml. */
115 struct memory_list
*nml
;
117 nml
= mem_realloc(*ml
, ML_SIZE(n
+ (*ml
)->n
));
123 /* Set ml with new elements and update count. */
125 while ((q
= va_arg(ap
, void *))) (*ml
)->p
[(*ml
)->n
++] = q
;
129 /** @relates memory_list */
132 debug_add_one_to_ml(unsigned char *file
, int line
, struct memory_list
**ml
, void *p
)
135 add_one_to_ml(struct memory_list
**ml
, void *p
)
138 /* None, so just return. */
141 errline
= line
, errfile
= file
;
142 elinks_error("add_one_to_ml(%p, NULL)", ml
);
148 /* If getml() wasn't called before or returned NULL,
149 * then we create it. */
150 *ml
= mem_alloc(ML_SIZE(1));
155 /* Enlarge existing ml. */
156 struct memory_list
*nml
;
158 nml
= mem_realloc(*ml
, ML_SIZE(1 + (*ml
)->n
));
164 /* Set ml with new element and update count. */
165 (*ml
)->p
[(*ml
)->n
++] = p
;
169 /** Free elements and memory list.
170 * It returns safely if passed a NULL pointer.
171 * @relates memory_list */
173 freeml(struct memory_list
*ml
)
179 for (i
= 0; i
< ml
->n
; i
++)