/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ctype.h>
#include <errno.h>
#include <float.h>
#include <limits.h>
#include <math.h>
#include <printf.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <printf.h>
#include <stddef.h>
#include "_itoa.h"
#include "../locale/localeinfo.h"
/* Include the shared code for parsing the format string. */
#include "printf-parse.h"
/* This function from the GNU C library is also used in libio.
To compile for use in libio, compile with -DUSE_IN_LIBIO. */
#ifdef USE_IN_LIBIO
/* This code is for use in libio. */
#include <libioP.h>
#define PUT(f, s, n) _IO_sputn (f, s, n)
#define PAD(padchar) \
if (specs[cnt].info.width > 0) \
done += _IO_padn (s, padchar, specs[cnt].info.width)
#define PUTC(c, f) _IO_putc (c, f)
#define vfprintf _IO_vfprintf
#define size_t _IO_size_t
#define FILE _IO_FILE
#define va_list _IO_va_list
#undef BUFSIZ
#define BUFSIZ _IO_BUFSIZ
#define ARGCHECK(s, format) \
do \
{ \
/* Check file argument for consistence. */ \
CHECK_FILE (s, -1); \
if (s->_flags & _IO_NO_WRITES || format == NULL) \
{ \
MAYBE_SET_EINVAL; \
return -1; \
} \
} while (0)
#define UNBUFFERED_P(s) ((s)->_IO_file_flags & _IO_UNBUFFERED)
#else /* ! USE_IN_LIBIO */
/* This code is for use in the GNU C library. */
#include <stdio.h>
#define PUTC(c, f) putc (c, f)
#define PUT(f, s, n) fwrite (s, 1, n, f)
ssize_t __printf_pad __P ((FILE *, char pad, size_t n));
#define PAD(padchar) \
if (specs[cnt].info.width > 0) \
{ if (__printf_pad (s, padchar, specs[cnt].info.width) == -1) \
return -1; else done += specs[cnt].info.width; }
#define ARGCHECK(s, format) \
do \
{ \
/* Check file argument for consistence. */ \
if (!__validfp(s) || !s->__mode.__write || format == NULL) \
{ \
errno = EINVAL; \
return -1; \
} \
if (!s->__seen) \
{ \
if (__flshfp (s, EOF) == EOF) \
return -1; \
} \
} while (0)
#define UNBUFFERED_P(s) ((s)->__buffer == NULL)
#endif /* USE_IN_LIBIO */
#define outchar(x) \
do \
{ \
register const int outc = (x); \
if (putc (outc, s) == EOF) \
return -1; \
else \
++done; \
} while (0)
#define outstring(string, len) \
do \
{ \
if (len > 20) \
{ \
if (PUT (s, string, len) != len) \
return -1; \
done += len; \
} \
else \
{ \
register const char *cp = string; \
register int l = len; \
while (l-- > 0) \
outchar (*cp++); \
} \
} while (0)
/* Helper function to provide temporary buffering for unbuffered streams. */
static int buffered_vfprintf