Annotation of embedaddon/lrzsz/lib/vasprintf.c, revision 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>