xref: /dflybsd-src/contrib/bmake/str.h (revision 9e7ae5a0527a977cab412aede3a532cfe2903bbb)
1*6eef5f0cSAntonio Huete Jimenez /*	$NetBSD: str.h,v 1.15 2021/12/15 10:57:01 rillig Exp $	*/
2*6eef5f0cSAntonio Huete Jimenez 
3*6eef5f0cSAntonio Huete Jimenez /*
4*6eef5f0cSAntonio Huete Jimenez  Copyright (c) 2021 Roland Illig <rillig@NetBSD.org>
5*6eef5f0cSAntonio Huete Jimenez  All rights reserved.
6*6eef5f0cSAntonio Huete Jimenez 
7*6eef5f0cSAntonio Huete Jimenez  Redistribution and use in source and binary forms, with or without
8*6eef5f0cSAntonio Huete Jimenez  modification, are permitted provided that the following conditions
9*6eef5f0cSAntonio Huete Jimenez  are met:
10*6eef5f0cSAntonio Huete Jimenez 
11*6eef5f0cSAntonio Huete Jimenez  1. Redistributions of source code must retain the above copyright
12*6eef5f0cSAntonio Huete Jimenez     notice, this list of conditions and the following disclaimer.
13*6eef5f0cSAntonio Huete Jimenez  2. Redistributions in binary form must reproduce the above copyright
14*6eef5f0cSAntonio Huete Jimenez     notice, this list of conditions and the following disclaimer in the
15*6eef5f0cSAntonio Huete Jimenez     documentation and/or other materials provided with the distribution.
16*6eef5f0cSAntonio Huete Jimenez 
17*6eef5f0cSAntonio Huete Jimenez  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18*6eef5f0cSAntonio Huete Jimenez  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19*6eef5f0cSAntonio Huete Jimenez  TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20*6eef5f0cSAntonio Huete Jimenez  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
21*6eef5f0cSAntonio Huete Jimenez  BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22*6eef5f0cSAntonio Huete Jimenez  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23*6eef5f0cSAntonio Huete Jimenez  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24*6eef5f0cSAntonio Huete Jimenez  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25*6eef5f0cSAntonio Huete Jimenez  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26*6eef5f0cSAntonio Huete Jimenez  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27*6eef5f0cSAntonio Huete Jimenez  POSSIBILITY OF SUCH DAMAGE.
28*6eef5f0cSAntonio Huete Jimenez  */
29*6eef5f0cSAntonio Huete Jimenez 
30*6eef5f0cSAntonio Huete Jimenez 
31*6eef5f0cSAntonio Huete Jimenez /*
32*6eef5f0cSAntonio Huete Jimenez  * Memory-efficient string handling.
33*6eef5f0cSAntonio Huete Jimenez  */
34*6eef5f0cSAntonio Huete Jimenez 
35*6eef5f0cSAntonio Huete Jimenez 
36*6eef5f0cSAntonio Huete Jimenez /* A read-only string that may need to be freed after use. */
37*6eef5f0cSAntonio Huete Jimenez typedef struct FStr {
38*6eef5f0cSAntonio Huete Jimenez 	const char *str;
39*6eef5f0cSAntonio Huete Jimenez 	void *freeIt;
40*6eef5f0cSAntonio Huete Jimenez } FStr;
41*6eef5f0cSAntonio Huete Jimenez 
42*6eef5f0cSAntonio Huete Jimenez /* A read-only range of a character array, NOT null-terminated. */
43*6eef5f0cSAntonio Huete Jimenez typedef struct Substring {
44*6eef5f0cSAntonio Huete Jimenez 	const char *start;
45*6eef5f0cSAntonio Huete Jimenez 	const char *end;
46*6eef5f0cSAntonio Huete Jimenez } Substring;
47*6eef5f0cSAntonio Huete Jimenez 
48*6eef5f0cSAntonio Huete Jimenez /*
49*6eef5f0cSAntonio Huete Jimenez  * Builds a string, only allocating memory if the string is different from the
50*6eef5f0cSAntonio Huete Jimenez  * expected string.
51*6eef5f0cSAntonio Huete Jimenez  */
52*6eef5f0cSAntonio Huete Jimenez typedef struct LazyBuf {
53*6eef5f0cSAntonio Huete Jimenez 	char *data;
54*6eef5f0cSAntonio Huete Jimenez 	size_t len;
55*6eef5f0cSAntonio Huete Jimenez 	size_t cap;
56*6eef5f0cSAntonio Huete Jimenez 	const char *expected;
57*6eef5f0cSAntonio Huete Jimenez } LazyBuf;
58*6eef5f0cSAntonio Huete Jimenez 
59*6eef5f0cSAntonio Huete Jimenez /* The result of splitting a string into words. */
60*6eef5f0cSAntonio Huete Jimenez typedef struct Words {
61*6eef5f0cSAntonio Huete Jimenez 	char **words;
62*6eef5f0cSAntonio Huete Jimenez 	size_t len;
63*6eef5f0cSAntonio Huete Jimenez 	void *freeIt;
64*6eef5f0cSAntonio Huete Jimenez } Words;
65*6eef5f0cSAntonio Huete Jimenez 
66*6eef5f0cSAntonio Huete Jimenez /* The result of splitting a string into words. */
67*6eef5f0cSAntonio Huete Jimenez typedef struct SubstringWords {
68*6eef5f0cSAntonio Huete Jimenez 	Substring *words;
69*6eef5f0cSAntonio Huete Jimenez 	size_t len;
70*6eef5f0cSAntonio Huete Jimenez 	void *freeIt;
71*6eef5f0cSAntonio Huete Jimenez } SubstringWords;
72*6eef5f0cSAntonio Huete Jimenez 
73*6eef5f0cSAntonio Huete Jimenez 
74*6eef5f0cSAntonio Huete Jimenez MAKE_INLINE FStr
FStr_Init(const char * str,void * freeIt)75*6eef5f0cSAntonio Huete Jimenez FStr_Init(const char *str, void *freeIt)
76*6eef5f0cSAntonio Huete Jimenez {
77*6eef5f0cSAntonio Huete Jimenez 	FStr fstr;
78*6eef5f0cSAntonio Huete Jimenez 	fstr.str = str;
79*6eef5f0cSAntonio Huete Jimenez 	fstr.freeIt = freeIt;
80*6eef5f0cSAntonio Huete Jimenez 	return fstr;
81*6eef5f0cSAntonio Huete Jimenez }
82*6eef5f0cSAntonio Huete Jimenez 
83*6eef5f0cSAntonio Huete Jimenez /* Return a string that is the sole owner of str. */
84*6eef5f0cSAntonio Huete Jimenez MAKE_INLINE FStr
FStr_InitOwn(char * str)85*6eef5f0cSAntonio Huete Jimenez FStr_InitOwn(char *str)
86*6eef5f0cSAntonio Huete Jimenez {
87*6eef5f0cSAntonio Huete Jimenez 	return FStr_Init(str, str);
88*6eef5f0cSAntonio Huete Jimenez }
89*6eef5f0cSAntonio Huete Jimenez 
90*6eef5f0cSAntonio Huete Jimenez /* Return a string that refers to the shared str. */
91*6eef5f0cSAntonio Huete Jimenez MAKE_INLINE FStr
FStr_InitRefer(const char * str)92*6eef5f0cSAntonio Huete Jimenez FStr_InitRefer(const char *str)
93*6eef5f0cSAntonio Huete Jimenez {
94*6eef5f0cSAntonio Huete Jimenez 	return FStr_Init(str, NULL);
95*6eef5f0cSAntonio Huete Jimenez }
96*6eef5f0cSAntonio Huete Jimenez 
97*6eef5f0cSAntonio Huete Jimenez MAKE_INLINE void
FStr_Done(FStr * fstr)98*6eef5f0cSAntonio Huete Jimenez FStr_Done(FStr *fstr)
99*6eef5f0cSAntonio Huete Jimenez {
100*6eef5f0cSAntonio Huete Jimenez 	free(fstr->freeIt);
101*6eef5f0cSAntonio Huete Jimenez #ifdef CLEANUP
102*6eef5f0cSAntonio Huete Jimenez 	fstr->str = NULL;
103*6eef5f0cSAntonio Huete Jimenez 	fstr->freeIt = NULL;
104*6eef5f0cSAntonio Huete Jimenez #endif
105*6eef5f0cSAntonio Huete Jimenez }
106*6eef5f0cSAntonio Huete Jimenez 
107*6eef5f0cSAntonio Huete Jimenez 
108*6eef5f0cSAntonio Huete Jimenez MAKE_STATIC Substring
Substring_Init(const char * start,const char * end)109*6eef5f0cSAntonio Huete Jimenez Substring_Init(const char *start, const char *end)
110*6eef5f0cSAntonio Huete Jimenez {
111*6eef5f0cSAntonio Huete Jimenez 	Substring sub;
112*6eef5f0cSAntonio Huete Jimenez 
113*6eef5f0cSAntonio Huete Jimenez 	sub.start = start;
114*6eef5f0cSAntonio Huete Jimenez 	sub.end = end;
115*6eef5f0cSAntonio Huete Jimenez 	return sub;
116*6eef5f0cSAntonio Huete Jimenez }
117*6eef5f0cSAntonio Huete Jimenez 
118*6eef5f0cSAntonio Huete Jimenez MAKE_INLINE Substring
Substring_InitStr(const char * str)119*6eef5f0cSAntonio Huete Jimenez Substring_InitStr(const char *str)
120*6eef5f0cSAntonio Huete Jimenez {
121*6eef5f0cSAntonio Huete Jimenez 	return Substring_Init(str, str + strlen(str));
122*6eef5f0cSAntonio Huete Jimenez }
123*6eef5f0cSAntonio Huete Jimenez 
124*6eef5f0cSAntonio Huete Jimenez MAKE_STATIC size_t
Substring_Length(Substring sub)125*6eef5f0cSAntonio Huete Jimenez Substring_Length(Substring sub)
126*6eef5f0cSAntonio Huete Jimenez {
127*6eef5f0cSAntonio Huete Jimenez 	return (size_t)(sub.end - sub.start);
128*6eef5f0cSAntonio Huete Jimenez }
129*6eef5f0cSAntonio Huete Jimenez 
130*6eef5f0cSAntonio Huete Jimenez MAKE_STATIC bool
Substring_IsEmpty(Substring sub)131*6eef5f0cSAntonio Huete Jimenez Substring_IsEmpty(Substring sub)
132*6eef5f0cSAntonio Huete Jimenez {
133*6eef5f0cSAntonio Huete Jimenez 	return sub.start == sub.end;
134*6eef5f0cSAntonio Huete Jimenez }
135*6eef5f0cSAntonio Huete Jimenez 
136*6eef5f0cSAntonio Huete Jimenez MAKE_INLINE bool
Substring_Equals(Substring sub,const char * str)137*6eef5f0cSAntonio Huete Jimenez Substring_Equals(Substring sub, const char *str)
138*6eef5f0cSAntonio Huete Jimenez {
139*6eef5f0cSAntonio Huete Jimenez 	size_t len = strlen(str);
140*6eef5f0cSAntonio Huete Jimenez 	return Substring_Length(sub) == len &&
141*6eef5f0cSAntonio Huete Jimenez 	       memcmp(sub.start, str, len) == 0;
142*6eef5f0cSAntonio Huete Jimenez }
143*6eef5f0cSAntonio Huete Jimenez 
144*6eef5f0cSAntonio Huete Jimenez MAKE_INLINE bool
Substring_Eq(Substring sub,Substring str)145*6eef5f0cSAntonio Huete Jimenez Substring_Eq(Substring sub, Substring str)
146*6eef5f0cSAntonio Huete Jimenez {
147*6eef5f0cSAntonio Huete Jimenez 	size_t len = Substring_Length(sub);
148*6eef5f0cSAntonio Huete Jimenez 	return len == Substring_Length(str) &&
149*6eef5f0cSAntonio Huete Jimenez 	       memcmp(sub.start, str.start, len) == 0;
150*6eef5f0cSAntonio Huete Jimenez }
151*6eef5f0cSAntonio Huete Jimenez 
152*6eef5f0cSAntonio Huete Jimenez MAKE_STATIC Substring
Substring_Sub(Substring sub,size_t start,size_t end)153*6eef5f0cSAntonio Huete Jimenez Substring_Sub(Substring sub, size_t start, size_t end)
154*6eef5f0cSAntonio Huete Jimenez {
155*6eef5f0cSAntonio Huete Jimenez 	assert(start <= Substring_Length(sub));
156*6eef5f0cSAntonio Huete Jimenez 	assert(end <= Substring_Length(sub));
157*6eef5f0cSAntonio Huete Jimenez 	return Substring_Init(sub.start + start, sub.start + end);
158*6eef5f0cSAntonio Huete Jimenez }
159*6eef5f0cSAntonio Huete Jimenez 
160*6eef5f0cSAntonio Huete Jimenez MAKE_STATIC bool
Substring_HasPrefix(Substring sub,Substring prefix)161*6eef5f0cSAntonio Huete Jimenez Substring_HasPrefix(Substring sub, Substring prefix)
162*6eef5f0cSAntonio Huete Jimenez {
163*6eef5f0cSAntonio Huete Jimenez 	return Substring_Length(sub) >= Substring_Length(prefix) &&
164*6eef5f0cSAntonio Huete Jimenez 	       memcmp(sub.start, prefix.start, Substring_Length(prefix)) == 0;
165*6eef5f0cSAntonio Huete Jimenez }
166*6eef5f0cSAntonio Huete Jimenez 
167*6eef5f0cSAntonio Huete Jimenez MAKE_STATIC bool
Substring_HasSuffix(Substring sub,Substring suffix)168*6eef5f0cSAntonio Huete Jimenez Substring_HasSuffix(Substring sub, Substring suffix)
169*6eef5f0cSAntonio Huete Jimenez {
170*6eef5f0cSAntonio Huete Jimenez 	size_t suffixLen = Substring_Length(suffix);
171*6eef5f0cSAntonio Huete Jimenez 	return Substring_Length(sub) >= suffixLen &&
172*6eef5f0cSAntonio Huete Jimenez 	       memcmp(sub.end - suffixLen, suffix.start, suffixLen) == 0;
173*6eef5f0cSAntonio Huete Jimenez }
174*6eef5f0cSAntonio Huete Jimenez 
175*6eef5f0cSAntonio Huete Jimenez /* Returns an independent, null-terminated copy of the substring. */
176*6eef5f0cSAntonio Huete Jimenez MAKE_STATIC FStr
Substring_Str(Substring sub)177*6eef5f0cSAntonio Huete Jimenez Substring_Str(Substring sub)
178*6eef5f0cSAntonio Huete Jimenez {
179*6eef5f0cSAntonio Huete Jimenez 	if (Substring_IsEmpty(sub))
180*6eef5f0cSAntonio Huete Jimenez 		return FStr_InitRefer("");
181*6eef5f0cSAntonio Huete Jimenez 	return FStr_InitOwn(bmake_strsedup(sub.start, sub.end));
182*6eef5f0cSAntonio Huete Jimenez }
183*6eef5f0cSAntonio Huete Jimenez 
184*6eef5f0cSAntonio Huete Jimenez MAKE_STATIC const char *
Substring_SkipFirst(Substring sub,char ch)185*6eef5f0cSAntonio Huete Jimenez Substring_SkipFirst(Substring sub, char ch)
186*6eef5f0cSAntonio Huete Jimenez {
187*6eef5f0cSAntonio Huete Jimenez 	const char *p;
188*6eef5f0cSAntonio Huete Jimenez 
189*6eef5f0cSAntonio Huete Jimenez 	for (p = sub.start; p != sub.end; p++)
190*6eef5f0cSAntonio Huete Jimenez 		if (*p == ch)
191*6eef5f0cSAntonio Huete Jimenez 			return p + 1;
192*6eef5f0cSAntonio Huete Jimenez 	return sub.start;
193*6eef5f0cSAntonio Huete Jimenez }
194*6eef5f0cSAntonio Huete Jimenez 
195*6eef5f0cSAntonio Huete Jimenez MAKE_STATIC const char *
Substring_LastIndex(Substring sub,char ch)196*6eef5f0cSAntonio Huete Jimenez Substring_LastIndex(Substring sub, char ch)
197*6eef5f0cSAntonio Huete Jimenez {
198*6eef5f0cSAntonio Huete Jimenez 	const char *p;
199*6eef5f0cSAntonio Huete Jimenez 
200*6eef5f0cSAntonio Huete Jimenez 	for (p = sub.end; p != sub.start; p--)
201*6eef5f0cSAntonio Huete Jimenez 		if (p[-1] == ch)
202*6eef5f0cSAntonio Huete Jimenez 			return p - 1;
203*6eef5f0cSAntonio Huete Jimenez 	return NULL;
204*6eef5f0cSAntonio Huete Jimenez }
205*6eef5f0cSAntonio Huete Jimenez 
206*6eef5f0cSAntonio Huete Jimenez MAKE_STATIC Substring
Substring_Dirname(Substring pathname)207*6eef5f0cSAntonio Huete Jimenez Substring_Dirname(Substring pathname)
208*6eef5f0cSAntonio Huete Jimenez {
209*6eef5f0cSAntonio Huete Jimenez 	const char *p;
210*6eef5f0cSAntonio Huete Jimenez 
211*6eef5f0cSAntonio Huete Jimenez 	for (p = pathname.end; p != pathname.start; p--)
212*6eef5f0cSAntonio Huete Jimenez 		if (p[-1] == '/')
213*6eef5f0cSAntonio Huete Jimenez 			return Substring_Init(pathname.start, p - 1);
214*6eef5f0cSAntonio Huete Jimenez 	return Substring_InitStr(".");
215*6eef5f0cSAntonio Huete Jimenez }
216*6eef5f0cSAntonio Huete Jimenez 
217*6eef5f0cSAntonio Huete Jimenez MAKE_STATIC Substring
Substring_Basename(Substring pathname)218*6eef5f0cSAntonio Huete Jimenez Substring_Basename(Substring pathname)
219*6eef5f0cSAntonio Huete Jimenez {
220*6eef5f0cSAntonio Huete Jimenez 	const char *p;
221*6eef5f0cSAntonio Huete Jimenez 
222*6eef5f0cSAntonio Huete Jimenez 	for (p = pathname.end; p != pathname.start; p--)
223*6eef5f0cSAntonio Huete Jimenez 		if (p[-1] == '/')
224*6eef5f0cSAntonio Huete Jimenez 			return Substring_Init(p, pathname.end);
225*6eef5f0cSAntonio Huete Jimenez 	return pathname;
226*6eef5f0cSAntonio Huete Jimenez }
227*6eef5f0cSAntonio Huete Jimenez 
228*6eef5f0cSAntonio Huete Jimenez 
229*6eef5f0cSAntonio Huete Jimenez MAKE_STATIC void
LazyBuf_Init(LazyBuf * buf,const char * expected)230*6eef5f0cSAntonio Huete Jimenez LazyBuf_Init(LazyBuf *buf, const char *expected)
231*6eef5f0cSAntonio Huete Jimenez {
232*6eef5f0cSAntonio Huete Jimenez 	buf->data = NULL;
233*6eef5f0cSAntonio Huete Jimenez 	buf->len = 0;
234*6eef5f0cSAntonio Huete Jimenez 	buf->cap = 0;
235*6eef5f0cSAntonio Huete Jimenez 	buf->expected = expected;
236*6eef5f0cSAntonio Huete Jimenez }
237*6eef5f0cSAntonio Huete Jimenez 
238*6eef5f0cSAntonio Huete Jimenez MAKE_INLINE void
LazyBuf_Done(LazyBuf * buf)239*6eef5f0cSAntonio Huete Jimenez LazyBuf_Done(LazyBuf *buf)
240*6eef5f0cSAntonio Huete Jimenez {
241*6eef5f0cSAntonio Huete Jimenez 	free(buf->data);
242*6eef5f0cSAntonio Huete Jimenez }
243*6eef5f0cSAntonio Huete Jimenez 
244*6eef5f0cSAntonio Huete Jimenez MAKE_STATIC void
LazyBuf_Add(LazyBuf * buf,char ch)245*6eef5f0cSAntonio Huete Jimenez LazyBuf_Add(LazyBuf *buf, char ch)
246*6eef5f0cSAntonio Huete Jimenez {
247*6eef5f0cSAntonio Huete Jimenez 
248*6eef5f0cSAntonio Huete Jimenez 	if (buf->data != NULL) {
249*6eef5f0cSAntonio Huete Jimenez 		if (buf->len == buf->cap) {
250*6eef5f0cSAntonio Huete Jimenez 			buf->cap *= 2;
251*6eef5f0cSAntonio Huete Jimenez 			buf->data = bmake_realloc(buf->data, buf->cap);
252*6eef5f0cSAntonio Huete Jimenez 		}
253*6eef5f0cSAntonio Huete Jimenez 		buf->data[buf->len++] = ch;
254*6eef5f0cSAntonio Huete Jimenez 
255*6eef5f0cSAntonio Huete Jimenez 	} else if (ch == buf->expected[buf->len]) {
256*6eef5f0cSAntonio Huete Jimenez 		buf->len++;
257*6eef5f0cSAntonio Huete Jimenez 		return;
258*6eef5f0cSAntonio Huete Jimenez 
259*6eef5f0cSAntonio Huete Jimenez 	} else {
260*6eef5f0cSAntonio Huete Jimenez 		buf->cap = buf->len + 16;
261*6eef5f0cSAntonio Huete Jimenez 		buf->data = bmake_malloc(buf->cap);
262*6eef5f0cSAntonio Huete Jimenez 		memcpy(buf->data, buf->expected, buf->len);
263*6eef5f0cSAntonio Huete Jimenez 		buf->data[buf->len++] = ch;
264*6eef5f0cSAntonio Huete Jimenez 	}
265*6eef5f0cSAntonio Huete Jimenez }
266*6eef5f0cSAntonio Huete Jimenez 
267*6eef5f0cSAntonio Huete Jimenez MAKE_STATIC void
LazyBuf_AddStr(LazyBuf * buf,const char * str)268*6eef5f0cSAntonio Huete Jimenez LazyBuf_AddStr(LazyBuf *buf, const char *str)
269*6eef5f0cSAntonio Huete Jimenez {
270*6eef5f0cSAntonio Huete Jimenez 	const char *p;
271*6eef5f0cSAntonio Huete Jimenez 
272*6eef5f0cSAntonio Huete Jimenez 	for (p = str; *p != '\0'; p++)
273*6eef5f0cSAntonio Huete Jimenez 		LazyBuf_Add(buf, *p);
274*6eef5f0cSAntonio Huete Jimenez }
275*6eef5f0cSAntonio Huete Jimenez 
276*6eef5f0cSAntonio Huete Jimenez MAKE_STATIC void
LazyBuf_AddBytesBetween(LazyBuf * buf,const char * start,const char * end)277*6eef5f0cSAntonio Huete Jimenez LazyBuf_AddBytesBetween(LazyBuf *buf, const char *start, const char *end)
278*6eef5f0cSAntonio Huete Jimenez {
279*6eef5f0cSAntonio Huete Jimenez 	const char *p;
280*6eef5f0cSAntonio Huete Jimenez 
281*6eef5f0cSAntonio Huete Jimenez 	for (p = start; p != end; p++)
282*6eef5f0cSAntonio Huete Jimenez 		LazyBuf_Add(buf, *p);
283*6eef5f0cSAntonio Huete Jimenez }
284*6eef5f0cSAntonio Huete Jimenez 
285*6eef5f0cSAntonio Huete Jimenez MAKE_INLINE void
LazyBuf_AddSubstring(LazyBuf * buf,Substring sub)286*6eef5f0cSAntonio Huete Jimenez LazyBuf_AddSubstring(LazyBuf *buf, Substring sub)
287*6eef5f0cSAntonio Huete Jimenez {
288*6eef5f0cSAntonio Huete Jimenez 	LazyBuf_AddBytesBetween(buf, sub.start, sub.end);
289*6eef5f0cSAntonio Huete Jimenez }
290*6eef5f0cSAntonio Huete Jimenez 
291*6eef5f0cSAntonio Huete Jimenez MAKE_STATIC Substring
LazyBuf_Get(const LazyBuf * buf)292*6eef5f0cSAntonio Huete Jimenez LazyBuf_Get(const LazyBuf *buf)
293*6eef5f0cSAntonio Huete Jimenez {
294*6eef5f0cSAntonio Huete Jimenez 	const char *start = buf->data != NULL ? buf->data : buf->expected;
295*6eef5f0cSAntonio Huete Jimenez 	return Substring_Init(start, start + buf->len);
296*6eef5f0cSAntonio Huete Jimenez }
297*6eef5f0cSAntonio Huete Jimenez 
298*6eef5f0cSAntonio Huete Jimenez /*
299*6eef5f0cSAntonio Huete Jimenez  * Returns the content of the buffer as a newly allocated string.
300*6eef5f0cSAntonio Huete Jimenez  *
301*6eef5f0cSAntonio Huete Jimenez  * See LazyBuf_Get to avoid unnecessary memory allocations.
302*6eef5f0cSAntonio Huete Jimenez  */
303*6eef5f0cSAntonio Huete Jimenez MAKE_STATIC FStr
LazyBuf_DoneGet(LazyBuf * buf)304*6eef5f0cSAntonio Huete Jimenez LazyBuf_DoneGet(LazyBuf *buf)
305*6eef5f0cSAntonio Huete Jimenez {
306*6eef5f0cSAntonio Huete Jimenez 	if (buf->data != NULL) {
307*6eef5f0cSAntonio Huete Jimenez 		LazyBuf_Add(buf, '\0');
308*6eef5f0cSAntonio Huete Jimenez 		return FStr_InitOwn(buf->data);
309*6eef5f0cSAntonio Huete Jimenez 	}
310*6eef5f0cSAntonio Huete Jimenez 	return Substring_Str(LazyBuf_Get(buf));
311*6eef5f0cSAntonio Huete Jimenez }
312*6eef5f0cSAntonio Huete Jimenez 
313*6eef5f0cSAntonio Huete Jimenez 
314*6eef5f0cSAntonio Huete Jimenez Words Str_Words(const char *, bool);
315*6eef5f0cSAntonio Huete Jimenez 
316*6eef5f0cSAntonio Huete Jimenez MAKE_INLINE void
Words_Free(Words w)317*6eef5f0cSAntonio Huete Jimenez Words_Free(Words w)
318*6eef5f0cSAntonio Huete Jimenez {
319*6eef5f0cSAntonio Huete Jimenez 	free(w.words);
320*6eef5f0cSAntonio Huete Jimenez 	free(w.freeIt);
321*6eef5f0cSAntonio Huete Jimenez }
322*6eef5f0cSAntonio Huete Jimenez 
323*6eef5f0cSAntonio Huete Jimenez 
324*6eef5f0cSAntonio Huete Jimenez SubstringWords Substring_Words(const char *, bool);
325*6eef5f0cSAntonio Huete Jimenez 
326*6eef5f0cSAntonio Huete Jimenez MAKE_INLINE void
SubstringWords_Init(SubstringWords * w)327*6eef5f0cSAntonio Huete Jimenez SubstringWords_Init(SubstringWords *w)
328*6eef5f0cSAntonio Huete Jimenez {
329*6eef5f0cSAntonio Huete Jimenez 	w->words = NULL;
330*6eef5f0cSAntonio Huete Jimenez 	w->len = 0;
331*6eef5f0cSAntonio Huete Jimenez 	w->freeIt = NULL;
332*6eef5f0cSAntonio Huete Jimenez }
333*6eef5f0cSAntonio Huete Jimenez 
334*6eef5f0cSAntonio Huete Jimenez MAKE_INLINE void
SubstringWords_Free(SubstringWords w)335*6eef5f0cSAntonio Huete Jimenez SubstringWords_Free(SubstringWords w)
336*6eef5f0cSAntonio Huete Jimenez {
337*6eef5f0cSAntonio Huete Jimenez 	free(w.words);
338*6eef5f0cSAntonio Huete Jimenez 	free(w.freeIt);
339*6eef5f0cSAntonio Huete Jimenez }
340*6eef5f0cSAntonio Huete Jimenez 
341*6eef5f0cSAntonio Huete Jimenez 
342*6eef5f0cSAntonio Huete Jimenez char *str_concat2(const char *, const char *);
343*6eef5f0cSAntonio Huete Jimenez char *str_concat3(const char *, const char *, const char *);
344*6eef5f0cSAntonio Huete Jimenez 
345*6eef5f0cSAntonio Huete Jimenez bool Str_Match(const char *, const char *);
346*6eef5f0cSAntonio Huete Jimenez 
347*6eef5f0cSAntonio Huete Jimenez void Str_Intern_Init(void);
348*6eef5f0cSAntonio Huete Jimenez void Str_Intern_End(void);
349*6eef5f0cSAntonio Huete Jimenez const char *Str_Intern(const char *);
350