summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDanny Smith <dannysmith@users.sourceforge.net>2007-06-29 10:11:57 +0000
committerDanny Smith <dannysmith@users.sourceforge.net>2007-06-29 10:11:57 +0000
commitb363c819dd4768db235519ae5b92607e945afc7c (patch)
tree4fecda787c202642ee25daa92cedabedec839851
parentd802576ca17c6552667116edbc8620f6a60a8975 (diff)
downloadcygnal-b363c819dd4768db235519ae5b92607e945afc7c.tar.gz
cygnal-b363c819dd4768db235519ae5b92607e945afc7c.tar.bz2
cygnal-b363c819dd4768db235519ae5b92607e945afc7c.zip
* mingwex/gdtoa/mingw_snprintf.c: New file.
* mingwex/Makefile.in (GDTOA_DISTFILES): Add mingw_snprintf.c. (GDTOA_OBJS): Add mingw_snprintf.O.
-rw-r--r--winsup/mingw/ChangeLog6
-rw-r--r--winsup/mingw/mingwex/Makefile.in7
-rwxr-xr-xwinsup/mingw/mingwex/gdtoa/mingw_snprintf.c1241
3 files changed, 1251 insertions, 3 deletions
diff --git a/winsup/mingw/ChangeLog b/winsup/mingw/ChangeLog
index bcf57c3c2..264940f6a 100644
--- a/winsup/mingw/ChangeLog
+++ b/winsup/mingw/ChangeLog
@@ -1,3 +1,9 @@
+2007-06-29 Danny Smith <dannysmith@users.sourceforge.net>
+
+ * mingwex/gdtoa/mingw_snprintf.c: New file.
+ * mingwex/Makefile.in (GDTOA_DISTFILES): Add mingw_snprintf.c.
+ (GDTOA_OBJS): Add mingw_snprintf.O.
+
2007-06-28 Danny Smith <dannysmith@users.sourceforge.net>
* msvcrt.def.in: Update comment.
diff --git a/winsup/mingw/mingwex/Makefile.in b/winsup/mingw/mingwex/Makefile.in
index 3471c246c..bc5db2162 100644
--- a/winsup/mingw/mingwex/Makefile.in
+++ b/winsup/mingw/mingwex/Makefile.in
@@ -38,7 +38,7 @@ DISTFILES = Makefile.in configure configure.in aclocal.m4 \
wcrtomb.c wctob.c mbrtowc.c btowc.c mb_wc_common.h \
gettimeofday.c isblank.c iswblank.c \
basename.c dirname.c \
- tsearch.c twalk.c tdelete.c tfind.c
+ tsearch.c twalk.c tdelete.c tfind.c
MATH_DISTFILES = \
acosf.c acosl.c asinf.c asinl.c atan2f.c atan2l.c \
@@ -90,7 +90,7 @@ GDTOA_DISTFILES = \
arithchk.c dmisc.c dtoa.c g__fmt.c g_dfmt.c g_ffmt.c g_xfmt.c \
gd_arith.h gd_qnan.h gdtoa.c gdtoa.h gdtoaimp.h gethex.c gmisc.c \
hd_init.c hexnan.c misc.c qnan.c README smisc.c strtodg.c strtodnrp.c \
- strtof.c strtopx.c sum.c ulp.c
+ strtof.c strtopx.c sum.c ulp.c mingw_snprintf.c
CC = @CC@
# FIXME: Which is it, CC or CC_FOR_TARGET?
CC_FOR_TARGET = $(CC)
@@ -190,7 +190,8 @@ COMPLEX_OBJS = \
GDTOA_OBJS = \
dmisc.o dtoa.o g__fmt.o g_dfmt.o g_ffmt.o g_xfmt.o gdtoa.o \
gethex.o gmisc.o hd_init.o hexnan.o misc.o smisc.o \
- strtodg.o strtodnrp.o strtof.o strtopx.o sum.o ulp.o
+ strtodg.o strtodnrp.o strtof.o strtopx.o sum.o ulp.o \
+ mingw_snprintf.o
LIB_OBJS = $(Q8_OBJS) $(CTYPE_OBJS) $(STDLIB_STUB_OBJS) \
$(STDIO_OBJS) $(MATH_OBJS) $(FENV_OBJS) \
diff --git a/winsup/mingw/mingwex/gdtoa/mingw_snprintf.c b/winsup/mingw/mingwex/gdtoa/mingw_snprintf.c
new file mode 100755
index 000000000..cb827bf4c
--- /dev/null
+++ b/winsup/mingw/mingwex/gdtoa/mingw_snprintf.c
@@ -0,0 +1,1241 @@
+/****************************************************************
+Copyright (C) 1997, 1999, 2001 Lucent Technologies
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name of Lucent or any of its entities
+not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
+****************************************************************/
+
+/* This implements most of ANSI C's printf, fprintf, and sprintf,
+ * with %.0g and %.0G giving the shortest decimal string
+ * that rounds to the number being converted, and with negative
+ * precisions allowed for %f.
+ */
+
+/*
+ * Extracted from the AMPL solvers library module
+ * http://www.netlib.org/ampl/solvers/printf.c
+ * and modified for use in libmingwex.a.
+ *
+ * libstdc++ amd libgfortran expect an snprintf that can handle host
+ * widest float type. This one handle 80 bit long double. Printing
+ * to streams using this alternative implementation is not yet
+ * supported,
+ *
+ * Danny Smith <dannysmith@users.sourceforge.net>
+ * 2007-06-01
+ */
+
+
+#ifdef KR_headers
+#include "varargs.h"
+#else
+#include "stddef.h"
+#include "stdarg.h"
+#include "stdlib.h"
+#endif
+
+#define VA_LIST va_list
+
+/* #include "stdio1.h" */
+#include "string.h"
+#include "errno.h"
+
+#ifdef KR_headers
+#define Const /* const */
+#define Voidptr char*
+#ifndef size_t__
+#define size_t int
+#define size_t__
+#endif
+
+#else
+
+#define Const const
+#define Voidptr void*
+
+#endif
+
+
+
+#ifdef USE_FILE_OUTPUT
+#undef MESS
+#ifndef Stderr
+#define Stderr stderr
+#endif
+
+#ifdef _windows_
+#undef PF_BUF
+#define MESS
+#include "mux0.h"
+#define stdout_or_err(f) (f == stdout)
+#else
+#define stdout_or_err(f) (f == Stderr || f == stdout)
+#endif
+
+#endif /* USE_FILE_OUTPUT */
+
+#include <math.h>
+#include <stdint.h>
+#include "gdtoa.h"
+
+
+#define Snprintf __mingw_snprintf
+#define Vsnprintf __mingw_vsnprintf
+
+
+static char* __ldtoa (long double ld, int mode, int ndig, int *decpt,
+ int *sign, char **rve)
+{
+
+ static FPI fpi = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, 0 };
+ ULong bits[2];
+ int ex, kind;
+ int fptype = __fpclassifyl (ld);
+ union
+ {
+ unsigned short L[6];
+ long double ld;
+ } u;
+
+ u.ld = ld;
+
+ *sign = u.L[4] & 0x8000;
+ ex = u.L[4] & 0x7fff;
+
+ bits[1] = (u.L[3] << 16) | u.L[2];
+ bits[0] = (u.L[1] << 16) | u.L[0];
+
+ if (fptype & FP_NAN) /* NaN or Inf */
+ {
+ if (fptype & FP_NORMAL)
+ kind = STRTOG_Infinite;
+ else
+ kind = STRTOG_NaN;
+ }
+ else if (fptype & FP_NORMAL) /* Normal or subnormal */
+ {
+ if (fptype & FP_ZERO)
+ {
+ kind = STRTOG_Denormal;
+ ex = 1;
+ }
+ else
+ kind = STRTOG_Normal;
+
+ ex -= 0x3fff + 63;
+ }
+ else
+ kind = STRTOG_Zero;
+
+ return __gdtoa (&fpi, ex, bits, &kind, mode, ndig, decpt, rve);
+}
+
+#ifdef USE_ULDIV
+/* This is for avoiding 64-bit divisions on the DEC Alpha, since */
+/* they are not portable among variants of OSF1 (DEC's Unix). */
+
+#define ULDIV(a,b) uldiv_ASL(a,(unsigned long)(b))
+
+#ifndef LLBITS
+#define LLBITS 6
+#endif
+#ifndef ULONG
+#define ULONG unsigned long
+#endif
+
+ static int
+klog(ULONG x)
+{
+ int k, rv = 0;
+
+ if (x > 1L)
+ for(k = 1 << LLBITS-1;;) {
+ if (x >= (1L << k)) {
+ rv |= k;
+ x >>= k;
+ }
+ if (!(k >>= 1))
+ break;
+ }
+ return rv;
+ }
+
+ ULONG
+uldiv_ASL(ULONG a, ULONG b)
+{
+ int ka;
+ ULONG c, k;
+ static ULONG b0;
+ static int kb;
+
+ if (a < b)
+ return 0;
+ if (b != b0) {
+ b0 = b;
+ kb = klog(b);
+ }
+ k = 1;
+ if ((ka = klog(a) - kb) > 0) {
+ k <<= ka;
+ b <<= ka;
+ }
+ c = 0;
+ for(;;) {
+ if (a >= b) {
+ a -= b;
+ c |= k;
+ }
+ if (!(k >>= 1))
+ break;
+ a <<= 1;
+ }
+ return c;
+ }
+
+#else
+#define ULDIV(a,b) a / b
+#endif /* USE_ULDIV */
+
+ typedef struct
+Finfo {
+ union {
+ #ifdef USE_FILE_OUTPUT
+ FILE *cf;
+ #endif
+ char *sf;
+ } u;
+ char *ob0, *obe1;
+ size_t lastlen;
+ } Finfo;
+
+ typedef char *(*Putfunc) ANSI((Finfo*, int*));
+
+#ifdef USE_FILE_OUTPUT
+#ifdef PF_BUF
+FILE *stderr_ASL = (FILE*)&stderr_ASL;
+void (*pfbuf_print_ASL) ANSI((char*));
+char *pfbuf_ASL;
+static char *pfbuf_next;
+static size_t pfbuf_len;
+extern Char *mymalloc_ASL ANSI((size_t));
+extern Char *myralloc_ASL ANSI((void *, size_t));
+
+#undef fflush
+#ifdef old_fflush_ASL
+#define fflush old_fflush_ASL
+#endif
+
+ void
+fflush_ASL(FILE *f)
+{
+ if (f == stderr_ASL) {
+ if (pfbuf_ASL && pfbuf_print_ASL) {
+ (*pfbuf_print_ASL)(pfbuf_ASL);
+ free(pfbuf_ASL);
+ pfbuf_ASL = 0;
+ }
+ }
+ else
+ fflush(f);
+ }
+
+ static void
+pf_put(char *buf, int len)
+{
+ size_t x, y;
+ if (!pfbuf_ASL) {
+ x = len + 256;
+ if (x < 512)
+ x = 512;
+ pfbuf_ASL = pfbuf_next = (char*)mymalloc_ASL(pfbuf_len = x);
+ }
+ else if ((y = (pfbuf_next - pfbuf_ASL) + len) >= pfbuf_len) {
+ x = pfbuf_len;
+ while((x <<= 1) <= y);
+ y = pfbuf_next - pfbuf_ASL;
+ pfbuf_ASL = (char*)myralloc_ASL(pfbuf_ASL, x);
+ pfbuf_next = pfbuf_ASL + y;
+ pfbuf_len = x;
+ }
+ memcpy(pfbuf_next, buf, len);
+ pfbuf_next += len;
+ *pfbuf_next = 0;
+ }
+
+ static char *
+pfput(Finfo *f, int *rvp)
+{
+ int n;
+ char *ob0 = f->ob0;
+ *rvp += n = (int)(f->obe1 - ob0);
+ pf_put(ob0, n);
+ return ob0;
+ }
+#endif /* PF_BUF */
+
+ static char *
+Fput
+#ifdef KR_headers
+ (f, rvp) register Finfo *f; int *rvp;
+#else
+ (register Finfo *f, int *rvp)
+#endif
+{
+ register char *ob0 = f->ob0;
+
+ *rvp += f->obe1 - ob0;
+ *f->obe1 = 0;
+ fputs(ob0, f->u.cf);
+ return ob0;
+ }
+
+
+#ifdef _windows_
+int stdout_fileno_ASL = 1;
+
+ static char *
+Wput
+#ifdef KR_headers
+ (f, rvp) register Finfo *f; int *rvp;
+#else
+ (register Finfo *f, int *rvp)
+#endif
+{
+ register char *ob0 = f->ob0;
+
+ *rvp += f->obe1 - ob0;
+ *f->obe1 = 0;
+ mwrite(ob0, f->obe1 - ob0);
+ return ob0;
+ }
+#endif /*_windows_*/
+#endif /* USE_FILE_OUTPUT */
+
+#ifndef INT_IS_LONG
+#if defined (__SIZEOF_LONG__) && defined (__SIZEOF_INT__) \
+ && (__SIZEOF_LONG__) == (__SIZEOF_INT__)
+#define INT_IS_LONG 1
+#endif
+#endif
+
+#define put(x) { *outbuf++ = x; if (outbuf == obe) outbuf = (*fput)(f,&rv); }
+
+ static int
+x_sprintf
+#ifdef KR_headers
+ (obe, fput, f, fmt, ap)
+ char *obe, *fmt; Finfo *f; Putfunc fput; va_list ap;
+#else
+ (char *obe, Putfunc fput, Finfo *f, const char *fmt, va_list ap)
+#endif
+{
+ char *digits, *ob0, *outbuf, *s, *s0, *se;
+ Const char *fmt0;
+ char buf[32];
+ long long i = 0;
+ unsigned long long j;
+ unsigned long long u = 0;
+
+ double x;
+ long double xx;
+ int flag_ld = 0;
+ int alt, base, c, decpt, dot, conv, i1, lead0, left,
+ prec, prec1, psign, rv, sgn, sign, width;
+ enum {
+ LEN_I,
+ LEN_L,
+ LEN_S,
+ LEN_LL
+ } len;
+ long long Ltmp;
+ intptr_t ip;
+ short sh;
+ long k;
+ unsigned short us;
+ unsigned long ui;
+ static char hex[] = "0123456789abcdef";
+ static char Hex[] = "0123456789ABCDEF";
+
+ ob0 = outbuf = f->ob0;
+ rv = 0;
+ for(;;) {
+ for(;;) {
+ switch(c = *fmt++) {
+ case 0:
+ goto done;
+ case '%':
+ break;
+ default:
+ put(c)
+ continue;
+ }
+ break;
+ }
+ alt=dot=lead0=left=prec=psign=sign=width=0;
+ len = LEN_I;
+ fmt0 = fmt;
+ fmtloop:
+ switch(conv = *fmt++) {
+ case ' ':
+ case '+':
+ sign = conv;
+ goto fmtloop;
+ case '-':
+ if (dot)
+ psign = 1;
+ else
+ left = 1;
+ goto fmtloop;
+ case '#':
+ alt = 1;
+ goto fmtloop;
+ case '0':
+ if (!lead0 && !dot) {
+ lead0 = 1;
+ goto fmtloop;
+ }
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ k = conv - '0';
+ while((c = *fmt) >= '0' && c <= '9') {
+ k = 10*k + c - '0';
+ fmt++;
+ }
+ if (dot)
+ prec = psign ? -k : k;
+ else
+ width = k;
+ goto fmtloop;
+ case 'h':
+ len = LEN_S;
+ goto fmtloop;
+#ifndef NO_MSVC_EXTENSIONS
+ case 'I':
+ if (fmt[0] == '3' && fmt[1] == '2')
+ {
+ fmt += 2;
+ len = LEN_L;
+ }
+ else if (fmt[0] == '6' && fmt[1] == '4')
+ {
+ fmt += 2;
+ len = LEN_LL;
+ }
+ else
+ len = sizeof (intptr_t) == sizeof (long long)
+ ? LEN_LL : LEN_L;
+ goto fmtloop;
+#endif
+ case 'l':
+ if (fmt[0] == 'l')
+ {
+ fmt++;
+ len = LEN_LL;
+ }
+ else
+ len = LEN_LL;
+ goto fmtloop;
+ case 'L':
+ flag_ld++;
+ goto fmtloop;
+ case '.':
+ dot = 1;
+ lead0 = 0;
+ goto fmtloop;
+ case '*':
+ k = va_arg(ap, int);
+ if (dot)
+ prec = k;
+ else {
+ if (k < 0) {
+ sign = '-';
+ k = -k;
+ }
+ width = k;
+ }
+ goto fmtloop;
+ case 'c':
+/* %lc (for wctomb conversion) is not implemented. */
+ c = va_arg(ap, int);
+ put(c)
+ continue;
+ case '%':
+ put(conv)
+ continue;
+ case 'u':
+ switch(len) {
+ case LEN_I:
+#if !INT_IS_LONG
+ ui = va_arg(ap, int);
+ i = ui;
+ break;
+#endif
+ case LEN_L:
+ ui = va_arg(ap, long);
+ i = ui;
+ break;
+ case LEN_S:
+ us = va_arg(ap, long);
+ i = us;
+ break;
+ case LEN_LL:
+ i = va_arg(ap, long long);
+ }
+ sign = 0;
+ goto have_i;
+ case 'i':
+ case 'd':
+ switch(len) {
+ case LEN_I:
+#if !INT_IS_LONG
+ k = va_arg(ap, int);
+ i = k;
+ break;
+#endif
+ case LEN_L:
+ k = va_arg(ap, long);
+ i = k;
+ break;
+ case LEN_S:
+ sh = va_arg(ap, long);
+ i = sh;
+ break;
+ case LEN_LL:
+ i = va_arg(ap, long long);
+
+ }
+ if (i < 0) {
+ sign = '-';
+ i = -i;
+ }
+ have_i:
+ base = 10;
+ u = i;
+ digits = hex;
+ baseloop:
+ s = buf;
+ if (!u)
+ alt = 0;
+ do {
+ j = ULDIV(u, base);
+ *s++ = digits[u - base * j];
+ }
+ while((u = j));
+ prec -= c = s - buf;
+ if (alt && conv == 'o' && prec <= 0)
+ prec = 1;
+ if ((width -= c) > 0) {
+ if (prec > 0)
+ width -= prec;
+ if (sign)
+ width--;
+ if (alt == 2)
+ width--;
+ }
+ if (left) {
+ if (alt == 2)
+ put('0') /* for 0x */
+ if (sign)
+ put(sign)
+ while(--prec >= 0)
+ put('0')
+ do put(*--s)
+ while(s > buf);
+ while(--width >= 0)
+ put(' ')
+ continue;
+ }
+ if (width > 0) {
+ if (lead0) {
+ if (alt == 2)
+ put('0')
+ if (sign)
+ put(sign)
+ while(--width >= 0)
+ put('0')
+ goto s_loop;
+ }
+ else
+ while(--width >= 0)
+ put(' ')
+ }
+ if (alt == 2)
+ put('0')
+ if (sign)
+ put(sign)
+ s_loop:
+ while(--prec >= 0)
+ put('0')
+ do put(*--s)
+ while(s > buf);
+ continue;
+ case 'n':
+ ip = va_arg(ap, intptr_t);
+ if (!ip)
+ ip = (intptr_t) &Ltmp;
+ c = outbuf - ob0 + rv;
+ switch(len) {
+ case LEN_I:
+#if !INT_IS_LONG
+ *(int*)ip = c;
+ break;
+#endif
+ case LEN_L:
+ *(long*)ip = c;
+ break;
+ case LEN_S:
+ *(short*)ip = c;
+ case LEN_LL:
+ *(long long*) ip = c;
+ break;
+ }
+ break;
+ case 'p':
+ alt = 1;
+ len = sizeof (intptr_t) == sizeof (long long)
+ ? LEN_LL : LEN_L;
+ /* no break */
+ case 'x':
+ digits = hex;
+ goto more_x;
+ case 'X':
+ digits = Hex;
+ more_x:
+ if (alt) {
+ alt = 2;
+ sign = conv;
+ }
+ else
+ sign = 0;
+ base = 16;
+ get_u:
+ switch(len) {
+ case LEN_I:
+#if !INT_IS_LONG
+ ui = va_arg(ap, int);
+ u = ui;
+ break;
+#endif
+ case LEN_L:
+ ui = va_arg(ap, long);
+ u = ui;
+ break;
+ case LEN_S:
+ us = va_arg(ap, long);
+ u = us;
+ break;
+ case LEN_LL:
+ u = va_arg(ap, long long);
+ }
+ if (!u)
+ sign = alt = 0;
+ goto baseloop;
+ case 'o':
+ base = 8;
+ digits = hex;
+ goto get_u;
+ case 's':
+/* %ls (for wctombs conversion) is not implemented. */
+ s0 = 0;
+ s = va_arg(ap, char*);
+ if (!s)
+ s = "<NULL>";
+ if (prec < 0)
+ prec = 0;
+ have_s:
+ if (dot) {
+ for(c = 0; c < prec; c++)
+ if (!s[c])
+ break;
+ prec = c;
+ }
+ else
+ prec = strlen(s);
+ width -= prec;
+ if (!left)
+ while(--width >= 0)
+ put(' ')
+ while(--prec >= 0)
+ put(*s++)
+ while(--width >= 0)
+ put(' ')
+ if (s0)
+ __freedtoa(s0);
+ continue;
+ case 'f':
+ if (!dot)
+ prec = 6;
+ if (flag_ld)
+ xx = va_arg(ap, long double);
+ else
+ {
+ x = va_arg(ap, double);
+ xx = x;
+ }
+
+ s = s0 = __ldtoa(xx, 3, prec, &decpt, &sgn, &se);
+ if (decpt == -32768) {
+ fmt9999:
+ dot = prec = alt = 0;
+ if (*s == 'N' || *s == 'I')
+ goto have_s;
+ decpt = strlen(s);
+ }
+ f_fmt:
+ if (sgn && (xx||sign))
+ sign = '-';
+ if (prec > 0)
+ width -= prec;
+ if (width > 0) {
+ if (sign)
+ --width;
+ if (decpt <= 0) {
+ --width;
+ if (prec > 0)
+ --width;
+ }
+ else {
+ if (s == se)
+ decpt = 1;
+ width -= decpt;
+ if (prec > 0 || alt)
+ --width;
+ }
+ }
+ if (width > 0 && !left) {
+ if (lead0) {
+ if (sign)
+ put(sign)
+ sign = 0;
+ do put('0')
+ while(--width > 0);
+ }
+ else do put(' ')
+ while(--width > 0);
+ }
+ if (sign)
+ put(sign)
+ if (decpt <= 0) {
+ put('0')
+ if (prec > 0 || alt)
+ put('.')
+ while(decpt < 0) {
+ put('0')
+ prec--;
+ decpt++;
+ }
+ }
+ else {
+ do {
+ if ((c = *s))
+ s++;
+ else
+ c = '0';
+ put(c)
+ }
+ while(--decpt > 0);
+ if (prec > 0 || alt)
+ put('.')
+ }
+ while(--prec >= 0) {
+ if ((c = *s))
+ s++;
+ else
+ c = '0';
+ put(c)
+ }
+ while(--width >= 0)
+ put(' ')
+ __freedtoa(s0);
+ continue;
+ case 'G':
+ case 'g':
+ if (!dot)
+ prec = 6;
+ if (flag_ld)
+ xx = va_arg(ap, long double);
+ else
+ {
+ x = va_arg(ap, double);
+ xx = x;
+ }
+ if (prec < 0)
+ prec = 0;
+ s = s0 = __ldtoa(xx, prec ? 2 : 0, prec, &decpt,
+ &sgn, &se);
+ if (decpt == -32768)
+ goto fmt9999;
+ c = se - s;
+ prec1 = prec;
+ if (!prec) {
+ prec = c;
+ prec1 = c + (s[1] || alt ? 5 : 4);
+ /* %.0g gives 10 rather than 1e1 */
+ }
+ if (decpt > -4 && decpt <= prec1) {
+ if (alt)
+ prec -= decpt;
+ else
+ prec = c - decpt;
+ if (prec < 0)
+ prec = 0;
+ goto f_fmt;
+ }
+ conv -= 2;
+ if (!alt && prec > c)
+ prec = c;
+ --prec;
+ goto e_fmt;
+ case 'e':
+ case 'E':
+ if (!dot)
+ prec = 6;
+ if (flag_ld)
+ xx = va_arg(ap, long double);
+ else
+ {
+ x = va_arg(ap, double);
+ xx = x;
+ }
+ if (prec < 0)
+ prec = 0;
+ s = s0 = __ldtoa(xx, prec ? 2 : 0, prec + 1, &decpt,
+ &sgn, &se);
+ if (decpt == -32768)
+ goto fmt9999;
+ e_fmt:
+ if (sgn && (xx||sign))
+ sign = '-';
+ if ((width -= prec + 5) > 0) {
+ if (sign)
+ --width;
+ if (prec || alt)
+ --width;
+ }
+
+ if ((c = --decpt) < 0)
+ c = -c;
+
+ while(c >= 100) {
+ --width;
+ c /= 10;
+ }
+ if (width > 0 && !left) {
+ if (lead0) {
+ if (sign)
+ put(sign)
+ sign = 0;
+ do put('0')
+ while(--width > 0);
+ }
+ else do put(' ')
+ while(--width > 0);
+ }
+ if (sign)
+ put(sign)
+ put(*s++)
+ if (prec || alt)
+ put('.')
+ while(--prec >= 0) {
+ if ((c = *s))
+ s++;
+ else
+ c = '0';
+ put(c)
+ }
+ put(conv)
+ if (decpt < 0) {
+ put('-')
+ decpt = -decpt;
+ }
+ else
+ put('+')
+ for(c = 2, k = 10; 10 * k <= decpt; c++, k *= 10);
+ for(;;) {
+ i1 = decpt / k;
+ put(i1 + '0')
+ if (--c <= 0)
+ break;
+ decpt -= i1*k;
+ decpt *= 10;
+ }
+ while(--width >= 0)
+ put(' ')
+ __freedtoa(s0);
+ continue;
+ default:
+ put('%')
+ while(fmt0 < fmt)
+ put(*fmt0++)
+ continue;
+ }
+ }
+ done:
+ *outbuf = 0;
+ return (f->lastlen = outbuf - ob0) + rv;
+ }
+
+#define Bsize 256
+#ifdef USE_FILE_OUTPUT
+ int
+Printf
+#ifdef KR_headers
+ (va_alist)
+ va_dcl
+{
+ char *fmt;
+
+ va_list ap;
+ int rv;
+ Finfo f;
+ char buf[Bsize];
+
+ va_start(ap);
+ fmt = va_arg(ap, char*);
+ /*}*/
+#else
+ (const char *fmt, ...)
+{
+ va_list ap;
+ int rv;
+ Finfo f;
+ char buf[Bsize];
+
+ va_start(ap, fmt);
+#endif
+ f.u.cf = stdout;
+ f.ob0 = buf;
+ f.obe1 = buf + Bsize - 1;
+#ifdef _windows_
+ if (fileno(stdout) == stdout_fileno_ASL) {
+ rv = x_sprintf(f.obe1, Wput, &f, fmt, ap);
+ mwrite(buf, f.lastlen);
+ }
+ else
+#endif
+#ifdef PF_BUF
+ if (stdout == stderr_ASL) {
+ rv = x_sprintf(f.obe1, pfput, &f, fmt, ap);
+ pf_put(buf, f.lastlen);
+ }
+ else
+#endif /* PF_BUF */
+ {
+ rv = x_sprintf(f.obe1, Fput, &f, fmt, ap);
+ fputs(buf, stdout);
+ }
+ va_end(ap);
+ return rv;
+ }
+
+ static char *
+Sput
+#ifdef KR_headers
+ (f, rvp) Finfo *f; int *rvp;
+#else
+ (Finfo *f, int *rvp)
+#endif
+{
+ if (Printf("\nBUG! Sput called!\n", f, rvp))
+ /* pass vp, rvp and return 0 to shut diagnostics off */
+ exit(250);
+ return 0;
+ }
+
+ int
+Sprintf
+#ifdef KR_headers
+ (va_alist)
+ va_dcl
+{
+ char *s, *fmt;
+ va_list ap;
+ int rv;
+ Finfo f;
+
+ va_start(ap);
+ s = va_arg(ap, char*);
+ fmt = va_arg(ap, char*);
+ /*}*/
+#else
+ (char *s, const char *fmt, ...)
+{
+ va_list ap;
+ int rv;
+ Finfo f;
+
+ va_start(ap, fmt);
+#endif
+ f.ob0 = s;
+ rv = x_sprintf(s, Sput, &f, fmt, ap);
+ va_end(ap);
+ return rv;
+ }
+
+int
+Fprintf
+#ifdef KR_headers
+ (va_alist)
+ va_dcl
+{
+ FILE *F;
+ char *s, *fmt;
+ va_list ap;
+ int rv;
+ Finfo f;
+ char buf[Bsize];
+
+ va_start(ap);
+ F = va_arg(ap, FILE*);
+ fmt = va_arg(ap, char*);
+ /*}*/
+#else
+ (FILE *F, const char *fmt, ...)
+{
+ va_list ap;
+ int rv;
+ Finfo f;
+ char buf[Bsize];
+
+ va_start(ap, fmt);
+#endif
+ f.u.cf = F;
+ f.ob0 = buf;
+ f.obe1 = buf + Bsize - 1;
+#ifdef MESS
+ if (stdout_or_err(F)) {
+#ifdef _windows_
+ if (fileno(stdout) == stdout_fileno_ASL) {
+ rv = x_sprintf(f.obe1, Wput, &f, fmt, ap);
+ mwrite(buf, f.lastlen);
+ }
+ else
+#endif
+#ifdef PF_BUF
+ if (F == stderr_ASL) {
+ rv = x_sprintf(f.obe1, pfput, &f, fmt, ap);
+ pf_put(buf, f.lastlen);
+ }
+ else
+#endif
+ {
+ rv = x_sprintf(f.obe1, Fput, &f, fmt, ap);
+ fputs(buf, F);
+ }
+ }
+ else
+#endif /*MESS*/
+ {
+#ifdef PF_BUF
+ if (F == stderr_ASL) {
+ rv = x_sprintf(f.obe1, pfput, &f, fmt, ap);
+ pf_put(buf, f.lastlen);
+ }
+ else
+#endif
+ {
+ rv = x_sprintf(f.obe1, Fput, &f, fmt, ap);
+ fputs(buf, F);
+ }
+ }
+ va_end(ap);
+ return rv;
+ }
+
+ int
+Vsprintf
+#ifdef KR_headers
+ (s, fmt, ap) char *s, *fmt; va_list ap;
+#else
+ (char *s, const char *fmt, va_list ap)
+#endif
+{
+ Finfo f;
+ return x_sprintf(f.ob0 = s, Sput, &f, fmt, ap);
+ }
+
+ int
+Vfprintf
+#ifdef KR_headers
+ (F, fmt, ap) FILE *F; char *fmt; va_list ap;
+#else
+ (FILE *F, const char *fmt, va_list ap)
+#endif
+{
+ char buf[Bsize];
+ int rv;
+ Finfo f;
+
+ f.u.cf = F;
+ f.ob0 = buf;
+ f.obe1 = buf + Bsize - 1;
+#ifdef MESS
+ if (stdout_or_err(F)) {
+#ifdef _windows_
+ if (fileno(stdout) == stdout_fileno_ASL) {
+ rv = x_sprintf(f.obe1, Wput, &f, fmt, ap);
+ mwrite(buf, f.lastlen);
+ }
+ else
+#endif
+#ifdef PF_BUF
+ if (F == stderr_ASL) {
+ rv = x_sprintf(f.obe1, pfput, &f, fmt, ap);
+ pf_put(buf, f.lastlen);
+ }
+ else
+#endif
+ {
+ rv = x_sprintf(f.obe1, Fput, &f, fmt, ap);
+ fputs(buf, F);
+ }
+ }
+ else
+#endif /*MESS*/
+ {
+#ifdef PF_BUF
+ if (F == stderr_ASL) {
+ rv = x_sprintf(f.obe1, pfput, &f, fmt, ap);
+ pf_put(buf, f.lastlen);
+ }
+ else
+#endif
+ {
+ rv = x_sprintf(f.obe1, Fput, &f, fmt, ap);
+ fputs(buf, F);
+ }
+ }
+ va_end(ap);
+ return rv;
+ }
+
+ void
+Perror
+#ifdef KR_headers
+ (s) char *s;
+#else
+ (const char *s)
+#endif
+{
+ if (s && *s)
+ fprintf(Stderr, "%s: ", s);
+ fprintf(Stderr, "%s\n", strerror(errno));
+ }
+#endif /* USE_FILE_OUTPUT */
+
+
+ static char *
+Snput
+#ifdef KR_headers
+ (f, rvp) Finfo *f; int *rvp;
+#else
+ (Finfo *f, int *rvp)
+#endif
+{
+ char *s, *s0;
+ size_t L;
+
+ *rvp += Bsize;
+ s0 = f->ob0;
+ s = f->u.sf;
+ if ((L = f->obe1 - s) > Bsize) {
+ L = Bsize;
+ goto copy;
+ }
+ if (L > 0) {
+ copy:
+ memcpy(s, s0, L);
+ f->u.sf = s + L;
+ }
+ return s0;
+ }
+
+
+ int
+Vsnprintf
+#ifdef KR_headers
+ (s, n, fmt, ap) char *s; size_t n; char *fmt; va_list ap;
+#else
+ (char *s, size_t n, const char *fmt, va_list ap)
+#endif
+{
+ Finfo f;
+ char buf[Bsize];
+ int L, rv;
+
+ if (n <= 0 || !s) {
+ n = 1;
+ s = buf;
+ }
+ f.u.sf = s;
+ f.ob0 = buf;
+ f.obe1 = s + n - 1;
+ rv = x_sprintf(buf + Bsize, Snput, &f, fmt, ap);
+ if (f.lastlen > (L = f.obe1 - f.u.sf))
+ f.lastlen = L;
+ if (f.lastlen > 0) {
+ memcpy(f.u.sf, buf, f.lastlen);
+ f.u.sf += f.lastlen;
+ }
+ *f.u.sf = 0;
+ return rv;
+ }
+ int
+Snprintf
+#ifdef KR_headers
+ (va_alist)
+ va_dcl
+{
+ char *s, *fmt;
+ int rv;
+ size_t n;
+ va_list ap;
+
+ va_start(ap);
+ s = va_arg(ap, char*);
+ n = va_arg(ap, size_t);
+ fmt = va_arg(ap, char*);
+ /*}*/
+#else
+ (char *s, size_t n, const char *fmt, ...)
+{
+ int rv;
+ va_list ap;
+
+ va_start(ap, fmt);
+#endif
+ rv = Vsnprintf(s, n, fmt, ap);
+ va_end(ap);
+ return rv;
+ }
+
+
+#if (EXPORT_WEAK_SNPRINTF_ALIAS)
+int __cdecl snprintf(char*, size_t, const char* , ...) __attribute__ ((weak, alias ("__mingw_snprintf")));
+int __cdecl vsnprintf (char*, size_t n, const char*, __gnuc_va_list) __attribute__ ((weak, alias ("__mingw_vsnprintf")));
+#endif
+