OSDN Git Service

* mingwex/gdtoa/mingw_snprintf.c: New file.
authordannysmith <dannysmith>
Fri, 29 Jun 2007 10:11:57 +0000 (10:11 +0000)
committerdannysmith <dannysmith>
Fri, 29 Jun 2007 10:11:57 +0000 (10:11 +0000)
* mingwex/Makefile.in (GDTOA_DISTFILES): Add mingw_snprintf.c.
(GDTOA_OBJS): Add mingw_snprintf.O.

winsup/mingw/ChangeLog
winsup/mingw/mingwex/Makefile.in
winsup/mingw/mingwex/gdtoa/mingw_snprintf.c [new file with mode: 0755]

index bcf57c3..264940f 100644 (file)
@@ -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.
index 3471c24..bc5db21 100644 (file)
@@ -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 (executable)
index 0000000..cb827bf
--- /dev/null
@@ -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
+