2 * Copyright (c) 1998-2002, Darren Hiebert
4 * This source code is released for free distribution under the terms of the
5 * GNU General Public License version 2 or (at your option) any later version.
7 * This module contains functions supporting resizeable strings.
13 #include "general.h" /* must always come first */
15 #include <limits.h> /* to define INT_MAX */
27 static const size_t vStringInitialSize
= 32;
30 * FUNCTION DEFINITIONS
37 extern void vStringResize (vString
*const string
, const size_t newSize
)
39 size_t size
= vStringInitialSize
;
41 while (size
< newSize
)
44 if (size
> string
->size
)
47 string
->buffer
= xRealloc (string
->buffer
, size
, char);
51 extern void vStringTruncate (vString
*const string
, const size_t length
)
53 Assert (length
<= string
->length
);
54 string
->length
= length
;
55 string
->buffer
[string
->length
] = '\0';
56 DebugStatement ( memset (string
->buffer
+ string
->length
, 0,
57 string
->size
- string
->length
); )
60 extern void vStringDelete (vString
*const string
)
64 if (string
->buffer
!= NULL
)
65 eFree (string
->buffer
);
70 extern vString
*vStringNew (void)
72 vString
*const string
= xMalloc (1, vString
);
75 string
->size
= vStringInitialSize
;
76 string
->buffer
= xMalloc (string
->size
, char);
78 vStringClear (string
);
83 extern vString
*vStringNewCopy (const vString
*const string
)
85 vString
*vs
= vStringNew ();
86 vStringCatS (vs
, string
->buffer
);
90 extern vString
*vStringNewInit (const char *const s
)
92 vString
*vs
= vStringNew ();
97 extern vString
*vStringNewNInit (const char *const s
, const size_t length
)
99 vString
*vs
= vStringNew ();
100 vStringNCatS (vs
, s
, length
);
104 static void stringCat (
105 vString
*const string
, const char *const s
, const size_t length
)
107 if (string
->length
+ length
+ 1 > string
->size
)
108 vStringResize (string
, string
->length
+ length
+ 1);
110 memcpy (string
->buffer
+ string
->length
, s
, length
);
111 string
->length
+= length
;
112 vStringPut (string
, '\0');
115 extern void vStringNCat (
116 vString
*const string
, const vString
*const s
, const size_t length
)
118 size_t len
= vStringLength (s
);
120 len
= len
< length
? len
: length
;
121 stringCat (string
, s
->buffer
, len
);
124 extern void vStringNCatS (
125 vString
*const string
, const char *const s
, const size_t length
)
127 size_t len
= strnlen (s
, length
);
129 stringCat (string
, s
, len
);
132 extern void vStringNCatSUnsafe (
133 vString
*const string
, const char *const s
, const size_t length
)
135 stringCat (string
, s
, length
);
138 extern void vStringCat (vString
*const string
, const vString
*const s
)
140 size_t len
= vStringLength (s
);
142 stringCat (string
, s
->buffer
, len
);
145 extern void vStringCatS (vString
*const string
, const char *const s
)
147 size_t len
= strlen (s
);
149 stringCat (string
, s
, len
);
152 /* Strip trailing newline from string.
154 extern bool vStringStripNewline (vString
*const string
)
156 const size_t final
= string
->length
- 1;
158 if (string
->length
== 0)
161 if (string
->buffer
[final
] == '\n')
163 string
->buffer
[final
] = '\0';
171 /* Strip leading white space from string.
173 extern void vStringStripLeading (vString
*const string
)
177 while (n
< string
->length
&& isspace ((unsigned char) string
->buffer
[n
]))
179 vStringTruncateLeading (string
, n
);
182 extern void vStringTruncateLeading (vString
*const string
, const size_t length
)
184 size_t n
= vStringLength (string
);
189 memmove (string
->buffer
, string
->buffer
+ n
, string
->length
- n
);
190 vStringTruncate (string
, string
->length
- n
);
194 /* Strip trailing white space from string.
196 extern void vStringStripTrailing (vString
*const string
)
198 while (string
->length
> 0 &&
199 isspace ((unsigned char) string
->buffer
[string
->length
- 1]))
202 string
->buffer
[string
->length
] = '\0';
206 /* Chop last character from string.
208 extern void vStringChop (vString
*const string
)
210 if (string
->length
> 0)
213 string
->buffer
[string
->length
] = '\0';
217 extern void vStringCopy (vString
*const string
, const vString
*const s
)
219 vStringClear (string
);
220 vStringCat (string
, s
);
223 extern void vStringCopyS (vString
*const string
, const char *const s
)
225 vStringClear (string
);
226 vStringCatS (string
, s
);
229 extern void vStringNCopy (
230 vString
*const string
, const vString
*const s
, const size_t length
)
232 vStringClear (string
);
233 vStringNCat (string
, s
, length
);
236 extern void vStringNCopyS (
237 vString
*const string
, const char *const s
, const size_t length
)
239 vStringClear (string
);
240 vStringNCatS (string
, s
, length
);
243 extern void vStringNCopySUnsafe (
244 vString
*const string
, const char *const s
, const size_t length
)
246 vStringClear (string
);
247 vStringNCatSUnsafe (string
, s
, length
);
250 extern void vStringCopyToLower (vString
*const dest
, const vString
*const src
)
252 const size_t length
= src
->length
;
253 const char *s
= src
->buffer
;
257 if (dest
->size
< src
->size
)
258 vStringResize (dest
, src
->size
);
260 for (i
= 0 ; i
< length
; ++i
)
261 d
[i
] = (char) tolower ((unsigned char) s
[i
]);
265 extern void vStringSetLength (vString
*const string
)
267 string
->length
= strlen (string
->buffer
);
270 extern vString
*vStringNewOwn (char *s
)
274 r
= vStringNewInit (s
);
280 extern char *vStringDeleteUnwrap (vString
*const string
)
287 buffer
= string
->buffer
;
288 string
->buffer
= NULL
;
299 extern char *vStringStrdup (const vString
*const string
)
301 char *str
= xMalloc (vStringLength(string
) + 1, char);
302 str
[vStringLength(string
)] = '\0';
303 memcpy (str
, string
->buffer
, vStringLength(string
));
307 static int valueToXDigit (int v
)
309 Assert (v
>= 0 && v
<= 0xF);
312 return 'A' + (v
- 0xA);
317 extern void vStringCatSWithEscaping (vString
* b
, const char *s
)
321 unsigned char c
= (unsigned char) *s
;
323 /* escape control characters (incl. \t) */
324 if ((c
> 0x00 && c
<= 0x1F) || c
== 0x7F || c
== '\\')
326 vStringPut (b
, '\\');
330 /* use a short form for known escapes */
349 vStringPut (b
, valueToXDigit ((c
& 0xF0) >> 4));
350 vStringPut (b
, valueToXDigit (c
& 0x0F));
358 extern void vStringCatSWithEscapingAsPattern (vString
*output
, const char* input
)
365 vStringPut(output
, '\\');
366 vStringPut(output
, '\\');
369 vStringPut(output
, '\\');
370 vStringPut(output
, '/');
373 vStringPut(output
, *input
);
381 extern vString
*vStringNewOrClear (vString
*const string
)
385 vStringClear (string
);
389 return vStringNew ();
392 extern vString
*vStringNewOrClearWithAutoRelease (vString
*const string
)
396 bool autoRelease
= false;
400 r
= vStringNewOrClear(string
);
402 DEFAULT_TRASH_BOX(r
, vStringDelete
);
407 extern void vStringTranslate(vString
*const string
, char fromC
, char toC
)
409 for (unsigned int i
= 0; i
< vStringLength(string
); i
++)
411 if (string
->buffer
[i
] == fromC
)
412 string
->buffer
[i
] = toC
;