svn commit: trunk/uClibc/libc/stdio

vda at uclibc.org vda at uclibc.org
Wed Apr 9 19:51:18 UTC 2008


Author: vda
Date: 2008-04-09 12:51:18 -0700 (Wed, 09 Apr 2008)
New Revision: 21683

Log:
Factor out the core of vprintf() into separate function
vprintf_internal, so that:
* vprintf() does locking and __STDIO_STREAM_TRANS_TO_WRITE thing,
  then calls vprintf_internal
* vsnprintf, vdprintf.c, vasprintf.c use
  vprintf_internal directly

This makes sprintf faster (since it doesn't do any locking)
and stops it from pulling in fseek in static compile.



Added:
   trunk/uClibc/libc/stdio/_vfprintf_internal.c
   trunk/uClibc/libc/stdio/_vfwprintf_internal.c

Modified:
   trunk/uClibc/libc/stdio/Makefile.in
   trunk/uClibc/libc/stdio/_stdio.h
   trunk/uClibc/libc/stdio/_vfprintf.c
   trunk/uClibc/libc/stdio/vasprintf.c
   trunk/uClibc/libc/stdio/vdprintf.c
   trunk/uClibc/libc/stdio/vsnprintf.c
   trunk/uClibc/libc/stdio/vswprintf.c


Changeset:
Modified: trunk/uClibc/libc/stdio/Makefile.in
===================================================================
--- trunk/uClibc/libc/stdio/Makefile.in	2008-04-09 11:38:48 UTC (rev 21682)
+++ trunk/uClibc/libc/stdio/Makefile.in	2008-04-09 19:51:18 UTC (rev 21683)
@@ -59,6 +59,7 @@
 ifneq ($(USE_OLD_VFPRINTF),y)
 VF_CSRC := \
 	vfprintf.c \
+	_vfprintf_internal.c \
 	_ppfs_init.c _ppfs_prepargs.c _ppfs_setargs.c _ppfs_parsespec.c \
 	register_printf_function.c parse_printf_format.c
 CSRC += $(VF_CSRC)
@@ -77,7 +78,7 @@
 CUSRC += fgetwc.c getwchar.c fgetws.c fputwc.c putwchar.c fputws.c
 # getwc (fgetwc alias) getwc_unlocked (fgetwc_unlocked alias)
 # putwc (fputwc alias) putwc_unlocked (fputwc_unlocked alias)
-CSRC += vfwprintf.c
+CSRC += vfwprintf.c _vfwprintf_internal.c
 CSRC += wscanf.c swscanf.c fwscanf.c vwscanf.c vswscanf.c vfwscanf.c
 endif
 

Modified: trunk/uClibc/libc/stdio/_stdio.h
===================================================================
--- trunk/uClibc/libc/stdio/_stdio.h	2008-04-09 11:38:48 UTC (rev 21682)
+++ trunk/uClibc/libc/stdio/_stdio.h	2008-04-09 19:51:18 UTC (rev 21683)
@@ -15,6 +15,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <stdarg.h>
 #include <unistd.h>
 #ifdef __UCLIBC_HAS_WCHAR__
 #include <wchar.h>
@@ -431,6 +432,18 @@
 #endif
 
 /**********************************************************************/
+
+extern int _vfprintf_internal (FILE * __restrict stream,
+			register const char * __restrict format,
+			va_list arg) attribute_hidden;
+
+#ifdef __UCLIBC_HAS_WCHAR__
+extern int _vfwprintf_internal (FILE * __restrict stream,
+			register const wchar_t * __restrict format,
+			va_list arg) attribute_hidden;
+#endif
+
+/**********************************************************************/
 /* Only use the macro below if you know fp is a valid FILE for a valid fd.
  * This is _not_ true for custom streams! */
 #define __FILENO_UNLOCKED(fp)	((fp)->__filedes)

Modified: trunk/uClibc/libc/stdio/_vfprintf.c
===================================================================
--- trunk/uClibc/libc/stdio/_vfprintf.c	2008-04-09 11:38:48 UTC (rev 21682)
+++ trunk/uClibc/libc/stdio/_vfprintf.c	2008-04-09 19:51:18 UTC (rev 21683)
@@ -1198,7 +1198,7 @@
 
 #endif
 /**********************************************************************/
-#if defined(L_vfprintf) || defined(L_vfwprintf)
+#if defined(L__vfprintf_internal) || defined(L__vfwprintf_internal)
 
 /* We only support ascii digits (or their USC equivalent codes) in
  * precision and width settings in *printf (wide) format strings.
@@ -1207,14 +1207,15 @@
 
 static size_t _charpad(FILE * __restrict stream, int padchar, size_t numpad);
 
-#ifdef L_vfprintf
+#ifdef L__vfprintf_internal
 
-#define VFPRINTF vfprintf
+#define VFPRINTF_internal _vfprintf_internal
 #define FMT_TYPE char
 #define OUTNSTR _outnstr
 #define STRLEN  strlen
 #define _PPFS_init _ppfs_init
-#define OUTPUT(F,S)			fputs_unlocked(S,F)
+/* Pulls in fseek: #define OUTPUT(F,S)	fputs_unlocked(S,F) */
+#define OUTPUT(F,S)			__stdio_fwrite((const unsigned char *)(S),strlen(S),(F))
 /* #define _outnstr(stream, string, len)	__stdio_fwrite(string, len, stream) */
 #define _outnstr(stream, string, len)	((len > 0) ? __stdio_fwrite(string, len, stream) : 0)
 #define FP_OUT _fp_out_narrow
@@ -1239,14 +1240,16 @@
 
 #endif /* __STDIO_PRINTF_FLOAT */
 
-#else  /* L_vfprintf */
+#else  /* L__vfprintf_internal */
 
-#define VFPRINTF vfwprintf
+#define VFPRINTF_internal _vfwprintf_internal
 #define FMT_TYPE wchar_t
 #define OUTNSTR _outnwcs
 #define STRLEN  wcslen
 #define _PPFS_init _ppwfs_init
+/* Pulls in fseek: */
 #define OUTPUT(F,S)			fputws(S,F)
+/* TODO: #define OUTPUT(F,S)		_wstdio_fwrite((S),wcslen(S),(F)) */
 #define _outnwcs(stream, wstring, len)	_wstdio_fwrite(wstring, len, stream)
 #define FP_OUT _fp_out_wide
 
@@ -1417,8 +1420,9 @@
 	return 0;
 }
 
-#endif /* L_vfprintf */
+#endif /* L__vfprintf_internal */
 
+
 static size_t _charpad(FILE * __restrict stream, int padchar, size_t numpad)
 {
 	size_t todo = numpad;
@@ -1439,12 +1443,12 @@
 						 register ppfs_t *ppfs, int *count)
 {
 	static const char spec_base[] = SPEC_BASE;
-#ifdef L_vfprintf
+#ifdef L__vfprintf_internal
 	static const char prefix[] = "+\0-\0 \0000x\0000X";
 	/*                            0  2  4  6   9 11*/
-#else  /* L_vfprintf */
+#else  /* L__vfprintf_internal */
 	static const wchar_t prefix[] = L"+\0-\0 \0000x\0000X";
-#endif /* L_vfprintf */
+#endif /* L__vfprintf_internal */
 	enum {
 		PREFIX_PLUS = 0,
 		PREFIX_MINUS = 2,
@@ -1465,7 +1469,7 @@
 	mbstate_t mbstate;
 #endif /* __UCLIBC_HAS_WCHAR__ */
 	size_t slen;
-#ifdef L_vfprintf
+#ifdef L__vfprintf_internal
 #define SLEN slen
 #else
 	size_t SLEN;
@@ -1532,7 +1536,7 @@
 			alphacase = __UIM_LOWER;
 
 #ifdef __UCLIBC_MJN3_ONLY__
-#ifdef L_vfprintf
+#ifdef L__vfprintf_internal
 #warning CONSIDER: Should we ignore these flags if stub locale?  What about custom specs?
 #endif
 #endif /* __UCLIBC_MJN3_ONLY__ */
@@ -1560,7 +1564,7 @@
 				padchar = ppfs->info.pad;
 			}
 #ifdef __UCLIBC_MJN3_ONLY__
-#ifdef L_vfprintf
+#ifdef L__vfprintf_internal
 #warning CONSIDER: If using outdigits and/or grouping, how should we interpret precision?
 #endif
 #endif /* __UCLIBC_MJN3_ONLY__ */
@@ -1580,7 +1584,7 @@
 				}
 			}
 			slen = (char *)(buf + sizeof(buf) - 1) - s;
-#ifdef L_vfwprintf
+#ifdef L__vfwprintf_internal
 			{
 				const char *q = s;
 				mbstate.__mask = 0; /* Initialize the mbstate. */
@@ -1605,13 +1609,13 @@
 				}
 				if (ppfs->conv_num == CONV_p) {/* null pointer */
 					s = "(nil)";
-#ifdef L_vfwprintf
+#ifdef L__vfwprintf_internal
 					SLEN =
 #endif
 					slen = 5;
 					numfill = 0;
 				} else if (numfill == 0) {	/* if precision 0, no output */
-#ifdef L_vfwprintf
+#ifdef L__vfwprintf_internal
 					SLEN =
 #endif
 					slen = 0;
@@ -1637,7 +1641,7 @@
 			return -1;			/* TODO -- try to continue? */
 #endif /* __STDIO_PRINTF_FLOAT */
 		} else if (ppfs->conv_num <= CONV_S) {	/* wide char or string */
-#ifdef L_vfprintf
+#ifdef L__vfprintf_internal
 
 #ifdef __UCLIBC_HAS_WCHAR__
 			mbstate.__mask = 0;	/* Initialize the mbstate. */
@@ -1692,7 +1696,7 @@
 				slen = 1;
 			}
 
-#else  /* L_vfprintf */
+#else  /* L__vfprintf_internal */
 
 			if (ppfs->conv_num == CONV_S) { /* wide string */
 				ws = *((wchar_t **) (*argptr));
@@ -1713,7 +1717,7 @@
 
 			if (ppfs->conv_num == CONV_s) { /* string */
 #ifdef __UCLIBC_MJN3_ONLY__
-#warning TODO: Fix %s for vfwprintf... output upto illegal sequence?
+#warning TODO: Fix %s for _vfwprintf_internal... output upto illegal sequence?
 #endif /* __UCLIBC_MJN3_ONLY__ */
 				s = *((char **) (*argptr));
 				if (s) {
@@ -1746,7 +1750,7 @@
 				goto CHAR_CASE;
 			}
 
-#endif /* L_vfprintf */
+#endif /* L__vfprintf_internal */
 
 #ifdef __UCLIBC_HAS_PRINTF_M_SPEC__
 		} else if (ppfs->conv_num == CONV_m) {
@@ -1778,7 +1782,7 @@
 		}
 
 #ifdef __UCLIBC_MJN3_ONLY__
-#ifdef L_vfprintf
+#ifdef L__vfprintf_internal
 #warning CONSIDER: If using outdigits and/or grouping, how should we pad?
 #endif
 #endif /* __UCLIBC_MJN3_ONLY__ */
@@ -1805,11 +1809,12 @@
 			numpad = 0;
 		}
 		OUTPUT(stream, prefix + prefix_num);
+
 		if (_charpad(stream, '0', numfill) != numfill) {
 			return -1;
 		}
 
-#ifdef L_vfprintf
+#ifdef L__vfprintf_internal
 
 #ifdef __UCLIBC_HAS_WCHAR__
 		if (!ws) {
@@ -1836,7 +1841,7 @@
 		}
 #endif /* __UCLIBC_HAS_WCHAR__ */
 
-#else  /* L_vfprintf */
+#else  /* L__vfprintf_internal */
 
 		if (!ws) {
 			assert(s);
@@ -1849,7 +1854,7 @@
 			}
 		}
 
-#endif /* L_vfprintf */
+#endif /* L__vfprintf_internal */
 		if (_charpad(stream, ' ', numpad) != numpad) {
 			return -1;
 		}
@@ -1860,35 +1865,21 @@
 
 libc_hidden_proto(fprintf)
 
-libc_hidden_proto(VFPRINTF)
-int VFPRINTF (FILE * __restrict stream,
+int VFPRINTF_internal (FILE * __restrict stream,
 			  register const FMT_TYPE * __restrict format,
 			  va_list arg)
 {
 	ppfs_t ppfs;
 	int count, r;
 	register const FMT_TYPE *s;
-	__STDIO_AUTO_THREADLOCK_VAR;
 
-	__STDIO_AUTO_THREADLOCK(stream);
-
 	count = 0;
 	s = format;
 
-	if 
-#ifdef L_vfprintf
-	(!__STDIO_STREAM_IS_NARROW_WRITING(stream)
-	 && __STDIO_STREAM_TRANS_TO_WRITE(stream, __FLAG_NARROW))
-#else
-	(!__STDIO_STREAM_IS_WIDE_WRITING(stream)
-	 && __STDIO_STREAM_TRANS_TO_WRITE(stream, __FLAG_WIDE))
-#endif
-	{
-		count = -1;
-	} else if (_PPFS_init(&ppfs, format) < 0) {	/* Bad format string. */
+	if (_PPFS_init(&ppfs, format) < 0) {	/* Bad format string. */
 		OUTNSTR(stream, (const unsigned char *) ppfs.fmtpos,
 				STRLEN((const FMT_TYPE *)(ppfs.fmtpos)));
-#if defined(L_vfprintf) && !defined(NDEBUG)
+#if defined(L__vfprintf_internal) && !defined(NDEBUG)
 		fprintf(stderr,"\nIMbS: \"%s\"\n\n", format);
 #endif
 		count = -1;
@@ -1930,14 +1921,66 @@
 		va_end(ppfs.arg);		/* Need to clean up after va_copy! */
 	}
 
-/* #if defined(L_vfprintf) && defined(__UCLIBC_HAS_WCHAR__) */
+/* #if defined(L__vfprintf_internal) && defined(__UCLIBC_HAS_WCHAR__) */
 /*  DONE: */
 /* #endif */
 
+	return count;
+}
+#endif /* defined(L__vfprintf_internal) || defined(L__vfwprintf_internal) */
+
+
+/**********************************************************************/
+#if defined(L_vfprintf) || defined(L_vfwprintf)
+
+/* This is just a wrapper around VFPRINTF_internal.
+ * Factoring out vfprintf internals allows:
+ * (1) vdprintf and vsnprintf don't need to setup fake locking,
+ * (2) __STDIO_STREAM_TRANS_TO_WRITE is not used in vfprintf internals,
+ * and thus fseek etc is not pulled in by vdprintf and vsnprintf.
+ *
+ * In order to not pull in fseek through fputs, OUTPUT() macro
+ * is using __stdio_fwrite (TODO: do the same for wide functions).
+ */
+#ifdef L_vfprintf
+#define VFPRINTF vfprintf
+#define VFPRINTF_internal _vfprintf_internal
+#define FMT_TYPE char
+#else
+#define VFPRINTF vfwprintf
+#define VFPRINTF_internal _vfwprintf_internal
+#define FMT_TYPE wchar_t
+#endif
+
+libc_hidden_proto(VFPRINTF)
+int VFPRINTF (FILE * __restrict stream,
+			  register const FMT_TYPE * __restrict format,
+			  va_list arg)
+{
+	int count;
+	__STDIO_AUTO_THREADLOCK_VAR;
+
+	__STDIO_AUTO_THREADLOCK(stream);
+
+	if 
+#ifdef L_vfprintf
+	(!__STDIO_STREAM_IS_NARROW_WRITING(stream)
+	 && __STDIO_STREAM_TRANS_TO_WRITE(stream, __FLAG_NARROW))
+#else
+	(!__STDIO_STREAM_IS_WIDE_WRITING(stream)
+	 && __STDIO_STREAM_TRANS_TO_WRITE(stream, __FLAG_WIDE))
+#endif
+	{
+		count = -1;
+	} else {
+		count = VFPRINTF_internal(stream, format, arg);
+	}
+
 	__STDIO_AUTO_THREADUNLOCK(stream);
 
 	return count;
 }
 libc_hidden_def(VFPRINTF)
-#endif
+#endif /* defined(L_vfprintf) || defined(L_vfwprintf) */
+
 /**********************************************************************/

Added: trunk/uClibc/libc/stdio/_vfprintf_internal.c
===================================================================
--- trunk/uClibc/libc/stdio/_vfprintf_internal.c	                        (rev 0)
+++ trunk/uClibc/libc/stdio/_vfprintf_internal.c	2008-04-09 19:51:18 UTC (rev 21683)
@@ -0,0 +1,9 @@
+/* Copyright (C) 2004      Manuel Novoa III <mjn3 at uclibc.org>
+ * Copyright (C) 2000-2006 Erik Andersen <andersen at uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ *
+ * Dedicated to Toni.  See uClibc/DEDICATION.mjn3 for details.
+ */
+#define L__vfprintf_internal
+#include "_vfprintf.c"

Added: trunk/uClibc/libc/stdio/_vfwprintf_internal.c
===================================================================
--- trunk/uClibc/libc/stdio/_vfwprintf_internal.c	                        (rev 0)
+++ trunk/uClibc/libc/stdio/_vfwprintf_internal.c	2008-04-09 19:51:18 UTC (rev 21683)
@@ -0,0 +1,9 @@
+/* Copyright (C) 2004      Manuel Novoa III <mjn3 at uclibc.org>
+ * Copyright (C) 2000-2006 Erik Andersen <andersen at uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ *
+ * Dedicated to Toni.  See uClibc/DEDICATION.mjn3 for details.
+ */
+#define L__vfwprintf_internal
+#include "_vfprintf.c"

Modified: trunk/uClibc/libc/stdio/vasprintf.c
===================================================================
--- trunk/uClibc/libc/stdio/vasprintf.c	2008-04-09 11:38:48 UTC (rev 21682)
+++ trunk/uClibc/libc/stdio/vasprintf.c	2008-04-09 19:51:18 UTC (rev 21683)
@@ -57,7 +57,7 @@
 
 #else  /* __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__ */
 
-	/* This implementation actually calls the printf machinery twice, but only
+	/* This implementation actually calls the printf machinery twice, but
 	 * only does one malloc.  This can be a problem though when custom printf
 	 * specs or the %m specifier are involved because the results of the
 	 * second call might be different from the first. */

Modified: trunk/uClibc/libc/stdio/vdprintf.c
===================================================================
--- trunk/uClibc/libc/stdio/vdprintf.c	2008-04-09 11:38:48 UTC (rev 21682)
+++ trunk/uClibc/libc/stdio/vdprintf.c	2008-04-09 19:51:18 UTC (rev 21683)
@@ -11,7 +11,6 @@
 #include "_stdio.h"
 #include <stdarg.h>
 
-libc_hidden_proto(vfprintf)
 libc_hidden_proto(fflush_unlocked)
 
 libc_hidden_proto(vdprintf)
@@ -54,7 +53,7 @@
 #endif
 	f.__nextopen = NULL;
 
-	rv = vfprintf(&f, format, arg);
+	rv = _vfprintf_internal(&f, format, arg);
 
 #ifdef __STDIO_BUFFERS
 	/* If not buffering, then fflush is unnecessary. */
@@ -67,5 +66,4 @@
 
 	return rv;
 }
-libc_hidden_def(vdprintf)
 #endif

Modified: trunk/uClibc/libc/stdio/vsnprintf.c
===================================================================
--- trunk/uClibc/libc/stdio/vsnprintf.c	2008-04-09 11:38:48 UTC (rev 21682)
+++ trunk/uClibc/libc/stdio/vsnprintf.c	2008-04-09 19:51:18 UTC (rev 21683)
@@ -10,8 +10,6 @@
 
 libc_hidden_proto(vsnprintf)
 
-libc_hidden_proto(vfprintf)
-
 #ifdef __UCLIBC_MJN3_ONLY__
 #warning WISHLIST: Implement vsnprintf for non-buffered and no custom stream case.
 #endif /* __UCLIBC_MJN3_ONLY__ */
@@ -61,7 +59,7 @@
 	__STDIO_STREAM_DISABLE_GETC(&f);
 	__STDIO_STREAM_ENABLE_PUTC(&f);
 
-	rv = vfprintf(&f, format, arg);
+	rv = _vfprintf_internal(&f, format, arg);
 	if (size) {
 		if (f.__bufpos == f.__bufend) {
 			--f.__bufpos;
@@ -203,7 +201,7 @@
 #endif
 	f.__nextopen = NULL;
 
-	rv = vfprintf(&f, format, arg);
+	rv = _vfprintf_internal(&f, format, arg);
 
 	return rv;
 }

Modified: trunk/uClibc/libc/stdio/vswprintf.c
===================================================================
--- trunk/uClibc/libc/stdio/vswprintf.c	2008-04-09 11:38:48 UTC (rev 21682)
+++ trunk/uClibc/libc/stdio/vswprintf.c	2008-04-09 19:51:18 UTC (rev 21683)
@@ -11,8 +11,6 @@
 
 libc_hidden_proto(vswprintf)
 
-libc_hidden_proto(vfwprintf)
-
 #ifndef __STDIO_BUFFERS
 #warning Skipping vswprintf since no buffering!
 #else  /* __STDIO_BUFFERS */
@@ -56,7 +54,7 @@
 	__STDIO_STREAM_DISABLE_GETC(&f);
 	__STDIO_STREAM_DISABLE_PUTC(&f);
 
-	rv = vfwprintf(&f, format, arg);
+	rv = _vfwprintf_internal(&f, format, arg);
 
 	/* NOTE: Return behaviour differs from snprintf... */
 	if (f.__bufpos == f.__bufend) {




More information about the uClibc-cvs mailing list