This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Re: Libiberty's snprintf for v3?
> From: Andreas Schwab <schwab at suse dot de>
>
> "Kaveh R. Ghazi" <ghazi at caip dot rutgers dot edu> writes:
>
> |> +
> |> + /* Copy `ap' before using it. */
> |> + va_copy (ap2, ap);
>
> You need to call va_end on the va_alist copy before returning.
> Andreas.
Oops. Better?
diff -rcp orig/egcc-CVS20030425/libiberty/vsnprintf.c egcc-CVS20030425/libiberty/vsnprintf.c
*** orig/egcc-CVS20030425/libiberty/vsnprintf.c Tue Apr 22 15:58:01 2003
--- egcc-CVS20030425/libiberty/vsnprintf.c Sat Apr 26 10:21:07 2003
*************** system version of this function is used.
*** 39,62 ****
*/
- #include "config.h"
#include "ansidecl.h"
#ifdef ANSI_PROTOTYPES
#include <stdarg.h>
#else
#include <varargs.h>
#endif
! #ifdef HAVE_STRING_H
! #include <string.h>
! #endif
! #ifdef HAVE_STDLIB_H
! #include <stdlib.h>
! #endif
#include "libiberty.h"
! /* This implementation relies on a working vasprintf. */
int
vsnprintf (s, n, format, ap)
char * s;
--- 39,80 ----
*/
#include "ansidecl.h"
#ifdef ANSI_PROTOTYPES
#include <stdarg.h>
+ #include <stddef.h>
#else
#include <varargs.h>
+ #define size_t unsigned long
#endif
! #include <stdio.h>
#include "libiberty.h"
! PTR memcpy PARAMS ((PTR, const PTR, size_t));
! int atexit PARAMS ((void (*)(void)));
!
! #ifndef va_copy
! # ifdef __va_copy
! # define va_copy(d,s) __va_copy((d),(s))
! # else
! # define va_copy(d,s) ((d) = (s))
! # endif
! #endif
!
! static FILE *nullstream = 0;
!
! #if defined(HAVE_ATEXIT) || defined (HAVE_ON_EXIT)
! static void close_nullstream PARAMS ((void));
! static void
! close_nullstream()
! {
! if (nullstream)
! fclose (nullstream);
! }
! #endif
!
int
vsnprintf (s, n, format, ap)
char * s;
*************** vsnprintf (s, n, format, ap)
*** 64,93 ****
const char *format;
va_list ap;
{
! char *buf = 0;
! int result = vasprintf (&buf, format, ap);
! if (!buf)
! return -1;
! if (result < 0)
{
! free (buf);
! return -1;
}
!
! result = strlen (buf);
if (n > 0)
{
! if ((long) n > result)
! memcpy (s, buf, result+1);
else
{
memcpy (s, buf, n-1);
s[n - 1] = 0;
}
}
! free (buf);
! return result;
}
#ifdef TEST
--- 82,136 ----
const char *format;
va_list ap;
{
! int size;
! /* Open a stream on /dev/null and arrange to close it at exit. */
! if (!nullstream)
{
! if ((nullstream = fopen ("/dev/null", "a")))
! {
! /* We don't want to rely on libiberty's atexit.c so that
! this file can be used outside libiberty. */
! #ifdef HAVE_ATEXIT
! atexit (close_nullstream);
! #else
! # ifdef HAVE_ON_EXIT
! on_exit ((void *)close_nullstream, 0);
! # endif
! #endif
! }
! else
! return -1;
}
!
! /* Copy `ap' since we use it twice, once here and once below. */
! {
! va_list ap2;
! va_copy (ap2, ap);
! size = vfprintf (nullstream, format, ap2);
! va_end (ap2);
! if (size < 0)
! return -1;
! }
!
if (n > 0)
{
! /* If `size' fits in `n' then just print to the user supplied
! buffer, otherwise print to a temporary space and copy `n'
! bytes. */
! if ((long) n > size)
! vsprintf (s, format, ap);
else
{
+ char *const buf = alloca (size + 1);
+
+ vsprintf (buf, format, ap);
memcpy (s, buf, n-1);
s[n - 1] = 0;
}
}
!
! return size;
}
#ifdef TEST
*************** vsnprintf (s, n, format, ap)
*** 96,101 ****
--- 139,148 ----
/* For assertions. */
#define VERIFY(P) do { if (!(P)) abort(); } while (0)
+ void abort PARAMS ((void));
+ int memcmp PARAMS ((const PTR, const PTR, size_t));
+ PTR memset PARAMS ((PTR, int, size_t));
+
static int ATTRIBUTE_PRINTF_3
checkit VPARAMS ((char *s, size_t n, const char *format, ...))
{