19313Ssos/* Concatenate variable number of strings. 29313Ssos Copyright (C) 1991, 1994, 2001 Free Software Foundation, Inc. 39313Ssos Written by Fred Fish @ Cygnus Support 49313Ssos 59313SsosThis file is part of the libiberty library. 69313SsosLibiberty is free software; you can redistribute it and/or 79313Ssosmodify it under the terms of the GNU Library General Public 89313SsosLicense as published by the Free Software Foundation; either 99313Ssosversion 2 of the License, or (at your option) any later version. 109313Ssos 119313SsosLibiberty is distributed in the hope that it will be useful, 129313Ssosbut WITHOUT ANY WARRANTY; without even the implied warranty of 139313SsosMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 149313SsosLibrary General Public License for more details. 159313Ssos 169313SsosYou should have received a copy of the GNU Library General Public 179313SsosLicense along with libiberty; see the file COPYING.LIB. If 189313Ssosnot, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, 199313SsosBoston, MA 02110-1301, USA. */ 209313Ssos 219313Ssos 229313Ssos/* 239313Ssos 249313Ssos@deftypefn Extension char* concat (const char *@var{s1}, const char *@var{s2}, @dots{}, @code{NULL}) 259313Ssos 269313SsosConcatenate zero or more of strings and return the result in freshly 279313Ssos@code{xmalloc}ed memory. Returns @code{NULL} if insufficient memory is 2850477Speteravailable. The argument list is terminated by the first @code{NULL} 299313Ssospointer encountered. Pointers to empty strings are ignored. 309313Ssos 3131784Seivind@end deftypefn 3231784Seivind 339313SsosNOTES 349313Ssos 3512458Sbde This function uses xmalloc() which is expected to be a front end 369313Ssos function to malloc() that deals with low memory situations. In 379313Ssos typical use, if malloc() returns NULL then xmalloc() diverts to an 389313Ssos error handler routine which never returns, and thus xmalloc will 3931561Sbde never return a NULL pointer. If the client application wishes to 409313Ssos deal with low memory situations itself, it should supply an xmalloc 419313Ssos that just directly invokes malloc and blindly returns whatever 429313Ssos malloc returns. 439313Ssos 4414331Speter*/ 4514331Speter 4612458Sbde 4712458Sbde#ifdef HAVE_CONFIG_H 4814331Speter#include "config.h" 4914331Speter#endif 509313Ssos#include "ansidecl.h" 519313Ssos#include "libiberty.h" 5230994Sphk#include <sys/types.h> /* size_t */ 539313Ssos 5412858Speter#include <stdarg.h> 559313Ssos 569313Ssos# if HAVE_STRING_H 579313Ssos# include <string.h> 5812858Speter# else 5914331Speter# if HAVE_STRINGS_H 609313Ssos# include <strings.h> 6114331Speter# endif 6214331Speter# endif 6314331Speter 649313Ssos#if HAVE_STDLIB_H 659313Ssos#include <stdlib.h> 669313Ssos#endif 679313Ssos 689313Ssosstatic inline unsigned long vconcat_length (const char *, va_list); 699313Ssosstatic inline unsigned long 709313Ssosvconcat_length (const char *first, va_list args) 7130994Sphk{ 729313Ssos unsigned long length = 0; 739313Ssos const char *arg; 749313Ssos 7530994Sphk for (arg = first; arg ; arg = va_arg (args, const char *)) 769313Ssos length += strlen (arg); 7712858Speter 789313Ssos return length; 799313Ssos} 809313Ssos 8112858Speterstatic inline char * 829313Ssosvconcat_copy (char *dst, const char *first, va_list args) 8314331Speter{ 8414331Speter char *end = dst; 8514331Speter const char *arg; 869313Ssos 8714331Speter for (arg = first; arg ; arg = va_arg (args, const char *)) 8814331Speter { 8914331Speter unsigned long length = strlen (arg); 9014331Speter memcpy (end, arg, length); 9114331Speter end += length; 929313Ssos } 939313Ssos *end = '\000'; 949313Ssos 959313Ssos return dst; 969313Ssos} 979313Ssos 989313Ssos/* @undocumented concat_length */ 999313Ssos 1009313Ssosunsigned long 1019313Ssosconcat_length (const char *first, ...) 1029313Ssos{ 1039313Ssos unsigned long length; 1049313Ssos 1059313Ssos VA_OPEN (args, first); 1069313Ssos VA_FIXEDARG (args, const char *, first); 1079313Ssos length = vconcat_length (first, args); 1089313Ssos VA_CLOSE (args); 1099313Ssos 1109313Ssos return length; 1119313Ssos} 1129313Ssos 1139313Ssos/* @undocumented concat_copy */ 1149313Ssos 1159313Ssoschar * 1169313Ssosconcat_copy (char *dst, const char *first, ...) 1179313Ssos{ 1189313Ssos char *save_dst; 1199313Ssos 1209313Ssos VA_OPEN (args, first); 1219313Ssos VA_FIXEDARG (args, char *, dst); 1229313Ssos VA_FIXEDARG (args, const char *, first); 1239313Ssos vconcat_copy (dst, first, args); 12430994Sphk save_dst = dst; /* With K&R C, dst goes out of scope here. */ 1259313Ssos VA_CLOSE (args); 1269313Ssos 1279313Ssos return save_dst; 12830994Sphk} 1299313Ssos 1309313Ssos#ifdef __cplusplus 13151418Sgreenextern "C" { 1329313Ssos#endif /* __cplusplus */ 13314331Speterchar *libiberty_concat_ptr; 13414331Speter#ifdef __cplusplus 13514331Speter} 13614331Speter#endif /* __cplusplus */ 1379313Ssos 1389313Ssos/* @undocumented concat_copy2 */ 1399313Ssos 1409313Ssoschar * 1419313Ssosconcat_copy2 (const char *first, ...) 1429313Ssos{ 1439313Ssos VA_OPEN (args, first); 1449313Ssos VA_FIXEDARG (args, const char *, first); 1459313Ssos vconcat_copy (libiberty_concat_ptr, first, args); 1469313Ssos VA_CLOSE (args); 1479313Ssos 1489313Ssos return libiberty_concat_ptr; 1499313Ssos} 1509313Ssos 1519313Ssoschar * 1529313Ssosconcat (const char *first, ...) 1539313Ssos{ 1549313Ssos char *newstr; 1559313Ssos 1569313Ssos /* First compute the size of the result and get sufficient memory. */ 1579313Ssos VA_OPEN (args, first); 1589313Ssos VA_FIXEDARG (args, const char *, first); 1599313Ssos newstr = XNEWVEC (char, vconcat_length (first, args) + 1); 1609313Ssos VA_CLOSE (args); 16149676Smarcel 16249676Smarcel /* Now copy the individual pieces to the result string. */ 16349676Smarcel VA_OPEN (args, first); 1649313Ssos VA_FIXEDARG (args, const char *, first); 1659313Ssos vconcat_copy (newstr, first, args); 1669313Ssos VA_CLOSE (args); 1679313Ssos 1689313Ssos return newstr; 1699313Ssos} 1709313Ssos 1719313Ssos/* 1729313Ssos 1739313Ssos@deftypefn Extension char* reconcat (char *@var{optr}, const char *@var{s1}, @dots{}, @code{NULL}) 1749313Ssos 1759313SsosSame as @code{concat}, except that if @var{optr} is not @code{NULL} it 1769313Ssosis freed after the string is created. This is intended to be useful 1779313Ssoswhen you're extending an existing string or building up a string in a 1789313Ssosloop: 1799313Ssos 1809313Ssos@example 1819313Ssos str = reconcat (str, "pre-", str, NULL); 1829313Ssos@end example 1839313Ssos 1849313Ssos@end deftypefn 1859313Ssos 1869313Ssos*/ 1879313Ssos 1889313Ssoschar * 1899313Ssosreconcat (char *optr, const char *first, ...) 1909313Ssos{ 1919313Ssos char *newstr; 19230994Sphk 1939313Ssos /* First compute the size of the result and get sufficient memory. */ 1949313Ssos VA_OPEN (args, first); 19512858Speter VA_FIXEDARG (args, char *, optr); 1969313Ssos VA_FIXEDARG (args, const char *, first); 1979313Ssos newstr = XNEWVEC (char, vconcat_length (first, args) + 1); 1989313Ssos VA_CLOSE (args); 19912858Speter 2009313Ssos /* Now copy the individual pieces to the result string. */ 20114331Speter VA_OPEN (args, first); 20214331Speter VA_FIXEDARG (args, char *, optr); 20314331Speter VA_FIXEDARG (args, const char *, first); 20414331Speter vconcat_copy (newstr, first, args); 20514331Speter if (optr) /* Done before VA_CLOSE so optr stays in scope for K&R C. */ 20614331Speter free (optr); 20751654Sphk VA_CLOSE (args); 20814331Speter 20947028Sphk return newstr; 2109313Ssos} 21114331Speter 21214331Speter#ifdef MAIN 21314331Speter#define NULLP (char *)0 2149313Ssos 2159313Ssos/* Simple little test driver. */ 2169313Ssos 2179313Ssos#include <stdio.h> 2189313Ssos 2199313Ssosint 2209313Ssosmain (void) 2219313Ssos{ 2229313Ssos printf ("\"\" = \"%s\"\n", concat (NULLP)); 22349845Smarcel printf ("\"a\" = \"%s\"\n", concat ("a", NULLP)); 22430994Sphk printf ("\"ab\" = \"%s\"\n", concat ("a", "b", NULLP)); 2259313Ssos printf ("\"abc\" = \"%s\"\n", concat ("a", "b", "c", NULLP)); 2269313Ssos printf ("\"abcd\" = \"%s\"\n", concat ("ab", "cd", NULLP)); 2279313Ssos printf ("\"abcde\" = \"%s\"\n", concat ("ab", "c", "de", NULLP)); 22830994Sphk printf ("\"abcdef\" = \"%s\"\n", concat ("", "a", "", "bcd", "ef", NULLP)); 2299313Ssos return 0; 2309313Ssos} 2319313Ssos 23249845Smarcel#endif 23330994Sphk