1d4c6f1e6SMasatake YAMATO /*
2d4c6f1e6SMasatake YAMATO * Copyright (c) 1998-2002, Darren Hiebert
3d4c6f1e6SMasatake YAMATO *
4d4c6f1e6SMasatake YAMATO * This source code is released for free distribution under the terms of the
50ce38835Sviccuad * GNU General Public License version 2 or (at your option) any later version.
6d4c6f1e6SMasatake YAMATO *
7d4c6f1e6SMasatake YAMATO * This module contains functions supporting resizeable strings.
8d4c6f1e6SMasatake YAMATO */
9d4c6f1e6SMasatake YAMATO
10d4c6f1e6SMasatake YAMATO /*
11d4c6f1e6SMasatake YAMATO * INCLUDE FILES
12d4c6f1e6SMasatake YAMATO */
13d4c6f1e6SMasatake YAMATO #include "general.h" /* must always come first */
14d4c6f1e6SMasatake YAMATO
15d4c6f1e6SMasatake YAMATO #include <limits.h> /* to define INT_MAX */
16d4c6f1e6SMasatake YAMATO #include <string.h>
17d4c6f1e6SMasatake YAMATO #include <ctype.h>
18d4c6f1e6SMasatake YAMATO
19d4c6f1e6SMasatake YAMATO #include "debug.h"
20d4c6f1e6SMasatake YAMATO #include "routines.h"
21d4c6f1e6SMasatake YAMATO #include "vstring.h"
2256065e52SMasatake YAMATO #include "trashbox.h"
23d4c6f1e6SMasatake YAMATO
24d4c6f1e6SMasatake YAMATO /*
25d4c6f1e6SMasatake YAMATO * DATA DEFINITIONS
26d4c6f1e6SMasatake YAMATO */
27d4c6f1e6SMasatake YAMATO static const size_t vStringInitialSize = 32;
28d4c6f1e6SMasatake YAMATO
29d4c6f1e6SMasatake YAMATO /*
30d4c6f1e6SMasatake YAMATO * FUNCTION DEFINITIONS
31d4c6f1e6SMasatake YAMATO */
32d4c6f1e6SMasatake YAMATO
33d4c6f1e6SMasatake YAMATO /*
34d4c6f1e6SMasatake YAMATO * External interface
35d4c6f1e6SMasatake YAMATO */
36d4c6f1e6SMasatake YAMATO
vStringResize(vString * const string,const size_t newSize)378a3d0750SJiří Techet extern void vStringResize (vString *const string, const size_t newSize)
38d4c6f1e6SMasatake YAMATO {
398a3d0750SJiří Techet size_t size = vStringInitialSize;
40d4c6f1e6SMasatake YAMATO
418a3d0750SJiří Techet while (size < newSize)
428a3d0750SJiří Techet size *= 2;
438a3d0750SJiří Techet
448a3d0750SJiří Techet if (size > string->size)
45d4c6f1e6SMasatake YAMATO {
468a3d0750SJiří Techet string->size = size;
478a3d0750SJiří Techet string->buffer = xRealloc (string->buffer, size, char);
48d4c6f1e6SMasatake YAMATO }
49d4c6f1e6SMasatake YAMATO }
50d4c6f1e6SMasatake YAMATO
vStringTruncate(vString * const string,const size_t length)514e3d9edfSColomban Wendling extern void vStringTruncate (vString *const string, const size_t length)
524e3d9edfSColomban Wendling {
534e3d9edfSColomban Wendling Assert (length <= string->length);
544e3d9edfSColomban Wendling string->length = length;
55cfc45e3bSJiří Techet string->buffer[string->length] = '\0';
564e3d9edfSColomban Wendling DebugStatement ( memset (string->buffer + string->length, 0,
574e3d9edfSColomban Wendling string->size - string->length); )
584e3d9edfSColomban Wendling }
594e3d9edfSColomban Wendling
vStringDelete(vString * const string)60d4c6f1e6SMasatake YAMATO extern void vStringDelete (vString *const string)
61d4c6f1e6SMasatake YAMATO {
62d4c6f1e6SMasatake YAMATO if (string != NULL)
63d4c6f1e6SMasatake YAMATO {
64d4c6f1e6SMasatake YAMATO if (string->buffer != NULL)
65d4c6f1e6SMasatake YAMATO eFree (string->buffer);
66d4c6f1e6SMasatake YAMATO eFree (string);
67d4c6f1e6SMasatake YAMATO }
68d4c6f1e6SMasatake YAMATO }
69d4c6f1e6SMasatake YAMATO
vStringNew(void)70d4c6f1e6SMasatake YAMATO extern vString *vStringNew (void)
71d4c6f1e6SMasatake YAMATO {
72d4c6f1e6SMasatake YAMATO vString *const string = xMalloc (1, vString);
73d4c6f1e6SMasatake YAMATO
74d4c6f1e6SMasatake YAMATO string->length = 0;
75d4c6f1e6SMasatake YAMATO string->size = vStringInitialSize;
76d4c6f1e6SMasatake YAMATO string->buffer = xMalloc (string->size, char);
77d4c6f1e6SMasatake YAMATO
78d4c6f1e6SMasatake YAMATO vStringClear (string);
79d4c6f1e6SMasatake YAMATO
80d4c6f1e6SMasatake YAMATO return string;
81d4c6f1e6SMasatake YAMATO }
82d4c6f1e6SMasatake YAMATO
vStringNewCopy(const vString * const string)83d4c6f1e6SMasatake YAMATO extern vString *vStringNewCopy (const vString *const string)
84d4c6f1e6SMasatake YAMATO {
85d4c6f1e6SMasatake YAMATO vString *vs = vStringNew ();
86d4c6f1e6SMasatake YAMATO vStringCatS (vs, string->buffer);
87d4c6f1e6SMasatake YAMATO return vs;
88d4c6f1e6SMasatake YAMATO }
89d4c6f1e6SMasatake YAMATO
vStringNewInit(const char * const s)90d4c6f1e6SMasatake YAMATO extern vString *vStringNewInit (const char *const s)
91d4c6f1e6SMasatake YAMATO {
92d4c6f1e6SMasatake YAMATO vString *vs = vStringNew ();
93d4c6f1e6SMasatake YAMATO vStringCatS (vs, s);
94d4c6f1e6SMasatake YAMATO return vs;
95d4c6f1e6SMasatake YAMATO }
96d4c6f1e6SMasatake YAMATO
vStringNewNInit(const char * const s,const size_t length)9753e1215bSMasatake YAMATO extern vString *vStringNewNInit (const char *const s, const size_t length)
9853e1215bSMasatake YAMATO {
9953e1215bSMasatake YAMATO vString *vs = vStringNew ();
10053e1215bSMasatake YAMATO vStringNCatS (vs, s, length);
10153e1215bSMasatake YAMATO return vs;
10253e1215bSMasatake YAMATO }
10353e1215bSMasatake YAMATO
stringCat(vString * const string,const char * const s,const size_t length)1046ee565f3SJiří Techet static void stringCat (
1056ee565f3SJiří Techet vString *const string, const char *const s, const size_t length)
1066ee565f3SJiří Techet {
1078a3d0750SJiří Techet if (string->length + length + 1 > string->size)
1088a3d0750SJiří Techet vStringResize (string, string->length + length + 1);
1096ee565f3SJiří Techet
1101398f48fSColomban Wendling memcpy (string->buffer + string->length, s, length);
1116ee565f3SJiří Techet string->length += length;
1126ee565f3SJiří Techet vStringPut (string, '\0');
1136ee565f3SJiří Techet }
1146ee565f3SJiří Techet
vStringNCat(vString * const string,const vString * const s,const size_t length)1156ee565f3SJiří Techet extern void vStringNCat (
1166ee565f3SJiří Techet vString *const string, const vString *const s, const size_t length)
1176ee565f3SJiří Techet {
1186ee565f3SJiří Techet size_t len = vStringLength (s);
1196ee565f3SJiří Techet
1206ee565f3SJiří Techet len = len < length ? len: length;
1216ee565f3SJiří Techet stringCat (string, s->buffer, len);
1226ee565f3SJiří Techet }
1236ee565f3SJiří Techet
vStringNCatS(vString * const string,const char * const s,const size_t length)124d4c6f1e6SMasatake YAMATO extern void vStringNCatS (
125d4c6f1e6SMasatake YAMATO vString *const string, const char *const s, const size_t length)
126d4c6f1e6SMasatake YAMATO {
1276ee565f3SJiří Techet size_t len = strlen (s);
128d4c6f1e6SMasatake YAMATO
1296ee565f3SJiří Techet len = len < length ? len : length;
1306ee565f3SJiří Techet stringCat (string, s, len);
131d4c6f1e6SMasatake YAMATO }
1326ee565f3SJiří Techet
vStringNCatSUnsafe(vString * const string,const char * const s,const size_t length)1330b374a37SMasatake YAMATO extern void vStringNCatSUnsafe (
1340b374a37SMasatake YAMATO vString *const string, const char *const s, const size_t length)
1350b374a37SMasatake YAMATO {
1360b374a37SMasatake YAMATO stringCat (string, s, length);
1370b374a37SMasatake YAMATO }
1380b374a37SMasatake YAMATO
vStringCat(vString * const string,const vString * const s)1396ee565f3SJiří Techet extern void vStringCat (vString *const string, const vString *const s)
1406ee565f3SJiří Techet {
1416ee565f3SJiří Techet size_t len = vStringLength (s);
1426ee565f3SJiří Techet
1436ee565f3SJiří Techet stringCat (string, s->buffer, len);
1446ee565f3SJiří Techet }
1456ee565f3SJiří Techet
vStringCatS(vString * const string,const char * const s)1466ee565f3SJiří Techet extern void vStringCatS (vString *const string, const char *const s)
1476ee565f3SJiří Techet {
1486ee565f3SJiří Techet size_t len = strlen (s);
1496ee565f3SJiří Techet
1506ee565f3SJiří Techet stringCat (string, s, len);
151d4c6f1e6SMasatake YAMATO }
152d4c6f1e6SMasatake YAMATO
153d4c6f1e6SMasatake YAMATO /* Strip trailing newline from string.
154d4c6f1e6SMasatake YAMATO */
vStringStripNewline(vString * const string)155*5b7dabdaSMasatake YAMATO extern bool vStringStripNewline (vString *const string)
156d4c6f1e6SMasatake YAMATO {
157d4c6f1e6SMasatake YAMATO const size_t final = string->length - 1;
1584cf620d6SMasatake YAMATO
1594cf620d6SMasatake YAMATO if (string->length == 0)
160*5b7dabdaSMasatake YAMATO return false;
1614cf620d6SMasatake YAMATO
162d4c6f1e6SMasatake YAMATO if (string->buffer [final] == '\n')
163d4c6f1e6SMasatake YAMATO {
164d4c6f1e6SMasatake YAMATO string->buffer [final] = '\0';
165d4c6f1e6SMasatake YAMATO string->length--;
166*5b7dabdaSMasatake YAMATO return true;
167d4c6f1e6SMasatake YAMATO }
168*5b7dabdaSMasatake YAMATO
169*5b7dabdaSMasatake YAMATO return false;
170d4c6f1e6SMasatake YAMATO }
171d4c6f1e6SMasatake YAMATO
172d4c6f1e6SMasatake YAMATO /* Strip leading white space from string.
173d4c6f1e6SMasatake YAMATO */
vStringStripLeading(vString * const string)174d4c6f1e6SMasatake YAMATO extern void vStringStripLeading (vString *const string)
175d4c6f1e6SMasatake YAMATO {
1769ea78ad8SColomban Wendling size_t n = 0;
1779ea78ad8SColomban Wendling
1789ea78ad8SColomban Wendling while (n < string->length && isspace ((int) string->buffer [n]))
1799ea78ad8SColomban Wendling n++;
1809ea78ad8SColomban Wendling if (n > 0)
181d4c6f1e6SMasatake YAMATO {
1829ea78ad8SColomban Wendling memmove (string->buffer, string->buffer + n, string->length - n);
1839ea78ad8SColomban Wendling vStringTruncate (string, string->length - n);
184d4c6f1e6SMasatake YAMATO }
185d4c6f1e6SMasatake YAMATO }
186d4c6f1e6SMasatake YAMATO
187d4c6f1e6SMasatake YAMATO /* Strip trailing white space from string.
188d4c6f1e6SMasatake YAMATO */
vStringStripTrailing(vString * const string)189d4c6f1e6SMasatake YAMATO extern void vStringStripTrailing (vString *const string)
190d4c6f1e6SMasatake YAMATO {
191d4c6f1e6SMasatake YAMATO while (string->length > 0 &&
192d4c6f1e6SMasatake YAMATO isspace ((int) string->buffer [string->length - 1]))
193d4c6f1e6SMasatake YAMATO {
194d4c6f1e6SMasatake YAMATO string->length--;
195d4c6f1e6SMasatake YAMATO string->buffer [string->length] = '\0';
196d4c6f1e6SMasatake YAMATO }
197d4c6f1e6SMasatake YAMATO }
198d4c6f1e6SMasatake YAMATO
199d4c6f1e6SMasatake YAMATO /* Chop last character from string.
200d4c6f1e6SMasatake YAMATO */
vStringChop(vString * const string)201d4c6f1e6SMasatake YAMATO extern void vStringChop (vString *const string)
202d4c6f1e6SMasatake YAMATO {
203d4c6f1e6SMasatake YAMATO if (string->length > 0)
204d4c6f1e6SMasatake YAMATO {
205d4c6f1e6SMasatake YAMATO --string->length;
206d4c6f1e6SMasatake YAMATO string->buffer [string->length] = '\0';
207d4c6f1e6SMasatake YAMATO }
208d4c6f1e6SMasatake YAMATO }
209d4c6f1e6SMasatake YAMATO
vStringCopy(vString * const string,const vString * const s)2106ee565f3SJiří Techet extern void vStringCopy (vString *const string, const vString *const s)
2116ee565f3SJiří Techet {
2126ee565f3SJiří Techet vStringClear (string);
2136ee565f3SJiří Techet vStringCat (string, s);
2146ee565f3SJiří Techet }
2156ee565f3SJiří Techet
vStringCopyS(vString * const string,const char * const s)216d4c6f1e6SMasatake YAMATO extern void vStringCopyS (vString *const string, const char *const s)
217d4c6f1e6SMasatake YAMATO {
218d4c6f1e6SMasatake YAMATO vStringClear (string);
219d4c6f1e6SMasatake YAMATO vStringCatS (string, s);
220d4c6f1e6SMasatake YAMATO }
221d4c6f1e6SMasatake YAMATO
vStringNCopy(vString * const string,const vString * const s,const size_t length)2226ee565f3SJiří Techet extern void vStringNCopy (
2236ee565f3SJiří Techet vString *const string, const vString *const s, const size_t length)
2246ee565f3SJiří Techet {
2256ee565f3SJiří Techet vStringClear (string);
2266ee565f3SJiří Techet vStringNCat (string, s, length);
2276ee565f3SJiří Techet }
2286ee565f3SJiří Techet
vStringNCopyS(vString * const string,const char * const s,const size_t length)229d4c6f1e6SMasatake YAMATO extern void vStringNCopyS (
230d4c6f1e6SMasatake YAMATO vString *const string, const char *const s, const size_t length)
231d4c6f1e6SMasatake YAMATO {
232d4c6f1e6SMasatake YAMATO vStringClear (string);
233d4c6f1e6SMasatake YAMATO vStringNCatS (string, s, length);
234d4c6f1e6SMasatake YAMATO }
235d4c6f1e6SMasatake YAMATO
vStringCopyToLower(vString * const dest,const vString * const src)236d4c6f1e6SMasatake YAMATO extern void vStringCopyToLower (vString *const dest, const vString *const src)
237d4c6f1e6SMasatake YAMATO {
238d4c6f1e6SMasatake YAMATO const size_t length = src->length;
239d4c6f1e6SMasatake YAMATO const char *s = src->buffer;
240d4c6f1e6SMasatake YAMATO char *d;
241d4c6f1e6SMasatake YAMATO size_t i;
242d4c6f1e6SMasatake YAMATO
243d4c6f1e6SMasatake YAMATO if (dest->size < src->size)
244d4c6f1e6SMasatake YAMATO vStringResize (dest, src->size);
245d4c6f1e6SMasatake YAMATO d = dest->buffer;
246d4c6f1e6SMasatake YAMATO for (i = 0 ; i < length ; ++i)
247d4c6f1e6SMasatake YAMATO {
248d4c6f1e6SMasatake YAMATO int c = s [i];
249d4c6f1e6SMasatake YAMATO
250d4c6f1e6SMasatake YAMATO d [i] = tolower (c);
251d4c6f1e6SMasatake YAMATO }
252d4c6f1e6SMasatake YAMATO d [i] = '\0';
253d4c6f1e6SMasatake YAMATO }
254d4c6f1e6SMasatake YAMATO
vStringSetLength(vString * const string)255d4c6f1e6SMasatake YAMATO extern void vStringSetLength (vString *const string)
256d4c6f1e6SMasatake YAMATO {
257d4c6f1e6SMasatake YAMATO string->length = strlen (string->buffer);
258d4c6f1e6SMasatake YAMATO }
259d4c6f1e6SMasatake YAMATO
vStringNewOwn(char * s)260d4c6f1e6SMasatake YAMATO extern vString *vStringNewOwn (char *s)
261d4c6f1e6SMasatake YAMATO {
262d4c6f1e6SMasatake YAMATO vString *r;
263d4c6f1e6SMasatake YAMATO
264d4c6f1e6SMasatake YAMATO r = vStringNewInit (s);
265d4c6f1e6SMasatake YAMATO eFree (s);
266d4c6f1e6SMasatake YAMATO
267d4c6f1e6SMasatake YAMATO return r;
268d4c6f1e6SMasatake YAMATO }
269d4c6f1e6SMasatake YAMATO
vStringDeleteUnwrap(vString * const string)270d4c6f1e6SMasatake YAMATO extern char *vStringDeleteUnwrap (vString *const string)
271d4c6f1e6SMasatake YAMATO {
272d4c6f1e6SMasatake YAMATO char *buffer = NULL;
273d4c6f1e6SMasatake YAMATO
274d4c6f1e6SMasatake YAMATO
275d4c6f1e6SMasatake YAMATO if (string != NULL)
276d4c6f1e6SMasatake YAMATO {
277d4c6f1e6SMasatake YAMATO buffer = string->buffer;
278d4c6f1e6SMasatake YAMATO string->buffer = NULL;
279d4c6f1e6SMasatake YAMATO
280d4c6f1e6SMasatake YAMATO string->size = 0;
281d4c6f1e6SMasatake YAMATO string->length = 0;
282d4c6f1e6SMasatake YAMATO
283d4c6f1e6SMasatake YAMATO eFree (string);
284d4c6f1e6SMasatake YAMATO }
285d4c6f1e6SMasatake YAMATO
286d4c6f1e6SMasatake YAMATO return buffer;
287d4c6f1e6SMasatake YAMATO }
288d4c6f1e6SMasatake YAMATO
vStringStrdup(const vString * const string)289f270909bSMasatake YAMATO extern char *vStringStrdup (const vString *const string)
290f270909bSMasatake YAMATO {
291f270909bSMasatake YAMATO char *str = xMalloc (vStringLength(string) + 1, char);
292f270909bSMasatake YAMATO str[vStringLength(string)] = '\0';
293f270909bSMasatake YAMATO memcpy (str, string->buffer, vStringLength(string));
294f270909bSMasatake YAMATO return str;
295f270909bSMasatake YAMATO }
296f270909bSMasatake YAMATO
valueToXDigit(int v)297e8175bbbSMasatake YAMATO static char valueToXDigit (int v)
298e8175bbbSMasatake YAMATO {
299e8175bbbSMasatake YAMATO Assert (v >= 0 && v <= 0xF);
300e8175bbbSMasatake YAMATO
301e8175bbbSMasatake YAMATO if (v >= 0xA)
302e8175bbbSMasatake YAMATO return 'A' + (v - 0xA);
303e8175bbbSMasatake YAMATO else
304e8175bbbSMasatake YAMATO return '0' + v;
305e8175bbbSMasatake YAMATO }
306e8175bbbSMasatake YAMATO
vStringCatSWithEscaping(vString * b,const char * s)307e8175bbbSMasatake YAMATO extern void vStringCatSWithEscaping (vString* b, const char *s)
308e8175bbbSMasatake YAMATO {
309e8175bbbSMasatake YAMATO for(; *s; s++)
310e8175bbbSMasatake YAMATO {
311e8175bbbSMasatake YAMATO int c = *s;
312e8175bbbSMasatake YAMATO
313e8175bbbSMasatake YAMATO /* escape control characters (incl. \t) */
314e8175bbbSMasatake YAMATO if ((c > 0x00 && c <= 0x1F) || c == 0x7F || c == '\\')
315e8175bbbSMasatake YAMATO {
316e8175bbbSMasatake YAMATO vStringPut (b, '\\');
317e8175bbbSMasatake YAMATO
318e8175bbbSMasatake YAMATO switch (c)
319e8175bbbSMasatake YAMATO {
320e8175bbbSMasatake YAMATO /* use a short form for known escapes */
321e8175bbbSMasatake YAMATO case '\a':
322e8175bbbSMasatake YAMATO c = 'a'; break;
323e8175bbbSMasatake YAMATO case '\b':
324e8175bbbSMasatake YAMATO c = 'b'; break;
325e8175bbbSMasatake YAMATO case '\t':
326e8175bbbSMasatake YAMATO c = 't'; break;
327e8175bbbSMasatake YAMATO case '\n':
328e8175bbbSMasatake YAMATO c = 'n'; break;
329e8175bbbSMasatake YAMATO case '\v':
330e8175bbbSMasatake YAMATO c = 'v'; break;
331e8175bbbSMasatake YAMATO case '\f':
332e8175bbbSMasatake YAMATO c = 'f'; break;
333e8175bbbSMasatake YAMATO case '\r':
334e8175bbbSMasatake YAMATO c = 'r'; break;
335e8175bbbSMasatake YAMATO case '\\':
336e8175bbbSMasatake YAMATO c = '\\'; break;
337e8175bbbSMasatake YAMATO default:
338e8175bbbSMasatake YAMATO vStringPut (b, 'x');
339e8175bbbSMasatake YAMATO vStringPut (b, valueToXDigit ((c & 0xF0) >> 4));
340e8175bbbSMasatake YAMATO vStringPut (b, valueToXDigit (c & 0x0F));
341e8175bbbSMasatake YAMATO continue;
342e8175bbbSMasatake YAMATO }
343e8175bbbSMasatake YAMATO }
344e8175bbbSMasatake YAMATO vStringPut (b, c);
345e8175bbbSMasatake YAMATO }
346e8175bbbSMasatake YAMATO }
347e8175bbbSMasatake YAMATO
vStringCatSWithEscapingAsPattern(vString * output,const char * input)3489042b8b4SMasatake YAMATO extern void vStringCatSWithEscapingAsPattern (vString *output, const char* input)
3499042b8b4SMasatake YAMATO {
3509042b8b4SMasatake YAMATO while (*input)
3519042b8b4SMasatake YAMATO {
3529042b8b4SMasatake YAMATO switch (*input)
3539042b8b4SMasatake YAMATO {
3549042b8b4SMasatake YAMATO case '\\':
3559042b8b4SMasatake YAMATO vStringPut(output, '\\');
3569042b8b4SMasatake YAMATO vStringPut(output, '\\');
3579042b8b4SMasatake YAMATO break;
3589042b8b4SMasatake YAMATO case '/':
3599042b8b4SMasatake YAMATO vStringPut(output, '\\');
3609042b8b4SMasatake YAMATO vStringPut(output, '/');
3619042b8b4SMasatake YAMATO break;
3629042b8b4SMasatake YAMATO default:
3639042b8b4SMasatake YAMATO vStringPut(output, *input);
3649042b8b4SMasatake YAMATO break;
3659042b8b4SMasatake YAMATO
3669042b8b4SMasatake YAMATO }
3679042b8b4SMasatake YAMATO input++;
3689042b8b4SMasatake YAMATO }
3699042b8b4SMasatake YAMATO }
3709042b8b4SMasatake YAMATO
vStringNewOrClear(vString * const string)371bffaa988SMasatake YAMATO extern vString *vStringNewOrClear (vString *const string)
372bffaa988SMasatake YAMATO {
373bffaa988SMasatake YAMATO if (string)
374bffaa988SMasatake YAMATO {
375bffaa988SMasatake YAMATO vStringClear (string);
376bffaa988SMasatake YAMATO return string;
377bffaa988SMasatake YAMATO }
378bffaa988SMasatake YAMATO else
379bffaa988SMasatake YAMATO return vStringNew ();
380bffaa988SMasatake YAMATO }
38156065e52SMasatake YAMATO
vStringNewOrClearWithAutoRelease(vString * const string)38256065e52SMasatake YAMATO extern vString *vStringNewOrClearWithAutoRelease (vString *const string)
38356065e52SMasatake YAMATO {
38456065e52SMasatake YAMATO vString *r;
38556065e52SMasatake YAMATO
38656065e52SMasatake YAMATO bool autoRelease = false;
38756065e52SMasatake YAMATO if (!string)
38856065e52SMasatake YAMATO autoRelease = true;
38956065e52SMasatake YAMATO
39056065e52SMasatake YAMATO r = vStringNewOrClear(string);
39156065e52SMasatake YAMATO if (autoRelease)
39233a6fdb8SMasatake YAMATO DEFAULT_TRASH_BOX(r, vStringDelete);
39356065e52SMasatake YAMATO
39456065e52SMasatake YAMATO return r;
39556065e52SMasatake YAMATO }
396c5a701a9SMasatake YAMATO
vStringTranslate(vString * const string,char fromC,char toC)397c5a701a9SMasatake YAMATO extern void vStringTranslate(vString *const string, char fromC, char toC)
398c5a701a9SMasatake YAMATO {
3994c64e833SMasatake YAMATO for (unsigned int i = 0; i < vStringLength(string); i++)
400c5a701a9SMasatake YAMATO {
401c5a701a9SMasatake YAMATO if (string->buffer[i] == fromC)
402c5a701a9SMasatake YAMATO string->buffer[i] = toC;
403c5a701a9SMasatake YAMATO }
404c5a701a9SMasatake YAMATO }
405