Prepend memory elements rather than appending them to the list.
[pwmd.git] / src / mem.c
blob4ba4eb9aaf3229b87fe41fca8a548cfc875f6629
1 /* vim:tw=78:ts=8:sw=4:set ft=c: */
2 /*
3 Copyright (C) 2006-2008 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 #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;
37 static struct memlist_s *memlist_remove(struct memlist_s *list, struct memlist_s *r)
39 struct memlist_s *m, *last = NULL, *p;
41 for (m = list; m; m = m->next) {
42 if (m->ptr == r->ptr) {
43 memset(m->ptr, 0, m->size);
44 free(m->ptr);
46 p = m->next;
47 free(m);
49 if (last) {
50 if (p)
51 last->next = p;
52 else
53 last->next = NULL;
55 else if (p)
56 list = p;
57 else
58 list = NULL;
60 break;
63 last = m;
66 return list;
69 static struct memlist_s *memlist_prepend(struct memlist_s *list, struct memlist_s *p)
71 p->next = list;
72 return p;
75 void xfree(void *ptr)
77 struct memlist_s *m;
79 if (!ptr)
80 return;
82 for (m = memlist; m; m = m->next) {
83 if (m->ptr == ptr) {
84 #ifdef DEBUG
85 fprintf(stderr, "%s: %p %i\n", __FUNCTION__, ptr, m->size);
86 #endif
87 memlist = memlist_remove(memlist, m);
88 return;
92 warnx(N_("%s: %p not found"), __FUNCTION__, ptr);
93 assert(0);
96 void *xmalloc(size_t size)
98 void *p;
99 struct memlist_s *m;
101 if (size <= 0)
102 return NULL;
104 if ((m = (struct memlist_s *)malloc(sizeof(struct memlist_s))) == NULL)
105 return NULL;
107 if ((p = malloc(size)) == NULL) {
108 free(m);
109 return NULL;
112 m->ptr = p;
113 m->size = size;
114 memlist = memlist_prepend(memlist, m);
115 #ifdef DEBUG
116 fprintf(stderr, "%s: %p %i\n", __FUNCTION__, p, size);
117 #endif
118 return m->ptr;
121 void *xcalloc(size_t nmemb, size_t size)
123 void *p;
124 struct memlist_s *m;
126 if (size <= 0)
127 return NULL;
129 if ((m = (struct memlist_s *)malloc(sizeof(struct memlist_s))) == NULL)
130 return NULL;
132 if ((p = calloc(nmemb, size)) == NULL) {
133 free(m);
134 return NULL;
137 m->ptr = p;
138 m->size = nmemb * size;
139 memlist = memlist_prepend(memlist, m);
140 #ifdef DEBUG
141 fprintf(stderr, "%s: %p %i\n", __FUNCTION__, p, nmemb * size);
142 #endif
143 return m->ptr;
146 void *xrealloc(void *ptr, size_t size)
148 void *p;
149 struct memlist_s *m;
151 if (!ptr)
152 return xmalloc(size);
154 if (size <= 0)
155 return ptr;
157 for (m = memlist; m; m = m->next) {
158 if (m->ptr == ptr) {
159 if ((p = malloc(size)) == NULL)
160 return NULL;
162 memcpy(p, m->ptr, size < m->size ? size : m->size);
163 memset(m->ptr, 0, m->size);
164 free(m->ptr);
165 m->ptr = p;
166 m->size = size;
167 #ifdef DEBUG
168 fprintf(stderr, "%s: %p %i\n", __FUNCTION__, p, size);
169 #endif
170 return m->ptr;
174 warnx(N_("%s: %p not found"), __FUNCTION__, ptr);
175 assert(0);
176 return NULL;
179 char *xstrdup(const char *str)
181 char *t, *tp;
182 size_t len;
183 const char *p;
185 if (!str)
186 return NULL;
188 len = strlen(str) + 1;
190 if ((t = (char *)xmalloc(len * sizeof(char))) == NULL)
191 return NULL;
193 for (p = str, tp = t; *p; p++)
194 *tp++ = *p;
196 *tp = 0;
197 #ifdef DEBUG
198 fprintf(stderr, "%s: %p\n", __FUNCTION__, t);
199 #endif
200 return t;
203 void xpanic(void)
205 struct memlist_s *m;
207 for (m = memlist; m; m = memlist)
208 xfree(m->ptr);
211 void xdump(void)
213 struct memlist_s *m;
214 size_t total = 0;
216 for (m = memlist; m; m = m->next) {
217 fprintf(stderr, "%s: %p %i\n", __FUNCTION__, m->ptr, m->size);
218 total += m->size;
221 fprintf(stderr, "Total unfreed: %i bytes\n", total);