Updated the copyright headers for 2009.
[pwmd.git] / src / mem.c
blobca3e548be8295bc05387850de9463fa84c695e9f
1 /* vim:tw=78:ts=8:sw=4:set ft=c: */
2 /*
3 Copyright (C) 2006-2009 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 02110-1301 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 #ifdef HAVE_CONFIG_H
27 #include <config.h>
28 #endif
30 #include "gettext.h"
31 #define N_(msgid) gettext(msgid)
33 #include "mem.h"
35 static struct memlist_s *memlist;
36 #ifdef DEBUG
37 static size_t allocations, deallocations;
38 #endif
40 static int memlist_remove(void *ptr, const char *func)
42 struct memlist_s *m, *last = NULL, *p;
43 int found = 0;
45 for (m = memlist; m; m = m->next) {
46 if (m->ptr == ptr) {
47 #ifdef DEBUG
48 fprintf(stderr, "%s: %p %i\n", func, ptr, m->size);
49 #endif
50 found = 1;
51 memset(m->ptr, 0, m->size);
52 free(m->ptr);
54 p = m->next;
55 free(m);
56 #ifdef DEBUG
57 deallocations++;
58 #endif
60 if (last) {
61 if (p)
62 last->next = p;
63 else
64 last->next = NULL;
66 else if (p)
67 memlist = p;
68 else
69 memlist = NULL;
71 break;
74 last = m;
77 return found;
80 static void memlist_prepend(struct memlist_s *new)
82 #ifdef DEBUG
83 allocations++;
84 #endif
85 new->next = memlist;
86 memlist = new;
89 void xfree(void *ptr)
91 if (!ptr)
92 return;
94 if (!memlist_remove(ptr, __FUNCTION__)) {
95 warnx(N_("%s: %p not found"), __FUNCTION__, ptr);
96 assert(0);
100 void *xmalloc(size_t size)
102 void *p;
103 struct memlist_s *m;
105 if (size <= 0)
106 return NULL;
108 if ((m = (struct memlist_s *)malloc(sizeof(struct memlist_s))) == NULL)
109 return NULL;
111 if ((p = malloc(size)) == NULL) {
112 free(m);
113 return NULL;
116 m->ptr = p;
117 m->size = size;
118 memlist_prepend(m);
119 #ifdef DEBUG
120 fprintf(stderr, "%s: %p %i\n", __FUNCTION__, p, size);
121 #endif
122 return m->ptr;
125 void *xcalloc(size_t nmemb, size_t size)
127 void *p;
128 struct memlist_s *m;
130 if (size <= 0)
131 return NULL;
133 if ((m = (struct memlist_s *)malloc(sizeof(struct memlist_s))) == NULL)
134 return NULL;
136 if ((p = calloc(nmemb, size)) == NULL) {
137 free(m);
138 return NULL;
141 m->ptr = p;
142 m->size = nmemb * size;
143 memlist_prepend(m);
144 #ifdef DEBUG
145 fprintf(stderr, "%s: %p %i\n", __FUNCTION__, p, nmemb * size);
146 #endif
147 return m->ptr;
150 void *xrealloc(void *ptr, size_t size)
152 void *p;
153 struct memlist_s *m;
155 if (!ptr)
156 return xmalloc(size);
158 if (size <= 0)
159 return ptr;
161 for (m = memlist; m; m = m->next) {
162 if (m->ptr == ptr) {
163 if ((p = malloc(size)) == NULL)
164 return NULL;
166 memcpy(p, m->ptr, size < m->size ? size : m->size);
167 memset(m->ptr, 0, m->size);
168 free(m->ptr);
169 m->ptr = p;
170 m->size = size;
171 #ifdef DEBUG
172 fprintf(stderr, "%s: %p %i\n", __FUNCTION__, p, size);
173 #endif
174 return m->ptr;
178 warnx(N_("%s: %p not found"), __FUNCTION__, ptr);
179 assert(0);
180 return NULL;
183 char *xstrdup(const char *str)
185 char *t, *tp;
186 size_t len;
187 const char *p;
189 if (!str)
190 return NULL;
192 len = strlen(str) + 1;
194 if ((t = (char *)xmalloc(len * sizeof(char))) == NULL)
195 return NULL;
197 for (p = str, tp = t; *p; p++)
198 *tp++ = *p;
200 *tp = 0;
201 #ifdef DEBUG
202 fprintf(stderr, "%s: %p\n", __FUNCTION__, t);
203 #endif
204 return t;
207 void xpanic(void)
209 struct memlist_s *m;
211 for (m = memlist; m; m = memlist)
212 xfree(m->ptr);
215 #ifdef DEBUG
216 void xdump(void)
218 struct memlist_s *m;
219 size_t total = 0;
221 for (m = memlist; m; m = m->next) {
222 fprintf(stderr, "%s: %p %i\n", __FUNCTION__, m->ptr, m->size);
223 total += m->size;
226 fprintf(stderr, "Total unfreed: %i bytes, allocations: %i, deallocations: %i\n", total,
227 allocations, deallocations);
229 #endif