]> git.ipfire.org Git - thirdparty/gcc.git/blame - libiberty/concat.c
MAINTAINERS (Various Maintainers): Add self.
[thirdparty/gcc.git] / libiberty / concat.c
CommitLineData
6599da04 1/* Concatenate variable number of strings.
0bdcca68 2 Copyright (C) 1991, 1994, 2001 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
18not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA. */
20
21
22/*
23
5bed56d9 24@deftypefn Extension char* concat (const char *@var{s1}, const char *@var{s2}, @dots{}, @code{NULL})
6599da04 25
aac04c15 26Concatenate zero or more of strings and return the result in freshly
5bed56d9 27@code{xmalloc}ed memory. Returns @code{NULL} if insufficient memory is
aac04c15
DD
28available. The argument list is terminated by the first @code{NULL}
29pointer encountered. Pointers to empty strings are ignored.
6599da04 30
aac04c15 31@end deftypefn
6599da04
JM
32
33NOTES
34
35 This function uses xmalloc() which is expected to be a front end
36 function to malloc() that deals with low memory situations. In
37 typical use, if malloc() returns NULL then xmalloc() diverts to an
38 error handler routine which never returns, and thus xmalloc will
39 never return a NULL pointer. If the client application wishes to
40 deal with low memory situations itself, it should supply an xmalloc
41 that just directly invokes malloc and blindly returns whatever
42 malloc returns.
aac04c15 43
6599da04
JM
44*/
45
46
b6a2f884
AJ
47#ifdef HAVE_CONFIG_H
48#include "config.h"
49#endif
6599da04
JM
50#include "ansidecl.h"
51#include "libiberty.h"
c8b28221 52#include <sys/types.h> /* size_t */
6599da04
JM
53
54#ifdef ANSI_PROTOTYPES
55#include <stdarg.h>
56#else
57#include <varargs.h>
58#endif
59
0bdcca68
RH
60# if HAVE_STRING_H
61# include <string.h>
62# else
63# if HAVE_STRINGS_H
64# include <strings.h>
65# endif
66# endif
6599da04 67
576fb787
KG
68#if HAVE_STDLIB_H
69#include <stdlib.h>
70#endif
71
c793eea7
KG
72static inline unsigned long vconcat_length PARAMS ((const char *, va_list));
73static inline unsigned long
74vconcat_length (first, args)
75 const char *first;
76 va_list args;
6599da04 77{
c793eea7
KG
78 unsigned long length = 0;
79 const char *arg;
6599da04 80
0bdcca68
RH
81 for (arg = first; arg ; arg = va_arg (args, const char *))
82 length += strlen (arg);
83
c793eea7
KG
84 return length;
85}
6599da04 86
c793eea7
KG
87static inline char *vconcat_copy PARAMS ((char *, const char *, va_list));
88static inline char *
89vconcat_copy (dst, first, args)
90 char *dst;
91 const char *first;
92 va_list args;
93{
94 char *end = dst;
95 const char *arg;
0bdcca68 96
0bdcca68
RH
97 for (arg = first; arg ; arg = va_arg (args, const char *))
98 {
c793eea7 99 unsigned long length = strlen (arg);
0bdcca68
RH
100 memcpy (end, arg, length);
101 end += length;
6599da04 102 }
0bdcca68 103 *end = '\000';
c793eea7
KG
104
105 return dst;
106}
107
aac04c15
DD
108/* @undocumented concat_length */
109
c793eea7
KG
110unsigned long
111concat_length VPARAMS ((const char *first, ...))
112{
113 unsigned long length;
114
115 VA_OPEN (args, first);
116 VA_FIXEDARG (args, const char *, first);
117 length = vconcat_length (first, args);
118 VA_CLOSE (args);
119
120 return length;
121}
122
aac04c15
DD
123/* @undocumented concat_copy */
124
c793eea7
KG
125char *
126concat_copy VPARAMS ((char *dst, const char *first, ...))
127{
128 char *save_dst;
129
130 VA_OPEN (args, first);
131 VA_FIXEDARG (args, char *, dst);
132 VA_FIXEDARG (args, const char *, first);
133 vconcat_copy (dst, first, args);
134 save_dst = dst; /* With K&R C, dst goes out of scope here. */
135 VA_CLOSE (args);
136
137 return save_dst;
138}
139
140char *libiberty_concat_ptr;
141
aac04c15
DD
142/* @undocumented concat_copy2 */
143
c793eea7
KG
144char *
145concat_copy2 VPARAMS ((const char *first, ...))
146{
147 VA_OPEN (args, first);
148 VA_FIXEDARG (args, const char *, first);
149 vconcat_copy (libiberty_concat_ptr, first, args);
150 VA_CLOSE (args);
151
152 return libiberty_concat_ptr;
153}
154
155char *
156concat VPARAMS ((const char *first, ...))
157{
158 char *newstr;
159
160 /* First compute the size of the result and get sufficient memory. */
161 VA_OPEN (args, first);
162 VA_FIXEDARG (args, const char *, first);
163 newstr = (char *) xmalloc (vconcat_length (first, args) + 1);
164 VA_CLOSE (args);
165
166 /* Now copy the individual pieces to the result string. */
167 VA_OPEN (args, first);
168 VA_FIXEDARG (args, const char *, first);
169 vconcat_copy (newstr, first, args);
e2dff3f2 170 VA_CLOSE (args);
6599da04 171
0bdcca68 172 return newstr;
6599da04
JM
173}
174
aac04c15
DD
175/*
176
5bed56d9 177@deftypefn Extension char* reconcat (char *@var{optr}, const char *@var{s1}, @dots{}, @code{NULL})
aac04c15
DD
178
179Same as @code{concat}, except that if @var{optr} is not @code{NULL} it
180is freed after the string is created. This is intended to be useful
181when you're extending an existing string or building up a string in a
182loop:
183
184@example
185 str = reconcat (str, "pre-", str, NULL);
186@end example
187
188@end deftypefn
189
190*/
191
ad43d46f
KG
192char *
193reconcat VPARAMS ((char *optr, const char *first, ...))
194{
195 char *newstr;
196
197 /* First compute the size of the result and get sufficient memory. */
198 VA_OPEN (args, first);
199 VA_FIXEDARG (args, char *, optr);
200 VA_FIXEDARG (args, const char *, first);
201 newstr = (char *) xmalloc (vconcat_length (first, args) + 1);
202 VA_CLOSE (args);
203
204 /* Now copy the individual pieces to the result string. */
205 VA_OPEN (args, first);
206 VA_FIXEDARG (args, char *, optr);
207 VA_FIXEDARG (args, const char *, first);
208 vconcat_copy (newstr, first, args);
c1766881 209 if (optr) /* Done before VA_CLOSE so optr stays in scope for K&R C. */
ad43d46f 210 free (optr);
c1766881 211 VA_CLOSE (args);
ad43d46f
KG
212
213 return newstr;
214}
215
6599da04 216#ifdef MAIN
0bdcca68 217#define NULLP (char *)0
6599da04
JM
218
219/* Simple little test driver. */
220
221#include <stdio.h>
222
223int
224main ()
225{
226 printf ("\"\" = \"%s\"\n", concat (NULLP));
227 printf ("\"a\" = \"%s\"\n", concat ("a", NULLP));
228 printf ("\"ab\" = \"%s\"\n", concat ("a", "b", NULLP));
229 printf ("\"abc\" = \"%s\"\n", concat ("a", "b", "c", NULLP));
230 printf ("\"abcd\" = \"%s\"\n", concat ("ab", "cd", NULLP));
231 printf ("\"abcde\" = \"%s\"\n", concat ("ab", "c", "de", NULLP));
232 printf ("\"abcdef\" = \"%s\"\n", concat ("", "a", "", "bcd", "ef", NULLP));
233 return 0;
234}
235
236#endif