1
/* An abstract string datatype.
2
Copyright (C) 1998, 1999, 2000, 2002 Free Software Foundation, Inc.
3
Contributed by Mark Mitchell (mark@markmitchell.com).
5
This file is part of GNU CC.
7
GNU CC is free software; you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation; either version 2, or (at your option)
12
In addition to the permissions in the GNU General Public License, the
13
Free Software Foundation gives you unlimited permission to link the
14
compiled version of this file into combinations with other programs,
15
and to distribute those combinations without any restriction coming
16
from the use of this file. (The General Public License restrictions
17
do apply in other respects; for example, they cover modification of
18
the file, and distribution when not linked into a combined
21
GNU CC is distributed in the hope that it will be useful,
22
but WITHOUT ANY WARRANTY; without even the implied warranty of
23
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24
GNU General Public License for more details.
26
You should have received a copy of the GNU General Public License
27
along with GNU CC; see the file COPYING. If not, write to
28
the Free Software Foundation, 59 Temple Place - Suite 330,
29
Boston, MA 02111-1307, USA. */
45
#include "libiberty.h"
46
#include "dyn-string.h"
48
/* If this file is being compiled for inclusion in the C++ runtime
49
library, as part of the demangler implementation, we don't want to
50
abort if an allocation fails. Instead, percolate an error code up
51
through the call chain. */
53
#if defined(IN_LIBGCC2) || defined(IN_GLIBCPP_V3)
54
#define RETURN_ON_ALLOCATION_FAILURE
57
/* Performs in-place initialization of a dyn_string struct. This
58
function can be used with a dyn_string struct on the stack or
59
embedded in another object. The contents of of the string itself
60
are still dynamically allocated. The string initially is capable
61
of holding at least SPACE characeters, including the terminating
62
NUL. If SPACE is 0, it will silently be increated to 1.
64
If RETURN_ON_ALLOCATION_FAILURE is defined and memory allocation
65
fails, returns 0. Otherwise returns 1. */
68
dyn_string_init (ds_struct_ptr, space)
69
struct dyn_string *ds_struct_ptr;
72
/* We need at least one byte in which to store the terminating NUL. */
76
#ifdef RETURN_ON_ALLOCATION_FAILURE
77
ds_struct_ptr->s = (char *) malloc (space);
78
if (ds_struct_ptr->s == NULL)
81
ds_struct_ptr->s = (char *) xmalloc (space);
83
ds_struct_ptr->allocated = space;
84
ds_struct_ptr->length = 0;
85
ds_struct_ptr->s[0] = '\0';
90
/* Create a new dynamic string capable of holding at least SPACE
91
characters, including the terminating NUL. If SPACE is 0, it will
92
be silently increased to 1. If RETURN_ON_ALLOCATION_FAILURE is
93
defined and memory allocation fails, returns NULL. Otherwise
94
returns the newly allocated string. */
97
dyn_string_new (space)
101
#ifdef RETURN_ON_ALLOCATION_FAILURE
102
result = (dyn_string_t) malloc (sizeof (struct dyn_string));
105
if (!dyn_string_init (result, space))
111
result = (dyn_string_t) xmalloc (sizeof (struct dyn_string));
112
dyn_string_init (result, space);
117
/* Free the memory used by DS. */
120
dyn_string_delete (ds)
127
/* Returns the contents of DS in a buffer allocated with malloc. It
128
is the caller's responsibility to deallocate the buffer using free.
129
DS is then set to the empty string. Deletes DS itself. */
132
dyn_string_release (ds)
135
/* Store the old buffer. */
136
char* result = ds->s;
137
/* The buffer is no longer owned by DS. */
141
/* Return the old buffer. */
145
/* Increase the capacity of DS so it can hold at least SPACE
146
characters, plus the terminating NUL. This function will not (at
147
present) reduce the capacity of DS. Returns DS on success.
149
If RETURN_ON_ALLOCATION_FAILURE is defined and a memory allocation
150
operation fails, deletes DS and returns NULL. */
153
dyn_string_resize (ds, space)
157
int new_allocated = ds->allocated;
159
/* Increase SPACE to hold the NUL termination. */
162
/* Increase allocation by factors of two. */
163
while (space > new_allocated)
166
if (new_allocated != ds->allocated)
168
ds->allocated = new_allocated;
169
/* We actually need more space. */
170
#ifdef RETURN_ON_ALLOCATION_FAILURE
171
ds->s = (char *) realloc (ds->s, ds->allocated);
178
ds->s = (char *) xrealloc (ds->s, ds->allocated);
185
/* Sets the contents of DS to the empty string. */
188
dyn_string_clear (ds)
191
/* A dyn_string always has room for at least the NUL terminator. */
196
/* Makes the contents of DEST the same as the contents of SRC. DEST
197
and SRC must be distinct. Returns 1 on success. On failure, if
198
RETURN_ON_ALLOCATION_FAILURE, deletes DEST and returns 0. */
201
dyn_string_copy (dest, src)
208
/* Make room in DEST. */
209
if (dyn_string_resize (dest, src->length) == NULL)
211
/* Copy DEST into SRC. */
212
strcpy (dest->s, src->s);
213
/* Update the size of DEST. */
214
dest->length = src->length;
218
/* Copies SRC, a NUL-terminated string, into DEST. Returns 1 on
219
success. On failure, if RETURN_ON_ALLOCATION_FAILURE, deletes DEST
223
dyn_string_copy_cstr (dest, src)
227
int length = strlen (src);
228
/* Make room in DEST. */
229
if (dyn_string_resize (dest, length) == NULL)
231
/* Copy DEST into SRC. */
232
strcpy (dest->s, src);
233
/* Update the size of DEST. */
234
dest->length = length;
238
/* Inserts SRC at the beginning of DEST. DEST is expanded as
239
necessary. SRC and DEST must be distinct. Returns 1 on success.
240
On failure, if RETURN_ON_ALLOCATION_FAILURE, deletes DEST and
244
dyn_string_prepend (dest, src)
248
return dyn_string_insert (dest, 0, src);
251
/* Inserts SRC, a NUL-terminated string, at the beginning of DEST.
252
DEST is expanded as necessary. Returns 1 on success. On failure,
253
if RETURN_ON_ALLOCATION_FAILURE, deletes DEST and returns 0. */
256
dyn_string_prepend_cstr (dest, src)
260
return dyn_string_insert_cstr (dest, 0, src);
263
/* Inserts SRC into DEST starting at position POS. DEST is expanded
264
as necessary. SRC and DEST must be distinct. Returns 1 on
265
success. On failure, if RETURN_ON_ALLOCATION_FAILURE, deletes DEST
269
dyn_string_insert (dest, pos, src)
279
if (dyn_string_resize (dest, dest->length + src->length) == NULL)
281
/* Make room for the insertion. Be sure to copy the NUL. */
282
for (i = dest->length; i >= pos; --i)
283
dest->s[i + src->length] = dest->s[i];
284
/* Splice in the new stuff. */
285
strncpy (dest->s + pos, src->s, src->length);
286
/* Compute the new length. */
287
dest->length += src->length;
291
/* Inserts SRC, a NUL-terminated string, into DEST starting at
292
position POS. DEST is expanded as necessary. Returns 1 on
293
success. On failure, RETURN_ON_ALLOCATION_FAILURE, deletes DEST
297
dyn_string_insert_cstr (dest, pos, src)
303
int length = strlen (src);
305
if (dyn_string_resize (dest, dest->length + length) == NULL)
307
/* Make room for the insertion. Be sure to copy the NUL. */
308
for (i = dest->length; i >= pos; --i)
309
dest->s[i + length] = dest->s[i];
310
/* Splice in the new stuff. */
311
strncpy (dest->s + pos, src, length);
312
/* Compute the new length. */
313
dest->length += length;
317
/* Inserts character C into DEST starting at position POS. DEST is
318
expanded as necessary. Returns 1 on success. On failure,
319
RETURN_ON_ALLOCATION_FAILURE, deletes DEST and returns 0. */
322
dyn_string_insert_char (dest, pos, c)
329
if (dyn_string_resize (dest, dest->length + 1) == NULL)
331
/* Make room for the insertion. Be sure to copy the NUL. */
332
for (i = dest->length; i >= pos; --i)
333
dest->s[i + 1] = dest->s[i];
334
/* Add the new character. */
336
/* Compute the new length. */
341
/* Append S to DS, resizing DS if necessary. Returns 1 on success.
342
On failure, if RETURN_ON_ALLOCATION_FAILURE, deletes DEST and
346
dyn_string_append (dest, s)
350
if (dyn_string_resize (dest, dest->length + s->length) == 0)
352
strcpy (dest->s + dest->length, s->s);
353
dest->length += s->length;
357
/* Append the NUL-terminated string S to DS, resizing DS if necessary.
358
Returns 1 on success. On failure, if RETURN_ON_ALLOCATION_FAILURE,
359
deletes DEST and returns 0. */
362
dyn_string_append_cstr (dest, s)
366
int len = strlen (s);
368
/* The new length is the old length plus the size of our string, plus
369
one for the null at the end. */
370
if (dyn_string_resize (dest, dest->length + len) == NULL)
372
strcpy (dest->s + dest->length, s);
377
/* Appends C to the end of DEST. Returns 1 on success. On failiure,
378
if RETURN_ON_ALLOCATION_FAILURE, deletes DEST and returns 0. */
381
dyn_string_append_char (dest, c)
385
/* Make room for the extra character. */
386
if (dyn_string_resize (dest, dest->length + 1) == NULL)
388
/* Append the character; it will overwrite the old NUL. */
389
dest->s[dest->length] = c;
390
/* Add a new NUL at the end. */
391
dest->s[dest->length + 1] = '\0';
392
/* Update the length. */
397
/* Sets the contents of DEST to the substring of SRC starting at START
398
and ending before END. START must be less than or equal to END,
399
and both must be between zero and the length of SRC, inclusive.
400
Returns 1 on success. On failure, if RETURN_ON_ALLOCATION_FAILURE,
401
deletes DEST and returns 0. */
404
dyn_string_substring (dest, src, start, end)
411
int length = end - start;
413
if (start > end || start > src->length || end > src->length)
416
/* Make room for the substring. */
417
if (dyn_string_resize (dest, length) == NULL)
419
/* Copy the characters in the substring, */
420
for (i = length; --i >= 0; )
421
dest->s[i] = src->s[start + i];
422
/* NUL-terimate the result. */
423
dest->s[length] = '\0';
424
/* Record the length of the substring. */
425
dest->length = length;
430
/* Returns non-zero if DS1 and DS2 have the same contents. */
433
dyn_string_eq (ds1, ds2)
437
/* If DS1 and DS2 have different lengths, they must not be the same. */
438
if (ds1->length != ds2->length)
441
return !strcmp (ds1->s, ds2->s);