diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2009-03-06 09:55:52 +0000 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2009-03-06 09:55:52 +0000 |
commit | 6121968b198dcbb93427b0a11453563ebe462bb4 (patch) | |
tree | 1b612b73db2b4572c591bf8644021b2407a8f602 /newlib/libc/stdio/vfprintf.c | |
parent | 6e0e5a4fc20a1de8124c454a5c14c616c68e4653 (diff) | |
download | newlib-6121968b198dcbb93427b0a11453563ebe462bb4.zip newlib-6121968b198dcbb93427b0a11453563ebe462bb4.tar.gz newlib-6121968b198dcbb93427b0a11453563ebe462bb4.tar.bz2 |
* libc/include/stdio.h (__VALIST): Guard against multiple definition.
* libc/include/wchar.h: Include stdarg.h.
(__VALIST): Define conditionally.
(fwprintf, swprintf, vfwprintf, vswprintf, vwprintf, wprintf: Declare.
(_fwprintf_r, _swprintf_r, _vfwprintf_r, _vswprintf_r, _vwprintf_r,
_wprintf_r): Declare.
* libc/stdio/Makefile.am: Add new files.
* libc/stdio/Makefile.in: Regenerate.
* libc/stdio/fwprintf.c: New file.
* libc/stdio/local.h (_svfwprintf_r, _svfiwprintf_r): Declare.
(__CH_CLASS, __STATE, __ACTION): Move definition from vfprintf.c here
and move to the __ namespace.
(__chclass, __state_table, __action_table): Declare.
* libc/stdio/stdio.tex: Add new documentation references.
* libc/stdio/swprintf.c: New file.
* libc/stdio/vfprintf.c (__SPRINT): New macro to call the right
__sprint_r function according to compilation unit. Use throughout.
(__ssprint_r): Rename STRING_ONLY variant from __sprint_r.
Make externaly available. Only define if INTEGER_ONLY is defined.
(__sprint_r): Make externaly available. Only define if INTEGER_ONLY
is defined. Handle stream orientation.
(__sbprintf): Copy FILE's _flags2 member as well.
(__chclass, __state_table, __action_table): Prepend __ to name and
make externally available.
* libc/stdio/vfwprintf.c: New file.
* libc/stdio/vswprintf.c: New file.
* libc/stdio/vwprintf.c: New file.
* libc/stdio/wprintf.c: New file.
Diffstat (limited to 'newlib/libc/stdio/vfprintf.c')
-rw-r--r-- | newlib/libc/stdio/vfprintf.c | 113 |
1 files changed, 56 insertions, 57 deletions
diff --git a/newlib/libc/stdio/vfprintf.c b/newlib/libc/stdio/vfprintf.c index ac1d919..e81b068 100644 --- a/newlib/libc/stdio/vfprintf.c +++ b/newlib/libc/stdio/vfprintf.c @@ -177,8 +177,18 @@ static char *rcsid = "$Id$"; #endif #ifdef STRING_ONLY -static int -_DEFUN(__sprint_r, (ptr, fp, uio), +#define __SPRINT __ssprint_r +#else +#define __SPRINT __sprint_r +#endif + +/* The __sprint_r/__ssprint_r functions are shared between all versions of + vfprintf and vfwprintf. They must only be defined once, which we do in + the INTEGER_ONLY versions here. */ +#ifdef STRING_ONLY +#ifdef INTEGER_ONLY +int +_DEFUN(__ssprint_r, (ptr, fp, uio), struct _reent *ptr _AND FILE *fp _AND register struct __suio *uio) @@ -268,29 +278,51 @@ err: uio->uio_iovcnt = 0; return EOF; } +#endif /* INTEGER_ONLY */ #else /* !STRING_ONLY */ +#ifdef INTEGER_ONLY /* * Flush out all the vectors defined by the given uio, * then reset it so that it can be reused. */ -static int +int _DEFUN(__sprint_r, (ptr, fp, uio), struct _reent *ptr _AND FILE *fp _AND register struct __suio *uio) { - register int err; + register int err = 0; if (uio->uio_resid == 0) { uio->uio_iovcnt = 0; return (0); } - err = __sfvwrite_r(ptr, fp, uio); + if (fp->_flags2 & __SWID) { + struct __siov *iov; + wchar_t *p; + int i, len; + + iov = uio->uio_iov; + for (; uio->uio_resid != 0; + uio->uio_resid -= len * sizeof (wchar_t), iov++) { + p = (wchar_t *) iov->iov_base; + len = iov->iov_len / sizeof (wchar_t); + for (i = 0; i < len; i++) { + if (_fputwc_r (ptr, p[i], fp) == WEOF) { + err = -1; + goto out; + } + } + } + } else + err = __sfvwrite_r(ptr, fp, uio); +out: uio->uio_resid = 0; uio->uio_iovcnt = 0; return (err); } +#endif /* INTEGER_ONLY */ /* * Helper function for `fprintf to unbuffered unix file': creates a @@ -310,6 +342,7 @@ _DEFUN(__sbprintf, (rptr, fp, fmt, ap), /* copy the important variables */ fake._flags = fp->_flags & ~__SNBF; + fake._flags2 = fp->_flags2; fake._file = fp->_file; fake._cookie = fp->_cookie; fake._write = fp->_write; @@ -564,7 +597,7 @@ _DEFUN(_VFPRINTF_R, (data, fp, fmt0, ap), uio.uio_resid += (len); \ iovp++; \ if (++uio.uio_iovcnt >= NIOV) { \ - if (__sprint_r(data, fp, &uio)) \ + if (__SPRINT(data, fp, &uio)) \ goto error; \ iovp = iov; \ } \ @@ -579,7 +612,7 @@ _DEFUN(_VFPRINTF_R, (data, fp, fmt0, ap), } \ } #define FLUSH() { \ - if (uio.uio_resid && __sprint_r(data, fp, &uio)) \ + if (uio.uio_resid && __SPRINT(data, fp, &uio)) \ goto error; \ uio.uio_iovcnt = 0; \ iovp = iov; \ @@ -1642,48 +1675,12 @@ exponent(char *p0, int exp, int fmtch) (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -typedef enum { - ZERO, /* '0' */ - DIGIT, /* '1-9' */ - DOLLAR, /* '$' */ - MODFR, /* spec modifier */ - SPEC, /* format specifier */ - DOT, /* '.' */ - STAR, /* '*' */ - FLAG, /* format flag */ - OTHER, /* all other chars */ - MAX_CH_CLASS /* place-holder */ -} CH_CLASS; - -typedef enum { - START, /* start */ - SFLAG, /* seen a flag */ - WDIG, /* seen digits in width area */ - WIDTH, /* processed width */ - SMOD, /* seen spec modifier */ - SDOT, /* seen dot */ - VARW, /* have variable width specifier */ - VARP, /* have variable precision specifier */ - PREC, /* processed precision */ - VWDIG, /* have digits in variable width specification */ - VPDIG, /* have digits in variable precision specification */ - DONE, /* done */ - MAX_STATE, /* place-holder */ -} STATE; - -typedef enum { - NOOP, /* do nothing */ - NUMBER, /* build a number from digits */ - SKIPNUM, /* skip over digits */ - GETMOD, /* get and process format modifier */ - GETARG, /* get and process argument */ - GETPW, /* get variable precision or width */ - GETPWB, /* get variable precision or width and pushback fmt char */ - GETPOS, /* get positional parameter value */ - PWPOS, /* get positional parameter value for variable width or precision */ -} ACTION; - -_CONST static CH_CLASS chclass[256] = { +/* The below constant state tables are shared between all versions of + vfprintf and vfwprintf. They must only be defined once, which we do in + the STRING_ONLY/INTEGER_ONLY versions here. */ +#if defined (STRING_ONLY) && defined(INTEGER_ONLY) + +_CONST __CH_CLASS __chclass[256] = { /* 00-07 */ OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, /* 08-0f */ OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, /* 10-17 */ OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, @@ -1718,7 +1715,7 @@ _CONST static CH_CLASS chclass[256] = { /* f8-ff */ OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, }; -_CONST static STATE state_table[MAX_STATE][MAX_CH_CLASS] = { +_CONST __STATE __state_table[MAX_STATE][MAX_CH_CLASS] = { /* '0' '1-9' '$' MODFR SPEC '.' '*' FLAG OTHER */ /* START */ { SFLAG, WDIG, DONE, SMOD, DONE, SDOT, VARW, SFLAG, DONE }, /* SFLAG */ { SFLAG, WDIG, DONE, SMOD, DONE, SDOT, VARW, SFLAG, DONE }, @@ -1733,7 +1730,7 @@ _CONST static STATE state_table[MAX_STATE][MAX_CH_CLASS] = { /* VPDIG */ { DONE, DONE, PREC, DONE, DONE, DONE, DONE, DONE, DONE }, }; -_CONST static ACTION action_table[MAX_STATE][MAX_CH_CLASS] = { +_CONST __ACTION __action_table[MAX_STATE][MAX_CH_CLASS] = { /* '0' '1-9' '$' MODFR SPEC '.' '*' FLAG OTHER */ /* START */ { NOOP, NUMBER, NOOP, GETMOD, GETARG, NOOP, NOOP, NOOP, NOOP }, /* SFLAG */ { NOOP, NUMBER, NOOP, GETMOD, GETARG, NOOP, NOOP, NOOP, NOOP }, @@ -1748,6 +1745,8 @@ _CONST static ACTION action_table[MAX_STATE][MAX_CH_CLASS] = { /* VPDIG */ { NOOP, NOOP, PWPOS, NOOP, NOOP, NOOP, NOOP, NOOP, NOOP }, }; +#endif /* STRING_ONLY && INTEGER_ONLY */ + /* function to get positional parameter N where n = N - 1 */ static union arg_val * _DEFUN(get_arg, (data, n, fmt, ap, numargs_p, args, arg_type, last_fmt), @@ -1764,9 +1763,9 @@ _DEFUN(get_arg, (data, n, fmt, ap, numargs_p, args, arg_type, last_fmt), int number, flags; int spec_type; int numargs = *numargs_p; - CH_CLASS chtype; - STATE state, next_state; - ACTION action; + __CH_CLASS chtype; + __STATE state, next_state; + __ACTION action; int pos, last_arg; int max_pos_arg = n; /* Only need types that can be reached via vararg promotions. */ @@ -1818,9 +1817,9 @@ _DEFUN(get_arg, (data, n, fmt, ap, numargs_p, args, arg_type, last_fmt), while (state != DONE) { ch = *fmt++; - chtype = chclass[ch]; - next_state = state_table[state][chtype]; - action = action_table[state][chtype]; + chtype = __chclass[ch]; + next_state = __state_table[state][chtype]; + action = __action_table[state][chtype]; state = next_state; switch (action) |