download vasprintf.c
Language: C
Copyright: (C) 1994 Free Software Foundation, Inc.
LOC: 142
Project Info
MinGW - Minimalist GNU for Windows(mingw)
Server: SourceForge
Type: cvs
...ingw\msys\rt\src\libiberty\
   aclocal.m4
   alloca.c
   argv.c
   asprintf.c
   atexit.c
   basename.c
   bcmp.c
   bcopy.c
   bsearch.c
   bzero.c
   calloc.c
   ChangeLog.MSYS
   choose-temp.c
   clock.c
   concat.c
   config.h-vms
   config.in
   config.table
   configure.in
   copysign.c
   cp-demangle.c
   cplus-dem.c
   dyn-string.c
   fdmatch.c
   ffs.c
   fibheap.c
   floatformat.c
   fnmatch.c
   getcwd.c
   getopt.c
   getopt1.c
   getpagesize.c
   getpwd.c
   getruntime.c
   hashtab.c
   hex.c
   index.c
   insque.c
   lbasename.c
   make-temp-file.c
   Makefile.in
   makefile.vms
   md5.c
   memchr.c
   memcmp.c
   memcpy.c
   memmove.c
   memset.c
   mkstemps.c
   mpw-config.in
   mpw-make.sed
   mpw.c
   msdos.c
   objalloc.c
   obstack.c
   partition.c
   pexecute.c
   putenv.c
   random.c
   regex.c
   rename.c
   rindex.c
   safe-ctype.c
   setenv.c
   sigsetmask.c
   sort.c
   spaces.c
   splay-tree.c
   strcasecmp.c
   strchr.c
   strdup.c
   strerror.c
   strncasecmp.c
   strncmp.c
   strrchr.c
   strsignal.c
   strstr.c
   strtod.c
   strtol.c
   strtoul.c
   ternary.c
   tmpnam.c
   vasprintf.c
   vfork.c
   vfprintf.c
   vprintf.c
   vsprintf.c
   waitpid.c
   xatexit.c
   xexit.c
   xmalloc.c
   xmemdup.c
   xstrdup.c
   xstrerror.c

/* Like vsprintf but provides a pointer to malloc'd storage, which must
   be freed by the caller.
   Copyright (C) 1994 Free Software Foundation, Inc.

This file is part of the libiberty library.
Libiberty is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.

Libiberty is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Library General Public License for more details.

You should have received a copy of the GNU Library General Public
License along with libiberty; see the file COPYING.LIB.  If
not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.  */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <ansidecl.h>
#ifdef ANSI_PROTOTYPES
#include <stdarg.h>
#else
#include <varargs.h>
#endif
#include <stdio.h>
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#else
extern unsigned long strtoul ();
extern PTR malloc ();
#endif
#include "libiberty.h"

#ifdef TEST
int global_total_width;
#endif


static int int_vasprintf PARAMS ((char **, const char *, va_list *));

static int
int_vasprintf (result, format, args)
     char **result;
     const char *format;
     va_list *args;
{
  const char *p = format;
  /* Add one to make sure that it is never zero, which might cause malloc
     to return NULL.  */
  int total_width = strlen (format) + 1;
  va_list ap;

  memcpy ((PTR) &ap, (PTR) args, sizeof (va_list));

  while (*p != '\0')
    {
      if (*p++ == '%')
	{
	  while (strchr ("-+ #0", *p))
	    ++p;
	  if (*p == '*')
	    {
	      ++p;
	      total_width += abs (va_arg (ap, int));
	    }
	  else
	    total_width += strtoul (p, (char **) &p, 10);
	  if (*p == '.')
	    {
	      ++p;
	      if (*p == '*')
		{
		  ++p;
		  total_width += abs (va_arg (ap, int));
		}
	      else
	      total_width += strtoul (p, (char **) &p, 10);
	    }
	  while (strchr ("hlL", *p))
	    ++p;
	  /* Should be big enough for any format specifier except %s and floats.  */
	  total_width += 30;
	  switch (*p)
	    {
	    case 'd':
	    case 'i':
	    case 'o':
	    case 'u':
	    case 'x':
	    case 'X':
	    case 'c':
	      (void) va_arg (ap, int);
	      break;
	    case 'f':
	    case 'e':
	    case 'E':
	    case 'g':
	    case 'G':
	      (void) va_arg (ap, double);
	      /* Since an ieee double can have an exponent of 307, we'll
		 make the buffer wide enough to cover the gross case. */
	      total_width += 307;
	      break;
	    case 's':
	      total_width += strlen (va_arg (ap, char *));
	      break;
	    case 'p':
	    case 'n':
	      (void) va_arg (ap, char *);
	      break;
	    }
	  p++;
	}
    }
#ifdef TEST
  global_total_width = total_width;
#endif
  *result = malloc (total_width);
  if (*result != NULL)
    return vsprintf (*result, format, *args);
  else
    return 0;
}

int
vasprintf (result, format, args)
     char **result;
     const char *format;
#if defined (_BSD_VA_LIST_) && defined (__FreeBSD__)
     _BSD_VA_LIST_ args;
#else
     va_list args;
#endif
{
  return int_vasprintf (result, format, &args);
}

#ifdef TEST
static void ATTRIBUTE_PRINTF_1
checkit VPARAMS ((const char *format, ...))
{
  char *result;
  VA_OPEN (args, format);
  VA_FIXEDARG (args, const char *, format);
  vasprintf (&result, format, args);
  VA_CLOSE (args);

  if (strlen (result) < (size_t) global_total_width)
    printf ("PASS: ");
  else
    printf ("FAIL: ");
  printf ("%d %s\n", global_total_width, result);

  free (result);
}

extern int main PARAMS ((void));

int
main ()
{
  checkit ("%d", 0x12345678);
  checkit ("%200d", 5);
  checkit ("%.300d", 6);
  checkit ("%100.150d", 7);
  checkit ("%s", "jjjjjjjjjiiiiiiiiiiiiiiioooooooooooooooooppppppppppppaa\n\
777777777777777777333333333333366666666666622222222222777777777777733333");
  checkit ("%f%s%d%s", 1.0, "foo", 77, "asdjffffffffffffffiiiiiiiiiiixxxxx");

  return 0;
}
#endif /* TEST */

About Koders | Resources | Downloads | Support | Black Duck | Submit Project | Terms of Service | DMCA | Privacy Policy | Site Map| Contact Us