]> git.ipfire.org Git - thirdparty/gcc.git/blame - libiberty/dyn-string.c
Cleaned up Jan's ChangeLog entries
[thirdparty/gcc.git] / libiberty / dyn-string.c
CommitLineData
69afa80d 1/* An abstract string datatype.
2b613c6a 2 Copyright (C) 1998, 1999, 2000, 2002 Free Software Foundation, Inc.
69afa80d
AS
3 Contributed by Mark Mitchell (mark@markmitchell.com).
4
5This file is part of GNU CC.
6
7GNU CC is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
2b613c6a
MM
12In addition to the permissions in the GNU General Public License, the
13Free Software Foundation gives you unlimited permission to link the
14compiled version of this file into combinations with other programs,
15and to distribute those combinations without any restriction coming
16from the use of this file. (The General Public License restrictions
17do apply in other respects; for example, they cover modification of
18the file, and distribution when not linked into a combined
19executable.)
20
69afa80d
AS
21GNU CC is distributed in the hope that it will be useful,
22but WITHOUT ANY WARRANTY; without even the implied warranty of
23MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24GNU General Public License for more details.
25
26You should have received a copy of the GNU General Public License
27along with GNU CC; see the file COPYING. If not, write to
28the Free Software Foundation, 59 Temple Place - Suite 330,
29Boston, MA 02111-1307, USA. */
30
31#ifdef HAVE_CONFIG_H
32#include "config.h"
33#endif
34
48f3e29b
PDM
35#include <stdio.h>
36
69afa80d
AS
37#ifdef HAVE_STRING_H
38#include <string.h>
39#endif
40
41#ifdef HAVE_STDLIB_H
42#include <stdlib.h>
43#endif
44
45#include "libiberty.h"
46#include "dyn-string.h"
47
051664b0
AS
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. */
52
bd7e6f2d 53#if defined(IN_LIBGCC2) || defined(IN_GLIBCPP_V3)
051664b0
AS
54#define RETURN_ON_ALLOCATION_FAILURE
55#endif
56
69afa80d
AS
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
051664b0 62 NUL. If SPACE is 0, it will silently be increated to 1.
69afa80d 63
051664b0
AS
64 If RETURN_ON_ALLOCATION_FAILURE is defined and memory allocation
65 fails, returns 0. Otherwise returns 1. */
66
67int
69afa80d
AS
68dyn_string_init (ds_struct_ptr, space)
69 struct dyn_string *ds_struct_ptr;
70 int space;
71{
72 /* We need at least one byte in which to store the terminating NUL. */
73 if (space == 0)
74 space = 1;
75
051664b0
AS
76#ifdef RETURN_ON_ALLOCATION_FAILURE
77 ds_struct_ptr->s = (char *) malloc (space);
78 if (ds_struct_ptr->s == NULL)
79 return 0;
80#else
69afa80d 81 ds_struct_ptr->s = (char *) xmalloc (space);
051664b0
AS
82#endif
83 ds_struct_ptr->allocated = space;
69afa80d
AS
84 ds_struct_ptr->length = 0;
85 ds_struct_ptr->s[0] = '\0';
69afa80d 86
051664b0
AS
87 return 1;
88}
89
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. */
69afa80d
AS
95
96dyn_string_t
97dyn_string_new (space)
98 int space;
99{
051664b0
AS
100 dyn_string_t result;
101#ifdef RETURN_ON_ALLOCATION_FAILURE
102 result = (dyn_string_t) malloc (sizeof (struct dyn_string));
103 if (result == NULL)
104 return NULL;
105 if (!dyn_string_init (result, space))
106 {
107 free (result);
108 return NULL;
109 }
110#else
111 result = (dyn_string_t) xmalloc (sizeof (struct dyn_string));
69afa80d 112 dyn_string_init (result, space);
051664b0 113#endif
69afa80d
AS
114 return result;
115}
116
117/* Free the memory used by DS. */
118
119void
120dyn_string_delete (ds)
121 dyn_string_t ds;
122{
123 free (ds->s);
124 free (ds);
125}
126
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.
051664b0 129 DS is then set to the empty string. Deletes DS itself. */
69afa80d
AS
130
131char*
132dyn_string_release (ds)
133 dyn_string_t ds;
134{
135 /* Store the old buffer. */
136 char* result = ds->s;
137 /* The buffer is no longer owned by DS. */
138 ds->s = NULL;
051664b0
AS
139 /* Delete DS. */
140 free (ds);
69afa80d
AS
141 /* Return the old buffer. */
142 return result;
143}
144
145/* Increase the capacity of DS so it can hold at least SPACE
146 characters, plus the terminating NUL. This function will not (at
051664b0
AS
147 present) reduce the capacity of DS. Returns DS on success.
148
149 If RETURN_ON_ALLOCATION_FAILURE is defined and a memory allocation
150 operation fails, deletes DS and returns NULL. */
69afa80d
AS
151
152dyn_string_t
153dyn_string_resize (ds, space)
154 dyn_string_t ds;
155 int space;
156{
157 int new_allocated = ds->allocated;
158
159 /* Increase SPACE to hold the NUL termination. */
160 ++space;
161
051664b0 162 /* Increase allocation by factors of two. */
69afa80d
AS
163 while (space > new_allocated)
164 new_allocated *= 2;
165
166 if (new_allocated != ds->allocated)
167 {
69afa80d 168 ds->allocated = new_allocated;
051664b0
AS
169 /* We actually need more space. */
170#ifdef RETURN_ON_ALLOCATION_FAILURE
171 ds->s = (char *) realloc (ds->s, ds->allocated);
172 if (ds->s == NULL)
173 {
174 free (ds);
175 return NULL;
176 }
177#else
69afa80d 178 ds->s = (char *) xrealloc (ds->s, ds->allocated);
051664b0 179#endif
69afa80d
AS
180 }
181
182 return ds;
183}
184
185/* Sets the contents of DS to the empty string. */
186
187void
188dyn_string_clear (ds)
189 dyn_string_t ds;
190{
191 /* A dyn_string always has room for at least the NUL terminator. */
192 ds->s[0] = '\0';
193 ds->length = 0;
194}
195
196/* Makes the contents of DEST the same as the contents of SRC. DEST
051664b0
AS
197 and SRC must be distinct. Returns 1 on success. On failure, if
198 RETURN_ON_ALLOCATION_FAILURE, deletes DEST and returns 0. */
69afa80d 199
051664b0 200int
69afa80d
AS
201dyn_string_copy (dest, src)
202 dyn_string_t dest;
203 dyn_string_t src;
204{
205 if (dest == src)
206 abort ();
207
208 /* Make room in DEST. */
051664b0
AS
209 if (dyn_string_resize (dest, src->length) == NULL)
210 return 0;
69afa80d
AS
211 /* Copy DEST into SRC. */
212 strcpy (dest->s, src->s);
213 /* Update the size of DEST. */
214 dest->length = src->length;
051664b0 215 return 1;
69afa80d
AS
216}
217
051664b0
AS
218/* Copies SRC, a NUL-terminated string, into DEST. Returns 1 on
219 success. On failure, if RETURN_ON_ALLOCATION_FAILURE, deletes DEST
220 and returns 0. */
69afa80d 221
051664b0 222int
69afa80d
AS
223dyn_string_copy_cstr (dest, src)
224 dyn_string_t dest;
225 const char *src;
226{
227 int length = strlen (src);
228 /* Make room in DEST. */
051664b0
AS
229 if (dyn_string_resize (dest, length) == NULL)
230 return 0;
69afa80d
AS
231 /* Copy DEST into SRC. */
232 strcpy (dest->s, src);
233 /* Update the size of DEST. */
234 dest->length = length;
051664b0 235 return 1;
69afa80d
AS
236}
237
238/* Inserts SRC at the beginning of DEST. DEST is expanded as
051664b0
AS
239 necessary. SRC and DEST must be distinct. Returns 1 on success.
240 On failure, if RETURN_ON_ALLOCATION_FAILURE, deletes DEST and
241 returns 0. */
69afa80d 242
051664b0 243int
69afa80d
AS
244dyn_string_prepend (dest, src)
245 dyn_string_t dest;
246 dyn_string_t src;
247{
051664b0 248 return dyn_string_insert (dest, 0, src);
69afa80d
AS
249}
250
251/* Inserts SRC, a NUL-terminated string, at the beginning of DEST.
051664b0
AS
252 DEST is expanded as necessary. Returns 1 on success. On failure,
253 if RETURN_ON_ALLOCATION_FAILURE, deletes DEST and returns 0. */
69afa80d 254
051664b0 255int
69afa80d
AS
256dyn_string_prepend_cstr (dest, src)
257 dyn_string_t dest;
258 const char *src;
259{
051664b0 260 return dyn_string_insert_cstr (dest, 0, src);
69afa80d
AS
261}
262
051664b0
AS
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
266 and returns 0. */
69afa80d 267
051664b0 268int
69afa80d
AS
269dyn_string_insert (dest, pos, src)
270 dyn_string_t dest;
271 int pos;
272 dyn_string_t src;
273{
274 int i;
275
276 if (src == dest)
277 abort ();
278
051664b0
AS
279 if (dyn_string_resize (dest, dest->length + src->length) == NULL)
280 return 0;
69afa80d
AS
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;
051664b0 288 return 1;
69afa80d
AS
289}
290
291/* Inserts SRC, a NUL-terminated string, into DEST starting at
051664b0
AS
292 position POS. DEST is expanded as necessary. Returns 1 on
293 success. On failure, RETURN_ON_ALLOCATION_FAILURE, deletes DEST
294 and returns 0. */
69afa80d 295
051664b0 296int
69afa80d
AS
297dyn_string_insert_cstr (dest, pos, src)
298 dyn_string_t dest;
299 int pos;
300 const char *src;
301{
302 int i;
303 int length = strlen (src);
304
051664b0
AS
305 if (dyn_string_resize (dest, dest->length + length) == NULL)
306 return 0;
69afa80d
AS
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;
051664b0 314 return 1;
69afa80d
AS
315}
316
31e0ab1f
AS
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. */
320
321int
322dyn_string_insert_char (dest, pos, c)
323 dyn_string_t dest;
324 int pos;
325 int c;
326{
327 int i;
328
329 if (dyn_string_resize (dest, dest->length + 1) == NULL)
330 return 0;
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. */
335 dest->s[pos] = c;
336 /* Compute the new length. */
337 ++dest->length;
338 return 1;
339}
340
051664b0
AS
341/* Append S to DS, resizing DS if necessary. Returns 1 on success.
342 On failure, if RETURN_ON_ALLOCATION_FAILURE, deletes DEST and
343 returns 0. */
69afa80d 344
051664b0
AS
345int
346dyn_string_append (dest, s)
347 dyn_string_t dest;
69afa80d
AS
348 dyn_string_t s;
349{
051664b0
AS
350 if (dyn_string_resize (dest, dest->length + s->length) == 0)
351 return 0;
352 strcpy (dest->s + dest->length, s->s);
353 dest->length += s->length;
354 return 1;
69afa80d
AS
355}
356
357/* Append the NUL-terminated string S to DS, resizing DS if necessary.
051664b0
AS
358 Returns 1 on success. On failure, if RETURN_ON_ALLOCATION_FAILURE,
359 deletes DEST and returns 0. */
69afa80d 360
051664b0
AS
361int
362dyn_string_append_cstr (dest, s)
363 dyn_string_t dest;
69afa80d
AS
364 const char *s;
365{
366 int len = strlen (s);
367
368 /* The new length is the old length plus the size of our string, plus
369 one for the null at the end. */
051664b0
AS
370 if (dyn_string_resize (dest, dest->length + len) == NULL)
371 return 0;
372 strcpy (dest->s + dest->length, s);
373 dest->length += len;
374 return 1;
69afa80d
AS
375}
376
051664b0
AS
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. */
69afa80d 379
051664b0
AS
380int
381dyn_string_append_char (dest, c)
382 dyn_string_t dest;
69197e7e 383 int c;
69afa80d
AS
384{
385 /* Make room for the extra character. */
051664b0
AS
386 if (dyn_string_resize (dest, dest->length + 1) == NULL)
387 return 0;
69afa80d 388 /* Append the character; it will overwrite the old NUL. */
051664b0 389 dest->s[dest->length] = c;
69afa80d 390 /* Add a new NUL at the end. */
051664b0 391 dest->s[dest->length + 1] = '\0';
69afa80d 392 /* Update the length. */
051664b0
AS
393 ++(dest->length);
394 return 1;
69afa80d
AS
395}
396
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,
051664b0
AS
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. */
69afa80d 402
051664b0 403int
69afa80d
AS
404dyn_string_substring (dest, src, start, end)
405 dyn_string_t dest;
406 dyn_string_t src;
407 int start;
408 int end;
409{
410 int i;
411 int length = end - start;
412
413 if (start > end || start > src->length || end > src->length)
414 abort ();
415
416 /* Make room for the substring. */
051664b0
AS
417 if (dyn_string_resize (dest, length) == NULL)
418 return 0;
69afa80d
AS
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;
051664b0
AS
426
427 return 1;
69afa80d
AS
428}
429
430/* Returns non-zero if DS1 and DS2 have the same contents. */
431
432int
433dyn_string_eq (ds1, ds2)
434 dyn_string_t ds1;
435 dyn_string_t ds2;
436{
437 /* If DS1 and DS2 have different lengths, they must not be the same. */
438 if (ds1->length != ds2->length)
439 return 0;
440 else
441 return !strcmp (ds1->s, ds2->s);
442}