home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 7 / FreshFishVol7.bin / bbs / gnu / libg++-2.6-fsf.lha / libg++-2.6 / libiberty / vasprintf.c < prev    next >
C/C++ Source or Header  |  1994-05-13  |  3KB  |  140 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 <varargs.h>
  23.  
  24. #ifdef TEST
  25. int global_total_width;
  26. #endif
  27.  
  28. unsigned long strtoul ();
  29. char *malloc ();
  30.  
  31. int
  32. vasprintf (result, format, args)
  33.      char **result;
  34.      char *format;
  35.      va_list args;
  36. {
  37.   char *p = format;
  38.   /* Add one to make sure that it is never zero, which might cause malloc
  39.      to return NULL.  */
  40.   int total_width = strlen (format) + 1;
  41.   va_list ap = args;
  42.  
  43.   while (*p != '\0')
  44.     {
  45.       if (*p++ == '%')
  46.     {
  47.       while (strchr ("-+ #0", *p))
  48.         ++p;
  49.       if (*p == '*')
  50.         {
  51.           ++p;
  52.           total_width += abs (va_arg (ap, int));
  53.         }
  54.       else
  55.         total_width += strtoul (p, &p, 10);
  56.       if (*p == '.')
  57.         {
  58.           ++p;
  59.           if (*p == '*')
  60.         {
  61.           ++p;
  62.           total_width += abs (va_arg (ap, int));
  63.         }
  64.           else
  65.           total_width += strtoul (p, &p, 10);
  66.         }
  67.       while (strchr ("hlL", *p))
  68.         ++p;
  69.       /* Should be big enough for any format specifier except %s.  */
  70.       total_width += 30;
  71.       switch (*p)
  72.         {
  73.         case 'd':
  74.         case 'i':
  75.         case 'o':
  76.         case 'u':
  77.         case 'x':
  78.         case 'X':
  79.         case 'c':
  80.           va_arg (ap, int);
  81.           break;
  82.         case 'f':
  83.         case 'e':
  84.         case 'E':
  85.         case 'g':
  86.         case 'G':
  87.           va_arg (ap, double);
  88.           break;
  89.         case 's':
  90.           total_width += strlen (va_arg (ap, char *));
  91.           break;
  92.         case 'p':
  93.         case 'n':
  94.           va_arg (ap, char *);
  95.           break;
  96.         }
  97.     }
  98.     }
  99. #ifdef TEST
  100.   global_total_width = total_width;
  101. #endif
  102.   *result = malloc (total_width);
  103.   if (*result != NULL)
  104.     return vsprintf (*result, format, args);
  105.   else
  106.     return 0;
  107. }
  108.  
  109. #ifdef TEST
  110. void
  111. checkit (va_alist)
  112.      va_dcl
  113. {
  114.   va_list args;
  115.   char *format;
  116.   char *result;
  117.  
  118.   va_start (args);
  119.   format = va_arg (args, char *);
  120.   vasprintf (&result, format, args);
  121.   if (strlen (result) < global_total_width)
  122.     printf ("PASS: ");
  123.   else
  124.     printf ("FAIL: ");
  125.   printf ("%d %s\n", global_total_width, result);
  126. }
  127.  
  128. int
  129. main ()
  130. {
  131.   checkit ("%d", 0x12345678);
  132.   checkit ("%200d", 5);
  133.   checkit ("%.300d", 6);
  134.   checkit ("%100.150d", 7);
  135.   checkit ("%s", "jjjjjjjjjiiiiiiiiiiiiiiioooooooooooooooooppppppppppppaa\n\
  136. 777777777777777777333333333333366666666666622222222222777777777777733333");
  137.   checkit ("%f%s%d%s", 1.0, "foo", 77, "asdjffffffffffffffiiiiiiiiiiixxxxx");
  138. }
  139. #endif /* TEST */
  140.