Annotation of embedaddon/lrzsz/lib/vasprintf.c, revision 1.1.1.1

1.1       misho       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 program is free software; you can redistribute it and/or modify
                      6: it under the terms of the GNU General Public License as published by
                      7: the Free Software Foundation; either version 2, or (at your option)
                      8: any later version.
                      9: 
                     10: This program is distributed in the hope that it will be useful,
                     11: but WITHOUT ANY WARRANTY; without even the implied warranty of
                     12: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     13: GNU General Public License for more details.
                     14: 
                     15: You should have received a copy of the GNU General Public License
                     16: along with this program; if not, write to the Free Software
                     17: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
                     18: 
                     19: #ifdef HAVE_CONFIG_H
                     20: # include <config.h>
                     21: #endif
                     22: 
                     23: #include <stdio.h>
                     24: #include <stdlib.h>
                     25: #include <string.h>
                     26: 
                     27: #if __STDC__
                     28: # include <stdarg.h>
                     29: #else
                     30: # include <varargs.h>
                     31: #endif
                     32: 
                     33: #ifdef TEST
                     34: int global_total_width;
                     35: #endif
                     36: 
                     37: /* unsigned long strtoul (); */
                     38: /* char *malloc (); */
                     39: 
                     40: static int
                     41: int_vasprintf (result, format, args)
                     42:      char **result;
                     43:      const char *format;
                     44:      va_list *args;
                     45: {
                     46:   const char *p = format;
                     47:   /* Add one to make sure that it is never zero, which might cause malloc
                     48:      to return NULL.  */
                     49:   int total_width = strlen (format) + 1;
                     50:   va_list ap;
                     51: 
                     52:   memcpy (&ap, args, sizeof (va_list));
                     53: 
                     54:   while (*p != '\0')
                     55:     {
                     56:       if (*p++ == '%')
                     57:        {
                     58:          while (strchr ("-+ #0", *p))
                     59:            ++p;
                     60:          if (*p == '*')
                     61:            {
                     62:              ++p;
                     63:              total_width += abs (va_arg (ap, int));
                     64:            }
                     65:          else
                     66:            total_width += strtoul (p, &p, 10);
                     67:          if (*p == '.')
                     68:            {
                     69:              ++p;
                     70:              if (*p == '*')
                     71:                {
                     72:                  ++p;
                     73:                  total_width += abs (va_arg (ap, int));
                     74:                }
                     75:              else
                     76:                total_width += strtoul (p, &p, 10);
                     77:            }
                     78:          while (strchr ("hlL", *p))
                     79:            ++p;
                     80:          /* Should be big enough for any format specifier except %s.  */
                     81:          total_width += 30;
                     82:          switch (*p)
                     83:            {
                     84:            case 'd':
                     85:            case 'i':
                     86:            case 'o':
                     87:            case 'u':
                     88:            case 'x':
                     89:            case 'X':
                     90:            case 'c':
                     91:              (void) va_arg (ap, int);
                     92:              break;
                     93:            case 'f':
                     94:            case 'e':
                     95:            case 'E':
                     96:            case 'g':
                     97:            case 'G':
                     98:              (void) va_arg (ap, double);
                     99:              break;
                    100:            case 's':
                    101:              total_width += strlen (va_arg (ap, char *));
                    102:              break;
                    103:            case 'p':
                    104:            case 'n':
                    105:              (void) va_arg (ap, char *);
                    106:              break;
                    107:            }
                    108:        }
                    109:     }
                    110: #ifdef TEST
                    111:   global_total_width = total_width;
                    112: #endif
                    113:   *result = malloc (total_width);
                    114:   if (*result != NULL)
                    115:     return vsprintf (*result, format, *args);
                    116:   else
                    117:     return 0;
                    118: }
                    119: 
                    120: int
                    121: vasprintf (result, format, args)
                    122:      char **result;
                    123:      const char *format;
                    124:      va_list args;
                    125: {
                    126:   return int_vasprintf (result, format, &args);
                    127: }
                    128: 
                    129: int
                    130: asprintf
                    131: #if __STDC__
                    132:      (char **result, const char *format, ...)
                    133: #else
                    134:      (result, va_alist)
                    135:      char **result;
                    136:      va_dcl
                    137: #endif
                    138: {
                    139:   va_list args;
                    140:   int done;
                    141: 
                    142: #if __STDC__
                    143:   va_start (args, format);
                    144: #else
                    145:   char *format;
                    146:   va_start (args);
                    147:   format = va_arg (args, char *);
                    148: #endif
                    149:   done = vasprintf (result, format, args);
                    150:   va_end (args);
                    151: 
                    152:   return done;
                    153: } 
                    154: 
                    155: #ifdef TEST
                    156: void
                    157: checkit
                    158: #if __STDC__
                    159:      (const char* format, ...)
                    160: #else
                    161:      (va_alist)
                    162:      va_dcl
                    163: #endif
                    164: {
                    165:   va_list args;
                    166:   char *result;
                    167: 
                    168: #if __STDC__
                    169:   va_start (args, format);
                    170: #else
                    171:   char *format;
                    172:   va_start (args);
                    173:   format = va_arg (args, char *);
                    174: #endif
                    175:   vasprintf (&result, format, args);
                    176:   if (strlen (result) < global_total_width)
                    177:     printf ("PASS: ");
                    178:   else
                    179:     printf ("FAIL: ");
                    180:   printf ("%d %s\n", global_total_width, result);
                    181: }
                    182: 
                    183: int
                    184: main ()
                    185: {
                    186:   checkit ("%d", 0x12345678);
                    187:   checkit ("%200d", 5);
                    188:   checkit ("%.300d", 6);
                    189:   checkit ("%100.150d", 7);
                    190:   checkit ("%s", "jjjjjjjjjiiiiiiiiiiiiiiioooooooooooooooooppppppppppppaa\n\
                    191: 777777777777777777333333333333366666666666622222222222777777777777733333");
                    192:   checkit ("%f%s%d%s", 1.0, "foo", 77, "asdjffffffffffffffiiiiiiiiiiixxxxx");
                    193: }
                    194: #endif /* TEST */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>