Mercurial > hg > CbC > CbC_gcc
annotate libiberty/concat.c @ 67:f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
author | nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 22 Mar 2011 17:18:12 +0900 |
parents | a06113de4d67 |
children | 04ced10e8804 |
rev | line source |
---|---|
0 | 1 /* Concatenate variable number of strings. |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
2 Copyright (C) 1991, 1994, 2001, 2011 Free Software Foundation, Inc. |
0 | 3 Written by Fred Fish @ Cygnus Support |
4 | |
5 This file is part of the libiberty library. | |
6 Libiberty is free software; you can redistribute it and/or | |
7 modify it under the terms of the GNU Library General Public | |
8 License as published by the Free Software Foundation; either | |
9 version 2 of the License, or (at your option) any later version. | |
10 | |
11 Libiberty is distributed in the hope that it will be useful, | |
12 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 Library General Public License for more details. | |
15 | |
16 You should have received a copy of the GNU Library General Public | |
17 License along with libiberty; see the file COPYING.LIB. If | |
18 not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, | |
19 Boston, MA 02110-1301, USA. */ | |
20 | |
21 | |
22 /* | |
23 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
24 @deftypefn Extension char* concat (const char *@var{s1}, const char *@var{s2}, @ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
25 @dots{}, @code{NULL}) |
0 | 26 |
27 Concatenate zero or more of strings and return the result in freshly | |
28 @code{xmalloc}ed memory. Returns @code{NULL} if insufficient memory is | |
29 available. The argument list is terminated by the first @code{NULL} | |
30 pointer encountered. Pointers to empty strings are ignored. | |
31 | |
32 @end deftypefn | |
33 | |
34 NOTES | |
35 | |
36 This function uses xmalloc() which is expected to be a front end | |
37 function to malloc() that deals with low memory situations. In | |
38 typical use, if malloc() returns NULL then xmalloc() diverts to an | |
39 error handler routine which never returns, and thus xmalloc will | |
40 never return a NULL pointer. If the client application wishes to | |
41 deal with low memory situations itself, it should supply an xmalloc | |
42 that just directly invokes malloc and blindly returns whatever | |
43 malloc returns. | |
44 | |
45 */ | |
46 | |
47 | |
48 #ifdef HAVE_CONFIG_H | |
49 #include "config.h" | |
50 #endif | |
51 #include "ansidecl.h" | |
52 #include "libiberty.h" | |
53 #include <sys/types.h> /* size_t */ | |
54 | |
55 #include <stdarg.h> | |
56 | |
57 # if HAVE_STRING_H | |
58 # include <string.h> | |
59 # else | |
60 # if HAVE_STRINGS_H | |
61 # include <strings.h> | |
62 # endif | |
63 # endif | |
64 | |
65 #if HAVE_STDLIB_H | |
66 #include <stdlib.h> | |
67 #endif | |
68 | |
69 static inline unsigned long vconcat_length (const char *, va_list); | |
70 static inline unsigned long | |
71 vconcat_length (const char *first, va_list args) | |
72 { | |
73 unsigned long length = 0; | |
74 const char *arg; | |
75 | |
76 for (arg = first; arg ; arg = va_arg (args, const char *)) | |
77 length += strlen (arg); | |
78 | |
79 return length; | |
80 } | |
81 | |
82 static inline char * | |
83 vconcat_copy (char *dst, const char *first, va_list args) | |
84 { | |
85 char *end = dst; | |
86 const char *arg; | |
87 | |
88 for (arg = first; arg ; arg = va_arg (args, const char *)) | |
89 { | |
90 unsigned long length = strlen (arg); | |
91 memcpy (end, arg, length); | |
92 end += length; | |
93 } | |
94 *end = '\000'; | |
95 | |
96 return dst; | |
97 } | |
98 | |
99 /* @undocumented concat_length */ | |
100 | |
101 unsigned long | |
102 concat_length (const char *first, ...) | |
103 { | |
104 unsigned long length; | |
105 | |
106 VA_OPEN (args, first); | |
107 VA_FIXEDARG (args, const char *, first); | |
108 length = vconcat_length (first, args); | |
109 VA_CLOSE (args); | |
110 | |
111 return length; | |
112 } | |
113 | |
114 /* @undocumented concat_copy */ | |
115 | |
116 char * | |
117 concat_copy (char *dst, const char *first, ...) | |
118 { | |
119 char *save_dst; | |
120 | |
121 VA_OPEN (args, first); | |
122 VA_FIXEDARG (args, char *, dst); | |
123 VA_FIXEDARG (args, const char *, first); | |
124 vconcat_copy (dst, first, args); | |
125 save_dst = dst; /* With K&R C, dst goes out of scope here. */ | |
126 VA_CLOSE (args); | |
127 | |
128 return save_dst; | |
129 } | |
130 | |
131 #ifdef __cplusplus | |
132 extern "C" { | |
133 #endif /* __cplusplus */ | |
134 char *libiberty_concat_ptr; | |
135 #ifdef __cplusplus | |
136 } | |
137 #endif /* __cplusplus */ | |
138 | |
139 /* @undocumented concat_copy2 */ | |
140 | |
141 char * | |
142 concat_copy2 (const char *first, ...) | |
143 { | |
144 VA_OPEN (args, first); | |
145 VA_FIXEDARG (args, const char *, first); | |
146 vconcat_copy (libiberty_concat_ptr, first, args); | |
147 VA_CLOSE (args); | |
148 | |
149 return libiberty_concat_ptr; | |
150 } | |
151 | |
152 char * | |
153 concat (const char *first, ...) | |
154 { | |
155 char *newstr; | |
156 | |
157 /* First compute the size of the result and get sufficient memory. */ | |
158 VA_OPEN (args, first); | |
159 VA_FIXEDARG (args, const char *, first); | |
160 newstr = XNEWVEC (char, vconcat_length (first, args) + 1); | |
161 VA_CLOSE (args); | |
162 | |
163 /* Now copy the individual pieces to the result string. */ | |
164 VA_OPEN (args, first); | |
165 VA_FIXEDARG (args, const char *, first); | |
166 vconcat_copy (newstr, first, args); | |
167 VA_CLOSE (args); | |
168 | |
169 return newstr; | |
170 } | |
171 | |
172 /* | |
173 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
174 @deftypefn Extension char* reconcat (char *@var{optr}, const char *@var{s1}, @ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
175 @dots{}, @code{NULL}) |
0 | 176 |
177 Same as @code{concat}, except that if @var{optr} is not @code{NULL} it | |
178 is freed after the string is created. This is intended to be useful | |
179 when you're extending an existing string or building up a string in a | |
180 loop: | |
181 | |
182 @example | |
183 str = reconcat (str, "pre-", str, NULL); | |
184 @end example | |
185 | |
186 @end deftypefn | |
187 | |
188 */ | |
189 | |
190 char * | |
191 reconcat (char *optr, const char *first, ...) | |
192 { | |
193 char *newstr; | |
194 | |
195 /* First compute the size of the result and get sufficient memory. */ | |
196 VA_OPEN (args, first); | |
197 VA_FIXEDARG (args, char *, optr); | |
198 VA_FIXEDARG (args, const char *, first); | |
199 newstr = XNEWVEC (char, vconcat_length (first, args) + 1); | |
200 VA_CLOSE (args); | |
201 | |
202 /* Now copy the individual pieces to the result string. */ | |
203 VA_OPEN (args, first); | |
204 VA_FIXEDARG (args, char *, optr); | |
205 VA_FIXEDARG (args, const char *, first); | |
206 vconcat_copy (newstr, first, args); | |
207 if (optr) /* Done before VA_CLOSE so optr stays in scope for K&R C. */ | |
208 free (optr); | |
209 VA_CLOSE (args); | |
210 | |
211 return newstr; | |
212 } | |
213 | |
214 #ifdef MAIN | |
215 #define NULLP (char *)0 | |
216 | |
217 /* Simple little test driver. */ | |
218 | |
219 #include <stdio.h> | |
220 | |
221 int | |
222 main (void) | |
223 { | |
224 printf ("\"\" = \"%s\"\n", concat (NULLP)); | |
225 printf ("\"a\" = \"%s\"\n", concat ("a", NULLP)); | |
226 printf ("\"ab\" = \"%s\"\n", concat ("a", "b", NULLP)); | |
227 printf ("\"abc\" = \"%s\"\n", concat ("a", "b", "c", NULLP)); | |
228 printf ("\"abcd\" = \"%s\"\n", concat ("ab", "cd", NULLP)); | |
229 printf ("\"abcde\" = \"%s\"\n", concat ("ab", "c", "de", NULLP)); | |
230 printf ("\"abcdef\" = \"%s\"\n", concat ("", "a", "", "bcd", "ef", NULLP)); | |
231 return 0; | |
232 } | |
233 | |
234 #endif |