Subversion Repositories Kolibri OS

Rev

Rev 5191 | Blame | Compare with Previous | Last modification | View Log | RSS feed

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