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