Mercurial > ~dholland > hg > tradcpp > index.cgi
annotate utils.c @ 136:59680a727e9d
Improve previous.
Just in case we ever crash and reach cleanup() while processing an
-include foo option, take the array entry for it out of the array to
make sure it doesn't get freed twice. This case shouldn't be
reachable, but it's better to be safe.
author | David A. Holland |
---|---|
date | Tue, 09 Jul 2013 13:38:43 -0400 |
parents | 60184aa42604 |
children | ed45f2d8d3bc |
rev | line source |
---|---|
3 | 1 /*- |
99
60184aa42604
add 2013 to copyrights where it seems warranted
David A. Holland
parents:
41
diff
changeset
|
2 * Copyright (c) 2010, 2013 The NetBSD Foundation, Inc. |
3 | 3 * All rights reserved. |
4 * | |
5 * This code is derived from software contributed to The NetBSD Foundation | |
6 * by David A. Holland. | |
7 * | |
8 * Redistribution and use in source and binary forms, with or without | |
9 * modification, are permitted provided that the following conditions | |
10 * are met: | |
11 * 1. Redistributions of source code must retain the above copyright | |
12 * notice, this list of conditions and the following disclaimer. | |
13 * 2. Redistributions in binary form must reproduce the above copyright | |
14 * notice, this list of conditions and the following disclaimer in the | |
15 * documentation and/or other materials provided with the distribution. | |
16 * | |
17 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | |
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | |
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | |
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
27 * POSSIBILITY OF SUCH DAMAGE. | |
28 */ | |
29 | |
30 #include <stdlib.h> | |
31 #include <string.h> | |
41 | 32 #include <assert.h> |
3 | 33 #include <err.h> |
34 | |
35 #include "utils.h" | |
36 | |
41 | 37 #define MALLOCDEBUG |
38 | |
16 | 39 const char ws[] = |
40 " \t\f\v" | |
41 ; | |
42 const char alnum[] = | |
43 "0123456789" | |
44 "abcdefghijklmnopqrstuvwxyz" | |
45 "ABCDEFGHIJKLMNOPQRSTUVWXYZ" | |
46 "_" | |
47 ; | |
48 | |
41 | 49 //////////////////////////////////////////////////////////// |
50 // malloc | |
51 | |
52 #define ROUNDUP(len, size) ((size) * (((len) + (size) - 1) / (size))) | |
53 | |
54 #ifdef MALLOCDEBUG | |
55 | |
56 struct mallocheader { | |
57 struct mallocheader *self; | |
58 size_t len; | |
59 }; | |
60 | |
61 static | |
62 size_t | |
63 adjustsize(size_t len) | |
64 { | |
65 const size_t sz = sizeof(struct mallocheader); | |
66 return ROUNDUP(len, sz) + 2*sz; | |
67 } | |
68 | |
69 static | |
70 void * | |
71 placeheaders(void *block, size_t len) | |
72 { | |
73 struct mallocheader *bothdr, *tophdr; | |
74 size_t roundedlen; | |
75 void *ret; | |
76 | |
77 roundedlen = ROUNDUP(len, sizeof(struct mallocheader)); | |
78 bothdr = block; | |
79 bothdr->len = len; | |
80 bothdr->self = block; | |
81 ret = bothdr + 1; | |
82 tophdr = (void *)(((unsigned char *)ret) + roundedlen); | |
83 tophdr->len = len; | |
84 tophdr->self = bothdr; | |
85 return ret; | |
86 } | |
87 | |
88 static | |
89 void * | |
90 checkheaders(void *block, size_t len) | |
91 { | |
92 struct mallocheader *bothdr, *tophdr; | |
93 size_t roundedlen; | |
94 | |
95 if (block == NULL) { | |
96 assert(len == 0); | |
97 return block; | |
98 } | |
99 | |
100 roundedlen = ROUNDUP(len, sizeof(struct mallocheader)); | |
101 bothdr = block; | |
102 bothdr--; | |
103 assert(bothdr->self == bothdr); | |
104 assert(bothdr->len == len); | |
105 tophdr = (void *)(((unsigned char *)(bothdr + 1)) + roundedlen); | |
106 assert(tophdr->self == bothdr); | |
107 assert(tophdr->len == len); | |
108 return bothdr; | |
109 } | |
110 | |
111 #else | |
112 | |
113 #define adjustsize(len) (len) | |
114 #define placeheaders(block, len) ((void)(len), (block)) | |
115 #define checkheaders(ptr, len) ((void)(len), (ptr)) | |
116 | |
117 #endif /* MALLOCDEBUG */ | |
118 | |
3 | 119 void * |
120 domalloc(size_t len) | |
121 { | |
122 void *ret; | |
41 | 123 size_t blocklen; |
3 | 124 |
41 | 125 blocklen = adjustsize(len); |
126 ret = malloc(blocklen); | |
3 | 127 if (ret == NULL) { |
128 warnx("Out of memory"); | |
129 die(); | |
130 } | |
41 | 131 |
132 return placeheaders(ret, len); | |
3 | 133 } |
134 | |
135 void * | |
39
337110e7240a
Pass the size to free; it makes debug checking easier.
David A. Holland
parents:
38
diff
changeset
|
136 dorealloc(void *ptr, size_t oldlen, size_t newlen) |
3 | 137 { |
138 void *ret; | |
41 | 139 void *blockptr; |
140 size_t newblocklen; | |
3 | 141 |
41 | 142 blockptr = checkheaders(ptr, oldlen); |
143 newblocklen = adjustsize(newlen); | |
144 | |
145 ret = realloc(blockptr, newblocklen); | |
3 | 146 if (ret == NULL) { |
147 warnx("Out of memory"); | |
148 die(); | |
149 } | |
41 | 150 |
151 return placeheaders(ret, newlen); | |
3 | 152 } |
153 | |
38
b156910b59b2
Wrap free() in dofree() to allow instrumenting it for debugging.
David A. Holland
parents:
20
diff
changeset
|
154 void |
39
337110e7240a
Pass the size to free; it makes debug checking easier.
David A. Holland
parents:
38
diff
changeset
|
155 dofree(void *ptr, size_t len) |
38
b156910b59b2
Wrap free() in dofree() to allow instrumenting it for debugging.
David A. Holland
parents:
20
diff
changeset
|
156 { |
41 | 157 void *blockptr; |
158 | |
159 blockptr = checkheaders(ptr, len); | |
160 free(blockptr); | |
38
b156910b59b2
Wrap free() in dofree() to allow instrumenting it for debugging.
David A. Holland
parents:
20
diff
changeset
|
161 } |
b156910b59b2
Wrap free() in dofree() to allow instrumenting it for debugging.
David A. Holland
parents:
20
diff
changeset
|
162 |
41 | 163 //////////////////////////////////////////////////////////// |
164 // string allocators | |
165 | |
3 | 166 char * |
167 dostrdup(const char *s) | |
168 { | |
169 char *ret; | |
170 size_t len; | |
171 | |
172 len = strlen(s); | |
173 ret = domalloc(len+1); | |
174 strcpy(ret, s); | |
175 return ret; | |
176 } | |
177 | |
178 char * | |
179 dostrdup2(const char *s, const char *t) | |
180 { | |
181 char *ret; | |
182 size_t len; | |
183 | |
184 len = strlen(s) + strlen(t); | |
185 ret = domalloc(len+1); | |
186 strcpy(ret, s); | |
187 strcat(ret, t); | |
188 return ret; | |
189 } | |
190 | |
191 char * | |
192 dostrdup3(const char *s, const char *t, const char *u) | |
193 { | |
194 char *ret; | |
195 size_t len; | |
196 | |
197 len = strlen(s) + strlen(t) + strlen(u); | |
198 ret = domalloc(len+1); | |
199 strcpy(ret, s); | |
200 strcat(ret, t); | |
201 strcat(ret, u); | |
202 return ret; | |
203 } | |
204 | |
20 | 205 char * |
206 dostrndup(const char *s, size_t len) | |
207 { | |
208 char *ret; | |
209 | |
210 ret = domalloc(len+1); | |
211 memcpy(ret, s, len); | |
212 ret[len] = '\0'; | |
213 return ret; | |
214 } | |
215 | |
39
337110e7240a
Pass the size to free; it makes debug checking easier.
David A. Holland
parents:
38
diff
changeset
|
216 void |
337110e7240a
Pass the size to free; it makes debug checking easier.
David A. Holland
parents:
38
diff
changeset
|
217 dostrfree(char *s) |
337110e7240a
Pass the size to free; it makes debug checking easier.
David A. Holland
parents:
38
diff
changeset
|
218 { |
337110e7240a
Pass the size to free; it makes debug checking easier.
David A. Holland
parents:
38
diff
changeset
|
219 dofree(s, strlen(s)+1); |
337110e7240a
Pass the size to free; it makes debug checking easier.
David A. Holland
parents:
38
diff
changeset
|
220 } |
337110e7240a
Pass the size to free; it makes debug checking easier.
David A. Holland
parents:
38
diff
changeset
|
221 |
41 | 222 //////////////////////////////////////////////////////////// |
223 // other stuff | |
224 | |
18 | 225 size_t |
226 notrailingws(char *buf, size_t len) | |
227 { | |
228 while (len > 0 && strchr(ws, buf[len-1])) { | |
229 buf[--len] = '\0'; | |
230 } | |
231 return len; | |
232 } | |
233 | |
234 bool | |
235 is_identifier(const char *str) | |
236 { | |
237 size_t len; | |
238 | |
239 len = strlen(str); | |
240 if (len != strspn(str, alnum)) { | |
241 return false; | |
242 } | |
243 if (str[0] >= '0' && str[0] <= '9') { | |
244 return false; | |
245 } | |
246 return true; | |
247 } |