Mercurial > ~dholland > hg > tradcpp > index.cgi
annotate utils.c @ 137:0816803b22d1
Improve usage reporting.
Since imake is a principal application for tradcpp and imake carefully
hides what it's doing when you run it, when rejecting an invalid
option be sure to report *what* that option is.
author | David A. Holland |
---|---|
date | Tue, 09 Jul 2013 13:43:27 -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 } |