2 91c13e54 2004-02-29 devnull * The authors of this software are Rob Pike and Ken Thompson.
3 91c13e54 2004-02-29 devnull * Copyright (c) 2002 by Lucent Technologies.
4 91c13e54 2004-02-29 devnull * Permission to use, copy, modify, and distribute this software for any
5 91c13e54 2004-02-29 devnull * purpose without fee is hereby granted, provided that this entire notice
6 91c13e54 2004-02-29 devnull * is included in all copies of any software which is or includes a copy
7 91c13e54 2004-02-29 devnull * or modification of this software and in all copies of the supporting
8 91c13e54 2004-02-29 devnull * documentation for such software.
9 91c13e54 2004-02-29 devnull * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
10 91c13e54 2004-02-29 devnull * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
11 91c13e54 2004-02-29 devnull * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
12 91c13e54 2004-02-29 devnull * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
14 91c13e54 2004-02-29 devnull #include <stdio.h>
15 91c13e54 2004-02-29 devnull #include <math.h>
16 91c13e54 2004-02-29 devnull #include <float.h>
17 91c13e54 2004-02-29 devnull #include <string.h>
18 91c13e54 2004-02-29 devnull #include <stdlib.h>
19 91c13e54 2004-02-29 devnull #include <errno.h>
20 91c13e54 2004-02-29 devnull #include <stdarg.h>
21 91c13e54 2004-02-29 devnull #include "fmt.h"
22 91c13e54 2004-02-29 devnull #include "fmtdef.h"
23 91c13e54 2004-02-29 devnull #include "nan.h"
27 91c13e54 2004-02-29 devnull FDEFLT = 6,
28 91c13e54 2004-02-29 devnull NSIGNIF = 17
32 91c13e54 2004-02-29 devnull * first few powers of 10, enough for about 1/2 of the
33 91c13e54 2004-02-29 devnull * total space for doubles.
35 91c13e54 2004-02-29 devnull static double pows10[] =
37 91c13e54 2004-02-29 devnull 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
38 91c13e54 2004-02-29 devnull 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
39 91c13e54 2004-02-29 devnull 1e20, 1e21, 1e22, 1e23, 1e24, 1e25, 1e26, 1e27, 1e28, 1e29,
40 91c13e54 2004-02-29 devnull 1e30, 1e31, 1e32, 1e33, 1e34, 1e35, 1e36, 1e37, 1e38, 1e39,
41 91c13e54 2004-02-29 devnull 1e40, 1e41, 1e42, 1e43, 1e44, 1e45, 1e46, 1e47, 1e48, 1e49,
42 91c13e54 2004-02-29 devnull 1e50, 1e51, 1e52, 1e53, 1e54, 1e55, 1e56, 1e57, 1e58, 1e59,
43 91c13e54 2004-02-29 devnull 1e60, 1e61, 1e62, 1e63, 1e64, 1e65, 1e66, 1e67, 1e68, 1e69,
44 91c13e54 2004-02-29 devnull 1e70, 1e71, 1e72, 1e73, 1e74, 1e75, 1e76, 1e77, 1e78, 1e79,
45 91c13e54 2004-02-29 devnull 1e80, 1e81, 1e82, 1e83, 1e84, 1e85, 1e86, 1e87, 1e88, 1e89,
46 91c13e54 2004-02-29 devnull 1e90, 1e91, 1e92, 1e93, 1e94, 1e95, 1e96, 1e97, 1e98, 1e99,
47 91c13e54 2004-02-29 devnull 1e100, 1e101, 1e102, 1e103, 1e104, 1e105, 1e106, 1e107, 1e108, 1e109,
48 91c13e54 2004-02-29 devnull 1e110, 1e111, 1e112, 1e113, 1e114, 1e115, 1e116, 1e117, 1e118, 1e119,
49 91c13e54 2004-02-29 devnull 1e120, 1e121, 1e122, 1e123, 1e124, 1e125, 1e126, 1e127, 1e128, 1e129,
50 91c13e54 2004-02-29 devnull 1e130, 1e131, 1e132, 1e133, 1e134, 1e135, 1e136, 1e137, 1e138, 1e139,
51 91c13e54 2004-02-29 devnull 1e140, 1e141, 1e142, 1e143, 1e144, 1e145, 1e146, 1e147, 1e148, 1e149,
52 91c13e54 2004-02-29 devnull 1e150, 1e151, 1e152, 1e153, 1e154, 1e155, 1e156, 1e157, 1e158, 1e159,
55 91c13e54 2004-02-29 devnull static double
56 91c13e54 2004-02-29 devnull pow10(int n)
58 91c13e54 2004-02-29 devnull double d;
62 91c13e54 2004-02-29 devnull if(n < 0){
63 91c13e54 2004-02-29 devnull if(n < DBL_MIN_10_EXP){
64 91c13e54 2004-02-29 devnull return 0.;
68 91c13e54 2004-02-29 devnull }else if(n > DBL_MAX_10_EXP){
69 91c13e54 2004-02-29 devnull return HUGE_VAL;
71 91c13e54 2004-02-29 devnull if(n < (int)(sizeof(pows10)/sizeof(pows10[0])))
72 91c13e54 2004-02-29 devnull d = pows10[n];
74 91c13e54 2004-02-29 devnull d = pows10[sizeof(pows10)/sizeof(pows10[0]) - 1];
76 91c13e54 2004-02-29 devnull n -= sizeof(pows10)/sizeof(pows10[0]) - 1;
77 91c13e54 2004-02-29 devnull if(n < (int)(sizeof(pows10)/sizeof(pows10[0]))){
78 91c13e54 2004-02-29 devnull d *= pows10[n];
81 91c13e54 2004-02-29 devnull d *= pows10[sizeof(pows10)/sizeof(pows10[0]) - 1];
85 91c13e54 2004-02-29 devnull return 1./d;
87 91c13e54 2004-02-29 devnull return d;
90 91c13e54 2004-02-29 devnull static int
91 91c13e54 2004-02-29 devnull xadd(char *a, int n, int v)
96 91c13e54 2004-02-29 devnull if(n < 0 || n >= NSIGNIF)
97 91c13e54 2004-02-29 devnull return 0;
98 91c13e54 2004-02-29 devnull for(b = a+n; b >= a; b--) {
99 91c13e54 2004-02-29 devnull c = *b + v;
100 91c13e54 2004-02-29 devnull if(c <= '9') {
102 91c13e54 2004-02-29 devnull return 0;
104 91c13e54 2004-02-29 devnull *b = '0';
107 91c13e54 2004-02-29 devnull *a = '1'; /* overflow adding */
108 91c13e54 2004-02-29 devnull return 1;
111 91c13e54 2004-02-29 devnull static int
112 91c13e54 2004-02-29 devnull xsub(char *a, int n, int v)
114 91c13e54 2004-02-29 devnull char *b;
117 91c13e54 2004-02-29 devnull for(b = a+n; b >= a; b--) {
118 91c13e54 2004-02-29 devnull c = *b - v;
119 91c13e54 2004-02-29 devnull if(c >= '0') {
121 91c13e54 2004-02-29 devnull return 0;
123 91c13e54 2004-02-29 devnull *b = '9';
126 91c13e54 2004-02-29 devnull *a = '9'; /* underflow subtracting */
127 91c13e54 2004-02-29 devnull return 1;
130 91c13e54 2004-02-29 devnull static void
131 91c13e54 2004-02-29 devnull xaddexp(char *p, int e)
133 91c13e54 2004-02-29 devnull char se[9];
136 91c13e54 2004-02-29 devnull *p++ = 'e';
137 91c13e54 2004-02-29 devnull if(e < 0) {
138 91c13e54 2004-02-29 devnull *p++ = '-';
142 91c13e54 2004-02-29 devnull while(e) {
143 91c13e54 2004-02-29 devnull se[i++] = e % 10 + '0';
144 91c13e54 2004-02-29 devnull e /= 10;
146 91c13e54 2004-02-29 devnull if(i == 0) {
147 91c13e54 2004-02-29 devnull *p++ = '0';
148 91c13e54 2004-02-29 devnull } else {
149 91c13e54 2004-02-29 devnull while(i > 0)
150 91c13e54 2004-02-29 devnull *p++ = se[--i];
152 91c13e54 2004-02-29 devnull *p++ = '\0';
155 91c13e54 2004-02-29 devnull static char*
156 91c13e54 2004-02-29 devnull xdodtoa(char *s1, double f, int chr, int prec, int *decpt, int *rsign)
158 91c13e54 2004-02-29 devnull char s2[NSIGNIF+10];
159 91c13e54 2004-02-29 devnull double g, h;
160 91c13e54 2004-02-29 devnull int e, d, i;
161 91c13e54 2004-02-29 devnull int c2, sign, oerr;
163 91c13e54 2004-02-29 devnull if(chr == 'F')
164 91c13e54 2004-02-29 devnull chr = 'f';
165 91c13e54 2004-02-29 devnull if(prec > NSIGNIF)
166 91c13e54 2004-02-29 devnull prec = NSIGNIF;
167 91c13e54 2004-02-29 devnull if(prec < 0)
168 91c13e54 2004-02-29 devnull prec = 0;
169 91c13e54 2004-02-29 devnull if(__isNaN(f)) {
170 91c13e54 2004-02-29 devnull *decpt = 9999;
171 91c13e54 2004-02-29 devnull *rsign = 0;
172 91c13e54 2004-02-29 devnull strcpy(s1, "nan");
173 91c13e54 2004-02-29 devnull return &s1[3];
175 91c13e54 2004-02-29 devnull sign = 0;
176 91c13e54 2004-02-29 devnull if(f < 0) {
180 91c13e54 2004-02-29 devnull *rsign = sign;
181 91c13e54 2004-02-29 devnull if(__isInf(f, 1) || __isInf(f, -1)) {
182 91c13e54 2004-02-29 devnull *decpt = 9999;
183 91c13e54 2004-02-29 devnull strcpy(s1, "inf");
184 91c13e54 2004-02-29 devnull return &s1[3];
189 91c13e54 2004-02-29 devnull if(g != 0) {
190 91c13e54 2004-02-29 devnull frexp(f, &e);
191 91c13e54 2004-02-29 devnull e = (int)(e * .301029995664);
192 91c13e54 2004-02-29 devnull if(e >= -150 && e <= +150) {
195 91c13e54 2004-02-29 devnull } else {
196 91c13e54 2004-02-29 devnull d = e/2;
197 91c13e54 2004-02-29 devnull h = f * pow10(-d);
199 91c13e54 2004-02-29 devnull g = h * pow10(d-e);
200 91c13e54 2004-02-29 devnull while(g < 1) {
202 91c13e54 2004-02-29 devnull g = h * pow10(d-e);
204 91c13e54 2004-02-29 devnull while(g >= 10) {
206 91c13e54 2004-02-29 devnull g = h * pow10(d-e);
211 91c13e54 2004-02-29 devnull * convert NSIGNIF digits and convert
212 91c13e54 2004-02-29 devnull * back to get accuracy.
214 91c13e54 2004-02-29 devnull for(i=0; i<NSIGNIF; i++) {
215 91c13e54 2004-02-29 devnull d = (int)g;
216 91c13e54 2004-02-29 devnull s1[i] = d + '0';
217 91c13e54 2004-02-29 devnull g = (g - d) * 10;
219 91c13e54 2004-02-29 devnull s1[i] = 0;
222 91c13e54 2004-02-29 devnull * try decimal rounding to eliminate 9s
224 91c13e54 2004-02-29 devnull c2 = prec + 1;
225 91c13e54 2004-02-29 devnull if(chr == 'f')
226 91c13e54 2004-02-29 devnull c2 += e;
227 91c13e54 2004-02-29 devnull oerr = errno;
228 91c13e54 2004-02-29 devnull if(c2 >= NSIGNIF-2) {
229 91c13e54 2004-02-29 devnull strcpy(s2, s1);
231 91c13e54 2004-02-29 devnull s1[NSIGNIF-2] = '0';
232 91c13e54 2004-02-29 devnull s1[NSIGNIF-1] = '0';
233 91c13e54 2004-02-29 devnull xaddexp(s1+NSIGNIF, e-NSIGNIF+1);
234 91c13e54 2004-02-29 devnull g = fmtstrtod(s1, nil);
235 91c13e54 2004-02-29 devnull if(g == f)
236 91c13e54 2004-02-29 devnull goto found;
237 91c13e54 2004-02-29 devnull if(xadd(s1, NSIGNIF-3, 1)) {
239 91c13e54 2004-02-29 devnull xaddexp(s1+NSIGNIF, e-NSIGNIF+1);
241 91c13e54 2004-02-29 devnull g = fmtstrtod(s1, nil);
242 91c13e54 2004-02-29 devnull if(g == f)
243 91c13e54 2004-02-29 devnull goto found;
244 91c13e54 2004-02-29 devnull strcpy(s1, s2);
249 91c13e54 2004-02-29 devnull * convert back so s1 gets exact answer
251 91c13e54 2004-02-29 devnull for(d = 0; d < 10; d++) {
252 91c13e54 2004-02-29 devnull xaddexp(s1+NSIGNIF, e-NSIGNIF+1);
253 91c13e54 2004-02-29 devnull g = fmtstrtod(s1, nil);
254 91c13e54 2004-02-29 devnull if(f > g) {
255 91c13e54 2004-02-29 devnull if(xadd(s1, NSIGNIF-1, 1))
257 91c13e54 2004-02-29 devnull continue;
259 91c13e54 2004-02-29 devnull if(f < g) {
260 91c13e54 2004-02-29 devnull if(xsub(s1, NSIGNIF-1, 1))
262 91c13e54 2004-02-29 devnull continue;
268 91c13e54 2004-02-29 devnull errno = oerr;
277 91c13e54 2004-02-29 devnull * round & adjust 'f' digits
279 91c13e54 2004-02-29 devnull c2 = prec + 1;
280 91c13e54 2004-02-29 devnull if(chr == 'f'){
281 91c13e54 2004-02-29 devnull if(xadd(s1, c2+e, 5))
283 91c13e54 2004-02-29 devnull c2 += e;
284 91c13e54 2004-02-29 devnull if(c2 < 0){
286 91c13e54 2004-02-29 devnull e = -prec - 1;
289 91c13e54 2004-02-29 devnull if(xadd(s1, c2, 5))
292 91c13e54 2004-02-29 devnull if(c2 > NSIGNIF){
293 91c13e54 2004-02-29 devnull c2 = NSIGNIF;
296 91c13e54 2004-02-29 devnull *decpt = e + 1;
299 91c13e54 2004-02-29 devnull * terminate the converted digits
301 91c13e54 2004-02-29 devnull s1[c2] = '\0';
302 91c13e54 2004-02-29 devnull return &s1[c2];
306 91c13e54 2004-02-29 devnull * this function works like the standard dtoa, if you want it.
309 91c13e54 2004-02-29 devnull static char*
310 91c13e54 2004-02-29 devnull __dtoa(double f, int mode, int ndigits, int *decpt, int *rsign, char **rve)
312 91c13e54 2004-02-29 devnull static char s2[NSIGNIF + 10];
313 91c13e54 2004-02-29 devnull char *es;
314 91c13e54 2004-02-29 devnull int chr, prec;
316 91c13e54 2004-02-29 devnull switch(mode) {
317 91c13e54 2004-02-29 devnull /* like 'e' */
322 91c13e54 2004-02-29 devnull chr = 'e';
324 91c13e54 2004-02-29 devnull /* like 'g' */
327 91c13e54 2004-02-29 devnull default:
328 91c13e54 2004-02-29 devnull chr = 'g';
330 91c13e54 2004-02-29 devnull /* like 'f' */
335 91c13e54 2004-02-29 devnull chr = 'f';
339 91c13e54 2004-02-29 devnull if(chr != 'f' && ndigits){
340 91c13e54 2004-02-29 devnull ndigits--;
342 91c13e54 2004-02-29 devnull prec = ndigits;
343 91c13e54 2004-02-29 devnull if(prec > NSIGNIF)
344 91c13e54 2004-02-29 devnull prec = NSIGNIF;
345 91c13e54 2004-02-29 devnull if(ndigits == 0)
346 91c13e54 2004-02-29 devnull prec = NSIGNIF;
347 91c13e54 2004-02-29 devnull es = xdodtoa(s2, f, chr, prec, decpt, rsign);
350 91c13e54 2004-02-29 devnull * strip trailing 0
352 91c13e54 2004-02-29 devnull for(; es > s2 + 1; es--){
353 91c13e54 2004-02-29 devnull if(es[-1] != '0'){
357 91c13e54 2004-02-29 devnull *es = '\0';
358 91c13e54 2004-02-29 devnull if(rve != NULL)
359 91c13e54 2004-02-29 devnull *rve = es;
360 91c13e54 2004-02-29 devnull return s2;
364 91c13e54 2004-02-29 devnull static int
365 91c13e54 2004-02-29 devnull fmtzdotpad(Fmt *f, int n, int pt)
367 91c13e54 2004-02-29 devnull char *t, *s;
369 91c13e54 2004-02-29 devnull Rune *rt, *rs;
371 91c13e54 2004-02-29 devnull if(f->runes){
372 91c13e54 2004-02-29 devnull rt = (Rune*)f->to;
373 91c13e54 2004-02-29 devnull rs = (Rune*)f->stop;
374 91c13e54 2004-02-29 devnull for(i = 0; i < n; i++){
375 91c13e54 2004-02-29 devnull if(i == pt){
376 91c13e54 2004-02-29 devnull FMTRCHAR(f, rt, rs, '.');
378 91c13e54 2004-02-29 devnull FMTRCHAR(f, rt, rs, '0');
380 91c13e54 2004-02-29 devnull f->nfmt += rt - (Rune*)f->to;
381 91c13e54 2004-02-29 devnull f->to = rt;
383 91c13e54 2004-02-29 devnull t = (char*)f->to;
384 91c13e54 2004-02-29 devnull s = (char*)f->stop;
385 91c13e54 2004-02-29 devnull for(i = 0; i < n; i++){
386 91c13e54 2004-02-29 devnull if(i == pt){
387 91c13e54 2004-02-29 devnull FMTCHAR(f, t, s, '.');
389 91c13e54 2004-02-29 devnull FMTCHAR(f, t, s, '0');
391 91c13e54 2004-02-29 devnull f->nfmt += t - (char *)f->to;
392 91c13e54 2004-02-29 devnull f->to = t;
394 91c13e54 2004-02-29 devnull return 0;
398 91c13e54 2004-02-29 devnull __efgfmt(Fmt *fmt)
400 91c13e54 2004-02-29 devnull double f;
401 91c13e54 2004-02-29 devnull char s1[NSIGNIF+10];
402 91c13e54 2004-02-29 devnull int e, d, n;
403 91c13e54 2004-02-29 devnull int c1, c2, c3, c4, ucase, sign, chr, prec, fl;
405 91c13e54 2004-02-29 devnull f = va_arg(fmt->args, double);
406 91c13e54 2004-02-29 devnull prec = FDEFLT;
407 91c13e54 2004-02-29 devnull fl = fmt->flags;
408 91c13e54 2004-02-29 devnull fmt->flags = 0;
409 91c13e54 2004-02-29 devnull if(fl & FmtPrec)
410 91c13e54 2004-02-29 devnull prec = fmt->prec;
411 91c13e54 2004-02-29 devnull chr = fmt->r;
412 91c13e54 2004-02-29 devnull ucase = 0;
413 91c13e54 2004-02-29 devnull if(chr == 'E'){
414 91c13e54 2004-02-29 devnull chr = 'e';
415 91c13e54 2004-02-29 devnull ucase = 1;
416 91c13e54 2004-02-29 devnull }else if(chr == 'F'){
417 91c13e54 2004-02-29 devnull chr = 'f';
418 91c13e54 2004-02-29 devnull ucase = 1;
419 91c13e54 2004-02-29 devnull }else if(chr == 'G'){
420 91c13e54 2004-02-29 devnull chr = 'g';
421 91c13e54 2004-02-29 devnull ucase = 1;
423 91c13e54 2004-02-29 devnull if(prec > 0 && chr == 'g')
425 91c13e54 2004-02-29 devnull if(prec < 0)
426 91c13e54 2004-02-29 devnull prec = 0;
428 91c13e54 2004-02-29 devnull xdodtoa(s1, f, chr, prec, &e, &sign);
430 91c13e54 2004-02-29 devnull if(*s1 == 'i' || *s1 == 'n'){
431 91c13e54 2004-02-29 devnull if(ucase){
432 91c13e54 2004-02-29 devnull if(*s1 == 'i'){
433 91c13e54 2004-02-29 devnull strcpy(s1, "INF");
435 91c13e54 2004-02-29 devnull strcpy(s1, "NAN");
438 91c13e54 2004-02-29 devnull fmt->flags = fl & (FmtWidth|FmtLeft);
439 91c13e54 2004-02-29 devnull return __fmtcpy(fmt, (const void*)s1, 3, 3);
443 91c13e54 2004-02-29 devnull * copy into final place
444 91c13e54 2004-02-29 devnull * c1 digits of leading '0'
445 91c13e54 2004-02-29 devnull * c2 digits from conversion
446 91c13e54 2004-02-29 devnull * c3 digits of trailing '0'
447 91c13e54 2004-02-29 devnull * c4 digits after '.'
450 91c13e54 2004-02-29 devnull c2 = prec + 1;
452 91c13e54 2004-02-29 devnull c4 = prec;
453 91c13e54 2004-02-29 devnull switch(chr) {
454 91c13e54 2004-02-29 devnull default:
455 91c13e54 2004-02-29 devnull chr = 'e';
457 91c13e54 2004-02-29 devnull case 'g':
459 91c13e54 2004-02-29 devnull * decide on 'e' of 'f' style convers
461 91c13e54 2004-02-29 devnull if(e >= -4 && e <= prec) {
462 91c13e54 2004-02-29 devnull c1 = -e;
463 91c13e54 2004-02-29 devnull c4 = prec - e;
464 91c13e54 2004-02-29 devnull chr = 'h'; /* flag for 'f' style */
467 91c13e54 2004-02-29 devnull case 'f':
468 91c13e54 2004-02-29 devnull c1 = -e;
469 91c13e54 2004-02-29 devnull if(c1 > prec)
470 91c13e54 2004-02-29 devnull c1 = prec + 1;
471 91c13e54 2004-02-29 devnull c2 += e;
476 91c13e54 2004-02-29 devnull * clean up c1 c2 and c3
478 91c13e54 2004-02-29 devnull if(c1 < 0)
480 91c13e54 2004-02-29 devnull if(c2 < 0)
482 91c13e54 2004-02-29 devnull if(c2 > NSIGNIF) {
483 91c13e54 2004-02-29 devnull c3 = c2-NSIGNIF;
484 91c13e54 2004-02-29 devnull c2 = NSIGNIF;
488 91c13e54 2004-02-29 devnull * trim trailing zeros for %g
490 91c13e54 2004-02-29 devnull if(!(fl & FmtSharp)
491 91c13e54 2004-02-29 devnull && (chr == 'g' || chr == 'h')){
492 91c13e54 2004-02-29 devnull if(c4 >= c3){
493 91c13e54 2004-02-29 devnull c4 -= c3;
496 91c13e54 2004-02-29 devnull c3 -= c4;
499 91c13e54 2004-02-29 devnull while(c4 && c2 > 1 && s1[c2 - 1] == '0'){
506 91c13e54 2004-02-29 devnull * calculate the total length
508 91c13e54 2004-02-29 devnull n = c1 + c2 + c3;
509 91c13e54 2004-02-29 devnull if(sign || (fl & (FmtSign|FmtSpace)))
511 91c13e54 2004-02-29 devnull if(c4 || (fl & FmtSharp)){
514 91c13e54 2004-02-29 devnull if(chr == 'e' || chr == 'g'){
516 91c13e54 2004-02-29 devnull if(e >= 100)
521 91c13e54 2004-02-29 devnull * pad to width if right justified
523 91c13e54 2004-02-29 devnull if((fl & (FmtWidth|FmtLeft)) == FmtWidth && n < fmt->width){
524 91c13e54 2004-02-29 devnull if(fl & FmtZero){
525 91c13e54 2004-02-29 devnull c1 += fmt->width - n;
527 91c13e54 2004-02-29 devnull if(__fmtpad(fmt, fmt->width - n) < 0){
528 91c13e54 2004-02-29 devnull return -1;
537 91c13e54 2004-02-29 devnull if(sign)
538 91c13e54 2004-02-29 devnull d = '-';
539 91c13e54 2004-02-29 devnull else if(fl & FmtSign)
540 91c13e54 2004-02-29 devnull d = '+';
541 91c13e54 2004-02-29 devnull else if(fl & FmtSpace)
542 91c13e54 2004-02-29 devnull d = ' ';
543 91c13e54 2004-02-29 devnull if(d && fmtrune(fmt, d) < 0){
544 91c13e54 2004-02-29 devnull return -1;
548 91c13e54 2004-02-29 devnull * copy digits
550 91c13e54 2004-02-29 devnull c4 = c1 + c2 + c3 - c4;
551 91c13e54 2004-02-29 devnull if(c1 > 0){
552 91c13e54 2004-02-29 devnull if(fmtzdotpad(fmt, c1, c4) < 0){
553 91c13e54 2004-02-29 devnull return -1;
555 91c13e54 2004-02-29 devnull c4 -= c1;
558 91c13e54 2004-02-29 devnull if(c4 >= 0 && c4 < c2){
559 91c13e54 2004-02-29 devnull if(__fmtcpy(fmt, s1, c4, c4) < 0 || fmtrune(fmt, '.') < 0)
560 91c13e54 2004-02-29 devnull return -1;
562 91c13e54 2004-02-29 devnull c2 -= c4;
563 91c13e54 2004-02-29 devnull c4 = -1;
565 91c13e54 2004-02-29 devnull if(__fmtcpy(fmt, (const void*)(s1 + d), c2, c2) < 0){
566 91c13e54 2004-02-29 devnull return -1;
568 91c13e54 2004-02-29 devnull c4 -= c2;
569 91c13e54 2004-02-29 devnull if(c3 > 0){
570 91c13e54 2004-02-29 devnull if(fmtzdotpad(fmt, c3, c4) < 0){
571 91c13e54 2004-02-29 devnull return -1;
573 91c13e54 2004-02-29 devnull c4 -= c3;
577 91c13e54 2004-02-29 devnull * strip trailing '0' on g conv
579 91c13e54 2004-02-29 devnull if((fl & FmtSharp) && c4 == 0 && fmtrune(fmt, '.') < 0){
580 91c13e54 2004-02-29 devnull return -1;
582 91c13e54 2004-02-29 devnull if(chr == 'e' || chr == 'g') {
584 91c13e54 2004-02-29 devnull if(ucase)
585 91c13e54 2004-02-29 devnull s1[d++] = 'E';
587 91c13e54 2004-02-29 devnull s1[d++] = 'e';
589 91c13e54 2004-02-29 devnull if(c1 < 0) {
590 91c13e54 2004-02-29 devnull s1[d++] = '-';
591 91c13e54 2004-02-29 devnull c1 = -c1;
593 91c13e54 2004-02-29 devnull s1[d++] = '+';
594 91c13e54 2004-02-29 devnull if(c1 >= 100) {
595 91c13e54 2004-02-29 devnull s1[d++] = c1/100 + '0';
596 91c13e54 2004-02-29 devnull c1 = c1%100;
598 91c13e54 2004-02-29 devnull s1[d++] = c1/10 + '0';
599 91c13e54 2004-02-29 devnull s1[d++] = c1%10 + '0';
600 91c13e54 2004-02-29 devnull if(__fmtcpy(fmt, s1, d, d) < 0){
601 91c13e54 2004-02-29 devnull return -1;
604 91c13e54 2004-02-29 devnull if((fl & (FmtWidth|FmtLeft)) == (FmtWidth|FmtLeft) && n < fmt->width){
605 91c13e54 2004-02-29 devnull if(__fmtpad(fmt, fmt->width - n) < 0){
606 91c13e54 2004-02-29 devnull return -1;
609 91c13e54 2004-02-29 devnull return 0;