diff options
Diffstat (limited to 'libc')
| -rw-r--r-- | libc/stdio/Makefile.in | 3 | ||||
| -rw-r--r-- | libc/stdio/_stdio.h | 13 | ||||
| -rw-r--r-- | libc/stdio/_vfprintf.c | 129 | ||||
| -rw-r--r-- | libc/stdio/_vfprintf_internal.c | 9 | ||||
| -rw-r--r-- | libc/stdio/_vfwprintf_internal.c | 9 | ||||
| -rw-r--r-- | libc/stdio/vasprintf.c | 2 | ||||
| -rw-r--r-- | libc/stdio/vdprintf.c | 4 | ||||
| -rw-r--r-- | libc/stdio/vsnprintf.c | 6 | ||||
| -rw-r--r-- | libc/stdio/vswprintf.c | 4 | 
9 files changed, 124 insertions, 55 deletions
| diff --git a/libc/stdio/Makefile.in b/libc/stdio/Makefile.in index d6134cb06..74f6d9aed 100644 --- a/libc/stdio/Makefile.in +++ b/libc/stdio/Makefile.in @@ -59,6 +59,7 @@ CUSRC := \  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 @@ CSRC += _wfwrite.c fwprintf.c swprintf.c vswprintf.c vwprintf.c wprintf.c \  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 diff --git a/libc/stdio/_stdio.h b/libc/stdio/_stdio.h index 74b891a03..e1fc26785 100644 --- a/libc/stdio/_stdio.h +++ b/libc/stdio/_stdio.h @@ -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 @@ extern size_t _wstdio_fwrite(const wchar_t *__restrict ws,  #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) diff --git a/libc/stdio/_vfprintf.c b/libc/stdio/_vfprintf.c index fd2975aa3..b3deaddb1 100644 --- a/libc/stdio/_vfprintf.c +++ b/libc/stdio/_vfprintf.c @@ -1198,7 +1198,7 @@ int register_printf_function(int spec, printf_function handler,  #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 @@ int register_printf_function(int spec, printf_function handler,  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 @@ static size_t _fp_out_narrow(FILE *fp, intptr_t type, intptr_t len, intptr_t buf  #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,7 +1420,8 @@ static int _ppwfs_init(register ppfs_t *ppfs, const wchar_t *fmt0)  	return 0;  } -#endif /* L_vfprintf */ +#endif /* L__vfprintf_internal */ +  static size_t _charpad(FILE * __restrict stream, int padchar, size_t numpad)  { @@ -1439,12 +1443,12 @@ static int _do_one_spec(FILE * __restrict stream,  						 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 @@ static int _do_one_spec(FILE * __restrict stream,  	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 @@ static int _do_one_spec(FILE * __restrict stream,  			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 @@ static int _do_one_spec(FILE * __restrict stream,  				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 @@ static int _do_one_spec(FILE * __restrict stream,  				}  			}  			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 @@ static int _do_one_spec(FILE * __restrict stream,  				}  				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 @@ static int _do_one_spec(FILE * __restrict stream,  			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 @@ static int _do_one_spec(FILE * __restrict stream,  				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 @@ static int _do_one_spec(FILE * __restrict stream,  			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 @@ static int _do_one_spec(FILE * __restrict stream,  				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 @@ static int _do_one_spec(FILE * __restrict stream,  		}  #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 @@ static int _do_one_spec(FILE * __restrict stream,  			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 @@ static int _do_one_spec(FILE * __restrict stream,  		}  #endif /* __UCLIBC_HAS_WCHAR__ */ -#else  /* L_vfprintf */ +#else  /* L__vfprintf_internal */  		if (!ws) {  			assert(s); @@ -1849,7 +1854,7 @@ static int _do_one_spec(FILE * __restrict stream,  			}  		} -#endif /* L_vfprintf */ +#endif /* L__vfprintf_internal */  		if (_charpad(stream, ' ', numpad) != numpad) {  			return -1;  		} @@ -1860,35 +1865,21 @@ static int _do_one_spec(FILE * __restrict stream,  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 @@ int VFPRINTF (FILE * __restrict stream,  		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) */ +  /**********************************************************************/ diff --git a/libc/stdio/_vfprintf_internal.c b/libc/stdio/_vfprintf_internal.c new file mode 100644 index 000000000..40bf39e26 --- /dev/null +++ b/libc/stdio/_vfprintf_internal.c @@ -0,0 +1,9 @@ +/* Copyright (C) 2004      Manuel Novoa III <mjn3@uclibc.org> + * Copyright (C) 2000-2006 Erik Andersen <andersen@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" diff --git a/libc/stdio/_vfwprintf_internal.c b/libc/stdio/_vfwprintf_internal.c new file mode 100644 index 000000000..8584cf4ae --- /dev/null +++ b/libc/stdio/_vfwprintf_internal.c @@ -0,0 +1,9 @@ +/* Copyright (C) 2004      Manuel Novoa III <mjn3@uclibc.org> + * Copyright (C) 2000-2006 Erik Andersen <andersen@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" diff --git a/libc/stdio/vasprintf.c b/libc/stdio/vasprintf.c index 7a34f6870..b7e2e0852 100644 --- a/libc/stdio/vasprintf.c +++ b/libc/stdio/vasprintf.c @@ -57,7 +57,7 @@ int vasprintf(char **__restrict buf, const char * __restrict format,  #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. */ diff --git a/libc/stdio/vdprintf.c b/libc/stdio/vdprintf.c index 0c29eb109..9e1b22eaf 100644 --- a/libc/stdio/vdprintf.c +++ b/libc/stdio/vdprintf.c @@ -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 @@ int vdprintf(int filedes, const char * __restrict format, va_list arg)  #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 @@ int vdprintf(int filedes, const char * __restrict format, va_list arg)  	return rv;  } -libc_hidden_def(vdprintf)  #endif diff --git a/libc/stdio/vsnprintf.c b/libc/stdio/vsnprintf.c index 51aaf43d0..4eef2c1a0 100644 --- a/libc/stdio/vsnprintf.c +++ b/libc/stdio/vsnprintf.c @@ -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 @@ int vsnprintf(char *__restrict buf, size_t size,  	__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 @@ int vsnprintf(char *__restrict buf, size_t size,  #endif  	f.__nextopen = NULL; -	rv = vfprintf(&f, format, arg); +	rv = _vfprintf_internal(&f, format, arg);  	return rv;  } diff --git a/libc/stdio/vswprintf.c b/libc/stdio/vswprintf.c index d09e08ac9..919ac2132 100644 --- a/libc/stdio/vswprintf.c +++ b/libc/stdio/vswprintf.c @@ -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 @@ int vswprintf(wchar_t *__restrict buf, size_t size,  	__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) { | 
