home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 4: GNU Archives / Linux Cubed Series 4 - GNU Archives.iso / gnu / cvs-1.8 / cvs-1 / cvs-1.8.1 / lib / vasprintf.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-06  |  3.6 KB  |  172 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. extern int abs ();
  35.  
  36. #ifdef TEST
  37. int global_total_width;
  38. #endif
  39.  
  40. unsigned long strtoul ();
  41. char *malloc ();
  42.  
  43. static int
  44. int_vasprintf (result, format, args)
  45.      char **result;
  46.      const char *format;
  47.      va_list *args;
  48. {
  49.   const char *p = format;
  50.   /* Add one to make sure that it is never zero, which might cause malloc
  51.      to return NULL.  */
  52.   int total_width = strlen (format) + 1;
  53.   va_list ap;
  54.  
  55.   memcpy (&ap, args, sizeof (va_list));
  56.  
  57.   while (*p != '\0')
  58.     {
  59.       if (*p++ == '%')
  60.     {
  61.       while (strchr ("-+ #0", *p))
  62.         ++p;
  63.       if (*p == '*')
  64.         {
  65.           ++p;
  66.           total_width += abs (va_arg (ap, int));
  67.         }
  68.       else
  69.         total_width += strtoul (p, &p, 10);
  70.       if (*p == '.')
  71.         {
  72.           ++p;
  73.           if (*p == '*')
  74.         {
  75.           ++p;
  76.           total_width += abs (va_arg (ap, int));
  77.         }
  78.           else
  79.           total_width += strtoul (p, &p, 10);
  80.         }
  81.       while (strchr ("hlL", *p))
  82.         ++p;
  83.       /* Should be big enough for any format specifier except %s.  */
  84.       total_width += 30;
  85.       switch (*p)
  86.         {
  87.         case 'd':
  88.         case 'i':
  89.         case 'o':
  90.         case 'u':
  91.         case 'x':
  92.         case 'X':
  93.         case 'c':
  94.           (void) va_arg (ap, int);
  95.           break;
  96.         case 'f':
  97.         case 'e':
  98.         case 'E':
  99.         case 'g':
  100.         case 'G':
  101.           (void) va_arg (ap, double);
  102.           break;
  103.         case 's':
  104.           total_width += strlen (va_arg (ap, char *));
  105.           break;
  106.         case 'p':
  107.         case 'n':
  108.           (void) va_arg (ap, char *);
  109.           break;
  110.         }
  111.     }
  112.     }
  113. #ifdef TEST
  114.   global_total_width = total_width;
  115. #endif
  116.   *result = malloc (total_width);
  117.   if (*result != NULL)
  118.     return vsprintf (*result, format, *args);
  119.   else
  120.     return 0;
  121. }
  122.  
  123. int
  124. vasprintf (result, format, args)
  125.      char **result;
  126.      const char *format;
  127.      va_list args;
  128. {
  129.   return int_vasprintf (result, format, &args);
  130. }
  131.  
  132. #ifdef TEST
  133. void
  134. checkit
  135. #ifdef __STDC__
  136.      (const char* format, ...)
  137. #else
  138.      (va_alist)
  139.      va_dcl
  140. #endif
  141. {
  142.   va_list args;
  143.   char *result;
  144.  
  145. #ifdef __STDC__
  146.   va_start (args, format);
  147. #else
  148.   char *format;
  149.   va_start (args);
  150.   format = va_arg (args, char *);
  151. #endif
  152.   vasprintf (&result, format, args);
  153.   if (strlen (result) < global_total_width)
  154.     printf ("PASS: ");
  155.   else
  156.     printf ("FAIL: ");
  157.   printf ("%d %s\n", global_total_width, result);
  158. }
  159.  
  160. int
  161. main ()
  162. {
  163.   checkit ("%d", 0x12345678);
  164.   checkit ("%200d", 5);
  165.   checkit ("%.300d", 6);
  166.   checkit ("%100.150d", 7);
  167.   checkit ("%s", "jjjjjjjjjiiiiiiiiiiiiiiioooooooooooooooooppppppppppppaa\n\
  168. 777777777777777777333333333333366666666666622222222222777777777777733333");
  169.   checkit ("%f%s%d%s", 1.0, "foo", 77, "asdjffffffffffffffiiiiiiiiiiixxxxx");
  170. }
  171. #endif /* TEST */
  172.