home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / cvs-1.8.7-src.tgz / tar.out / fsf / cvs / lib / vasprintf.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  4KB  |  175 lines

  1. /* Like vsprintf but provides a pointer to malloc'd storage, which must
  2.    be freed by the caller.
  3.    Copyright (C) 1994 Free Software Foundation, Inc.
  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., 675 Mass Ave,
  19. Cambridge, MA 02139, USA.  */
  20.  
  21. #include <stdio.h>
  22. #include <string.h>
  23.  
  24. #ifdef HAVE_CONFIG_H
  25. #include "config.h"
  26. #endif
  27.  
  28. #ifdef __STDC__
  29. #include <stdarg.h>
  30. #else
  31. #include <varargs.h>
  32. #endif
  33.  
  34. #ifdef TEST
  35. int global_total_width;
  36. #endif
  37.  
  38. #ifdef STDC_HEADERS
  39. #include <stdlib.h>
  40. #else
  41. extern int abs ();
  42. extern unsigned long strtoul ();
  43. extern char *malloc ();
  44. #endif
  45.  
  46. static int
  47. int_vasprintf (result, format, args)
  48.      char **result;
  49.      const char *format;
  50.      va_list *args;
  51. {
  52.   const char *p = format;
  53.   /* Add one to make sure that it is never zero, which might cause malloc
  54.      to return NULL.  */
  55.   int total_width = strlen (format) + 1;
  56.   va_list ap;
  57.  
  58.   memcpy (&ap, args, sizeof (va_list));
  59.  
  60.   while (*p != '\0')
  61.     {
  62.       if (*p++ == '%')
  63.     {
  64.       while (strchr ("-+ #0", *p))
  65.         ++p;
  66.       if (*p == '*')
  67.         {
  68.           ++p;
  69.           total_width += abs (va_arg (ap, int));
  70.         }
  71.       else
  72.         total_width += strtoul (p, &p, 10);
  73.       if (*p == '.')
  74.         {
  75.           ++p;
  76.           if (*p == '*')
  77.         {
  78.           ++p;
  79.           total_width += abs (va_arg (ap, int));
  80.         }
  81.           else
  82.           total_width += strtoul (p, &p, 10);
  83.         }
  84.       while (strchr ("hlL", *p))
  85.         ++p;
  86.       /* Should be big enough for any format specifier except %s.  */
  87.       total_width += 30;
  88.       switch (*p)
  89.         {
  90.         case 'd':
  91.         case 'i':
  92.         case 'o':
  93.         case 'u':
  94.         case 'x':
  95.         case 'X':
  96.         case 'c':
  97.           (void) va_arg (ap, int);
  98.           break;
  99.         case 'f':
  100.         case 'e':
  101.         case 'E':
  102.         case 'g':
  103.         case 'G':
  104.           (void) va_arg (ap, double);
  105.           break;
  106.         case 's':
  107.           total_width += strlen (va_arg (ap, char *));
  108.           break;
  109.         case 'p':
  110.         case 'n':
  111.           (void) va_arg (ap, char *);
  112.           break;
  113.         }
  114.     }
  115.     }
  116. #ifdef TEST
  117.   global_total_width = total_width;
  118. #endif
  119.   *result = malloc (total_width);
  120.   if (*result != NULL)
  121.     return vsprintf (*result, format, *args);
  122.   else
  123.     return 0;
  124. }
  125.  
  126. int
  127. vasprintf (result, format, args)
  128.      char **result;
  129.      const char *format;
  130.      va_list args;
  131. {
  132.   return int_vasprintf (result, format, &args);
  133. }
  134.  
  135. #ifdef TEST
  136. void
  137. checkit
  138. #ifdef __STDC__
  139.      (const char* format, ...)
  140. #else
  141.      (va_alist)
  142.      va_dcl
  143. #endif
  144. {
  145.   va_list args;
  146.   char *result;
  147.  
  148. #ifdef __STDC__
  149.   va_start (args, format);
  150. #else
  151.   char *format;
  152.   va_start (args);
  153.   format = va_arg (args, char *);
  154. #endif
  155.   vasprintf (&result, format, args);
  156.   if (strlen (result) < global_total_width)
  157.     printf ("PASS: ");
  158.   else
  159.     printf ("FAIL: ");
  160.   printf ("%d %s\n", global_total_width, result);
  161. }
  162.  
  163. int
  164. main ()
  165. {
  166.   checkit ("%d", 0x12345678);
  167.   checkit ("%200d", 5);
  168.   checkit ("%.300d", 6);
  169.   checkit ("%100.150d", 7);
  170.   checkit ("%s", "jjjjjjjjjiiiiiiiiiiiiiiioooooooooooooooooppppppppppppaa\n\
  171. 777777777777777777333333333333366666666666622222222222777777777777733333");
  172.   checkit ("%f%s%d%s", 1.0, "foo", 77, "asdjffffffffffffffiiiiiiiiiiixxxxx");
  173. }
  174. #endif /* TEST */
  175.