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