d46b2d9c83e481d5655da9a794e31cd1766efd37
[platform/upstream/bash.git] / lib / sh / snprintf.c
1 /* snprintf - formatted output to strings, with bounds checking and allocation */
2
3 /*
4  build a test version with
5    gcc -g -DDRIVER -I../.. -I../../include -o test-snprintf snprintf.c fmtu*long.o
6 */
7  
8 /*
9    Unix snprintf implementation.
10    derived from inetutils/libinetutils/snprintf.c Version 1.1
11
12    Copyright (C) 2001,2006,2010 Free Software Foundation, Inc.
13
14    This file is part of GNU Bash, the Bourne Again SHell.
15
16    Bash is free software: you can redistribute it and/or modify
17    it under the terms of the GNU General Public License as published by
18    the Free Software Foundation, either version 3 of the License, or
19    (at your option) any later version.
20
21    Bash is distributed in the hope that it will be useful,
22    but WITHOUT ANY WARRANTY; without even the implied warranty of
23    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24    GNU General Public License for more details.
25
26    You should have received a copy of the GNU General Public License
27    along with Bash.  If not, see <http://www.gnu.org/licenses/>.
28    
29    Revision History:
30
31    1.1:
32       *  added changes from Miles Bader
33       *  corrected a bug with %f
34       *  added support for %#g
35       *  added more comments :-)
36    1.0:
37       *  supporting must ANSI syntaxic_sugars
38    0.0:
39       *  support %s %c %d
40
41  THANKS(for the patches and ideas):
42      Miles Bader
43      Cyrille Rustom
44      Jacek Slabocewiz
45      Mike Parker(mouse)
46
47 */
48
49 /*
50  * Currently doesn't handle (and bash/readline doesn't use):
51  *      * *M$ width, precision specifications
52  *      * %N$ numbered argument conversions
53  *      * inf, nan floating values imperfect (if isinf(), isnan() not in libc)
54  *      * support for `F' is imperfect with ldfallback(), since underlying
55  *        printf may not handle it -- should ideally have another autoconf test
56  */
57
58 #define FLOATING_POINT
59
60 #ifdef HAVE_CONFIG_H
61 #  include <config.h>
62 #endif
63
64 /* GCC 4.2 on Snow Leopard doesn't like the snprintf prototype */
65 #if defined(DEBUG) && !defined (MACOSX)
66 #  undef HAVE_SNPRINTF
67 #  undef HAVE_ASPRINTF
68
69 #  define HAVE_SNPRINTF 0
70 #  define HAVE_ASPRINTF 0
71 #endif
72
73 #if defined(DRIVER) && !defined(HAVE_CONFIG_H)
74 #define HAVE_LONG_LONG
75 #define HAVE_LONG_DOUBLE
76 #ifdef __linux__
77 #define HAVE_PRINTF_A_FORMAT
78 #endif
79 #define HAVE_ISINF_IN_LIBC
80 #define HAVE_ISNAN_IN_LIBC
81 #define PREFER_STDARG
82 #define HAVE_STRINGIZE
83 #define HAVE_LIMITS_H
84 #define HAVE_STDDEF_H
85 #define HAVE_LOCALE_H
86 #define intmax_t long
87 #endif
88
89 #if !HAVE_SNPRINTF || !HAVE_ASPRINTF
90
91 #include <bashtypes.h>
92
93 #if defined(PREFER_STDARG)
94 #  include <stdarg.h>
95 #else
96 #  include <varargs.h>
97 #endif
98
99 #ifdef HAVE_LIMITS_H
100 #  include <limits.h>
101 #endif
102 #include <bashansi.h>
103 #ifdef HAVE_STDDEF_H
104 #  include <stddef.h>
105 #endif
106 #include <chartypes.h>
107
108 #ifdef HAVE_STDINT_H
109 #  include <stdint.h>
110 #endif
111
112 #ifdef FLOATING_POINT
113 #  include <float.h>    /* for manifest constants */
114 #  include <stdio.h>    /* for sprintf */
115 #endif
116
117 #include <typemax.h>
118
119 #ifdef HAVE_LOCALE_H
120 #  include <locale.h>
121 #endif
122
123 #include "stdc.h"
124 #include <shmbutil.h>
125
126 #ifndef DRIVER
127 #  include "shell.h"
128 #else
129 #  define FL_PREFIX     0x01    /* add 0x, 0X, or 0 prefix as appropriate */
130 #  define FL_ADDBASE    0x02    /* add base# prefix to converted value */
131 #  define FL_HEXUPPER   0x04    /* use uppercase when converting to hex */
132 #  define FL_UNSIGNED   0x08    /* don't add any sign */
133 extern char *fmtulong __P((unsigned long int, int, char *, size_t, int));
134 extern char *fmtullong __P((unsigned long long int, int, char *, size_t, int));
135 #endif
136
137 #ifndef FREE
138 #  define FREE(x)       if (x) free (x)
139 #endif
140
141 /* Bound on length of the string representing an integer value of type T.
142    Subtract one for the sign bit if T is signed;
143    302 / 1000 is log10 (2) rounded up;
144    add one for integer division truncation;
145    add one more for a minus sign if t is signed.  */
146 #define INT_STRLEN_BOUND(t) \
147   ((sizeof (t) * CHAR_BIT - TYPE_SIGNED (t)) * 302 / 1000 \
148      + 1 + TYPE_SIGNED (t))
149
150 /* conversion flags */
151 #define PF_ALTFORM      0x00001         /* # */
152 #define PF_HEXPREFIX    0x00002         /* 0[Xx] */
153 #define PF_LADJUST      0x00004         /* - */
154 #define PF_ZEROPAD      0x00008         /* 0 */
155 #define PF_PLUS         0x00010         /* + */
156 #define PF_SPACE        0x00020         /* ' ' */
157 #define PF_THOUSANDS    0x00040         /* ' */
158
159 #define PF_DOT          0x00080         /* `.precision' */
160 #define PF_STAR_P       0x00100         /* `*' after precision */
161 #define PF_STAR_W       0x00200         /* `*' before or without precision */
162
163 /* length modifiers */
164 #define PF_SIGNEDCHAR   0x00400         /* hh */
165 #define PF_SHORTINT     0x00800         /* h */
166 #define PF_LONGINT      0x01000         /* l */
167 #define PF_LONGLONG     0x02000         /* ll */
168 #define PF_LONGDBL      0x04000         /* L */
169 #define PF_INTMAX_T     0x08000         /* j */
170 #define PF_SIZE_T       0x10000         /* z */
171 #define PF_PTRDIFF_T    0x20000         /* t */
172
173 #define PF_ALLOCBUF     0x40000         /* for asprintf, vasprintf */
174
175 #define PFM_SN          0x01            /* snprintf, vsnprintf */
176 #define PFM_AS          0x02            /* asprintf, vasprintf */
177
178 #define ASBUFSIZE       128
179
180 #define x_digs  "0123456789abcdef"
181 #define X_digs  "0123456789ABCDEF"
182
183 static char intbuf[INT_STRLEN_BOUND(unsigned long) + 1];
184
185 static int decpoint;
186 static int thoussep;
187 static char *grouping;
188
189 /* 
190  * For the FLOATING POINT FORMAT :
191  *  the challenge was finding a way to
192  *  manipulate the Real numbers without having
193  *  to resort to mathematical function(it
194  *  would require to link with -lm) and not
195  *  going down to the bit pattern(not portable)
196  *
197  *  so a number, a real is:
198
199       real = integral + fraction
200
201       integral = ... + a(2)*10^2 + a(1)*10^1 + a(0)*10^0
202       fraction = b(1)*10^-1 + b(2)*10^-2 + ...
203
204       where:
205        0 <= a(i) => 9 
206        0 <= b(i) => 9 
207  
208     from then it was simple math
209  */
210
211 /*
212  * size of the buffer for the integral part
213  * and the fraction part 
214  */
215 #define MAX_INT  99 + 1 /* 1 for the null */
216 #define MAX_FRACT 307 + 1
217
218 /* 
219  * These functions use static buffers to store the results,
220  * and so are not reentrant
221  */
222 #define itoa(n) fmtulong(n, 10, intbuf, sizeof(intbuf), 0);
223 #define dtoa(n, p, f) numtoa(n, 10, p, f)
224
225 #define SWAP_INT(a,b) {int t; t = (a); (a) = (b); (b) = t;}
226
227 #define GETARG(type)    (va_arg(args, type))
228
229 /* Macros that do proper sign extension and handle length modifiers.  Used
230    for the integer conversion specifiers. */
231 #define GETSIGNED(p) \
232   (((p)->flags & PF_LONGINT) \
233         ? GETARG (long) \
234         : (((p)->flags & PF_SHORTINT) ? (long)(short)GETARG (int) \
235                                       : (long)GETARG (int)))
236
237 #define GETUNSIGNED(p) \
238   (((p)->flags & PF_LONGINT) \
239         ? GETARG (unsigned long) \
240         : (((p)->flags & PF_SHORTINT) ? (unsigned long)(unsigned short)GETARG (int) \
241                                       : (unsigned long)GETARG (unsigned int)))
242
243
244 #ifdef HAVE_LONG_DOUBLE
245 #define GETLDOUBLE(p) GETARG (long double)
246 #endif
247 #define GETDOUBLE(p) GETARG (double)
248
249 #define SET_SIZE_FLAGS(p, type) \
250   if (sizeof (type) > sizeof (int)) \
251     (p)->flags |= PF_LONGINT; \
252   if (sizeof (type) > sizeof (long)) \
253     (p)->flags |= PF_LONGLONG;
254
255 /* this struct holds everything we need */
256 struct DATA
257 {
258   int length;
259   char *base;           /* needed for [v]asprintf */
260   char *holder;
261   int counter;
262   const char *pf;
263
264 /* FLAGS */
265   int flags;
266   int justify;
267   int width, precision;
268   char pad;
269 };
270
271 /* the floating point stuff */
272 #ifdef FLOATING_POINT
273 static double pow_10 __P((int));
274 static int log_10 __P((double));
275 static double integral __P((double, double *));
276 static char *numtoa __P((double, int, int, char **));
277 #endif
278
279 static void init_data __P((struct DATA *, char *, size_t, const char *, int));
280 static void init_conv_flag __P((struct DATA *));
281
282 /* for the format */
283 #ifdef FLOATING_POINT
284 static void floating __P((struct DATA *, double));
285 static void exponent __P((struct DATA *, double));
286 #endif
287 static void number __P((struct DATA *, unsigned long, int));
288 #ifdef HAVE_LONG_LONG
289 static void lnumber __P((struct DATA *, unsigned long long, int));
290 #endif
291 static void pointer __P((struct DATA *, unsigned long));
292 static void strings __P((struct DATA *, char *));
293
294 #ifdef FLOATING_POINT
295 #  define FALLBACK_FMTSIZE      32
296 #  define FALLBACK_BASE         4096
297 #  define LFALLBACK_BASE        5120
298 #  ifdef HAVE_LONG_DOUBLE
299 static void ldfallback __P((struct DATA *, const char *, const char *, long double));
300 #  endif
301 static void dfallback __P((struct DATA *, const char *, const char *, double));
302 #endif
303
304 static char *groupnum __P((char *));
305
306 #ifndef HAVE_ISINF_IN_LIBC
307 static int isinf __P((double));
308 #endif
309 #ifndef HAVE_ISNAN_IN_LIBC
310 static int isnan __P((double));
311 #endif
312
313 #ifdef DRIVER
314 static void memory_error_and_abort ();
315 static void *xmalloc __P((size_t));
316 static void *xrealloc __P((void *, size_t));
317 static void xfree __P((void *));
318 #else
319 #  include <xmalloc.h>
320 #endif
321
322 /* those are defines specific to snprintf to hopefully
323  * make the code clearer :-)
324  */
325 #define RIGHT 1
326 #define LEFT  0
327 #define NOT_FOUND -1
328 #define FOUND 1
329 #define MAX_FIELD 15
330
331 /* round off to the precision */
332 #define ROUND(d, p) \
333             (d < 0.) ? \
334              d - pow_10(-(p)->precision) * 0.5 : \
335              d + pow_10(-(p)->precision) * 0.5
336
337 /* set default precision */
338 #define DEF_PREC(p) \
339             if ((p)->precision == NOT_FOUND) \
340               (p)->precision = 6
341
342 /* put a char.  increment the number of chars written even if we've exceeded
343    the vsnprintf/snprintf buffer size (for the return value) */
344 #define PUT_CHAR(c, p) \
345         do \
346           { \
347             if (((p)->flags & PF_ALLOCBUF) && ((p)->counter >= (p)->length - 1)) \
348               { \
349                 (p)->length += ASBUFSIZE; \
350                 (p)->base = (char *)xrealloc((p)->base, (p)->length); \
351                 (p)->holder = (p)->base + (p)->counter; /* in case reallocated */ \
352               } \
353             if ((p)->counter < (p)->length) \
354               *(p)->holder++ = (c); \
355             (p)->counter++; \
356           } \
357         while (0)
358
359 /* Output a string.  P->WIDTH has already been adjusted for padding. */
360 #define PUT_STRING(string, len, p) \
361         do \
362           { \
363             PAD_RIGHT (p); \
364             while ((len)-- > 0) \
365               { \
366                 PUT_CHAR (*(string), (p)); \
367                 (string)++; \
368               } \
369             PAD_LEFT (p); \
370           } \
371         while (0)
372
373 #define PUT_PLUS(d, p, zero) \
374             if ((d) > zero && (p)->justify == RIGHT) \
375               PUT_CHAR('+', p)
376
377 #define PUT_SPACE(d, p, zero) \
378             if (((p)->flags & PF_SPACE) && (d) > zero) \
379               PUT_CHAR(' ', p)
380
381 /* pad right */ 
382 #define PAD_RIGHT(p) \
383             if ((p)->width > 0 && (p)->justify != LEFT) \
384               for (; (p)->width > 0; (p)->width--) \
385                  PUT_CHAR((p)->pad, p)
386
387 /* pad left */
388 #define PAD_LEFT(p) \
389             if ((p)->width > 0 && (p)->justify == LEFT) \
390               for (; (p)->width > 0; (p)->width--) \
391                  PUT_CHAR((p)->pad, p)
392
393 /* pad with zeros from decimal precision */
394 #define PAD_ZERO(p) \
395         if ((p)->precision > 0) \
396           for (; (p)->precision > 0; (p)->precision--) \
397             PUT_CHAR('0', p)
398
399 /* if width and prec. in the args */
400 #define STAR_ARGS(p) \
401         do { \
402             if ((p)->flags & PF_STAR_W) \
403               { \
404                 (p)->width = GETARG (int); \
405                 if ((p)->width < 0) \
406                   { \
407                     (p)->flags |= PF_LADJUST; \
408                     (p)->justify = LEFT; \
409                     (p)->width = -(p)->width; \
410                   } \
411               } \
412             if ((p)->flags & PF_STAR_P) \
413               { \
414                 (p)->precision = GETARG (int); \
415                 if ((p)->precision < 0) \
416                   { \
417                     (p)->flags &= ~PF_STAR_P; \
418                     (p)->precision = NOT_FOUND; \
419                   } \
420               } \
421         } while (0)
422
423 #if defined (HAVE_LOCALE_H) && defined (HAVE_LOCALECONV)
424 #  define GETLOCALEDATA(d, t, g) \
425       do \
426         { \
427           struct lconv *lv; \
428           if ((d) == 0) { \
429           (d) = '.'; (t) = -1; (g) = 0; /* defaults */ \
430           lv = localeconv(); \
431           if (lv) \
432             { \
433               if (lv->decimal_point && lv->decimal_point[0]) \
434                 (d) = lv->decimal_point[0]; \
435               if (lv->thousands_sep && lv->thousands_sep[0]) \
436                 (t) = lv->thousands_sep[0]; \
437               (g) = lv->grouping ? lv->grouping : ""; \
438               if (*(g) == '\0' || *(g) == CHAR_MAX || (t) == -1) (g) = 0; \
439             } \
440           } \
441         } \
442       while (0);
443 #else
444 #  define GETLOCALEDATA(d, t, g) \
445       ( (d) = '.', (t) = ',', g = "\003" )
446 #endif
447
448 #ifdef FLOATING_POINT
449 /*
450  * Find the nth power of 10
451  */
452 static double
453 pow_10(n)
454      int n;
455
456   double P;
457
458   /* handle common cases with fast switch statement. */
459   switch (n)
460     {
461     case -3:    return .001;
462     case -2:    return .01;
463     case -1:    return .1;
464     case 0:     return 1.;
465     case 1:     return 10.;
466     case 2:     return 100.;
467     case 3:     return 1000.;
468     }
469
470   if (n < 0)
471     {
472       P = .0001;
473       for (n += 4; n < 0; n++)
474         P /= 10.;
475     }
476   else
477     {
478       P = 10000.;
479       for (n -= 4; n > 0; n--)
480         P *= 10.;
481     }
482
483   return P;
484 }
485
486 /*
487  * Find the integral part of the log in base 10 
488  * Note: this not a real log10()
489          I just need and approximation(integerpart) of x in:
490           10^x ~= r
491  * log_10(200) = 2;
492  * log_10(250) = 2;
493  *
494  * NOTE: do not call this with r == 0 -- an infinite loop results.
495  */
496 static int
497 log_10(r)
498      double r;
499
500   int i = 0;
501   double result = 1.;
502
503   if (r < 0.)
504     r = -r;
505
506   if (r < 1.)
507     {
508       while (result >= r)
509         {
510           result /= 10.;
511           i++;
512         }
513       return (-i);
514     }
515   else
516     {
517       while (result <= r)
518         {
519           result *= 10.;
520           i++;
521         }
522       return (i - 1);
523     }
524 }
525
526 /*
527  * This function return the fraction part of a double
528  * and set in ip the integral part.
529  * In many ways it resemble the modf() found on most Un*x
530  */
531 static double
532 integral(real, ip)
533      double real;
534      double *ip;
535
536   int j;
537   double i, s, p;
538   double real_integral = 0.;
539
540   /* take care of the obvious */
541   /* equal to zero ? */
542   if (real == 0.)
543     {
544       *ip = 0.;
545       return (0.);
546     }
547
548   /* negative number ? */
549   if (real < 0.)
550     real = -real;
551
552   /* a fraction ? */
553   if ( real < 1.)
554     {
555       *ip = 0.;
556       return real;
557     }
558
559   /* the real work :-) */
560   for (j = log_10(real); j >= 0; j--)
561     {
562       p = pow_10(j);
563       s = (real - real_integral)/p;
564       i = 0.;
565       while (i + 1. <= s)
566         i++;
567       real_integral += i*p;
568     }
569   *ip = real_integral;
570   return (real - real_integral);
571 }
572
573 #define PRECISION 1.e-6
574 /* 
575  * return an ascii representation of the integral part of the number
576  * and set fract to be an ascii representation of the fraction part
577  * the container for the fraction and the integral part or staticly
578  * declare with fix size 
579  */
580 static char *
581 numtoa(number, base, precision, fract)
582      double number;
583      int base, precision;
584      char **fract;
585 {
586   register int i, j;
587   double ip, fp; /* integer and fraction part */
588   double fraction;
589   int digits = MAX_INT - 1;
590   static char integral_part[MAX_INT];
591   static char fraction_part[MAX_FRACT];
592   double sign;
593   int ch;
594
595   /* taking care of the obvious case: 0.0 */
596   if (number == 0.)
597     { 
598       integral_part[0] = '0';
599       integral_part[1] = '\0';
600       /* The fractional part has to take the precision into account */
601       for (ch = 0; ch < precision-1; ch++)
602         fraction_part[ch] = '0';
603       fraction_part[ch] = '0';
604       fraction_part[ch+1] = '\0';
605       if (fract)
606         *fract = fraction_part;
607       return integral_part;
608     }
609
610   /* for negative numbers */
611   if ((sign = number) < 0.)
612     {
613       number = -number;
614       digits--; /* sign consume one digit */
615     }
616
617   fraction = integral(number, &ip);
618   number = ip;
619
620   /* do the integral part */
621   if (ip == 0.)
622     {
623       integral_part[0] = '0';
624       i = 1;
625     }
626   else
627     {
628       for ( i = 0; i < digits && number != 0.; ++i)
629         {
630           number /= base;
631           fp = integral(number, &ip);
632           ch = (int)((fp + PRECISION)*base); /* force to round */
633           integral_part[i] = (ch <= 9) ? ch + '0' : ch + 'a' - 10;
634           if (! ISXDIGIT((unsigned char)integral_part[i]))
635             break;      /* bail out overflow !! */
636           number = ip;
637          }
638     }
639      
640   /* Oh No !! out of bound, ho well fill it up ! */
641   if (number != 0.)
642     for (i = 0; i < digits; ++i)
643       integral_part[i] = '9';
644
645   /* put the sign ? */
646   if (sign < 0.)
647     integral_part[i++] = '-';
648
649   integral_part[i] = '\0';
650
651   /* reverse every thing */
652   for ( i--, j = 0; j < i; j++, i--)
653     SWAP_INT(integral_part[i], integral_part[j]);  
654
655   /* the fractional part */
656   for (i=0, fp=fraction; precision > 0 && i < MAX_FRACT ; i++, precision--)
657     {
658       fraction_part[i] = (int)((fp + PRECISION)*10. + '0');
659       if (! DIGIT(fraction_part[i])) /* underflow ? */
660         break;
661       fp = (fp*10.0) - (double)(long)((fp + PRECISION)*10.);
662     }
663   fraction_part[i] = '\0';
664
665   if (fract != (char **)0)
666     *fract = fraction_part;
667
668   return integral_part;
669 }
670 #endif
671
672 /* for %d and friends, it puts in holder
673  * the representation with the right padding
674  */
675 static void
676 number(p, d, base)
677      struct DATA *p;
678      unsigned long d;
679      int base;
680 {
681   char *tmp, *t;
682   long sd;
683   int flags;
684
685   /* An explicit precision turns off the zero-padding flag. */
686   if ((p->flags & PF_ZEROPAD) && p->precision >= 0 && (p->flags & PF_DOT))
687     p->flags &= ~PF_ZEROPAD;
688
689   sd = d;       /* signed for ' ' padding in base 10 */
690   flags = 0;
691   flags = (*p->pf == 'x' || *p->pf == 'X' || *p->pf == 'o' || *p->pf == 'u' || *p->pf == 'U') ? FL_UNSIGNED : 0;
692   if (*p->pf == 'X')
693     flags |= FL_HEXUPPER;
694
695   tmp = fmtulong (d, base, intbuf, sizeof(intbuf), flags);
696   t = 0;
697   if ((p->flags & PF_THOUSANDS))
698     {
699       GETLOCALEDATA(decpoint, thoussep, grouping);
700       if (grouping && (t = groupnum (tmp)))
701         tmp = t;
702     }
703
704   p->width -= strlen(tmp);
705   PAD_RIGHT(p);
706
707   if ((p->flags & PF_DOT) && p->precision > 0)
708     {
709       p->precision -= strlen(tmp);
710       PAD_ZERO(p);
711     }
712
713   switch (base)
714     {
715     case 10:
716       PUT_PLUS(sd, p, 0);
717       PUT_SPACE(sd, p, 0);
718       break;
719     case 8:
720       if (p->flags & PF_ALTFORM)
721         PUT_CHAR('0', p);
722       break;
723     case 16:
724       if (p->flags & PF_ALTFORM)
725         {
726           PUT_CHAR('0', p);
727           PUT_CHAR(*p->pf, p);
728         }
729       break;
730     }
731
732   while (*tmp)
733     {
734       PUT_CHAR(*tmp, p);
735       tmp++;
736     }
737
738   PAD_LEFT(p);
739   FREE (t);
740 }
741
742 #ifdef HAVE_LONG_LONG
743 /*
744  * identical to number() but works for `long long'
745  */
746 static void
747 lnumber(p, d, base)
748      struct DATA *p;
749      unsigned long long d;
750      int base;
751 {
752   char *tmp, *t;
753   long long sd;
754   int flags;
755
756   /* An explicit precision turns off the zero-padding flag. */
757   if ((p->flags & PF_ZEROPAD) && p->precision >= 0 && (p->flags & PF_DOT))
758     p->flags &= ~PF_ZEROPAD;
759
760   sd = d;       /* signed for ' ' padding in base 10 */
761   flags = (*p->pf == 'x' || *p->pf == 'X' || *p->pf == 'o' || *p->pf == 'u' || *p->pf == 'U') ? FL_UNSIGNED : 0;
762   if (*p->pf == 'X')
763     flags |= FL_HEXUPPER;
764
765   tmp = fmtullong (d, base, intbuf, sizeof(intbuf), flags);
766   t = 0;
767   if ((p->flags & PF_THOUSANDS))
768     {
769       GETLOCALEDATA(decpoint, thoussep, grouping);
770       if (grouping && (t = groupnum (tmp)))
771         tmp = t;
772     }
773
774   p->width -= strlen(tmp);
775   PAD_RIGHT(p);
776
777   if ((p->flags & PF_DOT) && p->precision > 0)
778     {
779       p->precision -= strlen(tmp);
780       PAD_ZERO(p);
781     }
782
783   switch (base)
784     {
785     case 10:
786       PUT_PLUS(sd, p, 0);
787       PUT_SPACE(sd, p, 0);
788       break;
789     case 8:
790       if (p->flags & PF_ALTFORM)
791         PUT_CHAR('0', p);
792       break;
793     case 16:
794       if (p->flags & PF_ALTFORM)
795         {
796           PUT_CHAR('0', p);
797           PUT_CHAR(*p->pf, p);
798         }
799       break;
800     }
801
802   while (*tmp)
803     {
804       PUT_CHAR(*tmp, p);
805       tmp++;
806     }
807
808   PAD_LEFT(p);
809   FREE (t);
810 }
811 #endif
812
813 static void
814 pointer(p, d)
815      struct DATA *p;
816      unsigned long d;
817 {
818   char *tmp;
819
820   tmp = fmtulong(d, 16, intbuf, sizeof(intbuf), 0);
821   p->width -= strlen(tmp);
822   PAD_RIGHT(p);
823
824   /* prefix '0x' for pointers */
825   PUT_CHAR('0', p);
826   PUT_CHAR('x', p);
827
828   while (*tmp)
829     {
830       PUT_CHAR(*tmp, p);
831       tmp++;
832     }
833
834   PAD_LEFT(p);
835 }
836
837 /* %s strings */
838 static void
839 strings(p, tmp)
840      struct DATA *p;
841      char *tmp;
842 {
843   size_t len;
844
845   len = strlen(tmp);
846   if (p->precision != NOT_FOUND) /* the smallest number */
847     len = (len < p->precision ? len : p->precision);
848   p->width -= len;
849
850   PUT_STRING (tmp, len, p);
851 }
852
853 #if HANDLE_MULTIBYTE
854 /* %ls wide-character strings */
855 static void
856 wstrings(p, tmp)
857      struct DATA *p;
858      wchar_t *tmp;
859 {
860   size_t len;
861   mbstate_t mbs;
862   char *os;
863   const wchar_t *ws;
864
865   memset (&mbs, '\0', sizeof (mbstate_t));
866   ws = (const wchar_t *)tmp;
867
868   os = (char *)NULL;
869   if (p->precision != NOT_FOUND)
870     {
871       os = (char *)xmalloc (p->precision + 1);
872       len = wcsrtombs (os, &ws, p->precision, &mbs);
873     }
874   else
875     {
876       len = wcsrtombs (NULL, &ws, 0, &mbs);
877       if (len != (size_t)-1)
878         {
879           memset (&mbs, '\0', sizeof (mbstate_t));
880           os = (char *)xmalloc (len + 1);
881           (void)wcsrtombs (os, &ws, len + 1, &mbs);
882         }
883     }
884   if (len == (size_t)-1)
885     {
886       /* invalid multibyte sequence; bail now. */
887       FREE (os);      
888       return;
889     }
890
891   p->width -= len;
892   PUT_STRING (os, len, p);
893   free (os);
894 }
895
896 static void
897 wchars (p, wc)
898      struct DATA *p;
899      wint_t wc;
900 {
901   char *lbuf, *l;
902   mbstate_t mbs;
903   size_t len;
904
905   lbuf = (char *)malloc (MB_CUR_MAX+1);
906   if (lbuf == 0)
907     return;
908   memset (&mbs, '\0', sizeof (mbstate_t));
909   len = wcrtomb (lbuf, wc, &mbs);
910   if (len == (size_t)-1)
911     /* conversion failed; bail now. */
912     return;
913   p->width -= len;
914   l = lbuf;
915   PUT_STRING (l, len, p);
916   free (lbuf);
917 }
918 #endif /* HANDLE_MULTIBYTE */
919
920 #ifdef FLOATING_POINT
921
922 #ifndef HAVE_ISINF_IN_LIBC
923 /* Half-assed versions, since we don't want to link with libm. */
924 static int
925 isinf(d)
926      double d;
927 {
928 #ifdef DBL_MAX
929   if (d < DBL_MIN)
930     return -1;
931   else if (d > DBL_MAX)
932     return 1;
933   else
934 #endif
935     return 0;
936 }
937 #endif
938
939 #ifndef HAVE_ISNAN_IN_LIBC
940 static int
941 isnan(d)
942      double d;
943 {
944   return 0;
945 }
946 #endif
947
948 /* Check for [+-]infinity and NaN.  If MODE == 1, we check for Infinity, else
949    (mode == 2) we check for NaN.  This does the necessary printing.  Returns
950    1 if Inf or Nan, 0 if not. */
951 static int
952 chkinfnan(p, d, mode)
953      struct DATA *p;
954      double d;
955      int mode;          /* == 1 for inf, == 2 for nan */
956 {
957   int i;
958   char *tmp;
959   char *big, *small;
960
961   i = (mode == 1) ? isinf(d) : isnan(d);
962   if (i == 0)
963     return 0;
964   big = (mode == 1) ? "INF" : "NAN";
965   small = (mode == 1) ? "inf" : "nan";
966
967   tmp = (*p->pf == 'F' || *p->pf == 'G' || *p->pf == 'E') ? big : small;
968
969   if (i < 0)
970     PUT_CHAR('-', p);
971
972   while (*tmp)
973     {
974       PUT_CHAR (*tmp, p);
975       tmp++;
976     }
977
978   return 1;
979 }
980
981 /* %f %F %g %G floating point representation */
982 static void
983 floating(p, d)
984      struct DATA *p;
985      double d;
986 {
987   char *tmp, *tmp2, *t;
988   int i;
989
990   if (d != 0 && (chkinfnan(p, d, 1) || chkinfnan(p, d, 2)))
991     return;     /* already printed nan or inf */
992
993   GETLOCALEDATA(decpoint, thoussep, grouping);
994   DEF_PREC(p);
995   d = ROUND(d, p);
996   tmp = dtoa(d, p->precision, &tmp2);
997   t = 0;
998   if ((p->flags & PF_THOUSANDS) && grouping && (t = groupnum (tmp)))
999     tmp = t;
1000
1001   if ((*p->pf == 'g' || *p->pf == 'G') && (p->flags & PF_ALTFORM) == 0)
1002     {
1003       /* smash the trailing zeros unless altform */
1004       for (i = strlen(tmp2) - 1; i >= 0 && tmp2[i] == '0'; i--)
1005         tmp2[i] = '\0'; 
1006       if (tmp2[0] == '\0')
1007         p->precision = 0;
1008     }
1009
1010   /* calculate the padding. 1 for the dot */
1011   p->width = p->width -
1012             ((d > 0. && p->justify == RIGHT) ? 1:0) -
1013             ((p->flags & PF_SPACE) ? 1:0) -
1014             strlen(tmp) - p->precision -
1015             ((p->precision != 0 || (p->flags & PF_ALTFORM)) ? 1 : 0);   /* radix char */
1016   PAD_RIGHT(p);  
1017   PUT_PLUS(d, p, 0.);
1018   PUT_SPACE(d, p, 0.);
1019
1020   while (*tmp)
1021     {
1022       PUT_CHAR(*tmp, p);        /* the integral */
1023       tmp++;
1024     }
1025   FREE (t);
1026
1027   if (p->precision != 0 || (p->flags & PF_ALTFORM))
1028     PUT_CHAR(decpoint, p);  /* put the '.' */
1029
1030   for (; *tmp2; tmp2++)
1031     PUT_CHAR(*tmp2, p); /* the fraction */
1032   
1033   PAD_LEFT(p);
1034
1035
1036 /* %e %E %g %G exponent representation */
1037 static void
1038 exponent(p, d)
1039      struct DATA *p;
1040      double d;
1041 {
1042   char *tmp, *tmp2;
1043   int j, i;
1044
1045   if (d != 0 && (chkinfnan(p, d, 1) || chkinfnan(p, d, 2)))
1046     return;     /* already printed nan or inf */
1047
1048   GETLOCALEDATA(decpoint, thoussep, grouping);
1049   DEF_PREC(p);
1050   if (d == 0.)
1051     j = 0;
1052   else
1053     {
1054       j = log_10(d);
1055       d = d / pow_10(j);  /* get the Mantissa */
1056       d = ROUND(d, p);            
1057     }
1058   tmp = dtoa(d, p->precision, &tmp2);
1059
1060   /* 1 for unit, 1 for the '.', 1 for 'e|E',
1061    * 1 for '+|-', 2 for 'exp' */
1062   /* calculate how much padding need */
1063   p->width = p->width - 
1064              ((d > 0. && p->justify == RIGHT) ? 1:0) -
1065              ((p->flags & PF_SPACE) ? 1:0) - p->precision - 6;
1066
1067   PAD_RIGHT(p);
1068   PUT_PLUS(d, p, 0.);
1069   PUT_SPACE(d, p, 0.);
1070
1071   while (*tmp)
1072     {
1073       PUT_CHAR(*tmp, p);
1074       tmp++;
1075     }
1076
1077   if (p->precision != 0 || (p->flags & PF_ALTFORM))
1078       PUT_CHAR(decpoint, p);  /* the '.' */
1079
1080   if ((*p->pf == 'g' || *p->pf == 'G') && (p->flags & PF_ALTFORM) == 0)
1081     /* smash the trailing zeros unless altform */
1082     for (i = strlen(tmp2) - 1; i >= 0 && tmp2[i] == '0'; i--)
1083       tmp2[i] = '\0'; 
1084
1085   for (; *tmp2; tmp2++)
1086     PUT_CHAR(*tmp2, p); /* the fraction */
1087
1088   /* the exponent put the 'e|E' */
1089   if (*p->pf == 'g' || *p->pf == 'e')
1090     PUT_CHAR('e', p);
1091   else
1092     PUT_CHAR('E', p);
1093
1094   /* the sign of the exp */
1095   if (j >= 0)
1096     PUT_CHAR('+', p);
1097   else
1098     {
1099       PUT_CHAR('-', p);
1100       j = -j;
1101     }
1102
1103    tmp = itoa(j);
1104    /* pad out to at least two spaces.  pad with `0' if the exponent is a
1105       single digit. */
1106    if (j <= 9)
1107      PUT_CHAR('0', p);
1108
1109    /* the exponent */
1110    while (*tmp)
1111      {
1112        PUT_CHAR(*tmp, p);
1113        tmp++;
1114      }
1115
1116    PAD_LEFT(p);
1117 }
1118 #endif
1119
1120 /* Return a new string with the digits in S grouped according to the locale's
1121    grouping info and thousands separator.  If no grouping should be performed,
1122    this returns NULL; the caller needs to check for it. */
1123 static char *
1124 groupnum (s)
1125      char *s;
1126 {
1127   char *se, *ret, *re, *g;
1128   int len, slen;
1129
1130   if (grouping == 0 || *grouping <= 0 || *grouping == CHAR_MAX)
1131     return ((char *)NULL);
1132
1133   /* find min grouping to size returned string */
1134   for (len = *grouping, g = grouping; *g; g++)
1135       if (*g > 0 && *g < len)
1136         len = *g;
1137
1138   slen = strlen (s);
1139   len = slen / len + 1;
1140   ret = (char *)xmalloc (slen + len + 1);
1141   re = ret + slen + len;
1142   *re = '\0';
1143
1144   g = grouping;
1145   se = s + slen;
1146   len = *g;
1147
1148   while (se > s)
1149     {
1150       *--re = *--se;
1151
1152       /* handle `-' inserted by numtoa() and the fmtu* family here. */
1153       if (se > s && se[-1] == '-')
1154         continue;
1155
1156       /* begin new group. */
1157       if (--len == 0 && se > s)
1158         {
1159           *--re = thoussep;
1160           len = *++g;           /* was g++, but that uses first char twice (glibc bug, too) */
1161           if (*g == '\0')
1162             len = *--g;         /* use previous grouping */
1163           else if (*g == CHAR_MAX)
1164             {
1165               do
1166                 *--re = *--se;
1167               while (se > s);
1168               break;
1169             }
1170         }
1171     }
1172
1173   if (re > ret)
1174 #ifdef HAVE_MEMMOVE
1175     memmove (ret, re, strlen (re) + 1);
1176 #else
1177     strcpy (ret, re);
1178 #endif
1179    
1180   return ret;
1181 }
1182
1183 /* initialize the conversion specifiers */
1184 static void
1185 init_conv_flag (p)
1186      struct DATA *p;
1187 {
1188   p->flags &= PF_ALLOCBUF;              /* preserve PF_ALLOCBUF flag */
1189   p->precision = p->width = NOT_FOUND;
1190   p->justify = NOT_FOUND;
1191   p->pad = ' ';
1192 }
1193
1194 static void
1195 init_data (p, string, length, format, mode)
1196      struct DATA *p;
1197      char *string;
1198      size_t length;
1199      const char *format;
1200      int mode;
1201 {
1202   p->length = length - 1; /* leave room for '\0' */
1203   p->holder = p->base = string;
1204   p->pf = format;
1205   p->counter = 0;
1206   p->flags = (mode == PFM_AS) ? PF_ALLOCBUF : 0;
1207 }
1208
1209 static int
1210 #if defined (__STDC__)
1211 vsnprintf_internal(struct DATA *data, char *string, size_t length, const char *format, va_list args)
1212 #else
1213 vsnprintf_internal(data, string, length, format, args)
1214      struct DATA *data;
1215      char *string;
1216      size_t length;
1217      const char *format;
1218      va_list args;
1219 #endif
1220 {
1221   double d; /* temporary holder */
1222 #ifdef HAVE_LONG_DOUBLE
1223   long double ld;       /* for later */
1224 #endif
1225   unsigned long ul;
1226 #ifdef HAVE_LONG_LONG
1227   unsigned long long ull;
1228 #endif
1229   int state, i, c, n;
1230   char *s;
1231 #if HANDLE_MULTIBYTE
1232   wchar_t *ws;
1233   wint_t wc;
1234 #endif
1235   const char *convstart;
1236   int negprec;
1237
1238   /* Sanity check, the string length must be >= 0.  C99 actually says that
1239      LENGTH can be zero here, in the case of snprintf/vsnprintf (it's never
1240      0 in the case of asprintf/vasprintf), and the return value is the number
1241      of characters that would have been written. */
1242   if (length < 0)
1243     return -1;
1244
1245   if (format == 0)
1246     return 0;
1247
1248   /* Reset these for each call because the locale might have changed. */
1249   decpoint = thoussep = 0;
1250   grouping = 0;
1251
1252   negprec = 0;
1253   for (; c = *(data->pf); data->pf++)
1254     {
1255       if (c != '%')
1256         {
1257           PUT_CHAR (c, data);
1258           continue;
1259         }
1260
1261       convstart = data->pf;
1262       init_conv_flag (data); /* initialise format flags */
1263
1264       state = 1;
1265       for (state = 1; state && *data->pf; )
1266         {
1267           c = *(++data->pf);
1268               /* fmtend = data->pf */
1269 #if defined (FLOATING_POINT) && defined (HAVE_LONG_DOUBLE)
1270           if (data->flags & PF_LONGDBL)
1271             {
1272               switch (c)
1273                 {
1274                 case 'f': case 'F':
1275                 case 'e': case 'E':
1276                 case 'g': case 'G':
1277 #  ifdef HAVE_PRINTF_A_FORMAT
1278                 case 'a': case 'A':
1279 #  endif
1280                   STAR_ARGS (data);
1281                   ld = GETLDOUBLE (data);
1282                   ldfallback (data, convstart, data->pf, ld);
1283                   goto conv_break;
1284                 }
1285             }
1286 #endif /* FLOATING_POINT && HAVE_LONG_DOUBLE */
1287
1288           switch (c)
1289             {
1290               /* Parse format flags */
1291               case '\0': /* a NULL here ? ? bail out */
1292                 *data->holder = '\0';
1293                 return data->counter;
1294                 break;
1295               case '#':
1296                 data->flags |= PF_ALTFORM;
1297                 continue;
1298               case '0':
1299                 data->flags |= PF_ZEROPAD;
1300                 data->pad = '0';
1301                 continue;
1302               case '*':
1303                 if (data->flags & PF_DOT)
1304                   data->flags |= PF_STAR_P;
1305                 else
1306                   data->flags |= PF_STAR_W;
1307                 continue;
1308               case '-':
1309                 if ((data->flags & PF_DOT) == 0)
1310                   {
1311                     data->flags |= PF_LADJUST;
1312                     data->justify = LEFT;
1313                   }
1314                 else
1315                   negprec = 1;
1316                 continue;
1317               case ' ':
1318                 if ((data->flags & PF_PLUS) == 0)
1319                   data->flags |= PF_SPACE;
1320                 continue;
1321               case '+':
1322                 if ((data->flags & PF_DOT) == 0)
1323                   {
1324                     data->flags |= PF_PLUS;
1325                     data->justify = RIGHT;
1326                   }
1327                 continue;
1328               case '\'':
1329                 data->flags |= PF_THOUSANDS;
1330                 continue;
1331
1332               case '1': case '2': case '3':
1333               case '4': case '5': case '6':
1334               case '7': case '8': case '9':
1335                 n = 0;
1336                 do
1337                   {
1338                     n = n * 10 + TODIGIT(c);
1339                     c = *(++data->pf);
1340                   }
1341                 while (DIGIT(c));
1342                 data->pf--;             /* went too far */
1343                 if (n < 0)
1344                   n = 0;
1345                 if (data->flags & PF_DOT)
1346                   data->precision = negprec ? NOT_FOUND : n;
1347                 else
1348                   data->width = n;
1349                 continue;
1350
1351               /* optional precision */
1352               case '.':
1353                 data->flags |= PF_DOT;
1354                 data->precision = 0;
1355                 continue;
1356
1357               /* length modifiers */
1358               case 'h':
1359                 data->flags |= (data->flags & PF_SHORTINT) ? PF_SIGNEDCHAR : PF_SHORTINT;
1360                 continue;
1361               case 'l':
1362                 data->flags |= (data->flags & PF_LONGINT) ? PF_LONGLONG : PF_LONGINT;
1363                 continue;
1364               case 'L':
1365                 data->flags |= PF_LONGDBL;
1366                 continue;
1367               case 'q':
1368                 data->flags |= PF_LONGLONG;
1369                 continue;
1370               case 'j':
1371                 data->flags |= PF_INTMAX_T;
1372                 SET_SIZE_FLAGS(data, intmax_t);
1373                 continue;
1374               case 'z':
1375                 data->flags |= PF_SIZE_T;
1376                 SET_SIZE_FLAGS(data, size_t);
1377                 continue;
1378               case 't':
1379                 data->flags |= PF_PTRDIFF_T;
1380                 SET_SIZE_FLAGS(data, ptrdiff_t);
1381                 continue;
1382                 
1383               /* Conversion specifiers */
1384 #ifdef FLOATING_POINT
1385               case 'f':  /* float, double */
1386               case 'F':
1387                 STAR_ARGS(data);
1388                 d = GETDOUBLE(data);
1389                 floating(data, d);
1390 conv_break:             
1391                 state = 0;
1392                 break;
1393               case 'g': 
1394               case 'G':
1395                 STAR_ARGS(data);
1396                 DEF_PREC(data);
1397                 d = GETDOUBLE(data);
1398                 i = (d != 0.) ? log_10(d) : -1;
1399                 /*
1400                  * for '%g|%G' ANSI: use f if exponent
1401                  * is in the range or [-4,p] exclusively
1402                  * else use %e|%E
1403                  */
1404                 if (-4 < i && i < data->precision)
1405                   {
1406                     /* reset precision */
1407                     data->precision -= i + 1;
1408                     floating(data, d);
1409                   }
1410                 else
1411                   {
1412                     /* reduce precision by 1 because of leading digit before
1413                        decimal point in e format. */
1414                     data->precision--;
1415                     exponent(data, d);
1416                   }
1417                 state = 0;
1418                 break;
1419               case 'e':
1420               case 'E':  /* Exponent double */
1421                 STAR_ARGS(data);
1422                 d = GETDOUBLE(data);
1423                 exponent(data, d);
1424                 state = 0;
1425                 break;
1426 #  ifdef HAVE_PRINTF_A_FORMAT
1427               case 'a':
1428               case 'A':
1429                 STAR_ARGS(data);
1430                 d = GETDOUBLE(data);
1431                 dfallback(data, convstart, data->pf, d);
1432                 state = 0;
1433                 break;
1434 #  endif /* HAVE_PRINTF_A_FORMAT */
1435 #endif /* FLOATING_POINT */
1436               case 'U':
1437                 data->flags |= PF_LONGINT;
1438                 /* FALLTHROUGH */
1439               case 'u':
1440                 STAR_ARGS(data);
1441 #ifdef HAVE_LONG_LONG
1442                 if (data->flags & PF_LONGLONG)
1443                   {
1444                     ull = GETARG (unsigned long long);
1445                     lnumber(data, ull, 10);
1446                   }
1447                 else
1448 #endif
1449                   {
1450                     ul = GETUNSIGNED(data);
1451                     number(data, ul, 10);
1452                   }
1453                 state = 0;
1454                 break;
1455               case 'D':
1456                 data->flags |= PF_LONGINT;
1457                 /* FALLTHROUGH */
1458               case 'd':  /* decimal */
1459               case 'i':
1460                 STAR_ARGS(data);
1461 #ifdef HAVE_LONG_LONG
1462                 if (data->flags & PF_LONGLONG)
1463                   {
1464                     ull = GETARG (long long);
1465                     lnumber(data, ull, 10);
1466                   }
1467                 else
1468 #endif
1469                   {
1470                     ul = GETSIGNED(data);
1471                     number(data, ul, 10);
1472                   }
1473                 state = 0;
1474                 break;
1475               case 'o':  /* octal */
1476                 STAR_ARGS(data);
1477 #ifdef HAVE_LONG_LONG
1478                 if (data->flags & PF_LONGLONG)
1479                   {
1480                     ull = GETARG (unsigned long long);
1481                     lnumber(data, ull, 8);
1482                   }
1483                 else
1484 #endif
1485                   {
1486                     ul = GETUNSIGNED(data);
1487                     number(data, ul, 8);
1488                   }
1489                 state = 0;
1490                 break;
1491               case 'x': 
1492               case 'X':  /* hexadecimal */
1493                 STAR_ARGS(data);
1494 #ifdef HAVE_LONG_LONG
1495                 if (data->flags & PF_LONGLONG)
1496                   {
1497                     ull = GETARG (unsigned long long);
1498                     lnumber(data, ull, 16);
1499                   }
1500                 else
1501 #endif
1502                   {
1503                     ul = GETUNSIGNED(data);
1504                     number(data, ul, 16);
1505                   }
1506                 state = 0;
1507                 break;
1508               case 'p':
1509                 STAR_ARGS(data);
1510                 ul = (unsigned long)GETARG (void *);
1511                 pointer(data, ul);
1512                 state = 0;
1513                 break;
1514 #if HANDLE_MULTIBYTE
1515               case 'C':
1516                 data->flags |= PF_LONGINT;
1517                 /* FALLTHROUGH */
1518 #endif
1519               case 'c': /* character */
1520                 STAR_ARGS(data);
1521 #if HANDLE_MULTIBYTE
1522                 if (data->flags & PF_LONGINT)
1523                   {
1524                     wc = GETARG (wint_t);
1525                     wchars (data, wc);
1526                   }
1527                 else
1528 #endif
1529                   {             
1530                     ul = GETARG (int);
1531                     PUT_CHAR(ul, data);
1532                   }
1533                 state = 0;
1534                 break;
1535 #if HANDLE_MULTIBYTE
1536               case 'S':
1537                 data->flags |= PF_LONGINT;
1538                 /* FALLTHROUGH */
1539 #endif
1540               case 's':  /* string */
1541                 STAR_ARGS(data);
1542 #if HANDLE_MULTIBYTE
1543                 if (data->flags & PF_LONGINT)
1544                   {
1545                     ws = GETARG (wchar_t *);
1546                     wstrings (data, ws);
1547                   }
1548                 else
1549 #endif
1550                   {
1551                     s = GETARG (char *);
1552                     strings(data, s);
1553                   }
1554                 state = 0;
1555                 break;
1556               case 'n':
1557 #ifdef HAVE_LONG_LONG
1558                 if (data->flags & PF_LONGLONG)
1559                   *(GETARG (long long *)) = data->counter;
1560                 else
1561 #endif
1562                 if (data->flags & PF_LONGINT)
1563                   *(GETARG (long *)) = data->counter;
1564                 else if (data->flags & PF_SHORTINT)
1565                   *(GETARG (short *)) = data->counter;
1566                 else
1567                   *(GETARG (int *)) = data->counter;
1568                 state = 0;
1569                 break;
1570               case '%':  /* nothing just % */
1571                 PUT_CHAR('%', data);
1572                 state = 0;
1573                 break;
1574               default:
1575                 /* is this an error ? maybe bail out */
1576                 state = 0;
1577                 break;
1578         } /* end switch */
1579       } /* end of `%' for loop */
1580     } /* end of format string for loop */
1581
1582   if (data->length >= 0)
1583     *data->holder = '\0'; /* the end ye ! */
1584
1585   return data->counter;
1586 }
1587
1588 #if defined (FLOATING_POINT) && defined (HAVE_LONG_DOUBLE)
1589 /*
1590  * Printing floating point numbers accurately is an art.  I'm not good
1591  * at it.  Fall back to sprintf for long double formats.
1592  */
1593 static void
1594 ldfallback (data, fs, fe, ld)
1595      struct DATA *data;
1596      const char *fs, *fe;
1597      long double ld;
1598 {
1599   register char *x;
1600   char fmtbuf[FALLBACK_FMTSIZE], *obuf;
1601   int fl;
1602
1603   fl = LFALLBACK_BASE + (data->precision < 6 ? 6 : data->precision) + 2;
1604   obuf = (char *)xmalloc (fl);
1605   fl = fe - fs + 1;
1606   strncpy (fmtbuf, fs, fl);
1607   fmtbuf[fl] = '\0';
1608
1609   if ((data->flags & PF_STAR_W) && (data->flags & PF_STAR_P))
1610     sprintf (obuf, fmtbuf, data->width, data->precision, ld);
1611   else if (data->flags & PF_STAR_W)
1612     sprintf (obuf, fmtbuf, data->width, ld);
1613   else if (data->flags & PF_STAR_P)
1614     sprintf (obuf, fmtbuf, data->precision, ld);
1615   else
1616     sprintf (obuf, fmtbuf, ld);
1617
1618   for (x = obuf; *x; x++)
1619     PUT_CHAR (*x, data);    
1620   xfree (obuf);
1621 }
1622 #endif /* FLOATING_POINT && HAVE_LONG_DOUBLE */
1623
1624 #ifdef FLOATING_POINT
1625 /* Used for %a, %A if the libc printf supports them. */
1626 static void
1627 dfallback (data, fs, fe, d)
1628      struct DATA *data;
1629      const char *fs, *fe;
1630      double d;
1631 {
1632   register char *x;
1633   char fmtbuf[FALLBACK_FMTSIZE], obuf[FALLBACK_BASE];
1634   int fl;
1635
1636   fl = fe - fs + 1;
1637   strncpy (fmtbuf, fs, fl);
1638   fmtbuf[fl] = '\0';
1639
1640   if ((data->flags & PF_STAR_W) && (data->flags & PF_STAR_P))
1641     sprintf (obuf, fmtbuf, data->width, data->precision, d);
1642   else if (data->flags & PF_STAR_W)
1643     sprintf (obuf, fmtbuf, data->width, d);
1644   else if (data->flags & PF_STAR_P)
1645     sprintf (obuf, fmtbuf, data->precision, d);
1646   else
1647     sprintf (obuf, fmtbuf, d);
1648
1649   for (x = obuf; *x; x++)
1650     PUT_CHAR (*x, data);    
1651 }
1652 #endif /* FLOATING_POINT */
1653
1654 #if !HAVE_SNPRINTF
1655
1656 int
1657 #if defined (__STDC__)
1658 vsnprintf(char *string, size_t length, const char *format, va_list args)
1659 #else
1660 vsnprintf(string, length, format, args)
1661      char *string;
1662      size_t length;
1663      const char *format;
1664      va_list args;
1665 #endif
1666 {
1667   struct DATA data;
1668
1669   if (string == 0 && length != 0)
1670     return 0;
1671   init_data (&data, string, length, format, PFM_SN);
1672   return (vsnprintf_internal(&data, string, length, format, args));
1673 }
1674
1675 int
1676 #if defined(PREFER_STDARG)
1677 snprintf(char *string, size_t length, const char * format, ...)
1678 #else
1679 snprintf(string, length, format, va_alist)
1680      char *string;
1681      size_t length;
1682      const char *format;
1683      va_dcl
1684 #endif
1685 {
1686   struct DATA data;
1687   int rval;
1688   va_list args;
1689
1690   SH_VA_START(args, format);
1691
1692   if (string == 0 && length != 0)
1693     return 0;
1694   init_data (&data, string, length, format, PFM_SN);
1695   rval = vsnprintf_internal (&data, string, length, format, args);
1696
1697   va_end(args);
1698
1699   return rval;
1700 }
1701
1702 #endif /* HAVE_SNPRINTF */
1703
1704 #if !HAVE_ASPRINTF
1705
1706 int
1707 #if defined (__STDC__)
1708 vasprintf(char **stringp, const char *format, va_list args)
1709 #else
1710 vasprintf(stringp, format, args)
1711      char **stringp;
1712      const char *format;
1713      va_list args;
1714 #endif
1715 {
1716   struct DATA data;
1717   char *string;
1718   int r;
1719
1720   string = (char *)xmalloc(ASBUFSIZE);
1721   init_data (&data, string, ASBUFSIZE, format, PFM_AS);
1722   r = vsnprintf_internal(&data, string, ASBUFSIZE, format, args);
1723   *stringp = data.base;         /* not string in case reallocated */
1724   return r;
1725 }
1726
1727 int
1728 #if defined(PREFER_STDARG)
1729 asprintf(char **stringp, const char * format, ...)
1730 #else
1731 asprintf(stringp, format, va_alist)
1732      char **stringp;
1733      const char *format;
1734      va_dcl
1735 #endif
1736 {
1737   int rval;
1738   va_list args;
1739
1740   SH_VA_START(args, format);
1741
1742   rval = vasprintf (stringp, format, args);
1743
1744   va_end(args);
1745
1746   return rval;
1747 }
1748
1749 #endif /* !HAVE_ASPRINTF */
1750
1751 #endif /* !HAVE_SNPRINTF || !HAVE_ASPRINTF */
1752
1753 #ifdef DRIVER
1754
1755 static void
1756 memory_error_and_abort ()
1757 {
1758   write (2, "out of virtual memory\n", 22);
1759   abort ();
1760 }
1761
1762 static void *
1763 xmalloc(bytes)
1764      size_t bytes;
1765 {
1766   void *ret;
1767
1768   ret = malloc(bytes);
1769   if (ret == 0)
1770     memory_error_and_abort ();
1771   return ret;
1772 }
1773
1774 static void *
1775 xrealloc (pointer, bytes)
1776      void *pointer;
1777      size_t bytes;
1778 {
1779   void *ret;
1780
1781   ret = pointer ? realloc(pointer, bytes) : malloc(bytes);
1782   if (ret == 0)
1783     memory_error_and_abort ();
1784   return ret;
1785 }
1786
1787 static void
1788 xfree(x)
1789      void *x;
1790 {
1791   if (x)
1792     free (x);
1793 }
1794
1795 /* set of small tests for snprintf() */
1796 main()
1797 {
1798   char holder[100];
1799   char *h;
1800   int i, si, ai;
1801
1802 #ifdef HAVE_LOCALE_H
1803   setlocale(LC_ALL, "");
1804 #endif
1805
1806 #if 1
1807   si = snprintf((char *)NULL, 0, "abcde\n");
1808   printf("snprintf returns %d with NULL first argument and size of 0\n", si);
1809   si = snprintf(holder, 0, "abcde\n");
1810   printf("snprintf returns %d with non-NULL first argument and size of 0\n", si);
1811   si = snprintf((char *)NULL, 16, "abcde\n");
1812   printf("snprintf returns %d with NULL first argument and non-zero size\n", si);
1813   
1814 /*
1815   printf("Suite of test for snprintf:\n");
1816   printf("a_format\n");
1817   printf("printf() format\n");
1818   printf("snprintf() format\n\n");
1819 */
1820 /* Checking the field widths */
1821
1822   printf("/%%ld %%ld/, 336, 336\n");
1823   snprintf(holder, sizeof holder, "/%ld %ld/\n", 336, 336);
1824   asprintf(&h, "/%ld %ld/\n", 336, 336);
1825   printf("/%ld %ld/\n", 336, 336);
1826   printf("%s", holder);
1827   printf("%s\n", h);
1828
1829   printf("/%%d/, 336\n");
1830   snprintf(holder, sizeof holder, "/%d/\n", 336);
1831   asprintf(&h, "/%d/\n", 336);
1832   printf("/%d/\n", 336);
1833   printf("%s", holder);
1834   printf("%s\n", h);
1835
1836   printf("/%%2d/, 336\n");
1837   snprintf(holder, sizeof holder, "/%2d/\n", 336);
1838   asprintf(&h, "/%2d/\n", 336);
1839   printf("/%2d/\n", 336);
1840   printf("%s", holder);
1841   printf("%s\n", h);
1842
1843   printf("/%%10d/, 336\n");
1844   snprintf(holder, sizeof holder, "/%10d/\n", 336);
1845   asprintf(&h, "/%10d/\n", 336);
1846   printf("/%10d/\n", 336);
1847   printf("%s", holder);
1848   printf("%s\n", h);
1849
1850   printf("/%%-10d/, 336\n");
1851   snprintf(holder, sizeof holder, "/%-10d/\n", 336);
1852   asprintf(&h, "/%-10d/\n", 336);
1853   printf("/%-10d/\n", 336);
1854   printf("%s", holder);
1855   printf("%s\n", h);
1856
1857
1858 /* floating points */
1859
1860   printf("/%%f/, 1234.56\n");
1861   snprintf(holder, sizeof holder, "/%f/\n", 1234.56);
1862   asprintf(&h, "/%f/\n", 1234.56);
1863   printf("/%f/\n", 1234.56);
1864   printf("%s", holder);
1865   printf("%s\n", h);
1866
1867   printf("/%%e/, 1234.56\n");
1868   snprintf(holder, sizeof holder, "/%e/\n", 1234.56);
1869   asprintf(&h, "/%e/\n", 1234.56);
1870   printf("/%e/\n", 1234.56);
1871   printf("%s", holder);
1872   printf("%s\n", h);
1873
1874   printf("/%%4.2f/, 1234.56\n");
1875   snprintf(holder, sizeof holder, "/%4.2f/\n", 1234.56);
1876   asprintf(&h, "/%4.2f/\n", 1234.56);
1877   printf("/%4.2f/\n", 1234.56);
1878   printf("%s", holder);
1879   printf("%s\n", h);
1880
1881   printf("/%%3.1f/, 1234.56\n");
1882   snprintf(holder, sizeof holder, "/%3.1f/\n", 1234.56);
1883   asprintf(&h, "/%3.1f/\n", 1234.56);
1884   printf("/%3.1f/\n", 1234.56);
1885   printf("%s", holder);
1886   printf("%s\n", h);
1887
1888   printf("/%%10.3f/, 1234.56\n");
1889   snprintf(holder, sizeof holder, "/%10.3f/\n", 1234.56);
1890   asprintf(&h, "/%10.3f/\n", 1234.56);
1891   printf("/%10.3f/\n", 1234.56);
1892   printf("%s", holder);
1893   printf("%s\n", h);
1894
1895   printf("/%%10.3e/, 1234.56\n");
1896   snprintf(holder, sizeof holder, "/%10.3e/\n", 1234.56);
1897   asprintf(&h, "/%10.3e/\n", 1234.56);
1898   printf("/%10.3e/\n", 1234.56);
1899   printf("%s", holder);
1900   printf("%s\n", h);
1901
1902   printf("/%%+4.2f/, 1234.56\n");
1903   snprintf(holder, sizeof holder, "/%+4.2f/\n", 1234.56);
1904   asprintf(&h, "/%+4.2f/\n", 1234.56);
1905   printf("/%+4.2f/\n", 1234.56);
1906   printf("%s", holder);
1907   printf("%s\n", h);
1908
1909   printf("/%%010.2f/, 1234.56\n");
1910   snprintf(holder, sizeof holder, "/%010.2f/\n", 1234.56);
1911   asprintf(&h, "/%010.2f/\n", 1234.56);
1912   printf("/%010.2f/\n", 1234.56);
1913   printf("%s", holder);
1914   printf("%s\n", h);
1915
1916 #define BLURB "Outstanding acting !"
1917 /* strings precisions */
1918
1919   printf("/%%2s/, \"%s\"\n", BLURB);
1920   snprintf(holder, sizeof holder, "/%2s/\n", BLURB);
1921   asprintf(&h, "/%2s/\n", BLURB);
1922   printf("/%2s/\n", BLURB);
1923   printf("%s", holder);
1924   printf("%s\n", h);
1925
1926   printf("/%%22s/ %s\n", BLURB);
1927   snprintf(holder, sizeof holder, "/%22s/\n", BLURB);
1928   asprintf(&h, "/%22s/\n", BLURB);
1929   printf("/%22s/\n", BLURB);
1930   printf("%s", holder);
1931   printf("%s\n", h);
1932
1933   printf("/%%22.5s/ %s\n", BLURB);
1934   snprintf(holder, sizeof holder, "/%22.5s/\n", BLURB);
1935   asprintf(&h, "/%22.5s/\n", BLURB);
1936   printf("/%22.5s/\n", BLURB);
1937   printf("%s", holder);
1938   printf("%s\n", h);
1939
1940   printf("/%%-22.5s/ %s\n", BLURB);
1941   snprintf(holder, sizeof holder, "/%-22.5s/\n", BLURB);
1942   asprintf(&h, "/%-22.5s/\n", BLURB);
1943   printf("/%-22.5s/\n", BLURB);
1944   printf("%s", holder);
1945   printf("%s\n", h);
1946
1947 /* see some flags */
1948
1949   printf("%%x %%X %%#x, 31, 31, 31\n");
1950   snprintf(holder, sizeof holder, "%x %X %#x\n", 31, 31, 31);
1951   asprintf(&h, "%x %X %#x\n", 31, 31, 31);
1952   printf("%x %X %#x\n", 31, 31, 31);
1953   printf("%s", holder);
1954   printf("%s\n", h);
1955
1956   printf("**%%d**%% d**%% d**, 42, 42, -42\n");
1957   snprintf(holder, sizeof holder, "**%d**% d**% d**\n", 42, 42, -42);
1958   asprintf(&h, "**%d**% d**% d**\n", 42, 42, -42);
1959   printf("**%d**% d**% d**\n", 42, 42, -42);
1960   printf("%s", holder);
1961   printf("%s\n", h);
1962
1963 /* other flags */
1964
1965   printf("/%%g/, 31.4\n");
1966   snprintf(holder, sizeof holder, "/%g/\n", 31.4);
1967   asprintf(&h, "/%g/\n", 31.4);
1968   printf("/%g/\n", 31.4);
1969   printf("%s", holder);
1970   printf("%s\n", h);
1971
1972   printf("/%%.6g/, 31.4\n");
1973   snprintf(holder, sizeof holder, "/%.6g/\n", 31.4);
1974   asprintf(&h, "/%.6g/\n", 31.4);
1975   printf("/%.6g/\n", 31.4);
1976   printf("%s", holder);
1977   printf("%s\n", h);
1978
1979   printf("/%%.1G/, 31.4\n");
1980   snprintf(holder, sizeof holder, "/%.1G/\n", 31.4);
1981   asprintf(&h, "/%.1G/\n", 31.4);
1982   printf("/%.1G/\n", 31.4);
1983   printf("%s", holder);
1984   printf("%s\n", h);
1985
1986   printf("/%%.1G/, 3100000000.4\n");
1987   snprintf(holder, sizeof holder, "/%.1G/\n", 3100000000.4);  
1988   asprintf(&h, "/%.1G/\n", 3100000000.4);  
1989   printf("/%.1G/\n", 3100000000.4); 
1990   printf("%s", holder);
1991   printf("%s\n", h);
1992
1993   printf("abc%%n\n");
1994   printf("abc%n", &i); printf("%d\n", i);
1995   snprintf(holder, sizeof holder, "abc%n", &i);
1996   printf("%s", holder); printf("%d\n\n", i);
1997   asprintf(&h, "abc%n", &i);
1998   printf("%s", h); printf("%d\n\n", i);
1999   
2000   printf("%%*.*s --> 10.10\n");
2001   snprintf(holder, sizeof holder, "%*.*s\n", 10, 10, BLURB);
2002   asprintf(&h, "%*.*s\n", 10, 10, BLURB);
2003   printf("%*.*s\n", 10, 10, BLURB);
2004   printf("%s", holder);
2005   printf("%s\n", h);
2006
2007   printf("%%%%%%%%\n");
2008   snprintf(holder, sizeof holder, "%%%%\n");
2009   asprintf(&h, "%%%%\n");
2010   printf("%%%%\n");
2011   printf("%s", holder);
2012   printf("%s\n", h);
2013
2014 #define BIG "Hello this is a too big string for the buffer"
2015 /*  printf("A buffer to small of 10, trying to put this:\n");*/
2016   printf("<%%>, %s\n", BIG); 
2017   i = snprintf(holder, 10, "%s\n", BIG);
2018   i = asprintf(&h, "%s", BIG);
2019   printf("<%s>\n", BIG);
2020   printf("<%s>\n", holder);
2021   printf("<%s>\n\n", h);
2022
2023   printf ("<%%p> vsnprintf\n");
2024   i = snprintf(holder, 100, "%p", vsnprintf);
2025   i = asprintf(&h, "%p", vsnprintf);
2026   printf("<%p>\n", vsnprintf);
2027   printf("<%s>\n", holder);  
2028   printf("<%s>\n\n", h);
2029
2030   printf ("<%%lu> LONG_MAX+1\n");
2031   i = snprintf(holder, 100, "%lu", (unsigned long)(LONG_MAX)+1);
2032   i = asprintf(&h, "%lu", (unsigned long)(LONG_MAX)+1);
2033   printf("<%lu>\n", (unsigned long)(LONG_MAX)+1);
2034   printf("<%s>\n", holder);
2035   printf("<%s>\n\n", h);
2036
2037 #ifdef HAVE_LONG_LONG
2038   printf ("<%%llu> LLONG_MAX+1\n");
2039   i = snprintf(holder, 100, "%llu", (unsigned long long)(LLONG_MAX)+1);
2040   i = asprintf(&h, "%llu", (unsigned long long)(LLONG_MAX)+1);
2041   printf("<%llu>\n", (unsigned long long)(LLONG_MAX)+1);
2042   printf("<%s>\n", holder);
2043   printf("<%s>\n\n", h);
2044 #endif
2045
2046 #ifdef HAVE_LONG_DOUBLE
2047   printf ("<%%6.2LE> 42.42\n");
2048   i = snprintf(holder, 100, "%6.2LE", (long double)42.42);
2049   i = asprintf(&h, "%6.2LE", (long double)42.42);
2050   printf ("<%6.2LE>\n", (long double)42.42);
2051   printf ("<%s>\n", holder);
2052   printf ("<%s>\n\n", h);
2053 #endif
2054
2055 #ifdef HAVE_PRINTF_A_FORMAT
2056   printf ("<%%6.2A> 42.42\n");
2057   i = snprintf(holder, 100, "%6.2A", 42.42);
2058   i = asprintf(&h, "%6.2A", 42.42);
2059   printf ("<%6.2A>\n", 42.42);
2060   printf ("<%s>\n", holder);
2061   printf ("<%s>\n\n", h);
2062
2063   printf ("<%%6.2LA> 42.42\n");
2064   i = snprintf(holder, 100, "%6.2LA", (long double)42.42);
2065   i = asprintf(&h, "%6.2LA", (long double)42.42);
2066   printf ("<%6.2LA>\n", (long double)42.42);
2067   printf ("<%s>\n", holder);
2068   printf ("<%s>\n\n", h);
2069 #endif
2070
2071   printf ("<%%.10240f> DBL_MAX\n");
2072   si = snprintf(holder, 100, "%.10240f", DBL_MAX);
2073   ai = asprintf(&h, "%.10240f", DBL_MAX);
2074   printf ("<%.10240f>\n", DBL_MAX);
2075   printf ("<%d> <%s>\n", si, holder);
2076   printf ("<%d> <%s>\n\n", ai, h);
2077
2078   printf ("<%%.10240Lf> LDBL_MAX\n");
2079   si = snprintf(holder, 100, "%.10240Lf", (long double)LDBL_MAX);
2080   ai = asprintf(&h, "%.10240Lf", (long double)LDBL_MAX);
2081   printf ("<%.10240Lf>\n", (long double)LDBL_MAX);
2082   printf ("<%d> <%s>\n", si, holder);
2083   printf ("<%d> <%s>\n\n", ai, h);
2084
2085   /* huh? */
2086   printf("/%%g/, 421.2345\n");
2087   snprintf(holder, sizeof holder, "/%g/\n", 421.2345);
2088   asprintf(&h, "/%g/\n", 421.2345);
2089   printf("/%g/\n", 421.2345);
2090   printf("%s", holder);
2091   printf("%s\n", h);
2092
2093   printf("/%%g/, 4214.2345\n");
2094   snprintf(holder, sizeof holder, "/%g/\n", 4214.2345);
2095   asprintf(&h, "/%g/\n", 4214.2345);
2096   printf("/%g/\n", 4214.2345);
2097   printf("%s", holder);
2098   printf("%s\n", h);
2099
2100   printf("/%%.5g/, 4214.2345\n");
2101   snprintf(holder, sizeof holder, "/%.5g/\n", 4214.2345);
2102   asprintf(&h, "/%.5g/\n", 4214.2345);
2103   printf("/%.5g/\n", 4214.2345);
2104   printf("%s", holder);
2105   printf("%s\n", h);
2106
2107   printf("/%%.4g/, 4214.2345\n");
2108   snprintf(holder, sizeof holder, "/%.4g/\n", 4214.2345);
2109   asprintf(&h, "/%.4g/\n", 4214.2345);
2110   printf("/%.4g/\n", 4214.2345);
2111   printf("%s", holder);
2112   printf("%s\n", h);
2113
2114   printf("/%%'ld %%'ld/, 12345, 1234567\n");
2115   snprintf(holder, sizeof holder, "/%'ld %'ld/\n", 12345, 1234567);
2116   asprintf(&h, "/%'ld %'ld/\n", 12345, 1234567);
2117   printf("/%'ld %'ld/\n", 12345, 1234567);
2118   printf("%s", holder);
2119   printf("%s\n", h);
2120
2121   printf("/%%'ld %%'ld/, 336, 3336\n");
2122   snprintf(holder, sizeof holder, "/%'ld %'ld/\n", 336, 3336);
2123   asprintf(&h, "/%'ld %'ld/\n", 336, 3336);
2124   printf("/%'ld %'ld/\n", 336, 3336);
2125   printf("%s", holder);
2126   printf("%s\n", h);
2127
2128   printf("/%%'ld %%'ld/, -42786, -142786\n");
2129   snprintf(holder, sizeof holder, "/%'ld %'ld/\n", -42786, -142786);
2130   asprintf(&h, "/%'ld %'ld/\n", -42786, -142786);
2131   printf("/%'ld %'ld/\n", -42786, -142786);
2132   printf("%s", holder);
2133   printf("%s\n", h);
2134
2135   printf("/%%'f %%'f/, 421.2345, 421234.56789\n");
2136   snprintf(holder, sizeof holder, "/%'f %'f/\n", 421.2345, 421234.56789);
2137   asprintf(&h, "/%'f %'f/\n", 421.2345, 421234.56789);
2138   printf("/%'f %'f/\n", 421.2345, 421234.56789);
2139   printf("%s", holder);
2140   printf("%s\n", h);
2141
2142   printf("/%%'f %%'f/, -421.2345, -421234.56789\n");
2143   snprintf(holder, sizeof holder, "/%'f %'f/\n", -421.2345, -421234.56789);
2144   asprintf(&h, "/%'f %'f/\n", -421.2345, -421234.56789);
2145   printf("/%'f %'f/\n", -421.2345, -421234.56789);
2146   printf("%s", holder);
2147   printf("%s\n", h);
2148
2149   printf("/%%'g %%'g/, 421.2345, 421234.56789\n");
2150   snprintf(holder, sizeof holder, "/%'g %'g/\n", 421.2345, 421234.56789);
2151   asprintf(&h, "/%'g %'g/\n", 421.2345, 421234.56789);
2152   printf("/%'g %'g/\n", 421.2345, 421234.56789);
2153   printf("%s", holder);
2154   printf("%s\n", h);
2155
2156   printf("/%%'g %%'g/, -421.2345, -421234.56789\n");
2157   snprintf(holder, sizeof holder, "/%'g %'g/\n", -421.2345, -421234.56789);
2158   asprintf(&h, "/%'g %'g/\n", -421.2345, -421234.56789);
2159   printf("/%'g %'g/\n", -421.2345, -421234.56789);
2160   printf("%s", holder);
2161   printf("%s\n", h);
2162 #endif
2163
2164   printf("/%%'g/, 4213455.8392\n");
2165   snprintf(holder, sizeof holder, "/%'g/\n", 4213455.8392);
2166   asprintf(&h, "/%'g/\n", 4213455.8392);
2167   printf("/%'g/\n", 4213455.8392);
2168   printf("%s", holder);
2169   printf("%s\n", h);
2170
2171   exit (0);
2172 }
2173 #endif