File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / lrzsz / lib / vasprintf.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Thu Oct 24 15:49:50 2019 UTC (4 years, 8 months ago) by misho
Branches: lrzsz, MAIN
CVS tags: v0_12_20p5, HEAD
lrzsz ver 0.12.20

    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>