]> git.ipfire.org Git - thirdparty/gcc.git/blame - libiberty/concat.c
demangle-expected: Add regression test.
[thirdparty/gcc.git] / libiberty / concat.c
CommitLineData
6599da04 1/* Concatenate variable number of strings.
996c0cb0 2 Copyright (C) 1991, 1994, 2001, 2011 Free Software Foundation, Inc.
6599da04
JM
3 Written by Fred Fish @ Cygnus Support
4
5This file is part of the libiberty library.
6Libiberty is free software; you can redistribute it and/or
7modify it under the terms of the GNU Library General Public
8License as published by the Free Software Foundation; either
9version 2 of the License, or (at your option) any later version.
10
11Libiberty is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14Library General Public License for more details.
15
16You should have received a copy of the GNU Library General Public
17License along with libiberty; see the file COPYING.LIB. If
ee58dffd
NC
18not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
19Boston, MA 02110-1301, USA. */
6599da04
JM
20
21
22/*
23
996c0cb0
RW
24@deftypefn Extension char* concat (const char *@var{s1}, const char *@var{s2}, @
25 @dots{}, @code{NULL})
6599da04 26
aac04c15 27Concatenate zero or more of strings and return the result in freshly
5bed56d9 28@code{xmalloc}ed memory. Returns @code{NULL} if insufficient memory is
aac04c15
DD
29available. The argument list is terminated by the first @code{NULL}
30pointer encountered. Pointers to empty strings are ignored.
6599da04 31
aac04c15 32@end deftypefn
6599da04
JM
33
34NOTES
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.
aac04c15 44
6599da04
JM
45*/
46
47
b6a2f884
AJ
48#ifdef HAVE_CONFIG_H
49#include "config.h"
50#endif
6599da04
JM
51#include "ansidecl.h"
52#include "libiberty.h"
c8b28221 53#include <sys/types.h> /* size_t */
6599da04 54
6599da04 55#include <stdarg.h>
6599da04 56
0bdcca68
RH
57# if HAVE_STRING_H
58# include <string.h>
59# else
60# if HAVE_STRINGS_H
61# include <strings.h>
62# endif
63# endif
6599da04 64
576fb787
KG
65#if HAVE_STDLIB_H
66#include <stdlib.h>
67#endif
68
9486db4f 69static inline unsigned long vconcat_length (const char *, va_list);
c793eea7 70static inline unsigned long
9486db4f 71vconcat_length (const char *first, va_list args)
6599da04 72{
c793eea7
KG
73 unsigned long length = 0;
74 const char *arg;
6599da04 75
0bdcca68
RH
76 for (arg = first; arg ; arg = va_arg (args, const char *))
77 length += strlen (arg);
78
c793eea7
KG
79 return length;
80}
6599da04 81
c793eea7 82static inline char *
9486db4f 83vconcat_copy (char *dst, const char *first, va_list args)
c793eea7
KG
84{
85 char *end = dst;
86 const char *arg;
0bdcca68 87
0bdcca68
RH
88 for (arg = first; arg ; arg = va_arg (args, const char *))
89 {
c793eea7 90 unsigned long length = strlen (arg);
0bdcca68
RH
91 memcpy (end, arg, length);
92 end += length;
6599da04 93 }
0bdcca68 94 *end = '\000';
c793eea7
KG
95
96 return dst;
97}
98
aac04c15
DD
99/* @undocumented concat_length */
100
c793eea7 101unsigned long
9486db4f 102concat_length (const char *first, ...)
c793eea7
KG
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
aac04c15
DD
114/* @undocumented concat_copy */
115
c793eea7 116char *
9486db4f 117concat_copy (char *dst, const char *first, ...)
c793eea7
KG
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
d7cf8390
GDR
131#ifdef __cplusplus
132extern "C" {
133#endif /* __cplusplus */
c793eea7 134char *libiberty_concat_ptr;
d7cf8390
GDR
135#ifdef __cplusplus
136}
137#endif /* __cplusplus */
c793eea7 138
aac04c15
DD
139/* @undocumented concat_copy2 */
140
c793eea7 141char *
9486db4f 142concat_copy2 (const char *first, ...)
c793eea7
KG
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
152char *
9486db4f 153concat (const char *first, ...)
c793eea7
KG
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);
d7cf8390 160 newstr = XNEWVEC (char, vconcat_length (first, args) + 1);
c793eea7
KG
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);
e2dff3f2 167 VA_CLOSE (args);
6599da04 168
0bdcca68 169 return newstr;
6599da04
JM
170}
171
aac04c15
DD
172/*
173
996c0cb0
RW
174@deftypefn Extension char* reconcat (char *@var{optr}, const char *@var{s1}, @
175 @dots{}, @code{NULL})
aac04c15
DD
176
177Same as @code{concat}, except that if @var{optr} is not @code{NULL} it
178is freed after the string is created. This is intended to be useful
179when you're extending an existing string or building up a string in a
180loop:
181
182@example
183 str = reconcat (str, "pre-", str, NULL);
184@end example
185
186@end deftypefn
187
188*/
189
ad43d46f 190char *
9486db4f 191reconcat (char *optr, const char *first, ...)
ad43d46f
KG
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);
d7cf8390 199 newstr = XNEWVEC (char, vconcat_length (first, args) + 1);
ad43d46f
KG
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);
c1766881 207 if (optr) /* Done before VA_CLOSE so optr stays in scope for K&R C. */
ad43d46f 208 free (optr);
c1766881 209 VA_CLOSE (args);
ad43d46f
KG
210
211 return newstr;
212}
213
6599da04 214#ifdef MAIN
0bdcca68 215#define NULLP (char *)0
6599da04
JM
216
217/* Simple little test driver. */
218
219#include <stdio.h>
220
221int
9486db4f 222main (void)
6599da04
JM
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