X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=libiberty%2Fconcat.c;h=7846a19393bde021841b75a7f06803c7d965c6dd;hb=173373c6f6388171d1d62a217fae90a052395be2;hp=2e0ce4996e7ee171e7c53b6a6a43e2d0c749a2b4;hpb=926150e277db625c7bc261146344113a9f9ffb06;p=deliverable%2Fbinutils-gdb.git diff --git a/libiberty/concat.c b/libiberty/concat.c index 2e0ce4996e..7846a19393 100644 --- a/libiberty/concat.c +++ b/libiberty/concat.c @@ -1,5 +1,5 @@ /* Concatenate variable number of strings. - Copyright (C) 1991, 1994, 2001 Free Software Foundation, Inc. + Copyright (C) 1991, 1994, 2001, 2011, 2013 Free Software Foundation, Inc. Written by Fred Fish @ Cygnus Support This file is part of the libiberty library. @@ -15,53 +15,32 @@ Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with libiberty; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ +not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +Boston, MA 02110-1301, USA. */ /* -NAME +@deftypefn Extension char* concat (const char *@var{s1}, const char *@var{s2}, @ + @dots{}, @code{NULL}) - concat -- concatenate a variable number of strings +Concatenate zero or more of strings and return the result in freshly +@code{xmalloc}ed memory. The argument list is terminated by the first +@code{NULL} pointer encountered. Pointers to empty strings are ignored. -SYNOPSIS +@end deftypefn - #include - - char *concat (s1, s2, s3, ..., NULL) - -DESCRIPTION - - Concatenate a variable number of strings and return the result - in freshly malloc'd memory. - - Returns NULL if insufficient memory is available. The argument - list is terminated by the first NULL pointer encountered. Pointers - to empty strings are ignored. - -NOTES - - This function uses xmalloc() which is expected to be a front end - function to malloc() that deals with low memory situations. In - typical use, if malloc() returns NULL then xmalloc() diverts to an - error handler routine which never returns, and thus xmalloc will - never return a NULL pointer. If the client application wishes to - deal with low memory situations itself, it should supply an xmalloc - that just directly invokes malloc and blindly returns whatever - malloc returns. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif #include "ansidecl.h" #include "libiberty.h" #include /* size_t */ -#ifdef ANSI_PROTOTYPES #include -#else -#include -#endif # if HAVE_STRING_H # include @@ -71,57 +50,145 @@ NOTES # endif # endif -/* VARARGS */ -#ifdef ANSI_PROTOTYPES -char * -concat (const char *first, ...) -#else -char * -concat (va_alist) - va_dcl -#endif -{ - register size_t length; - register char *newstr; - register char *end; - register const char *arg; - va_list args; -#ifndef ANSI_PROTOTYPES - const char *first; +#if HAVE_STDLIB_H +#include #endif - /* First compute the size of the result and get sufficient memory. */ -#ifdef ANSI_PROTOTYPES - va_start (args, first); -#else - va_start (args); - first = va_arg (args, const char *); -#endif +static inline unsigned long vconcat_length (const char *, va_list); +static inline unsigned long +vconcat_length (const char *first, va_list args) +{ + unsigned long length = 0; + const char *arg; - length = 0; for (arg = first; arg ; arg = va_arg (args, const char *)) length += strlen (arg); - va_end (args); - - newstr = (char *) xmalloc (length + 1); + return length; +} - /* Now copy the individual pieces to the result string. */ -#ifdef ANSI_PROTOTYPES - va_start (args, first); -#else - va_start (args); - first = va_arg (args, const char *); -#endif +static inline char * +vconcat_copy (char *dst, const char *first, va_list args) +{ + char *end = dst; + const char *arg; - end = newstr; for (arg = first; arg ; arg = va_arg (args, const char *)) { - length = strlen (arg); + unsigned long length = strlen (arg); memcpy (end, arg, length); end += length; } *end = '\000'; + + return dst; +} + +/* @undocumented concat_length */ + +unsigned long +concat_length (const char *first, ...) +{ + unsigned long length; + va_list args; + + va_start (args, first); + length = vconcat_length (first, args); + va_end (args); + + return length; +} + +/* @undocumented concat_copy */ + +char * +concat_copy (char *dst, const char *first, ...) +{ + char *save_dst; + va_list args; + + va_start (args, first); + vconcat_copy (dst, first, args); + save_dst = dst; /* With K&R C, dst goes out of scope here. */ + va_end (args); + + return save_dst; +} + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ +char *libiberty_concat_ptr; +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +/* @undocumented concat_copy2 */ + +char * +concat_copy2 (const char *first, ...) +{ + va_list args; + va_start (args, first); + vconcat_copy (libiberty_concat_ptr, first, args); + va_end (args); + + return libiberty_concat_ptr; +} + +char * +concat (const char *first, ...) +{ + char *newstr; + va_list args; + + /* First compute the size of the result and get sufficient memory. */ + va_start (args, first); + newstr = XNEWVEC (char, vconcat_length (first, args) + 1); + va_end (args); + + /* Now copy the individual pieces to the result string. */ + va_start (args, first); + vconcat_copy (newstr, first, args); + va_end (args); + + return newstr; +} + +/* + +@deftypefn Extension char* reconcat (char *@var{optr}, const char *@var{s1}, @ + @dots{}, @code{NULL}) + +Same as @code{concat}, except that if @var{optr} is not @code{NULL} it +is freed after the string is created. This is intended to be useful +when you're extending an existing string or building up a string in a +loop: + +@example + str = reconcat (str, "pre-", str, NULL); +@end example + +@end deftypefn + +*/ + +char * +reconcat (char *optr, const char *first, ...) +{ + char *newstr; + va_list args; + + /* First compute the size of the result and get sufficient memory. */ + va_start (args, first); + newstr = XNEWVEC (char, vconcat_length (first, args) + 1); + va_end (args); + + /* Now copy the individual pieces to the result string. */ + va_start (args, first); + vconcat_copy (newstr, first, args); + if (optr) /* Done before VA_CLOSE so optr stays in scope for K&R C. */ + free (optr); va_end (args); return newstr; @@ -135,7 +202,7 @@ concat (va_alist) #include int -main () +main (void) { printf ("\"\" = \"%s\"\n", concat (NULLP)); printf ("\"a\" = \"%s\"\n", concat ("a", NULLP));