From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 6415 invoked by alias); 22 Apr 2003 23:13:33 -0000 Mailing-List: contact gcc-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-owner@gcc.gnu.org Received: (qmail 6401 invoked from network); 22 Apr 2003 23:13:33 -0000 Received: from unknown (HELO caip.rutgers.edu) (128.6.236.10) by sources.redhat.com with SMTP; 22 Apr 2003 23:13:33 -0000 Received: (from ghazi@localhost) by caip.rutgers.edu (8.9.3/8.9.3) id TAA04743; Tue, 22 Apr 2003 19:13:32 -0400 (EDT) Date: Tue, 22 Apr 2003 23:53:00 -0000 From: "Kaveh R. Ghazi" Message-Id: <200304222313.TAA04743@caip.rutgers.edu> To: dj@redhat.com Subject: Re: Libiberty's snprintf for v3? Cc: gcc@gcc.gnu.org, libstdc++@gcc.gnu.org, pcarlini@unitus.it References: <200304220052.h3M0qO830610@greed.delorie.com> <200304220247.WAA19945@caip.rutgers.edu> <200304220313.h3M3D4c32419@greed.delorie.com> X-SW-Source: 2003-04/txt/msg01102.txt.bz2 > From: DJ Delorie > > > Ok, but that's only a concern if these platforms are missing > > [v]snprintf and therefore would rely on the libiberty copy. > > E.g. I'd expect that cygwin has snprintf. Don't know about the > > others. > > > > Can you please clarify the other platforms' situations? > > [v]snprintf will be in djgpp 2.04, but isn't in the current 2.03. Ok I'd be interested in concrete measurements. For the sake of this discussion, I've written a new vsnprintf.c which uses the strategy I outlined previously. (It's mixed with a patch to remove system header includes, but ignore that for the moment.) I'd be interested to know how fast or slow this new vsnprintf.c is vs. the current one in libiberty on djgpp 2.03. I tested the speed by wrapping the -DTEST main program with a large loop and defining CLEAR(X) and VERIFY(X) to be empty so that it isolates the calls to checkit which simply wraps vsnprintf. On unix (sparc-solaris2.7) it's either 10% or 20% faster depending on whether it has to call alloca for extra space, as in when the resulting string would be longer than `n'. --Kaveh diff -rcp orig/egcc-CVS20030421/libiberty/vsnprintf.c egcc-CVS20030421/libiberty/vsnprintf.c *** orig/egcc-CVS20030421/libiberty/vsnprintf.c Tue Apr 22 12:11:27 2003 --- egcc-CVS20030421/libiberty/vsnprintf.c Tue Apr 22 16:35:27 2003 *************** system version of this function is used. *** 39,62 **** */ - #include "config.h" #include "ansidecl.h" #ifdef ANSI_PROTOTYPES #include #else #include #endif ! #ifdef HAVE_STRING_H ! #include ! #endif ! #ifdef HAVE_STDLIB_H ! #include #endif ! #include "libiberty.h" - /* This implementation relies on a working vasprintf. */ int vsnprintf (s, n, format, ap) char * s; --- 39,79 ---- */ #include "ansidecl.h" #ifdef ANSI_PROTOTYPES #include + #include #else #include + #define size_t unsigned long #endif ! ! 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 ! #include ! ! 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 --- 81,133 ---- const char *format; va_list ap; { ! int size; ! va_list ap2; ! /* 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' before using it. */ + va_copy (ap2, ap); ! size = vfprintf (nullstream, format, ap); ! 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, ap2); else { + char *const buf = alloca (size + 1); + + vsprintf (buf, format, ap2); memcpy (s, buf, n-1); s[n - 1] = 0; } } ! ! return size; } #ifdef TEST *************** vsnprintf (s, n, format, ap) *** 96,101 **** --- 136,145 ---- /* 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, ...)) {