merge from gcc
[deliverable/binutils-gdb.git] / libiberty / concat.c
CommitLineData
252b5132 1/* Concatenate variable number of strings.
d4d868a2 2 Copyright (C) 1991, 1994, 2001, 2011 Free Software Foundation, Inc.
252b5132
RH
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
979c05d3
NC
18not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
19Boston, MA 02110-1301, USA. */
252b5132
RH
20
21
22/*
23
d4d868a2
RW
24@deftypefn Extension char* concat (const char *@var{s1}, const char *@var{s2}, @
25 @dots{}, @code{NULL})
252b5132 26
ba19b94f 27Concatenate zero or more of strings and return the result in freshly
5d852400 28@code{xmalloc}ed memory. Returns @code{NULL} if insufficient memory is
ba19b94f
DD
29available. The argument list is terminated by the first @code{NULL}
30pointer encountered. Pointers to empty strings are ignored.
252b5132 31
ba19b94f 32@end deftypefn
252b5132
RH
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.
ba19b94f 44
252b5132
RH
45*/
46
47
65a4f13c
DD
48#ifdef HAVE_CONFIG_H
49#include "config.h"
50#endif
252b5132
RH
51#include "ansidecl.h"
52#include "libiberty.h"
926150e2 53#include <sys/types.h> /* size_t */
252b5132 54
252b5132 55#include <stdarg.h>
252b5132 56
d42dae6c
DD
57# if HAVE_STRING_H
58# include <string.h>
59# else
60# if HAVE_STRINGS_H
61# include <strings.h>
62# endif
63# endif
252b5132 64
916aaa12
DD
65#if HAVE_STDLIB_H
66#include <stdlib.h>
67#endif
68
9334f9c6 69static inline unsigned long vconcat_length (const char *, va_list);
54c20242 70static inline unsigned long
9334f9c6 71vconcat_length (const char *first, va_list args)
252b5132 72{
54c20242
DD
73 unsigned long length = 0;
74 const char *arg;
252b5132 75
d42dae6c
DD
76 for (arg = first; arg ; arg = va_arg (args, const char *))
77 length += strlen (arg);
78
54c20242
DD
79 return length;
80}
252b5132 81
54c20242 82static inline char *
9334f9c6 83vconcat_copy (char *dst, const char *first, va_list args)
54c20242
DD
84{
85 char *end = dst;
86 const char *arg;
d42dae6c 87
d42dae6c
DD
88 for (arg = first; arg ; arg = va_arg (args, const char *))
89 {
54c20242 90 unsigned long length = strlen (arg);
d42dae6c
DD
91 memcpy (end, arg, length);
92 end += length;
252b5132 93 }
d42dae6c 94 *end = '\000';
54c20242
DD
95
96 return dst;
97}
98
ba19b94f
DD
99/* @undocumented concat_length */
100
54c20242 101unsigned long
9334f9c6 102concat_length (const char *first, ...)
54c20242
DD
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
ba19b94f
DD
114/* @undocumented concat_copy */
115
54c20242 116char *
9334f9c6 117concat_copy (char *dst, const char *first, ...)
54c20242
DD
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
abf6a75b
DD
131#ifdef __cplusplus
132extern "C" {
133#endif /* __cplusplus */
54c20242 134char *libiberty_concat_ptr;
abf6a75b
DD
135#ifdef __cplusplus
136}
137#endif /* __cplusplus */
54c20242 138
ba19b94f
DD
139/* @undocumented concat_copy2 */
140
54c20242 141char *
9334f9c6 142concat_copy2 (const char *first, ...)
54c20242
DD
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 *
9334f9c6 153concat (const char *first, ...)
54c20242
DD
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);
abf6a75b 160 newstr = XNEWVEC (char, vconcat_length (first, args) + 1);
54c20242
DD
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);
8a423cb3 167 VA_CLOSE (args);
252b5132 168
d42dae6c 169 return newstr;
252b5132
RH
170}
171
ba19b94f
DD
172/*
173
d4d868a2
RW
174@deftypefn Extension char* reconcat (char *@var{optr}, const char *@var{s1}, @
175 @dots{}, @code{NULL})
ba19b94f
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
99ee3a8f 190char *
9334f9c6 191reconcat (char *optr, const char *first, ...)
99ee3a8f
DD
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);
abf6a75b 199 newstr = XNEWVEC (char, vconcat_length (first, args) + 1);
99ee3a8f
DD
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);
66c94e19 207 if (optr) /* Done before VA_CLOSE so optr stays in scope for K&R C. */
99ee3a8f 208 free (optr);
66c94e19 209 VA_CLOSE (args);
99ee3a8f
DD
210
211 return newstr;
212}
213
252b5132 214#ifdef MAIN
d42dae6c 215#define NULLP (char *)0
252b5132
RH
216
217/* Simple little test driver. */
218
219#include <stdio.h>
220
221int
9334f9c6 222main (void)
252b5132
RH
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
This page took 0.565124 seconds and 4 git commands to generate.