OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [bootloaders/] [orpmon/] [common/] [cprintf.c] - Diff between revs 355 and 406

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 355 Rev 406
/*
/*
FUNCTION
FUNCTION
<<vprintf>>, <<vfprintf>>, <<vsprintf>>---format argument list
<<vprintf>>, <<vfprintf>>, <<vsprintf>>---format argument list
 
 
INDEX
INDEX
        vprintf
        vprintf
INDEX
INDEX
        vfprintf
        vfprintf
INDEX
INDEX
        vsprintf
        vsprintf
INDEX
INDEX
        vsnprintf
        vsnprintf
 
 
ANSI_SYNOPSIS
ANSI_SYNOPSIS
        #include <stdio.h>
        #include <stdio.h>
        #include <stdarg.h>
        #include <stdarg.h>
        int vprintf(const char *<[fmt]>, va_list <[list]>);
        int vprintf(const char *<[fmt]>, va_list <[list]>);
        int vfprintf(FILE *<[fp]>, const char *<[fmt]>, va_list <[list]>);
        int vfprintf(FILE *<[fp]>, const char *<[fmt]>, va_list <[list]>);
        int vsprintf(char *<[str]>, const char *<[fmt]>, va_list <[list]>);
        int vsprintf(char *<[str]>, const char *<[fmt]>, va_list <[list]>);
        int vsnprintf(char *<[str]>, size_t <[size]>, const char *<[fmt]>, va_list <[list]>);
        int vsnprintf(char *<[str]>, size_t <[size]>, const char *<[fmt]>, va_list <[list]>);
 
 
        int _vprintf_r(void *<[reent]>, const char *<[fmt]>,
        int _vprintf_r(void *<[reent]>, const char *<[fmt]>,
                        va_list <[list]>);
                        va_list <[list]>);
        int _vfprintf_r(void *<[reent]>, FILE *<[fp]>, const char *<[fmt]>,
        int _vfprintf_r(void *<[reent]>, FILE *<[fp]>, const char *<[fmt]>,
                        va_list <[list]>);
                        va_list <[list]>);
        int _vsprintf_r(void *<[reent]>, char *<[str]>, const char *<[fmt]>,
        int _vsprintf_r(void *<[reent]>, char *<[str]>, const char *<[fmt]>,
                        va_list <[list]>);
                        va_list <[list]>);
        int _vsnprintf_r(void *<[reent]>, char *<[str]>, size_t <[size]>, const char *<[fmt]>,
        int _vsnprintf_r(void *<[reent]>, char *<[str]>, size_t <[size]>, const char *<[fmt]>,
                        va_list <[list]>);
                        va_list <[list]>);
 
 
TRAD_SYNOPSIS
TRAD_SYNOPSIS
        #include <stdio.h>
        #include <stdio.h>
        #include <varargs.h>
        #include <varargs.h>
        int vprintf( <[fmt]>, <[list]>)
        int vprintf( <[fmt]>, <[list]>)
        char *<[fmt]>;
        char *<[fmt]>;
        va_list <[list]>;
        va_list <[list]>;
 
 
        int vfprintf(<[fp]>, <[fmt]>, <[list]>)
        int vfprintf(<[fp]>, <[fmt]>, <[list]>)
        FILE *<[fp]>;
        FILE *<[fp]>;
        char *<[fmt]>;
        char *<[fmt]>;
        va_list <[list]>;
        va_list <[list]>;
 
 
        int vsprintf(<[str]>, <[fmt]>, <[list]>)
        int vsprintf(<[str]>, <[fmt]>, <[list]>)
        char *<[str]>;
        char *<[str]>;
        char *<[fmt]>;
        char *<[fmt]>;
        va_list <[list]>;
        va_list <[list]>;
 
 
        int vsnprintf(<[str]>, <[size]>, <[fmt]>, <[list]>)
        int vsnprintf(<[str]>, <[size]>, <[fmt]>, <[list]>)
        char *<[str]>;
        char *<[str]>;
        size_t <[size]>;
        size_t <[size]>;
        char *<[fmt]>;
        char *<[fmt]>;
        va_list <[list]>;
        va_list <[list]>;
 
 
        int _vprintf_r(<[reent]>, <[fmt]>, <[list]>)
        int _vprintf_r(<[reent]>, <[fmt]>, <[list]>)
        char *<[reent]>;
        char *<[reent]>;
        char *<[fmt]>;
        char *<[fmt]>;
        va_list <[list]>;
        va_list <[list]>;
 
 
        int _vfprintf_r(<[reent]>, <[fp]>, <[fmt]>, <[list]>)
        int _vfprintf_r(<[reent]>, <[fp]>, <[fmt]>, <[list]>)
        char *<[reent]>;
        char *<[reent]>;
        FILE *<[fp]>;
        FILE *<[fp]>;
        char *<[fmt]>;
        char *<[fmt]>;
        va_list <[list]>;
        va_list <[list]>;
 
 
        int _vsprintf_r(<[reent]>, <[str]>, <[fmt]>, <[list]>)
        int _vsprintf_r(<[reent]>, <[str]>, <[fmt]>, <[list]>)
        char *<[reent]>;
        char *<[reent]>;
        char *<[str]>;
        char *<[str]>;
        char *<[fmt]>;
        char *<[fmt]>;
        va_list <[list]>;
        va_list <[list]>;
 
 
        int _vsnprintf_r(<[reent]>, <[str]>, <[size]>, <[fmt]>, <[list]>)
        int _vsnprintf_r(<[reent]>, <[str]>, <[size]>, <[fmt]>, <[list]>)
        char *<[reent]>;
        char *<[reent]>;
        char *<[str]>;
        char *<[str]>;
        size_t <[size]>;
        size_t <[size]>;
        char *<[fmt]>;
        char *<[fmt]>;
        va_list <[list]>;
        va_list <[list]>;
 
 
DESCRIPTION
DESCRIPTION
<<vprintf>>, <<vfprintf>>, <<vsprintf>> and <<vsnprintf>> are (respectively)
<<vprintf>>, <<vfprintf>>, <<vsprintf>> and <<vsnprintf>> are (respectively)
variants of <<printf>>, <<fprintf>>, <<sprintf>> and <<snprintf>>.  They differ
variants of <<printf>>, <<fprintf>>, <<sprintf>> and <<snprintf>>.  They differ
only in allowing their caller to pass the variable argument list as a
only in allowing their caller to pass the variable argument list as a
<<va_list>> object (initialized by <<va_start>>) rather than directly
<<va_list>> object (initialized by <<va_start>>) rather than directly
accepting a variable number of arguments.
accepting a variable number of arguments.
 
 
RETURNS
RETURNS
The return values are consistent with the corresponding functions:
The return values are consistent with the corresponding functions:
<<vsprintf>> returns the number of bytes in the output string,
<<vsprintf>> returns the number of bytes in the output string,
save that the concluding <<NULL>> is not counted.
save that the concluding <<NULL>> is not counted.
<<vprintf>> and <<vfprintf>> return the number of characters transmitted.
<<vprintf>> and <<vfprintf>> return the number of characters transmitted.
If an error occurs, <<vprintf>> and <<vfprintf>> return <<EOF>>. No
If an error occurs, <<vprintf>> and <<vfprintf>> return <<EOF>>. No
error returns occur for <<vsprintf>>.
error returns occur for <<vsprintf>>.
 
 
PORTABILITY
PORTABILITY
ANSI C requires all three functions.
ANSI C requires all three functions.
 
 
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
*/
*/
 
 
/*-
/*-
 * Copyright (c) 1990 The Regents of the University of California.
 * Copyright (c) 1990 The Regents of the University of California.
 * All rights reserved.
 * All rights reserved.
 *
 *
 * This code is derived from software contributed to Berkeley by
 * This code is derived from software contributed to Berkeley by
 * Chris Torek.
 * Chris Torek.
 *
 *
 * Redistribution and use in source and binary forms, with or without
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * modification, are permitted provided that the following conditions
 * are met:
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    must display the following acknowledgement:
 *      This product includes software developed by the University of
 *      This product includes software developed by the University of
 *      California, Berkeley and its contributors.
 *      California, Berkeley and its contributors.
 * 4. Neither the name of the University nor the names of its contributors
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *    without specific prior written permission.
 *
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * SUCH DAMAGE.
 */
 */
 
 
#define INTEGER_ONLY
#define INTEGER_ONLY
#define _HAVE_STDC_
#define _HAVE_STDC_
#define _NOLONGLONG
#define _NOLONGLONG
#define u_long unsigned long
#define u_long unsigned long
#define u_short unsigned short
#define u_short unsigned short
#define u_int unsigned int
#define u_int unsigned int
#define _uquad_t u_long
#define _uquad_t u_long
#define _POINTER_INT int
#define _POINTER_INT int
#define _CONST const
#define _CONST const
#define NULL 0
#define NULL 0
 
 
#include "common.h"
#include "common.h"
#include "support.h"
#include "support.h"
 
 
#if defined(LIBC_SCCS) && !defined(lint)
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)vfprintf.c   5.50 (Berkeley) 12/16/92";*/
/*static char *sccsid = "from: @(#)vfprintf.c   5.50 (Berkeley) 12/16/92";*/
static char *rcsid = "$Id: cprintf.c,v 1.2 2002-04-19 11:08:25 markom Exp $";
static char *rcsid = "$Id: cprintf.c,v 1.2 2002-04-19 11:08:25 markom Exp $";
#endif /* LIBC_SCCS and not lint */
#endif /* LIBC_SCCS and not lint */
 
 
/*
/*
 * Actual printf innards.
 * Actual printf innards.
 *
 *
 * This code is large and complicated...
 * This code is large and complicated...
 */
 */
 
 
#ifdef INTEGER_ONLY
#ifdef INTEGER_ONLY
#define VFPRINTF vfiprintf
#define VFPRINTF vfiprintf
#define _VFPRINTF_R _vfiprintf_r
#define _VFPRINTF_R _vfiprintf_r
#else
#else
#define VFPRINTF vfprintf
#define VFPRINTF vfprintf
#define _VFPRINTF_R _vfprintf_r
#define _VFPRINTF_R _vfprintf_r
#define FLOATING_POINT
#define FLOATING_POINT
#endif
#endif
 
 
#define _NO_LONGLONG
#define _NO_LONGLONG
#if defined WANT_PRINTF_LONG_LONG && defined __GNUC__
#if defined WANT_PRINTF_LONG_LONG && defined __GNUC__
# undef _NO_LONGLONG
# undef _NO_LONGLONG
#endif
#endif
 
 
#include <stdarg.h>
#include <stdarg.h>
 
 
#ifdef FLOATING_POINT
#ifdef FLOATING_POINT
//#include <locale.h>
//#include <locale.h>
//#include <math.h>
//#include <math.h>
//#include "floatio.h"
//#include "floatio.h"
 
 
#define BUF             (MAXEXP+MAXFRACT+1)     /* + decimal point */
#define BUF             (MAXEXP+MAXFRACT+1)     /* + decimal point */
#define DEFPREC         6
#define DEFPREC         6
 
 
static char *cvt _PARAMS((struct _reent *, double, int, int, char *, int *, int, int *));
static char *cvt
 
_PARAMS((struct _reent *, double, int, int, char *, int *, int, int *));
static int exponent _PARAMS((char *, int, int));
static int exponent _PARAMS((char *, int, int));
 
 
#else /* no FLOATING_POINT */
#else /* no FLOATING_POINT */
 
 
#define BUF             40
#define BUF             40
 
 
#endif /* FLOATING_POINT */
#endif /* FLOATING_POINT */
 
 
/*
/*
 * Macros for converting digits to letters and vice versa
 * Macros for converting digits to letters and vice versa
 */
 */
#define to_digit(c)     ((c) - '0')
#define to_digit(c)     ((c) - '0')
#define is_digit(c)     ((unsigned)to_digit(c) <= 9)
#define is_digit(c)     ((unsigned)to_digit(c) <= 9)
#define to_char(n)      ((n) + '0')
#define to_char(n)      ((n) + '0')
 
 
/*
/*
 * Flags used during conversion.
 * Flags used during conversion.
 */
 */
#define ALT             0x001           /* alternate form */
#define ALT             0x001   /* alternate form */
#define HEXPREFIX       0x002           /* add 0x or 0X prefix */
#define HEXPREFIX       0x002   /* add 0x or 0X prefix */
#define LADJUST         0x004           /* left adjustment */
#define LADJUST         0x004   /* left adjustment */
#define LONGDBL         0x008           /* long double; unimplemented */
#define LONGDBL         0x008   /* long double; unimplemented */
#define LONGINT         0x010           /* long integer */
#define LONGINT         0x010   /* long integer */
#define QUADINT         0x020           /* quad integer */
#define QUADINT         0x020   /* quad integer */
#define SHORTINT        0x040           /* short integer */
#define SHORTINT        0x040   /* short integer */
#define ZEROPAD         0x080           /* zero (as opposed to blank) pad */
#define ZEROPAD         0x080   /* zero (as opposed to blank) pad */
#define FPT             0x100           /* Floating point number */
#define FPT             0x100   /* Floating point number */
 
 
        /*
        /*
         * Choose PADSIZE to trade efficiency vs. size.  If larger printf
         * Choose PADSIZE to trade efficiency vs. size.  If larger printf
         * fields occur frequently, increase PADSIZE and make the initialisers
         * fields occur frequently, increase PADSIZE and make the initialisers
         * below longer.
         * below longer.
         */
         */
#define PADSIZE 16              /* pad chunk size */
#define PADSIZE 16              /* pad chunk size */
        static _CONST char blanks[PADSIZE] =
        static _CONST char blanks[PADSIZE] =
         {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};
    { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
 
' ' };
        static _CONST char zeroes[PADSIZE] =
        static _CONST char zeroes[PADSIZE] =
         {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
    { '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
 
'0' };
 
 
inline void pc (_CONST char c) {
inline void pc(_CONST char c)
 
{
#ifdef OR1K
#ifdef OR1K
  putc (c);
        putc(c);
#else
#else
  printf ("%c", c);
        printf("%c", c);
#endif
#endif
}
}
 
 
        /*
        /*
         * BEWARE, these `goto error' on error, and PAD uses `n'.
         * BEWARE, these `goto error' on error, and PAD uses `n'.
         */
         */
inline void     PRINT(_CONST char *ptr, int len) {
inline void PRINT(_CONST char *ptr, int len)
 
{
  int i;
  int i;
  for (i = 0; i < len; i++)
        for (i = 0; i < len; i++)
          pc(*(ptr++));
                pc(*(ptr++));
}
}
 
 
inline void PAD(int howmany, _CONST char *with) {
inline void PAD(int howmany, _CONST char *with)
 
{
  int n;
  int n;
        if ((n = howmany) > 0) {
        if ((n = howmany) > 0) {
                while (n > PADSIZE) {
                while (n > PADSIZE) {
                        PRINT(with, PADSIZE);
                        PRINT(with, PADSIZE);
                        n -= PADSIZE;
                        n -= PADSIZE;
                }
                }
                PRINT(with, n);
                PRINT(with, n);
        }
        }
}
}
 
 
int printf(const char *fmt0,    ...)
int printf(const char *fmt0, ...)
{
{
        register char *fmt;     /* format string */
        register char *fmt;     /* format string */
        register int ch;        /* character from fmt */
        register int ch;        /* character from fmt */
        int n;  /* handy integers (short term usage) */
        int n;                  /* handy integers (short term usage) */
        register char *cp;      /* handy char pointer (short term usage) */
        register char *cp;      /* handy char pointer (short term usage) */
        register int flags;     /* flags as above */
        register int flags;     /* flags as above */
        int ret;                /* return value accumulator */
        int ret;                /* return value accumulator */
        int width;              /* width from format (%8d), or 0 */
        int width;              /* width from format (%8d), or 0 */
        int prec;               /* precision from format (%.3d), or -1 */
        int prec;               /* precision from format (%.3d), or -1 */
        char sign;              /* sign prefix (' ', '+', '-', or \0) */
        char sign;              /* sign prefix (' ', '+', '-', or \0) */
        va_list ap;
        va_list ap;
 
 
#ifdef FLOATING_POINT
#ifdef FLOATING_POINT
        char *decimal_point = localeconv()->decimal_point;
        char *decimal_point = localeconv()->decimal_point;
        char softsign;          /* temporary negative sign for floats */
        char softsign;          /* temporary negative sign for floats */
        /*
        /*
         * Although it is natural to declare this double here, the
         * Although it is natural to declare this double here, the
         * declaration causes gcc to save FP registers even when not
         * declaration causes gcc to save FP registers even when not
         * printing an FP number.  This results in surprising use
         * printing an FP number.  This results in surprising use
         * of FP registers to print integers or strings on at least the
         * of FP registers to print integers or strings on at least the
         * PowerPC.  A more proper solution would be to move FP printing
         * PowerPC.  A more proper solution would be to move FP printing
         * to another file, but this does seem to work.
         * to another file, but this does seem to work.
         */
         */
#if 0
#if 0
        double _double;         /* double precision arguments %[eEfgG] */
        double _double;         /* double precision arguments %[eEfgG] */
#else
#else
                                /* double precision arguments %[eEfgG] */
                                /* double precision arguments %[eEfgG] */
        union { int i; double d; } _double_ = {0};
        union {
 
                int i;
 
                double d;
 
        } _double_ = {
 
        0};
#define _double (_double_.d)
#define _double (_double_.d)
#endif
#endif
        int expt;               /* integer value of exponent */
        int expt;               /* integer value of exponent */
        int expsize;            /* character count for expstr */
        int expsize;            /* character count for expstr */
        int ndig;               /* actual number of digits returned by cvt */
        int ndig;               /* actual number of digits returned by cvt */
        char expstr[7];         /* buffer for exponent string */
        char expstr[7];         /* buffer for exponent string */
#endif
#endif
 
 
#ifndef _NO_LONGLONG
#ifndef _NO_LONGLONG
#define quad_t    long long
#define quad_t    long long
#define u_quad_t  unsigned long long
#define u_quad_t  unsigned long long
#endif
#endif
 
 
#ifndef _NO_LONGLONG
#ifndef _NO_LONGLONG
        u_quad_t _uquad;        /* integer arguments %[diouxX] */
        u_quad_t _uquad;        /* integer arguments %[diouxX] */
#else
#else
        u_long _uquad;
        u_long _uquad;
#endif
#endif
        enum { OCT, DEC, HEX } base;/* base for [diouxX] conversion */
        enum { OCT, DEC, HEX } base;    /* base for [diouxX] conversion */
        int dprec;              /* a copy of prec if [diouxX], 0 otherwise */
        int dprec;              /* a copy of prec if [diouxX], 0 otherwise */
        int realsz;             /* field size expanded by dprec */
        int realsz;             /* field size expanded by dprec */
        int size;               /* size of converted field or string */
        int size;               /* size of converted field or string */
        char *xdigs = (char *)0;         /* digits for [xX] conversion */
        char *xdigs = (char *)0; /* digits for [xX] conversion */
#define NIOV 8
#define NIOV 8
 
 
char buf[BUF];          /* space for %c, %[diouxX], %[eEfgG] */
        char buf[BUF];          /* space for %c, %[diouxX], %[eEfgG] */
char ox[2];             /* space for 0x hex-prefix */
        char ox[2];             /* space for 0x hex-prefix */
 
 
#define FLUSH()
#define FLUSH()
 
 
        /*
        /*
         * To extend shorts properly, we need both signed and unsigned
         * To extend shorts properly, we need both signed and unsigned
         * argument extraction methods.
         * argument extraction methods.
         */
         */
#ifndef _NO_LONGLONG
#ifndef _NO_LONGLONG
#define SARG() \
#define SARG() \
        (flags&QUADINT ? va_arg(ap, quad_t) : \
        (flags&QUADINT ? va_arg(ap, quad_t) : \
            flags&LONGINT ? va_arg(ap, long) : \
            flags&LONGINT ? va_arg(ap, long) : \
            flags&SHORTINT ? (long)(short)va_arg(ap, int) : \
            flags&SHORTINT ? (long)(short)va_arg(ap, int) : \
            (long)va_arg(ap, int))
            (long)va_arg(ap, int))
#define UARG() \
#define UARG() \
        (flags&QUADINT ? va_arg(ap, u_quad_t) : \
        (flags&QUADINT ? va_arg(ap, u_quad_t) : \
            flags&LONGINT ? va_arg(ap, u_long) : \
            flags&LONGINT ? va_arg(ap, u_long) : \
            flags&SHORTINT ? (u_long)(u_short)va_arg(ap, int) : \
            flags&SHORTINT ? (u_long)(u_short)va_arg(ap, int) : \
            (u_long)va_arg(ap, u_int))
            (u_long)va_arg(ap, u_int))
#else
#else
#define SARG() \
#define SARG() \
        (flags&LONGINT ? va_arg(ap, long) : \
        (flags&LONGINT ? va_arg(ap, long) : \
            flags&SHORTINT ? (long)(short)va_arg(ap, int) : \
            flags&SHORTINT ? (long)(short)va_arg(ap, int) : \
            (long)va_arg(ap, int))
            (long)va_arg(ap, int))
#define UARG() \
#define UARG() \
        (flags&LONGINT ? va_arg(ap, u_long) : \
        (flags&LONGINT ? va_arg(ap, u_long) : \
            flags&SHORTINT ? (u_long)(u_short)va_arg(ap, int) : \
            flags&SHORTINT ? (u_long)(u_short)va_arg(ap, int) : \
            (u_long)va_arg(ap, u_int))
            (u_long)va_arg(ap, u_int))
#endif
#endif
 
 
  va_start (ap, fmt0);
        va_start(ap, fmt0);
        fmt = (char *)fmt0;
        fmt = (char *)fmt0;
        ret = 0;
        ret = 0;
 
 
        /*
        /*
         * Scan the format for conversions (`%' character).
         * Scan the format for conversions (`%' character).
         */
         */
        for (;;) {
        for (;;) {
 
 
          while (*fmt != 0 && *fmt != '%') {
                while (*fmt != 0 && *fmt != '%') {
            pc (*fmt);
                        pc(*fmt);
      fmt++;
                        fmt++;
      ret++;
                        ret++;
    }
                }
                if (!*fmt)
                if (!*fmt)
                        goto done;
                        goto done;
 
 
    fmt++; /* Skip % */
                fmt++;          /* Skip % */
                flags = 0;
                flags = 0;
                dprec = 0;
                dprec = 0;
                width = 0;
                width = 0;
                prec = -1;
                prec = -1;
                sign = '\0';
                sign = '\0';
 
 
rflag:          ch = *fmt++;
rflag:          ch = *fmt++;
reswitch:       switch (ch) {
reswitch:       switch (ch) {
                case ' ':
                case ' ':
                        /*
                        /*
                         * ``If the space and + flags both appear, the space
                         * ``If the space and + flags both appear, the space
                         * flag will be ignored.''
                         * flag will be ignored.''
                         *      -- ANSI X3J11
                         *      -- ANSI X3J11
                         */
                         */
                        if (!sign)
                        if (!sign)
                                sign = ' ';
                                sign = ' ';
                        goto rflag;
                        goto rflag;
                case '#':
                case '#':
                        flags |= ALT;
                        flags |= ALT;
                        goto rflag;
                        goto rflag;
                case '*':
                case '*':
                        /*
                        /*
                         * ``A negative field width argument is taken as a
                         * ``A negative field width argument is taken as a
                         * - flag followed by a positive field width.''
                         * - flag followed by a positive field width.''
                         *      -- ANSI X3J11
                         *      -- ANSI X3J11
                         * They don't exclude field widths read from args.
                         * They don't exclude field widths read from args.
                         */
                         */
                        if ((width = va_arg(ap, int)) >= 0)
                        if ((width = va_arg(ap, int)) >= 0)
                                goto rflag;
                                 goto rflag;
                        width = -width;
                        width = -width;
                        /* FALLTHROUGH */
                        /* FALLTHROUGH */
                case '-':
                case '-':
                        flags |= LADJUST;
                        flags |= LADJUST;
                        goto rflag;
                        goto rflag;
                case '+':
                case '+':
                        sign = '+';
                        sign = '+';
                        goto rflag;
                        goto rflag;
                case '.':
                case '.':
                        if ((ch = *fmt++) == '*') {
                        if ((ch = *fmt++) == '*') {
                                n = va_arg(ap, int);
                                n = va_arg(ap, int);
                                prec = n < 0 ? -1 : n;
                                prec = n < 0 ? -1 : n;
                                goto rflag;
                                goto rflag;
                        }
                        }
                        n = 0;
                        n = 0;
                        while (is_digit(ch)) {
                        while (is_digit(ch)) {
                                n = 10 * n + to_digit(ch);
                                n = 10 * n + to_digit(ch);
                                ch = *fmt++;
                                ch = *fmt++;
                        }
                        }
                        prec = n < 0 ? -1 : n;
                        prec = n < 0 ? -1 : n;
                        goto reswitch;
                        goto reswitch;
                case '0':
                case '0':
                        /*
                        /*
                         * ``Note that 0 is taken as a flag, not as the
                         * ``Note that 0 is taken as a flag, not as the
                         * beginning of a field width.''
                         * beginning of a field width.''
                         *      -- ANSI X3J11
                         *      -- ANSI X3J11
                         */
                         */
                        flags |= ZEROPAD;
                        flags |= ZEROPAD;
                        goto rflag;
                        goto rflag;
                case '1': case '2': case '3': case '4':
                case '1':
                case '5': case '6': case '7': case '8': case '9':
                case '2':
 
                case '3':
 
                case '4':
 
                case '5':
 
                case '6':
 
                case '7':
 
                case '8':
 
                case '9':
                        n = 0;
                        n = 0;
                        do {
                        do {
                                n = 10 * n + to_digit(ch);
                                n = 10 * n + to_digit(ch);
                                ch = *fmt++;
                                ch = *fmt++;
                        } while (is_digit(ch));
                        } while (is_digit(ch));
                        width = n;
                        width = n;
                        goto reswitch;
                        goto reswitch;
#ifdef FLOATING_POINT
#ifdef FLOATING_POINT
                case 'L':
                case 'L':
                        flags |= LONGDBL;
                        flags |= LONGDBL;
                        goto rflag;
                        goto rflag;
#endif
#endif
                case 'h':
                case 'h':
                        flags |= SHORTINT;
                        flags |= SHORTINT;
                        goto rflag;
                        goto rflag;
                case 'l':
                case 'l':
                        if (*fmt == 'l') {
                        if (*fmt == 'l') {
                                fmt++;
                                fmt++;
                                flags |= QUADINT;
                                flags |= QUADINT;
                        } else {
                        } else {
                                flags |= LONGINT;
                                flags |= LONGINT;
                        }
                        }
                        goto rflag;
                        goto rflag;
                case 'q':
                case 'q':
                        flags |= QUADINT;
                        flags |= QUADINT;
                        goto rflag;
                        goto rflag;
                case 'c':
                case 'c':
                        *(cp = buf) = va_arg(ap, int);
                        *(cp = buf) = va_arg(ap, int);
                        size = 1;
                        size = 1;
                        sign = '\0';
                        sign = '\0';
                        break;
                        break;
                case 'D':
                case 'D':
                        flags |= LONGINT;
                        flags |= LONGINT;
                        /*FALLTHROUGH*/
                 /*FALLTHROUGH*/ case 'd':
                case 'd':
 
                case 'i':
                case 'i':
                        _uquad = SARG();
                        _uquad = SARG();
#ifndef _NO_LONGLONG
#ifndef _NO_LONGLONG
                        if ((quad_t)_uquad < 0)
                        if ((quad_t) _uquad < 0)
#else
#else
                        if ((long) _uquad < 0)
                        if ((long)_uquad < 0)
#endif
#endif
                        {
                        {
 
 
                                _uquad = -_uquad;
                                _uquad = -_uquad;
                                sign = '-';
                                sign = '-';
                        }
                        }
                        base = DEC;
                        base = DEC;
                        goto number;
                        goto number;
#ifdef FLOATING_POINT
#ifdef FLOATING_POINT
                case 'e':
                case 'e':
                case 'E':
                case 'E':
                case 'f':
                case 'f':
                case 'g':
                case 'g':
                case 'G':
                case 'G':
                        if (prec == -1) {
                        if (prec == -1) {
                                prec = DEFPREC;
                                prec = DEFPREC;
                        } else if ((ch == 'g' || ch == 'G') && prec == 0) {
                        } else if ((ch == 'g' || ch == 'G') && prec == 0) {
                                prec = 1;
                                prec = 1;
                        }
                        }
 
 
                        if (flags & LONGDBL) {
                        if (flags & LONGDBL) {
                                _double = (double) va_arg(ap, long double);
                                _double = (double)va_arg(ap, long double);
                        } else {
                        } else {
                                _double = va_arg(ap, double);
                                _double = va_arg(ap, double);
                        }
                        }
 
 
                        /* do this before tricky precision changes */
                        /* do this before tricky precision changes */
                        if (isinf(_double)) {
                        if (isinf(_double)) {
                                if (_double < 0)
                                if (_double < 0)
                                        sign = '-';
                                        sign = '-';
                                cp = "Inf";
                                cp = "Inf";
                                size = 3;
                                size = 3;
                                break;
                                break;
                        }
                        }
                        if (isnan(_double)) {
                        if (isnan(_double)) {
                                cp = "NaN";
                                cp = "NaN";
                                size = 3;
                                size = 3;
                                break;
                                break;
                        }
                        }
 
 
                        flags |= FPT;
                        flags |= FPT;
                        cp = cvt(data, _double, prec, flags, &softsign,
                        cp = cvt(data, _double, prec, flags, &softsign,
                                &expt, ch, &ndig);
                                 &expt, ch, &ndig);
                        if (ch == 'g' || ch == 'G') {
                        if (ch == 'g' || ch == 'G') {
                                if (expt <= -4 || expt > prec)
                                if (expt <= -4 || expt > prec)
                                        ch = (ch == 'g') ? 'e' : 'E';
                                        ch = (ch == 'g') ? 'e' : 'E';
                                else
                                else
                                        ch = 'g';
                                        ch = 'g';
                        }
                        }
                        if (ch <= 'e') {        /* 'e' or 'E' fmt */
                        if (ch <= 'e') {        /* 'e' or 'E' fmt */
                                --expt;
                                --expt;
                                expsize = exponent(expstr, expt, ch);
                                expsize = exponent(expstr, expt, ch);
                                size = expsize + ndig;
                                size = expsize + ndig;
                                if (ndig > 1 || flags & ALT)
                                if (ndig > 1 || flags & ALT)
                                        ++size;
                                        ++size;
                        } else if (ch == 'f') {         /* f fmt */
                        } else if (ch == 'f') { /* f fmt */
                                if (expt > 0) {
                                if (expt > 0) {
                                        size = expt;
                                        size = expt;
                                        if (prec || flags & ALT)
                                        if (prec || flags & ALT)
                                                size += prec + 1;
                                                size += prec + 1;
                                } else  /* "0.X" */
                                } else  /* "0.X" */
                                        size = prec + 2;
                                        size = prec + 2;
                        } else if (expt >= ndig) {      /* fixed g fmt */
                        } else if (expt >= ndig) {      /* fixed g fmt */
                                size = expt;
                                size = expt;
                                if (flags & ALT)
                                if (flags & ALT)
                                        ++size;
                                        ++size;
                        } else
                        } else
                                size = ndig + (expt > 0 ?
                                size = ndig + (expt > 0 ? 1 : 2 - expt);
                                        1 : 2 - expt);
 
 
 
                        if (softsign)
                        if (softsign)
                                sign = '-';
                                sign = '-';
                        break;
                        break;
#endif /* FLOATING_POINT */
#endif /* FLOATING_POINT */
                case 'n':
                case 'n':
#ifndef _NO_LONGLONG
#ifndef _NO_LONGLONG
                        if (flags & QUADINT)
                        if (flags & QUADINT)
                                *va_arg(ap, quad_t *) = ret;
                                *va_arg(ap, quad_t *) = ret;
                        else
                        else
#endif
#endif
                        if (flags & LONGINT)
                        if (flags & LONGINT)
                                *va_arg(ap, long *) = ret;
                                *va_arg(ap, long *) = ret;
                        else if (flags & SHORTINT)
                        else if (flags & SHORTINT)
                                *va_arg(ap, short *) = ret;
                                *va_arg(ap, short *) = ret;
                        else
                        else
                                *va_arg(ap, int *) = ret;
                                *va_arg(ap, int *) = ret;
                        continue;       /* no output */
                        continue;       /* no output */
                case 'O':
                case 'O':
                        flags |= LONGINT;
                        flags |= LONGINT;
                        /*FALLTHROUGH*/
                 /*FALLTHROUGH*/ case 'o':
                case 'o':
 
                        _uquad = UARG();
                        _uquad = UARG();
                        base = OCT;
                        base = OCT;
                        goto nosign;
                        goto nosign;
                case 'p':
                case 'p':
                        /*
                        /*
                         * ``The argument shall be a pointer to void.  The
                         * ``The argument shall be a pointer to void.  The
                         * value of the pointer is converted to a sequence
                         * value of the pointer is converted to a sequence
                         * of printable characters, in an implementation-
                         * of printable characters, in an implementation-
                         * defined manner.''
                         * defined manner.''
                         *      -- ANSI X3J11
                         *      -- ANSI X3J11
                         */
                         */
                        /* NOSTRICT */
                        /* NOSTRICT */
                        _uquad = (u_long)(unsigned _POINTER_INT)va_arg(ap, void *);
                        _uquad =
 
                            (u_long) (unsigned _POINTER_INT)va_arg(ap, void *);
                        base = HEX;
                        base = HEX;
                        xdigs = "0123456789abcdef";
                        xdigs = "0123456789abcdef";
                        flags |= HEXPREFIX;
                        flags |= HEXPREFIX;
                        ch = 'x';
                        ch = 'x';
                        goto nosign;
                        goto nosign;
                case 's':
                case 's':
                        if ((cp = va_arg(ap, char *)) == NULL)
                        if ((cp = va_arg(ap, char *)) == NULL)
                                cp = "(null)";
                                cp = "(null)";
                        if (prec >= 0) {
                        if (prec >= 0) {
                                /*
                                /*
                                 * can't use strlen; can only look for the
                                 * can't use strlen; can only look for the
                                 * NUL in the first `prec' characters, and
                                 * NUL in the first `prec' characters, and
                                 * strlen() will go further.
                                 * strlen() will go further.
                                 */
                                 */
                                char *p = (char *)memchr(cp, 0, prec);
                                char *p = (char *)memchr(cp, 0, prec);
 
 
                                if (p != NULL) {
                                if (p != NULL) {
                                        size = p - cp;
                                        size = p - cp;
                                        if (size > prec)
                                        if (size > prec)
                                                size = prec;
                                                size = prec;
                                } else
                                } else
                                        size = prec;
                                        size = prec;
                        } else
                        } else
                                size = strlen(cp);
                                size = strlen(cp);
                        sign = '\0';
                        sign = '\0';
                        break;
                        break;
                case 'U':
                case 'U':
                        flags |= LONGINT;
                        flags |= LONGINT;
                        /*FALLTHROUGH*/
                 /*FALLTHROUGH*/ case 'u':
                case 'u':
 
                        _uquad = UARG();
                        _uquad = UARG();
                        base = DEC;
                        base = DEC;
                        goto nosign;
                        goto nosign;
                case 'X':
                case 'X':
                        xdigs = "0123456789ABCDEF";
                        xdigs = "0123456789ABCDEF";
                        goto hex;
                        goto hex;
                case 'x':
                case 'x':
                        xdigs = "0123456789abcdef";
                        xdigs = "0123456789abcdef";
hex:                    _uquad = UARG();
hex:                    _uquad = UARG();
                        base = HEX;
                        base = HEX;
                        /* leading 0x/X only if non-zero */
                        /* leading 0x/X only if non-zero */
                        if (flags & ALT && _uquad != 0)
                        if (flags & ALT && _uquad != 0)
                                flags |= HEXPREFIX;
                                flags |= HEXPREFIX;
 
 
                        /* unsigned conversions */
                        /* unsigned conversions */
nosign:                 sign = '\0';
nosign:         sign = '\0';
                        /*
                        /*
                         * ``... diouXx conversions ... if a precision is
                         * ``... diouXx conversions ... if a precision is
                         * specified, the 0 flag will be ignored.''
                         * specified, the 0 flag will be ignored.''
                         *      -- ANSI X3J11
                         *      -- ANSI X3J11
                         */
                         */
number:                 if ((dprec = prec) >= 0)
number:         if ((dprec = prec) >= 0)
                                flags &= ~ZEROPAD;
                                flags &= ~ZEROPAD;
 
 
                        /*
                        /*
                         * ``The result of converting a zero value with an
                         * ``The result of converting a zero value with an
                         * explicit precision of zero is no characters.''
                         * explicit precision of zero is no characters.''
                         *      -- ANSI X3J11
                         *      -- ANSI X3J11
                         */
                         */
                        cp = buf + BUF;
                        cp = buf + BUF;
                        if (_uquad != 0 || prec != 0) {
                        if (_uquad != 0 || prec != 0) {
                                /*
                                /*
                                 * Unsigned mod is hard, and unsigned mod
                                 * Unsigned mod is hard, and unsigned mod
                                 * by a constant is easier than that by
                                 * by a constant is easier than that by
                                 * a variable; hence this switch.
                                 * a variable; hence this switch.
                                 */
                                 */
                                switch (base) {
                                switch (base) {
                                case OCT:
                                case OCT:
                                        do {
                                        do {
                                                *--cp = to_char(_uquad & 7);
                                                *--cp = to_char(_uquad & 7);
                                                _uquad >>= 3;
                                                _uquad >>= 3;
                                        } while (_uquad);
                                        } while (_uquad);
                                        /* handle octal leading 0 */
                                        /* handle octal leading 0 */
                                        if (flags & ALT && *cp != '0')
                                        if (flags & ALT && *cp != '0')
                                                *--cp = '0';
                                                *--cp = '0';
                                        break;
                                        break;
 
 
                                case DEC:
                                case DEC:
                                        /* many numbers are 1 digit */
                                        /* many numbers are 1 digit */
                                        while (_uquad >= 10) {
                                        while (_uquad >= 10) {
                                                *--cp = to_char(_uquad % 10);
                                                *--cp = to_char(_uquad % 10);
                                                _uquad /= 10;
                                                _uquad /= 10;
                                        }
                                        }
                                        *--cp = to_char(_uquad);
                                        *--cp = to_char(_uquad);
                                        break;
                                        break;
 
 
                                case HEX:
                                case HEX:
                                        do {
                                        do {
                                                *--cp = xdigs[_uquad & 15];
                                                *--cp = xdigs[_uquad & 15];
                                                _uquad >>= 4;
                                                _uquad >>= 4;
                                        } while (_uquad);
                                        } while (_uquad);
                                        break;
                                        break;
 
 
                                default:
                                default:
                                        cp = "bug in vfprintf: bad base";
                                        cp = "bug in vfprintf: bad base";
                                        size = strlen(cp);
                                        size = strlen(cp);
                                        goto skipsize;
                                        goto skipsize;
                                }
                                }
                        }
                        }
                        size = buf + BUF - cp;
                        size = buf + BUF - cp;
                skipsize:
skipsize:
                        break;
                        break;
                default:        /* "%?" prints ?, unless ? is NUL */
                default:        /* "%?" prints ?, unless ? is NUL */
                        if (ch == '\0')
                        if (ch == '\0')
                                goto done;
                                goto done;
                        /* pretend it was %c with argument ch */
                        /* pretend it was %c with argument ch */
                        cp = buf;
                        cp = buf;
                        *cp = ch;
                        *cp = ch;
                        size = 1;
                        size = 1;
                        sign = '\0';
                        sign = '\0';
                        break;
                        break;
                }
                }
 
 
                /*
                /*
                 * All reasonable formats wind up here.  At this point, `cp'
                 * All reasonable formats wind up here.  At this point, `cp'
                 * points to a string which (if not flags&LADJUST) should be
                 * points to a string which (if not flags&LADJUST) should be
                 * padded out to `width' places.  If flags&ZEROPAD, it should
                 * padded out to `width' places.  If flags&ZEROPAD, it should
                 * first be prefixed by any sign or other prefix; otherwise,
                 * first be prefixed by any sign or other prefix; otherwise,
                 * it should be blank padded before the prefix is emitted.
                 * it should be blank padded before the prefix is emitted.
                 * After any left-hand padding and prefixing, emit zeroes
                 * After any left-hand padding and prefixing, emit zeroes
                 * required by a decimal [diouxX] precision, then print the
                 * required by a decimal [diouxX] precision, then print the
                 * string proper, then emit zeroes required by any leftover
                 * string proper, then emit zeroes required by any leftover
                 * floating precision; finally, if LADJUST, pad with blanks.
                 * floating precision; finally, if LADJUST, pad with blanks.
                 *
                 *
                 * Compute actual size, so we know how much to pad.
                 * Compute actual size, so we know how much to pad.
                 * size excludes decimal prec; realsz includes it.
                 * size excludes decimal prec; realsz includes it.
                 */
                 */
                realsz = dprec > size ? dprec : size;
                realsz = dprec > size ? dprec : size;
                if (sign)
                if (sign)
                        realsz++;
                        realsz++;
                else if (flags & HEXPREFIX)
                else if (flags & HEXPREFIX)
                        realsz+= 2;
                        realsz += 2;
 
 
                /* right-adjusting blank padding */
                /* right-adjusting blank padding */
                if ((flags & (LADJUST|ZEROPAD)) == 0)
                if ((flags & (LADJUST | ZEROPAD)) == 0)
                        PAD(width - realsz, blanks);
                        PAD(width - realsz, blanks);
 
 
                /* prefix */
                /* prefix */
                if (sign) {
                if (sign) {
                        PRINT(&sign, 1);
                        PRINT(&sign, 1);
                } else if (flags & HEXPREFIX) {
                } else if (flags & HEXPREFIX) {
                        ox[0] = '0';
                        ox[0] = '0';
                        ox[1] = ch;
                        ox[1] = ch;
                        PRINT(ox, 2);
                        PRINT(ox, 2);
                }
                }
 
 
                /* right-adjusting zero padding */
                /* right-adjusting zero padding */
                if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD)
                if ((flags & (LADJUST | ZEROPAD)) == ZEROPAD)
                        PAD(width - realsz, zeroes);
                        PAD(width - realsz, zeroes);
 
 
                /* leading zeroes from decimal precision */
                /* leading zeroes from decimal precision */
                PAD(dprec - size, zeroes);
                PAD(dprec - size, zeroes);
 
 
                /* the string or number proper */
                /* the string or number proper */
#ifdef FLOATING_POINT
#ifdef FLOATING_POINT
                if ((flags & FPT) == 0) {
                if ((flags & FPT) == 0) {
                        PRINT(cp, size);
                        PRINT(cp, size);
                } else {        /* glue together f_p fragments */
                } else {        /* glue together f_p fragments */
                        if (ch >= 'f') {        /* 'f' or 'g' */
                        if (ch >= 'f') {        /* 'f' or 'g' */
                                if (_double == 0) {
                                if (_double == 0) {
                                        /* kludge for __dtoa irregularity */
                                        /* kludge for __dtoa irregularity */
                                        PRINT("0", 1);
                                        PRINT("0", 1);
                                        if (expt < ndig || (flags & ALT) != 0) {
                                        if (expt < ndig || (flags & ALT) != 0) {
                                                PRINT(decimal_point, 1);
                                                PRINT(decimal_point, 1);
                                                PAD(ndig - 1, zeroes);
                                                PAD(ndig - 1, zeroes);
                                        }
                                        }
                                } else if (expt <= 0) {
                                } else if (expt <= 0) {
                                        PRINT("0", 1);
                                        PRINT("0", 1);
                                        PRINT(decimal_point, 1);
                                        PRINT(decimal_point, 1);
                                        PAD(-expt, zeroes);
                                        PAD(-expt, zeroes);
                                        PRINT(cp, ndig);
                                        PRINT(cp, ndig);
                                } else if (expt >= ndig) {
                                } else if (expt >= ndig) {
                                        PRINT(cp, ndig);
                                        PRINT(cp, ndig);
                                        PAD(expt - ndig, zeroes);
                                        PAD(expt - ndig, zeroes);
                                        if (flags & ALT)
                                        if (flags & ALT)
                                                PRINT(".", 1);
                                                PRINT(".", 1);
                                } else {
                                } else {
                                        PRINT(cp, expt);
                                        PRINT(cp, expt);
                                        cp += expt;
                                        cp += expt;
                                        PRINT(".", 1);
                                        PRINT(".", 1);
                                        PRINT(cp, ndig-expt);
                                        PRINT(cp, ndig - expt);
                                }
                                }
                        } else {        /* 'e' or 'E' */
                        } else {        /* 'e' or 'E' */
                                if (ndig > 1 || flags & ALT) {
                                if (ndig > 1 || flags & ALT) {
                                        ox[0] = *cp++;
                                        ox[0] = *cp++;
                                        ox[1] = '.';
                                        ox[1] = '.';
                                        PRINT(ox, 2);
                                        PRINT(ox, 2);
                                        if (_double || flags & ALT == 0) {
                                        if (_double || flags & ALT == 0) {
                                                PRINT(cp, ndig-1);
                                                PRINT(cp, ndig - 1);
                                        } else  /* 0.[0..] */
                                        } else  /* 0.[0..] */
                                                /* __dtoa irregularity */
                                                /* __dtoa irregularity */
                                                PAD(ndig - 1, zeroes);
                                                PAD(ndig - 1, zeroes);
                                } else  /* XeYYY */
                                } else  /* XeYYY */
                                        PRINT(cp, 1);
                                        PRINT(cp, 1);
                                PRINT(expstr, expsize);
                                PRINT(expstr, expsize);
                        }
                        }
                }
                }
#else
#else
                PRINT(cp, size);
                PRINT(cp, size);
#endif
#endif
                /* left-adjusting padding (always blank) */
                /* left-adjusting padding (always blank) */
                if (flags & LADJUST)
                if (flags & LADJUST)
                        PAD(width - realsz, blanks);
                        PAD(width - realsz, blanks);
 
 
                /* finally, adjust ret */
                /* finally, adjust ret */
                ret += width > realsz ? width : realsz;
                ret += width > realsz ? width : realsz;
 
 
                FLUSH();        /* copy out the I/O vectors */
                FLUSH();        /* copy out the I/O vectors */
        }
        }
done:
done:
  va_end (ap);
        va_end(ap);
        FLUSH();
        FLUSH();
        return (ret);
        return (ret);
        /* NOTREACHED */
        /* NOTREACHED */
}
}
 
 
#ifdef FLOATING_POINT
#ifdef FLOATING_POINT
 
 
extern char *_dtoa_r _PARAMS((struct _reent *, double, int,
extern char *_dtoa_r _PARAMS((struct _reent *, double, int,
                              int, int *, int *, char **));
                              int, int *, int *, char **));
 
 
static char *
static char *cvt(data, value, ndigits, flags, sign, decpt, ch, length)
cvt(data, value, ndigits, flags, sign, decpt, ch, length)
 
        struct _reent *data;
        struct _reent *data;
        double value;
double value;
        int ndigits, flags, *decpt, ch, *length;
int ndigits, flags, *decpt, ch, *length;
        char *sign;
char *sign;
{
{
        int mode, dsgn;
        int mode, dsgn;
        char *digits, *bp, *rve;
        char *digits, *bp, *rve;
        union double_union tmp;
        union double_union tmp;
 
 
        if (ch == 'f') {
        if (ch == 'f') {
                mode = 3;               /* ndigits after the decimal point */
                mode = 3;       /* ndigits after the decimal point */
        } else {
        } else {
                /* To obtain ndigits after the decimal point for the 'e'
                /* To obtain ndigits after the decimal point for the 'e'
                 * and 'E' formats, round to ndigits + 1 significant
                 * and 'E' formats, round to ndigits + 1 significant
                 * figures.
                 * figures.
                 */
                 */
                if (ch == 'e' || ch == 'E') {
                if (ch == 'e' || ch == 'E') {
                        ndigits++;
                        ndigits++;
                }
                }
                mode = 2;               /* ndigits significant digits */
                mode = 2;       /* ndigits significant digits */
        }
        }
 
 
        tmp.d = value;
        tmp.d = value;
        if (word0(tmp) & Sign_bit) { /* this will check for < 0 and -0.0 */
        if (word0(tmp) & Sign_bit) {    /* this will check for < 0 and -0.0 */
                value = -value;
                value = -value;
                *sign = '-';
                *sign = '-';
        } else
        } else
                *sign = '\000';
                *sign = '\000';
        digits = _dtoa_r(data, value, mode, ndigits, decpt, &dsgn, &rve);
        digits = _dtoa_r(data, value, mode, ndigits, decpt, &dsgn, &rve);
        if ((ch != 'g' && ch != 'G') || flags & ALT) {  /* Print trailing zeros */
        if ((ch != 'g' && ch != 'G') || flags & ALT) {  /* Print trailing zeros */
                bp = digits + ndigits;
                bp = digits + ndigits;
                if (ch == 'f') {
                if (ch == 'f') {
                        if (*digits == '0' && value)
                        if (*digits == '0' && value)
                                *decpt = -ndigits + 1;
                                *decpt = -ndigits + 1;
                        bp += *decpt;
                        bp += *decpt;
                }
                }
                if (value == 0)  /* kludge for __dtoa irregularity */
                if (value == 0)  /* kludge for __dtoa irregularity */
                        rve = bp;
                        rve = bp;
                while (rve < bp)
                while (rve < bp)
                        *rve++ = '0';
                        *rve++ = '0';
        }
        }
        *length = rve - digits;
        *length = rve - digits;
        return (digits);
        return (digits);
}
}
 
 
static int
static int exponent(p0, exp, fmtch)
exponent(p0, exp, fmtch)
 
        char *p0;
        char *p0;
        int exp, fmtch;
int exp, fmtch;
{
{
        register char *p, *t;
        register char *p, *t;
        char expbuf[MAXEXP];
        char expbuf[MAXEXP];
 
 
        p = p0;
        p = p0;
        *p++ = fmtch;
        *p++ = fmtch;
        if (exp < 0) {
        if (exp < 0) {
                exp = -exp;
                exp = -exp;
                *p++ = '-';
                *p++ = '-';
        }
        } else
        else
 
                *p++ = '+';
                *p++ = '+';
        t = expbuf + MAXEXP;
        t = expbuf + MAXEXP;
        if (exp > 9) {
        if (exp > 9) {
                do {
                do {
                        *--t = to_char(exp % 10);
                        *--t = to_char(exp % 10);
                } while ((exp /= 10) > 9);
                } while ((exp /= 10) > 9);
                *--t = to_char(exp);
                *--t = to_char(exp);
                for (; t < expbuf + MAXEXP; *p++ = *t++);
                for (; t < expbuf + MAXEXP; *p++ = *t++);
        }
        } else {
        else {
 
                *p++ = '0';
                *p++ = '0';
                *p++ = to_char(exp);
                *p++ = to_char(exp);
        }
        }
        return (p - p0);
        return (p - p0);
}
}
#endif /* FLOATING_POINT */
#endif /* FLOATING_POINT */
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.