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