Mercurial > hg > CbC > CbC_gcc
annotate libiberty/dyn-string.c @ 108:7ad14f446135
add CbC-example/rectypeTest/
author | Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Thu, 14 Jun 2012 20:30:24 +0900 |
parents | 77e2b8dfacca |
children | 04ced10e8804 |
rev | line source |
---|---|
0 | 1 /* An abstract string datatype. |
2 Copyright (C) 1998, 1999, 2000, 2002, 2004 Free Software Foundation, Inc. | |
3 Contributed by Mark Mitchell (mark@markmitchell.com). | |
4 | |
5 This file is part of GNU CC. | |
6 | |
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) | |
10 any later version. | |
11 | |
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 | |
19 executable.) | |
20 | |
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. | |
25 | |
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, 51 Franklin Street - Fifth Floor, | |
29 Boston, MA 02110-1301, USA. */ | |
30 | |
31 #ifdef HAVE_CONFIG_H | |
32 #include "config.h" | |
33 #endif | |
34 | |
35 #include <stdio.h> | |
36 | |
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 | |
48 /* Performs in-place initialization of a dyn_string struct. This | |
49 function can be used with a dyn_string struct on the stack or | |
50 embedded in another object. The contents of of the string itself | |
51 are still dynamically allocated. The string initially is capable | |
52 of holding at least SPACE characeters, including the terminating | |
53 NUL. If SPACE is 0, it will silently be increated to 1. | |
54 | |
55 If RETURN_ON_ALLOCATION_FAILURE is defined and memory allocation | |
56 fails, returns 0. Otherwise returns 1. */ | |
57 | |
58 int | |
59 dyn_string_init (struct dyn_string *ds_struct_ptr, int space) | |
60 { | |
61 /* We need at least one byte in which to store the terminating NUL. */ | |
62 if (space == 0) | |
63 space = 1; | |
64 | |
65 #ifdef RETURN_ON_ALLOCATION_FAILURE | |
66 ds_struct_ptr->s = (char *) malloc (space); | |
67 if (ds_struct_ptr->s == NULL) | |
68 return 0; | |
69 #else | |
70 ds_struct_ptr->s = XNEWVEC (char, space); | |
71 #endif | |
72 ds_struct_ptr->allocated = space; | |
73 ds_struct_ptr->length = 0; | |
74 ds_struct_ptr->s[0] = '\0'; | |
75 | |
76 return 1; | |
77 } | |
78 | |
79 /* Create a new dynamic string capable of holding at least SPACE | |
80 characters, including the terminating NUL. If SPACE is 0, it will | |
81 be silently increased to 1. If RETURN_ON_ALLOCATION_FAILURE is | |
82 defined and memory allocation fails, returns NULL. Otherwise | |
83 returns the newly allocated string. */ | |
84 | |
85 dyn_string_t | |
86 dyn_string_new (int space) | |
87 { | |
88 dyn_string_t result; | |
89 #ifdef RETURN_ON_ALLOCATION_FAILURE | |
90 result = (dyn_string_t) malloc (sizeof (struct dyn_string)); | |
91 if (result == NULL) | |
92 return NULL; | |
93 if (!dyn_string_init (result, space)) | |
94 { | |
95 free (result); | |
96 return NULL; | |
97 } | |
98 #else | |
99 result = XNEW (struct dyn_string); | |
100 dyn_string_init (result, space); | |
101 #endif | |
102 return result; | |
103 } | |
104 | |
105 /* Free the memory used by DS. */ | |
106 | |
107 void | |
108 dyn_string_delete (dyn_string_t ds) | |
109 { | |
110 free (ds->s); | |
111 free (ds); | |
112 } | |
113 | |
114 /* Returns the contents of DS in a buffer allocated with malloc. It | |
115 is the caller's responsibility to deallocate the buffer using free. | |
116 DS is then set to the empty string. Deletes DS itself. */ | |
117 | |
118 char* | |
119 dyn_string_release (dyn_string_t ds) | |
120 { | |
121 /* Store the old buffer. */ | |
122 char* result = ds->s; | |
123 /* The buffer is no longer owned by DS. */ | |
124 ds->s = NULL; | |
125 /* Delete DS. */ | |
126 free (ds); | |
127 /* Return the old buffer. */ | |
128 return result; | |
129 } | |
130 | |
131 /* Increase the capacity of DS so it can hold at least SPACE | |
132 characters, plus the terminating NUL. This function will not (at | |
133 present) reduce the capacity of DS. Returns DS on success. | |
134 | |
135 If RETURN_ON_ALLOCATION_FAILURE is defined and a memory allocation | |
136 operation fails, deletes DS and returns NULL. */ | |
137 | |
138 dyn_string_t | |
139 dyn_string_resize (dyn_string_t ds, int space) | |
140 { | |
141 int new_allocated = ds->allocated; | |
142 | |
143 /* Increase SPACE to hold the NUL termination. */ | |
144 ++space; | |
145 | |
146 /* Increase allocation by factors of two. */ | |
147 while (space > new_allocated) | |
148 new_allocated *= 2; | |
149 | |
150 if (new_allocated != ds->allocated) | |
151 { | |
152 ds->allocated = new_allocated; | |
153 /* We actually need more space. */ | |
154 #ifdef RETURN_ON_ALLOCATION_FAILURE | |
155 ds->s = (char *) realloc (ds->s, ds->allocated); | |
156 if (ds->s == NULL) | |
157 { | |
158 free (ds); | |
159 return NULL; | |
160 } | |
161 #else | |
162 ds->s = XRESIZEVEC (char, ds->s, ds->allocated); | |
163 #endif | |
164 } | |
165 | |
166 return ds; | |
167 } | |
168 | |
169 /* Sets the contents of DS to the empty string. */ | |
170 | |
171 void | |
172 dyn_string_clear (dyn_string_t ds) | |
173 { | |
174 /* A dyn_string always has room for at least the NUL terminator. */ | |
175 ds->s[0] = '\0'; | |
176 ds->length = 0; | |
177 } | |
178 | |
179 /* Makes the contents of DEST the same as the contents of SRC. DEST | |
180 and SRC must be distinct. Returns 1 on success. On failure, if | |
181 RETURN_ON_ALLOCATION_FAILURE, deletes DEST and returns 0. */ | |
182 | |
183 int | |
184 dyn_string_copy (dyn_string_t dest, dyn_string_t src) | |
185 { | |
186 if (dest == src) | |
187 abort (); | |
188 | |
189 /* Make room in DEST. */ | |
190 if (dyn_string_resize (dest, src->length) == NULL) | |
191 return 0; | |
192 /* Copy DEST into SRC. */ | |
193 strcpy (dest->s, src->s); | |
194 /* Update the size of DEST. */ | |
195 dest->length = src->length; | |
196 return 1; | |
197 } | |
198 | |
199 /* Copies SRC, a NUL-terminated string, into DEST. Returns 1 on | |
200 success. On failure, if RETURN_ON_ALLOCATION_FAILURE, deletes DEST | |
201 and returns 0. */ | |
202 | |
203 int | |
204 dyn_string_copy_cstr (dyn_string_t dest, const char *src) | |
205 { | |
206 int length = strlen (src); | |
207 /* Make room in DEST. */ | |
208 if (dyn_string_resize (dest, length) == NULL) | |
209 return 0; | |
210 /* Copy DEST into SRC. */ | |
211 strcpy (dest->s, src); | |
212 /* Update the size of DEST. */ | |
213 dest->length = length; | |
214 return 1; | |
215 } | |
216 | |
217 /* Inserts SRC at the beginning of DEST. DEST is expanded as | |
218 necessary. SRC and DEST must be distinct. Returns 1 on success. | |
219 On failure, if RETURN_ON_ALLOCATION_FAILURE, deletes DEST and | |
220 returns 0. */ | |
221 | |
222 int | |
223 dyn_string_prepend (dyn_string_t dest, dyn_string_t src) | |
224 { | |
225 return dyn_string_insert (dest, 0, src); | |
226 } | |
227 | |
228 /* Inserts SRC, a NUL-terminated string, at the beginning of DEST. | |
229 DEST is expanded as necessary. Returns 1 on success. On failure, | |
230 if RETURN_ON_ALLOCATION_FAILURE, deletes DEST and returns 0. */ | |
231 | |
232 int | |
233 dyn_string_prepend_cstr (dyn_string_t dest, const char *src) | |
234 { | |
235 return dyn_string_insert_cstr (dest, 0, src); | |
236 } | |
237 | |
238 /* Inserts SRC into DEST starting at position POS. DEST is expanded | |
239 as necessary. SRC and DEST must be distinct. Returns 1 on | |
240 success. On failure, if RETURN_ON_ALLOCATION_FAILURE, deletes DEST | |
241 and returns 0. */ | |
242 | |
243 int | |
244 dyn_string_insert (dyn_string_t dest, int pos, dyn_string_t src) | |
245 { | |
246 int i; | |
247 | |
248 if (src == dest) | |
249 abort (); | |
250 | |
251 if (dyn_string_resize (dest, dest->length + src->length) == NULL) | |
252 return 0; | |
253 /* Make room for the insertion. Be sure to copy the NUL. */ | |
254 for (i = dest->length; i >= pos; --i) | |
255 dest->s[i + src->length] = dest->s[i]; | |
256 /* Splice in the new stuff. */ | |
257 strncpy (dest->s + pos, src->s, src->length); | |
258 /* Compute the new length. */ | |
259 dest->length += src->length; | |
260 return 1; | |
261 } | |
262 | |
263 /* Inserts SRC, a NUL-terminated string, into DEST starting at | |
264 position POS. DEST is expanded as necessary. Returns 1 on | |
265 success. On failure, RETURN_ON_ALLOCATION_FAILURE, deletes DEST | |
266 and returns 0. */ | |
267 | |
268 int | |
269 dyn_string_insert_cstr (dyn_string_t dest, int pos, const char *src) | |
270 { | |
271 int i; | |
272 int length = strlen (src); | |
273 | |
274 if (dyn_string_resize (dest, dest->length + length) == NULL) | |
275 return 0; | |
276 /* Make room for the insertion. Be sure to copy the NUL. */ | |
277 for (i = dest->length; i >= pos; --i) | |
278 dest->s[i + length] = dest->s[i]; | |
279 /* Splice in the new stuff. */ | |
280 strncpy (dest->s + pos, src, length); | |
281 /* Compute the new length. */ | |
282 dest->length += length; | |
283 return 1; | |
284 } | |
285 | |
286 /* Inserts character C into DEST starting at position POS. DEST is | |
287 expanded as necessary. Returns 1 on success. On failure, | |
288 RETURN_ON_ALLOCATION_FAILURE, deletes DEST and returns 0. */ | |
289 | |
290 int | |
291 dyn_string_insert_char (dyn_string_t dest, int pos, int c) | |
292 { | |
293 int i; | |
294 | |
295 if (dyn_string_resize (dest, dest->length + 1) == NULL) | |
296 return 0; | |
297 /* Make room for the insertion. Be sure to copy the NUL. */ | |
298 for (i = dest->length; i >= pos; --i) | |
299 dest->s[i + 1] = dest->s[i]; | |
300 /* Add the new character. */ | |
301 dest->s[pos] = c; | |
302 /* Compute the new length. */ | |
303 ++dest->length; | |
304 return 1; | |
305 } | |
306 | |
307 /* Append S to DS, resizing DS if necessary. Returns 1 on success. | |
308 On failure, if RETURN_ON_ALLOCATION_FAILURE, deletes DEST and | |
309 returns 0. */ | |
310 | |
311 int | |
312 dyn_string_append (dyn_string_t dest, dyn_string_t s) | |
313 { | |
314 if (dyn_string_resize (dest, dest->length + s->length) == 0) | |
315 return 0; | |
316 strcpy (dest->s + dest->length, s->s); | |
317 dest->length += s->length; | |
318 return 1; | |
319 } | |
320 | |
321 /* Append the NUL-terminated string S to DS, resizing DS if necessary. | |
322 Returns 1 on success. On failure, if RETURN_ON_ALLOCATION_FAILURE, | |
323 deletes DEST and returns 0. */ | |
324 | |
325 int | |
326 dyn_string_append_cstr (dyn_string_t dest, const char *s) | |
327 { | |
328 int len = strlen (s); | |
329 | |
330 /* The new length is the old length plus the size of our string, plus | |
331 one for the null at the end. */ | |
332 if (dyn_string_resize (dest, dest->length + len) == NULL) | |
333 return 0; | |
334 strcpy (dest->s + dest->length, s); | |
335 dest->length += len; | |
336 return 1; | |
337 } | |
338 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
339 /* Appends C to the end of DEST. Returns 1 on success. On failure, |
0 | 340 if RETURN_ON_ALLOCATION_FAILURE, deletes DEST and returns 0. */ |
341 | |
342 int | |
343 dyn_string_append_char (dyn_string_t dest, int c) | |
344 { | |
345 /* Make room for the extra character. */ | |
346 if (dyn_string_resize (dest, dest->length + 1) == NULL) | |
347 return 0; | |
348 /* Append the character; it will overwrite the old NUL. */ | |
349 dest->s[dest->length] = c; | |
350 /* Add a new NUL at the end. */ | |
351 dest->s[dest->length + 1] = '\0'; | |
352 /* Update the length. */ | |
353 ++(dest->length); | |
354 return 1; | |
355 } | |
356 | |
357 /* Sets the contents of DEST to the substring of SRC starting at START | |
358 and ending before END. START must be less than or equal to END, | |
359 and both must be between zero and the length of SRC, inclusive. | |
360 Returns 1 on success. On failure, if RETURN_ON_ALLOCATION_FAILURE, | |
361 deletes DEST and returns 0. */ | |
362 | |
363 int | |
364 dyn_string_substring (dyn_string_t dest, dyn_string_t src, | |
365 int start, int end) | |
366 { | |
367 int i; | |
368 int length = end - start; | |
369 | |
370 if (start > end || start > src->length || end > src->length) | |
371 abort (); | |
372 | |
373 /* Make room for the substring. */ | |
374 if (dyn_string_resize (dest, length) == NULL) | |
375 return 0; | |
376 /* Copy the characters in the substring, */ | |
377 for (i = length; --i >= 0; ) | |
378 dest->s[i] = src->s[start + i]; | |
379 /* NUL-terimate the result. */ | |
380 dest->s[length] = '\0'; | |
381 /* Record the length of the substring. */ | |
382 dest->length = length; | |
383 | |
384 return 1; | |
385 } | |
386 | |
387 /* Returns non-zero if DS1 and DS2 have the same contents. */ | |
388 | |
389 int | |
390 dyn_string_eq (dyn_string_t ds1, dyn_string_t ds2) | |
391 { | |
392 /* If DS1 and DS2 have different lengths, they must not be the same. */ | |
393 if (ds1->length != ds2->length) | |
394 return 0; | |
395 else | |
396 return !strcmp (ds1->s, ds2->s); | |
397 } |