Mercurial > ~dholland > hg > tradcpp > index.cgi
annotate utils.c @ 167:fa9752f194c6
Don't shortcut macro expansion of non-parameter macros.
It won't work once we have more kinds of expansion items than strings
and arguments, viz., magic tokens for __FILE__ and __LINE__ and so on.
(separate version of this applied against Joerg's changes, because we
need to revert some of them)
author | David A. Holland |
---|---|
date | Fri, 12 Jun 2015 01:55:31 -0400 |
parents | 4ea0ce804d22 |
children |
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 |
34 #include "utils.h" | |
35 | |
41 | 36 #define MALLOCDEBUG |
37 | |
16 | 38 const char ws[] = |
39 " \t\f\v" | |
40 ; | |
41 const char alnum[] = | |
42 "0123456789" | |
43 "abcdefghijklmnopqrstuvwxyz" | |
44 "ABCDEFGHIJKLMNOPQRSTUVWXYZ" | |
45 "_" | |
46 ; | |
47 | |
41 | 48 //////////////////////////////////////////////////////////// |
49 // malloc | |
50 | |
51 #define ROUNDUP(len, size) ((size) * (((len) + (size) - 1) / (size))) | |
52 | |
53 #ifdef MALLOCDEBUG | |
54 | |
55 struct mallocheader { | |
56 struct mallocheader *self; | |
57 size_t len; | |
58 }; | |
59 | |
60 static | |
61 size_t | |
62 adjustsize(size_t len) | |
63 { | |
64 const size_t sz = sizeof(struct mallocheader); | |
65 return ROUNDUP(len, sz) + 2*sz; | |
66 } | |
67 | |
68 static | |
69 void * | |
70 placeheaders(void *block, size_t len) | |
71 { | |
72 struct mallocheader *bothdr, *tophdr; | |
73 size_t roundedlen; | |
74 void *ret; | |
75 | |
76 roundedlen = ROUNDUP(len, sizeof(struct mallocheader)); | |
77 bothdr = block; | |
78 bothdr->len = len; | |
79 bothdr->self = block; | |
80 ret = bothdr + 1; | |
81 tophdr = (void *)(((unsigned char *)ret) + roundedlen); | |
82 tophdr->len = len; | |
83 tophdr->self = bothdr; | |
84 return ret; | |
85 } | |
86 | |
87 static | |
88 void * | |
89 checkheaders(void *block, size_t len) | |
90 { | |
91 struct mallocheader *bothdr, *tophdr; | |
92 size_t roundedlen; | |
93 | |
94 if (block == NULL) { | |
95 assert(len == 0); | |
96 return block; | |
97 } | |
98 | |
99 roundedlen = ROUNDUP(len, sizeof(struct mallocheader)); | |
100 bothdr = block; | |
101 bothdr--; | |
102 assert(bothdr->self == bothdr); | |
103 assert(bothdr->len == len); | |
104 tophdr = (void *)(((unsigned char *)(bothdr + 1)) + roundedlen); | |
105 assert(tophdr->self == bothdr); | |
106 assert(tophdr->len == len); | |
107 return bothdr; | |
108 } | |
109 | |
110 #else | |
111 | |
112 #define adjustsize(len) (len) | |
113 #define placeheaders(block, len) ((void)(len), (block)) | |
114 #define checkheaders(ptr, len) ((void)(len), (ptr)) | |
115 | |
116 #endif /* MALLOCDEBUG */ | |
117 | |
3 | 118 void * |
119 domalloc(size_t len) | |
120 { | |
121 void *ret; | |
41 | 122 size_t blocklen; |
3 | 123 |
41 | 124 blocklen = adjustsize(len); |
125 ret = malloc(blocklen); | |
3 | 126 if (ret == NULL) { |
143 | 127 complain(NULL, "Out of memory"); |
3 | 128 die(); |
129 } | |
41 | 130 |
131 return placeheaders(ret, len); | |
3 | 132 } |
133 | |
134 void * | |
39
337110e7240a
Pass the size to free; it makes debug checking easier.
David A. Holland
parents:
38
diff
changeset
|
135 dorealloc(void *ptr, size_t oldlen, size_t newlen) |
3 | 136 { |
137 void *ret; | |
41 | 138 void *blockptr; |
139 size_t newblocklen; | |
3 | 140 |
41 | 141 blockptr = checkheaders(ptr, oldlen); |
142 newblocklen = adjustsize(newlen); | |
143 | |
144 ret = realloc(blockptr, newblocklen); | |
3 | 145 if (ret == NULL) { |
143 | 146 complain(NULL, "Out of memory"); |
3 | 147 die(); |
148 } | |
41 | 149 |
150 return placeheaders(ret, newlen); | |
3 | 151 } |
152 | |
38
b156910b59b2
Wrap free() in dofree() to allow instrumenting it for debugging.
David A. Holland
parents:
20
diff
changeset
|
153 void |
39
337110e7240a
Pass the size to free; it makes debug checking easier.
David A. Holland
parents:
38
diff
changeset
|
154 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
|
155 { |
41 | 156 void *blockptr; |
157 | |
158 blockptr = checkheaders(ptr, len); | |
159 free(blockptr); | |
38
b156910b59b2
Wrap free() in dofree() to allow instrumenting it for debugging.
David A. Holland
parents:
20
diff
changeset
|
160 } |
b156910b59b2
Wrap free() in dofree() to allow instrumenting it for debugging.
David A. Holland
parents:
20
diff
changeset
|
161 |
41 | 162 //////////////////////////////////////////////////////////// |
163 // string allocators | |
164 | |
3 | 165 char * |
166 dostrdup(const char *s) | |
167 { | |
168 char *ret; | |
169 size_t len; | |
170 | |
171 len = strlen(s); | |
172 ret = domalloc(len+1); | |
173 strcpy(ret, s); | |
174 return ret; | |
175 } | |
176 | |
177 char * | |
178 dostrdup2(const char *s, const char *t) | |
179 { | |
180 char *ret; | |
181 size_t len; | |
182 | |
183 len = strlen(s) + strlen(t); | |
184 ret = domalloc(len+1); | |
185 strcpy(ret, s); | |
186 strcat(ret, t); | |
187 return ret; | |
188 } | |
189 | |
190 char * | |
191 dostrdup3(const char *s, const char *t, const char *u) | |
192 { | |
193 char *ret; | |
194 size_t len; | |
195 | |
196 len = strlen(s) + strlen(t) + strlen(u); | |
197 ret = domalloc(len+1); | |
198 strcpy(ret, s); | |
199 strcat(ret, t); | |
200 strcat(ret, u); | |
201 return ret; | |
202 } | |
203 | |
20 | 204 char * |
205 dostrndup(const char *s, size_t len) | |
206 { | |
207 char *ret; | |
208 | |
209 ret = domalloc(len+1); | |
210 memcpy(ret, s, len); | |
211 ret[len] = '\0'; | |
212 return ret; | |
213 } | |
214 | |
39
337110e7240a
Pass the size to free; it makes debug checking easier.
David A. Holland
parents:
38
diff
changeset
|
215 void |
337110e7240a
Pass the size to free; it makes debug checking easier.
David A. Holland
parents:
38
diff
changeset
|
216 dostrfree(char *s) |
337110e7240a
Pass the size to free; it makes debug checking easier.
David A. Holland
parents:
38
diff
changeset
|
217 { |
337110e7240a
Pass the size to free; it makes debug checking easier.
David A. Holland
parents:
38
diff
changeset
|
218 dofree(s, strlen(s)+1); |
337110e7240a
Pass the size to free; it makes debug checking easier.
David A. Holland
parents:
38
diff
changeset
|
219 } |
337110e7240a
Pass the size to free; it makes debug checking easier.
David A. Holland
parents:
38
diff
changeset
|
220 |
41 | 221 //////////////////////////////////////////////////////////// |
222 // other stuff | |
223 | |
18 | 224 size_t |
225 notrailingws(char *buf, size_t len) | |
226 { | |
227 while (len > 0 && strchr(ws, buf[len-1])) { | |
228 buf[--len] = '\0'; | |
229 } | |
230 return len; | |
231 } | |
232 | |
233 bool | |
234 is_identifier(const char *str) | |
235 { | |
236 size_t len; | |
237 | |
238 len = strlen(str); | |
239 if (len != strspn(str, alnum)) { | |
240 return false; | |
241 } | |
242 if (str[0] >= '0' && str[0] <= '9') { | |
243 return false; | |
244 } | |
245 return true; | |
246 } |