Compile will Valgrind support even when DEBUG is not defined. The
[pwmd.git] / src / mem.c
blob8db5b3b6ba5602760ebd17283b5cd924f5e66883
1 /* vim:tw=78:ts=8:sw=4:set ft=c: */
2 /*
3 Copyright (C) 2006-2007 Ben Kibbey <bjk@luxsci.net>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <unistd.h>
22 #include <string.h>
23 #include <assert.h>
24 #include <err.h>
26 #include "mem.h"
28 static struct memlist_s *memlist;
30 static struct memlist_s *memlist_remove(struct memlist_s *list, struct memlist_s *r)
32 struct memlist_s *m, *last = NULL, *p;
34 for (m = list; m; m = m->next) {
35 if (m->ptr == r->ptr) {
36 memset(m->ptr, 0, m->size);
37 free(m->ptr);
39 if (RUNNING_ON_VALGRIND)
40 VALGRIND_FREELIKE_BLOCK(m->ptr, 0);
42 p = m->next;
43 free(m);
45 if (RUNNING_ON_VALGRIND)
46 VALGRIND_FREELIKE_BLOCK(m, 0);
48 if (last) {
49 if (p)
50 last->next = p;
51 else
52 last->next = NULL;
54 else if (p)
55 list = p;
56 else
57 list = NULL;
59 break;
62 last = m;
65 return list;
68 static struct memlist_s *memlist_append(struct memlist_s *list, struct memlist_s *p)
70 struct memlist_s *m;
72 if (!list) {
73 list = p;
74 list->next = NULL;
75 return list;
78 for (m = list; m; m = m->next) {
79 if (!m->next) {
80 m->next = p;
81 m = m->next;
82 m->next = NULL;
83 break;
87 return list;
90 void xfree(void *ptr)
92 struct memlist_s *m;
94 if (!ptr)
95 return;
97 for (m = memlist; m; m = m->next) {
98 if (m->ptr == ptr) {
99 #ifdef DEBUG
100 fprintf(stderr, "xfree(): %p %i\n", ptr, m->size);
101 #endif
102 memlist = memlist_remove(memlist, m);
103 return;
107 warnx("xfree(): %p not found", ptr);
108 assert(0);
111 void *xmalloc(size_t size)
113 void *p;
114 struct memlist_s *m;
116 if (size <= 0)
117 return NULL;
119 if ((m = (struct memlist_s *)malloc(sizeof(struct memlist_s))) == NULL)
120 return NULL;
122 if (RUNNING_ON_VALGRIND)
123 VALGRIND_MALLOCLIKE_BLOCK(m, sizeof(struct memlist_s), 0, 0);
125 if ((p = malloc(size)) == NULL) {
126 free(m);
128 if (RUNNING_ON_VALGRIND)
129 VALGRIND_FREELIKE_BLOCK(m, 0);
131 return NULL;
134 if (RUNNING_ON_VALGRIND)
135 VALGRIND_MALLOCLIKE_BLOCK(p, size, 0, 0);
137 m->ptr = p;
138 m->size = size;
139 memlist = memlist_append(memlist, m);
140 #ifdef DEBUG
141 fprintf(stderr, "xmalloc(): %p %i\n", p, size);
142 #endif
143 return m->ptr;
146 void *xcalloc(size_t nmemb, size_t size)
148 void *p;
149 struct memlist_s *m;
151 if (size <= 0)
152 return NULL;
154 if ((m = (struct memlist_s *)malloc(sizeof(struct memlist_s))) == NULL)
155 return NULL;
157 if (RUNNING_ON_VALGRIND)
158 VALGRIND_MALLOCLIKE_BLOCK(m, sizeof(struct memlist_s), 0, 0);
160 if ((p = calloc(nmemb, size)) == NULL) {
161 free(m);
163 if (RUNNING_ON_VALGRIND)
164 VALGRIND_FREELIKE_BLOCK(m, 0);
166 return NULL;
169 if (RUNNING_ON_VALGRIND)
170 VALGRIND_MALLOCLIKE_BLOCK(p, nmemb * size, 0, 1);
172 m->ptr = p;
173 m->size = nmemb * size;
174 memlist = memlist_append(memlist, m);
175 #ifdef DEBUG
176 fprintf(stderr, "xcalloc(): %p %i\n", p, nmemb * size);
177 #endif
178 return m->ptr;
181 void *xrealloc(void *ptr, size_t size)
183 void *p;
184 struct memlist_s *m;
186 if (!ptr)
187 return xmalloc(size);
189 if (size <= 0)
190 return ptr;
192 for (m = memlist; m; m = m->next) {
193 if (m->ptr == ptr) {
194 if ((p = malloc(size)) == NULL)
195 return NULL;
197 if (RUNNING_ON_VALGRIND)
198 VALGRIND_MALLOCLIKE_BLOCK(p, size, 0, 0);
200 memcpy(p, m->ptr, (size < m->size) ? size : m->size);
201 memset(m->ptr, 0, m->size);
202 free(m->ptr);
204 if (RUNNING_ON_VALGRIND)
205 VALGRIND_FREELIKE_BLOCK(m->ptr, 0);
207 m->ptr = p;
208 m->size = size;
209 #ifdef DEBUG
210 fprintf(stderr, "xrealloc(): %p %i\n", p, size);
211 #endif
212 return m->ptr;
216 warnx("xrealloc(): %p not found", ptr);
217 assert(0);
218 return NULL;
221 char *xstrdup(const char *str)
223 char *t, *tp;
224 size_t len;
225 const char *p;
227 if (!str)
228 return NULL;
230 len = strlen(str) + 1;
232 if ((t = (char *)xmalloc(len * sizeof(char))) == NULL)
233 return NULL;
235 for (p = str, tp = t; *p; p++)
236 *tp++ = *p;
238 *tp = 0;
239 #ifdef DEBUG
240 fprintf(stderr, "xstrdup(): %p\n", t);
241 #endif
242 return t;
245 void xpanic(void)
247 #ifndef DEBUG
248 struct memlist_s *m;
250 for (m = memlist; m; m = memlist)
251 xfree(m->ptr);
252 #endif