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