vx32

Local 9vx git repository for patches.
git clone git://r-36.net/vx32
Log | Files | Refs

fmt.c (65393B)


      1 /*
      2  * The authors of this software are Rob Pike and Ken Thompson,
      3  * with contributions from Mike Burrows and Sean Dorward.
      4  *
      5  *     Copyright (c) 2002-2006 by Lucent Technologies.
      6  *     Portions Copyright (c) 2004 Google Inc.
      7  * 
      8  * Permission to use, copy, modify, and distribute this software for any
      9  * purpose without fee is hereby granted, provided that this entire notice
     10  * is included in all copies of any software which is or includes a copy
     11  * or modification of this software and in all copies of the supporting
     12  * documentation for such software.
     13  * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
     14  * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES 
     15  * NOR GOOGLE INC MAKE ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING 
     16  * THE MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
     17  */
     18 #include <stdio.h>
     19 #include <math.h>
     20 #include <float.h>
     21 #include <string.h>
     22 #include <stdlib.h>
     23 #include <errno.h>
     24 #include <stdarg.h>
     25 #include <assert.h>
     26 #include <ctype.h>
     27 #include <unistd.h>
     28 #include "u.h"
     29 #include "utf.h"
     30 #include "fmt.h"
     31 
     32 #define PLAN9PORT /* Get Plan 9 verbs */
     33 
     34 /*
     35  * compiler directive on Plan 9
     36  */
     37 #ifndef USED
     38 #define USED(x) if(x);else
     39 #endif
     40 
     41 /*
     42  * nil cannot be ((void*)0) on ANSI C,
     43  * because it is used for function pointers
     44  */
     45 #undef	nil
     46 #define	nil	0
     47 
     48 #undef	nelem
     49 #define	nelem(x)	(sizeof (x)/sizeof (x)[0])
     50 
     51 /* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
     52 
     53 /*
     54  * dofmt -- format to a buffer
     55  * the number of characters formatted is returned,
     56  * or -1 if there was an error.
     57  * if the buffer is ever filled, flush is called.
     58  * it should reset the buffer and return whether formatting should continue.
     59  */
     60 
     61 typedef int (*Fmts)(Fmt*);
     62 
     63 typedef struct Quoteinfo Quoteinfo;
     64 struct Quoteinfo
     65 {
     66 	int	quoted;		/* if set, string must be quoted */
     67 	int	nrunesin;	/* number of input runes that can be accepted */
     68 	int	nbytesin;	/* number of input bytes that can be accepted */
     69 	int	nrunesout;	/* number of runes that will be generated */
     70 	int	nbytesout;	/* number of bytes that will be generated */
     71 };
     72 
     73 /* Edit .+1,/^$/ |cfn |grep -v static | grep __ */
     74 double       __Inf(int sign);
     75 double       __NaN(void);
     76 int          __badfmt(Fmt *f);
     77 int          __charfmt(Fmt *f);
     78 int          __countfmt(Fmt *f);
     79 int          __efgfmt(Fmt *fmt);
     80 int          __errfmt(Fmt *f);
     81 int          __flagfmt(Fmt *f);
     82 int          __fmtFdFlush(Fmt *f);
     83 int          __fmtcpy(Fmt *f, const void *vm, int n, int sz);
     84 void*        __fmtdispatch(Fmt *f, void *fmt, int isrunes);
     85 void *       __fmtflush(Fmt *f, void *t, int len);
     86 void         __fmtlock(void);
     87 int          __fmtpad(Fmt *f, int n);
     88 double       __fmtpow10(int n);
     89 int          __fmtrcpy(Fmt *f, const void *vm, int n);
     90 void         __fmtunlock(void);
     91 int          __ifmt(Fmt *f);
     92 int          __isInf(double d, int sign);
     93 int          __isNaN(double d);
     94 int          __needsep(int*, char**);
     95 int          __needsquotes(char *s, int *quotelenp);
     96 int          __percentfmt(Fmt *f);
     97 void         __quotesetup(char *s, Rune *r, int nin, int nout, Quoteinfo *q, int sharp, int runesout);
     98 int          __quotestrfmt(int runesin, Fmt *f);
     99 int          __rfmtpad(Fmt *f, int n);
    100 int          __runefmt(Fmt *f);
    101 int          __runeneedsquotes(Rune *r, int *quotelenp);
    102 int          __runesfmt(Fmt *f);
    103 int          __strfmt(Fmt *f);
    104 
    105 #define FMTCHAR(f, t, s, c)\
    106 	do{\
    107 	if(t + 1 > (char*)s){\
    108 		t = (char*)__fmtflush(f, t, 1);\
    109 		if(t != nil)\
    110 			s = (char*)f->stop;\
    111 		else\
    112 			return -1;\
    113 	}\
    114 	*t++ = c;\
    115 	}while(0)
    116 
    117 #define FMTRCHAR(f, t, s, c)\
    118 	do{\
    119 	if(t + 1 > (Rune*)s){\
    120 		t = (Rune*)__fmtflush(f, t, sizeof(Rune));\
    121 		if(t != nil)\
    122 			s = (Rune*)f->stop;\
    123 		else\
    124 			return -1;\
    125 	}\
    126 	*t++ = c;\
    127 	}while(0)
    128 
    129 #define FMTRUNE(f, t, s, r)\
    130 	do{\
    131 	Rune _rune;\
    132 	int _runelen;\
    133 	if(t + UTFmax > (char*)s && t + (_runelen = runelen(r)) > (char*)s){\
    134 		t = (char*)__fmtflush(f, t, _runelen);\
    135 		if(t != nil)\
    136 			s = (char*)f->stop;\
    137 		else\
    138 			return -1;\
    139 	}\
    140 	if(r < Runeself)\
    141 		*t++ = r;\
    142 	else{\
    143 		_rune = r;\
    144 		t += runetochar(t, &_rune);\
    145 	}\
    146 	}while(0)
    147 
    148 #ifdef va_copy
    149 #	define VA_COPY(a,b) va_copy(a,b)
    150 #	define VA_END(a) va_end(a)
    151 #else
    152 #	define VA_COPY(a,b) (a) = (b)
    153 #	define VA_END(a)
    154 #endif
    155 
    156 
    157 /* ---------- end preamble -------- */
    158 
    159 /* -------------- charstod.c --------------- */
    160 /* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
    161 // #include <stdarg.h>
    162 // #include <string.h>
    163 // #include "plan9.h"
    164 // #include "fmt.h"
    165 // #include "fmtdef.h"
    166 
    167 /*
    168  * Reads a floating-point number by interpreting successive characters
    169  * returned by (*f)(vp).  The last call it makes to f terminates the
    170  * scan, so is not a character in the number.  It may therefore be
    171  * necessary to back up the input stream up one byte after calling charstod.
    172  */
    173 
    174 double
    175 fmtcharstod(int(*f)(void*), void *vp)
    176 {
    177 	double num, dem;
    178 	int neg, eneg, dig, exp, c;
    179 
    180 	num = 0;
    181 	neg = 0;
    182 	dig = 0;
    183 	exp = 0;
    184 	eneg = 0;
    185 
    186 	c = (*f)(vp);
    187 	while(c == ' ' || c == '\t')
    188 		c = (*f)(vp);
    189 	if(c == '-' || c == '+'){
    190 		if(c == '-')
    191 			neg = 1;
    192 		c = (*f)(vp);
    193 	}
    194 	while(c >= '0' && c <= '9'){
    195 		num = num*10 + c-'0';
    196 		c = (*f)(vp);
    197 	}
    198 	if(c == '.')
    199 		c = (*f)(vp);
    200 	while(c >= '0' && c <= '9'){
    201 		num = num*10 + c-'0';
    202 		dig++;
    203 		c = (*f)(vp);
    204 	}
    205 	if(c == 'e' || c == 'E'){
    206 		c = (*f)(vp);
    207 		if(c == '-' || c == '+'){
    208 			if(c == '-'){
    209 				dig = -dig;
    210 				eneg = 1;
    211 			}
    212 			c = (*f)(vp);
    213 		}
    214 		while(c >= '0' && c <= '9'){
    215 			exp = exp*10 + c-'0';
    216 			c = (*f)(vp);
    217 		}
    218 	}
    219 	exp -= dig;
    220 	if(exp < 0){
    221 		exp = -exp;
    222 		eneg = !eneg;
    223 	}
    224 	dem = __fmtpow10(exp);
    225 	if(eneg)
    226 		num /= dem;
    227 	else
    228 		num *= dem;
    229 	if(neg)
    230 		return -num;
    231 	return num;
    232 }
    233 /* -------------- dofmt.c --------------- */
    234 /* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
    235 /* Copyright (c) 2004 Google Inc.; see LICENSE */
    236 
    237 // #include <stdarg.h>
    238 // #include <string.h>
    239 // #include "plan9.h"
    240 // #include "fmt.h"
    241 // #include "fmtdef.h"
    242 
    243 /* format the output into f->to and return the number of characters fmted  */
    244 int
    245 dofmt(Fmt *f, char *fmt)
    246 {
    247 	Rune rune, *rt, *rs;
    248 	int r;
    249 	char *t, *s;
    250 	int n, nfmt;
    251 
    252 	nfmt = f->nfmt;
    253 	for(;;){
    254 		if(f->runes){
    255 			rt = (Rune*)f->to;
    256 			rs = (Rune*)f->stop;
    257 			while((r = *(uchar*)fmt) && r != '%'){
    258 				if(r < Runeself)
    259 					fmt++;
    260 				else{
    261 					fmt += chartorune(&rune, fmt);
    262 					r = rune;
    263 				}
    264 				FMTRCHAR(f, rt, rs, r);
    265 			}
    266 			fmt++;
    267 			f->nfmt += rt - (Rune *)f->to;
    268 			f->to = rt;
    269 			if(!r)
    270 				return f->nfmt - nfmt;
    271 			f->stop = rs;
    272 		}else{
    273 			t = (char*)f->to;
    274 			s = (char*)f->stop;
    275 			while((r = *(uchar*)fmt) && r != '%'){
    276 				if(r < Runeself){
    277 					FMTCHAR(f, t, s, r);
    278 					fmt++;
    279 				}else{
    280 					n = chartorune(&rune, fmt);
    281 					if(t + n > s){
    282 						t = (char*)__fmtflush(f, t, n);
    283 						if(t != nil)
    284 							s = (char*)f->stop;
    285 						else
    286 							return -1;
    287 					}
    288 					while(n--)
    289 						*t++ = *fmt++;
    290 				}
    291 			}
    292 			fmt++;
    293 			f->nfmt += t - (char *)f->to;
    294 			f->to = t;
    295 			if(!r)
    296 				return f->nfmt - nfmt;
    297 			f->stop = s;
    298 		}
    299 
    300 		fmt = (char*)__fmtdispatch(f, fmt, 0);
    301 		if(fmt == nil)
    302 			return -1;
    303 	}
    304 }
    305 
    306 void *
    307 __fmtflush(Fmt *f, void *t, int len)
    308 {
    309 	if(f->runes)
    310 		f->nfmt += (Rune*)t - (Rune*)f->to;
    311 	else
    312 		f->nfmt += (char*)t - (char *)f->to;
    313 	f->to = t;
    314 	if(f->flush == 0 || (*f->flush)(f) == 0 || (char*)f->to + len > (char*)f->stop){
    315 		f->stop = f->to;
    316 		return nil;
    317 	}
    318 	return f->to;
    319 }
    320 
    321 /*
    322  * put a formatted block of memory sz bytes long of n runes into the output buffer,
    323  * left/right justified in a field of at least f->width characters (if FmtWidth is set)
    324  */
    325 int
    326 __fmtpad(Fmt *f, int n)
    327 {
    328 	char *t, *s;
    329 	int i;
    330 
    331 	t = (char*)f->to;
    332 	s = (char*)f->stop;
    333 	for(i = 0; i < n; i++)
    334 		FMTCHAR(f, t, s, ' ');
    335 	f->nfmt += t - (char *)f->to;
    336 	f->to = t;
    337 	return 0;
    338 }
    339 
    340 int
    341 __rfmtpad(Fmt *f, int n)
    342 {
    343 	Rune *t, *s;
    344 	int i;
    345 
    346 	t = (Rune*)f->to;
    347 	s = (Rune*)f->stop;
    348 	for(i = 0; i < n; i++)
    349 		FMTRCHAR(f, t, s, ' ');
    350 	f->nfmt += t - (Rune *)f->to;
    351 	f->to = t;
    352 	return 0;
    353 }
    354 
    355 int
    356 __fmtcpy(Fmt *f, const void *vm, int n, int sz)
    357 {
    358 	Rune *rt, *rs, r;
    359 	char *t, *s, *m, *me;
    360 	ulong fl;
    361 	int nc, w;
    362 
    363 	m = (char*)vm;
    364 	me = m + sz;
    365 	fl = f->flags;
    366 	w = 0;
    367 	if(fl & FmtWidth)
    368 		w = f->width;
    369 	if((fl & FmtPrec) && n > f->prec)
    370 		n = f->prec;
    371 	if(f->runes){
    372 		if(!(fl & FmtLeft) && __rfmtpad(f, w - n) < 0)
    373 			return -1;
    374 		rt = (Rune*)f->to;
    375 		rs = (Rune*)f->stop;
    376 		for(nc = n; nc > 0; nc--){
    377 			r = *(uchar*)m;
    378 			if(r < Runeself)
    379 				m++;
    380 			else if((me - m) >= UTFmax || fullrune(m, me-m))
    381 				m += chartorune(&r, m);
    382 			else
    383 				break;
    384 			FMTRCHAR(f, rt, rs, r);
    385 		}
    386 		f->nfmt += rt - (Rune *)f->to;
    387 		f->to = rt;
    388 		if(fl & FmtLeft && __rfmtpad(f, w - n) < 0)
    389 			return -1;
    390 	}else{
    391 		if(!(fl & FmtLeft) && __fmtpad(f, w - n) < 0)
    392 			return -1;
    393 		t = (char*)f->to;
    394 		s = (char*)f->stop;
    395 		for(nc = n; nc > 0; nc--){
    396 			r = *(uchar*)m;
    397 			if(r < Runeself)
    398 				m++;
    399 			else if((me - m) >= UTFmax || fullrune(m, me-m))
    400 				m += chartorune(&r, m);
    401 			else
    402 				break;
    403 			FMTRUNE(f, t, s, r);
    404 		}
    405 		f->nfmt += t - (char *)f->to;
    406 		f->to = t;
    407 		if(fl & FmtLeft && __fmtpad(f, w - n) < 0)
    408 			return -1;
    409 	}
    410 	return 0;
    411 }
    412 
    413 int
    414 __fmtrcpy(Fmt *f, const void *vm, int n)
    415 {
    416 	Rune r, *m, *me, *rt, *rs;
    417 	char *t, *s;
    418 	ulong fl;
    419 	int w;
    420 
    421 	m = (Rune*)vm;
    422 	fl = f->flags;
    423 	w = 0;
    424 	if(fl & FmtWidth)
    425 		w = f->width;
    426 	if((fl & FmtPrec) && n > f->prec)
    427 		n = f->prec;
    428 	if(f->runes){
    429 		if(!(fl & FmtLeft) && __rfmtpad(f, w - n) < 0)
    430 			return -1;
    431 		rt = (Rune*)f->to;
    432 		rs = (Rune*)f->stop;
    433 		for(me = m + n; m < me; m++)
    434 			FMTRCHAR(f, rt, rs, *m);
    435 		f->nfmt += rt - (Rune *)f->to;
    436 		f->to = rt;
    437 		if(fl & FmtLeft && __rfmtpad(f, w - n) < 0)
    438 			return -1;
    439 	}else{
    440 		if(!(fl & FmtLeft) && __fmtpad(f, w - n) < 0)
    441 			return -1;
    442 		t = (char*)f->to;
    443 		s = (char*)f->stop;
    444 		for(me = m + n; m < me; m++){
    445 			r = *m;
    446 			FMTRUNE(f, t, s, r);
    447 		}
    448 		f->nfmt += t - (char *)f->to;
    449 		f->to = t;
    450 		if(fl & FmtLeft && __fmtpad(f, w - n) < 0)
    451 			return -1;
    452 	}
    453 	return 0;
    454 }
    455 
    456 /* fmt out one character */
    457 int
    458 __charfmt(Fmt *f)
    459 {
    460 	char x[1];
    461 
    462 	x[0] = va_arg(f->args, int);
    463 	f->prec = 1;
    464 	return __fmtcpy(f, (const char*)x, 1, 1);
    465 }
    466 
    467 /* fmt out one rune */
    468 int
    469 __runefmt(Fmt *f)
    470 {
    471 	Rune x[1];
    472 
    473 	x[0] = va_arg(f->args, int);
    474 	return __fmtrcpy(f, (const void*)x, 1);
    475 }
    476 
    477 /* public helper routine: fmt out a null terminated string already in hand */
    478 int
    479 fmtstrcpy(Fmt *f, char *s)
    480 {
    481 	int i, j;
    482 
    483 	if(!s)
    484 		return __fmtcpy(f, "<nil>", 5, 5);
    485 	/* if precision is specified, make sure we don't wander off the end */
    486 	if(f->flags & FmtPrec){
    487 #ifdef PLAN9PORT
    488 		Rune r;
    489 		i = 0;
    490 		for(j=0; j<f->prec && s[i]; j++)
    491 			i += chartorune(&r, s+i);
    492 #else
    493 		/* ANSI requires precision in bytes, not Runes */
    494 		for(i=0; i<f->prec; i++)
    495 			if(s[i] == 0)
    496 				break;
    497 		j = utfnlen(s, i);	/* won't print partial at end */
    498 #endif
    499 		return __fmtcpy(f, s, j, i);
    500 	}
    501 	return __fmtcpy(f, s, utflen(s), strlen(s));
    502 }
    503 
    504 /* fmt out a null terminated utf string */
    505 int
    506 __strfmt(Fmt *f)
    507 {
    508 	char *s;
    509 
    510 	s = va_arg(f->args, char *);
    511 	return fmtstrcpy(f, s);
    512 }
    513 
    514 /* public helper routine: fmt out a null terminated rune string already in hand */
    515 int
    516 fmtrunestrcpy(Fmt *f, Rune *s)
    517 {
    518 	Rune *e;
    519 	int n, p;
    520 
    521 	if(!s)
    522 		return __fmtcpy(f, "<nil>", 5, 5);
    523 	/* if precision is specified, make sure we don't wander off the end */
    524 	if(f->flags & FmtPrec){
    525 		p = f->prec;
    526 		for(n = 0; n < p; n++)
    527 			if(s[n] == 0)
    528 				break;
    529 	}else{
    530 		for(e = s; *e; e++)
    531 			;
    532 		n = e - s;
    533 	}
    534 	return __fmtrcpy(f, s, n);
    535 }
    536 
    537 /* fmt out a null terminated rune string */
    538 int
    539 __runesfmt(Fmt *f)
    540 {
    541 	Rune *s;
    542 
    543 	s = va_arg(f->args, Rune *);
    544 	return fmtrunestrcpy(f, s);
    545 }
    546 
    547 /* fmt a % */
    548 int
    549 __percentfmt(Fmt *f)
    550 {
    551 	Rune x[1];
    552 
    553 	x[0] = f->r;
    554 	f->prec = 1;
    555 	return __fmtrcpy(f, (const void*)x, 1);
    556 }
    557 
    558 /* fmt an integer */
    559 int
    560 __ifmt(Fmt *f)
    561 {
    562 	char buf[140], *p, *conv;
    563 	/* 140: for 64 bits of binary + 3-byte sep every 4 digits */
    564 	uvlong vu;
    565 	ulong u;
    566 	int neg, base, i, n, fl, w, isv;
    567 	int ndig, len, excess, bytelen;
    568 	char *grouping;
    569 	char *thousands;
    570 
    571 	neg = 0;
    572 	fl = f->flags;
    573 	isv = 0;
    574 	vu = 0;
    575 	u = 0;
    576 #ifndef PLAN9PORT
    577 	/*
    578 	 * Unsigned verbs for ANSI C
    579 	 */
    580 	switch(f->r){
    581 	case 'o':
    582 	case 'p':
    583 	case 'u':
    584 	case 'x':
    585 	case 'X':
    586 		fl |= FmtUnsigned;
    587 		fl &= ~(FmtSign|FmtSpace);
    588 		break;
    589 	}
    590 #endif
    591 	if(f->r == 'p'){
    592 		u = (ulong)va_arg(f->args, void*);
    593 		f->r = 'x';
    594 		fl |= FmtUnsigned;
    595 	}else if(fl & FmtVLong){
    596 		isv = 1;
    597 		if(fl & FmtUnsigned)
    598 			vu = va_arg(f->args, uvlong);
    599 		else
    600 			vu = va_arg(f->args, vlong);
    601 	}else if(fl & FmtLong){
    602 		if(fl & FmtUnsigned)
    603 			u = va_arg(f->args, ulong);
    604 		else
    605 			u = va_arg(f->args, long);
    606 	}else if(fl & FmtByte){
    607 		if(fl & FmtUnsigned)
    608 			u = (uchar)va_arg(f->args, int);
    609 		else
    610 			u = (char)va_arg(f->args, int);
    611 	}else if(fl & FmtShort){
    612 		if(fl & FmtUnsigned)
    613 			u = (ushort)va_arg(f->args, int);
    614 		else
    615 			u = (short)va_arg(f->args, int);
    616 	}else{
    617 		if(fl & FmtUnsigned)
    618 			u = va_arg(f->args, uint);
    619 		else
    620 			u = va_arg(f->args, int);
    621 	}
    622 	conv = "0123456789abcdef";
    623 	grouping = "\4";	/* for hex, octal etc. (undefined by spec but nice) */
    624 	thousands = f->thousands;
    625 	switch(f->r){
    626 	case 'd':
    627 	case 'i':
    628 	case 'u':
    629 		base = 10;
    630 		grouping = f->grouping;
    631 		break;
    632 	case 'X':
    633 		conv = "0123456789ABCDEF";
    634 		/* fall through */
    635 	case 'x':
    636 		base = 16;
    637 		thousands = ":";
    638 		break;
    639 	case 'b':
    640 		base = 2;
    641 		thousands = ":";
    642 		break;
    643 	case 'o':
    644 		base = 8;
    645 		break;
    646 	default:
    647 		return -1;
    648 	}
    649 	if(!(fl & FmtUnsigned)){
    650 		if(isv && (vlong)vu < 0){
    651 			vu = -(vlong)vu;
    652 			neg = 1;
    653 		}else if(!isv && (long)u < 0){
    654 			u = -(long)u;
    655 			neg = 1;
    656 		}
    657 	}
    658 	p = buf + sizeof buf - 1;
    659 	n = 0;	/* in runes */
    660 	excess = 0;	/* number of bytes > number runes */
    661 	ndig = 0;
    662 	len = utflen(thousands);
    663 	bytelen = strlen(thousands);
    664 	if(isv){
    665 		while(vu){
    666 			i = vu % base;
    667 			vu /= base;
    668 			if((fl & FmtComma) && n % 4 == 3){
    669 				*p-- = ',';
    670 				n++;
    671 			}
    672 			if((fl & FmtApost) && __needsep(&ndig, &grouping)){
    673 				n += len;
    674 				excess += bytelen - len;
    675 				p -= bytelen;
    676 				memmove(p+1, thousands, bytelen);
    677 			}
    678 			*p-- = conv[i];
    679 			n++;
    680 		}
    681 	}else{
    682 		while(u){
    683 			i = u % base;
    684 			u /= base;
    685 			if((fl & FmtComma) && n % 4 == 3){
    686 				*p-- = ',';
    687 				n++;
    688 			}
    689 			if((fl & FmtApost) && __needsep(&ndig, &grouping)){
    690 				n += len;
    691 				excess += bytelen - len;
    692 				p -= bytelen;
    693 				memmove(p+1, thousands, bytelen);
    694 			}
    695 			*p-- = conv[i];
    696 			n++;
    697 		}
    698 	}
    699 	if(n == 0){
    700 		/*
    701 		 * "The result of converting a zero value with
    702 		 * a precision of zero is no characters."  - ANSI
    703 		 *
    704 		 * "For o conversion, # increases the precision, if and only if
    705 		 * necessary, to force the first digit of the result to be a zero
    706 		 * (if the value and precision are both 0, a single 0 is printed)." - ANSI
    707 		 */
    708 		if(!(fl & FmtPrec) || f->prec != 0 || (f->r == 'o' && (fl & FmtSharp))){
    709 			*p-- = '0';
    710 			n = 1;
    711 			if(fl & FmtApost)
    712 				__needsep(&ndig, &grouping);
    713 		}
    714 		
    715 		/*
    716 		 * Zero values don't get 0x.
    717 		 */
    718 		if(f->r == 'x' || f->r == 'X')
    719 			fl &= ~FmtSharp;
    720 	}
    721 	for(w = f->prec; n < w && p > buf+3; n++){
    722 		if((fl & FmtApost) && __needsep(&ndig, &grouping)){
    723 			n += len;
    724 			excess += bytelen - len;
    725 			p -= bytelen;
    726 			memmove(p+1, thousands, bytelen);
    727 		}
    728 		*p-- = '0';
    729 	}
    730 	if(neg || (fl & (FmtSign|FmtSpace)))
    731 		n++;
    732 	if(fl & FmtSharp){
    733 		if(base == 16)
    734 			n += 2;
    735 		else if(base == 8){
    736 			if(p[1] == '0')
    737 				fl &= ~FmtSharp;
    738 			else
    739 				n++;
    740 		}
    741 	}
    742 	if((fl & FmtZero) && !(fl & (FmtLeft|FmtPrec))){
    743 		w = 0;
    744 		if(fl & FmtWidth)
    745 			w = f->width;
    746 		for(; n < w && p > buf+3; n++){
    747 			if((fl & FmtApost) && __needsep(&ndig, &grouping)){
    748 				n += len;
    749 				excess += bytelen - len;
    750 				p -= bytelen;
    751 				memmove(p+1, thousands, bytelen);
    752 			}
    753 			*p-- = '0';
    754 		}
    755 		f->flags &= ~FmtWidth;
    756 	}
    757 	if(fl & FmtSharp){
    758 		if(base == 16)
    759 			*p-- = f->r;
    760 		if(base == 16 || base == 8)
    761 			*p-- = '0';
    762 	}
    763 	if(neg)
    764 		*p-- = '-';
    765 	else if(fl & FmtSign)
    766 		*p-- = '+';
    767 	else if(fl & FmtSpace)
    768 		*p-- = ' ';
    769 	f->flags &= ~FmtPrec;
    770 	return __fmtcpy(f, p + 1, n, n + excess);
    771 }
    772 
    773 int
    774 __countfmt(Fmt *f)
    775 {
    776 	void *p;
    777 	ulong fl;
    778 
    779 	fl = f->flags;
    780 	p = va_arg(f->args, void*);
    781 	if(fl & FmtVLong){
    782 		*(vlong*)p = f->nfmt;
    783 	}else if(fl & FmtLong){
    784 		*(long*)p = f->nfmt;
    785 	}else if(fl & FmtByte){
    786 		*(char*)p = f->nfmt;
    787 	}else if(fl & FmtShort){
    788 		*(short*)p = f->nfmt;
    789 	}else{
    790 		*(int*)p = f->nfmt;
    791 	}
    792 	return 0;
    793 }
    794 
    795 int
    796 __flagfmt(Fmt *f)
    797 {
    798 	switch(f->r){
    799 	case ',':
    800 		f->flags |= FmtComma;
    801 		break;
    802 	case '-':
    803 		f->flags |= FmtLeft;
    804 		break;
    805 	case '+':
    806 		f->flags |= FmtSign;
    807 		break;
    808 	case '#':
    809 		f->flags |= FmtSharp;
    810 		break;
    811 	case '\'':
    812 		f->flags |= FmtApost;
    813 		break;
    814 	case ' ':
    815 		f->flags |= FmtSpace;
    816 		break;
    817 	case 'u':
    818 		f->flags |= FmtUnsigned;
    819 		break;
    820 	case 'h':
    821 		if(f->flags & FmtShort)
    822 			f->flags |= FmtByte;
    823 		f->flags |= FmtShort;
    824 		break;
    825 	case 'L':
    826 		f->flags |= FmtLDouble;
    827 		break;
    828 	case 'l':
    829 		if(f->flags & FmtLong)
    830 			f->flags |= FmtVLong;
    831 		f->flags |= FmtLong;
    832 		break;
    833 	}
    834 	return 1;
    835 }
    836 
    837 /* default error format */
    838 int
    839 __badfmt(Fmt *f)
    840 {
    841 	char x[3];
    842 
    843 	x[0] = '%';
    844 	x[1] = f->r;
    845 	x[2] = '%';
    846 	f->prec = 3;
    847 	__fmtcpy(f, (const void*)x, 3, 3);
    848 	return 0;
    849 }
    850 /* -------------- fltfmt.c --------------- */
    851 /* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
    852 // #include <stdio.h>
    853 // #include <math.h>
    854 // #include <float.h>
    855 // #include <string.h>
    856 // #include <stdlib.h>
    857 // #include <errno.h>
    858 // #include <stdarg.h>
    859 // #include <fmt.h>
    860 // #include <assert.h>
    861 // #include "plan9.h"
    862 // #include "fmt.h"
    863 // #include "fmtdef.h"
    864 // #include "nan.h"
    865 
    866 enum
    867 {
    868 	FDIGIT	= 30,
    869 	FDEFLT	= 6,
    870 	NSIGNIF	= 17
    871 };
    872 
    873 /*
    874  * first few powers of 10, enough for about 1/2 of the
    875  * total space for doubles.
    876  */
    877 static double pows10[] =
    878 {
    879 	  1e0,   1e1,   1e2,   1e3,   1e4,   1e5,   1e6,   1e7,   1e8,   1e9,  
    880 	 1e10,  1e11,  1e12,  1e13,  1e14,  1e15,  1e16,  1e17,  1e18,  1e19,  
    881 	 1e20,  1e21,  1e22,  1e23,  1e24,  1e25,  1e26,  1e27,  1e28,  1e29,  
    882 	 1e30,  1e31,  1e32,  1e33,  1e34,  1e35,  1e36,  1e37,  1e38,  1e39,  
    883 	 1e40,  1e41,  1e42,  1e43,  1e44,  1e45,  1e46,  1e47,  1e48,  1e49,  
    884 	 1e50,  1e51,  1e52,  1e53,  1e54,  1e55,  1e56,  1e57,  1e58,  1e59,  
    885 	 1e60,  1e61,  1e62,  1e63,  1e64,  1e65,  1e66,  1e67,  1e68,  1e69,  
    886 	 1e70,  1e71,  1e72,  1e73,  1e74,  1e75,  1e76,  1e77,  1e78,  1e79,  
    887 	 1e80,  1e81,  1e82,  1e83,  1e84,  1e85,  1e86,  1e87,  1e88,  1e89,  
    888 	 1e90,  1e91,  1e92,  1e93,  1e94,  1e95,  1e96,  1e97,  1e98,  1e99,  
    889 	1e100, 1e101, 1e102, 1e103, 1e104, 1e105, 1e106, 1e107, 1e108, 1e109, 
    890 	1e110, 1e111, 1e112, 1e113, 1e114, 1e115, 1e116, 1e117, 1e118, 1e119, 
    891 	1e120, 1e121, 1e122, 1e123, 1e124, 1e125, 1e126, 1e127, 1e128, 1e129, 
    892 	1e130, 1e131, 1e132, 1e133, 1e134, 1e135, 1e136, 1e137, 1e138, 1e139, 
    893 	1e140, 1e141, 1e142, 1e143, 1e144, 1e145, 1e146, 1e147, 1e148, 1e149, 
    894 	1e150, 1e151, 1e152, 1e153, 1e154, 1e155, 1e156, 1e157, 1e158, 1e159, 
    895 };
    896 #define	npows10 ((int)(sizeof(pows10)/sizeof(pows10[0])))
    897 #define	pow10(x)  fmtpow10(x)
    898 
    899 static double
    900 pow10(int n)
    901 {
    902 	double d;
    903 	int neg;
    904 
    905 	neg = 0;
    906 	if(n < 0){
    907 		if(n < DBL_MIN_10_EXP)
    908 			return 0.;
    909 		neg = 1;
    910 		n = -n;
    911 	}else if(n > DBL_MAX_10_EXP)
    912 		return HUGE_VAL;
    913 
    914 	if(n < npows10)
    915 		d = pows10[n];
    916 	else{
    917 		d = pows10[npows10-1];
    918 		for(;;){
    919 			n -= npows10 - 1;
    920 			if(n < npows10){
    921 				d *= pows10[n];
    922 				break;
    923 			}
    924 			d *= pows10[npows10 - 1];
    925 		}
    926 	}
    927 	if(neg)
    928 		return 1./d;
    929 	return d;
    930 }
    931 
    932 /*
    933  * add 1 to the decimal integer string a of length n.
    934  * if 99999 overflows into 10000, return 1 to tell caller
    935  * to move the virtual decimal point.
    936  */
    937 static int
    938 xadd1(char *a, int n)
    939 {
    940 	char *b;
    941 	int c;
    942 
    943 	if(n < 0 || n > NSIGNIF)
    944 		return 0;
    945 	for(b = a+n-1; b >= a; b--) {
    946 		c = *b + 1;
    947 		if(c <= '9') {
    948 			*b = c;
    949 			return 0;
    950 		}
    951 		*b = '0';
    952 	}
    953 	/*
    954 	 * need to overflow adding digit.
    955 	 * shift number down and insert 1 at beginning.
    956 	 * decimal is known to be 0s or we wouldn't
    957 	 * have gotten this far.  (e.g., 99999+1 => 00000)
    958 	 */
    959 	a[0] = '1';
    960 	return 1;
    961 }
    962 
    963 /*
    964  * subtract 1 from the decimal integer string a.
    965  * if 10000 underflows into 09999, make it 99999
    966  * and return 1 to tell caller to move the virtual 
    967  * decimal point.  this way, xsub1 is inverse of xadd1.
    968  */
    969 static int
    970 xsub1(char *a, int n)
    971 {
    972 	char *b;
    973 	int c;
    974 
    975 	if(n < 0 || n > NSIGNIF)
    976 		return 0;
    977 	for(b = a+n-1; b >= a; b--) {
    978 		c = *b - 1;
    979 		if(c >= '0') {
    980 			if(c == '0' && b == a) {
    981 				/*
    982 				 * just zeroed the top digit; shift everyone up.
    983 				 * decimal is known to be 9s or we wouldn't
    984 				 * have gotten this far.  (e.g., 10000-1 => 09999)
    985 				 */
    986 				*b = '9';
    987 				return 1;
    988 			}
    989 			*b = c;
    990 			return 0;
    991 		}
    992 		*b = '9';
    993 	}
    994 	/*
    995 	 * can't get here.  the number a is always normalized
    996 	 * so that it has a nonzero first digit.
    997 	 */
    998 	abort();
    999 }
   1000 
   1001 /*
   1002  * format exponent like sprintf(p, "e%+02d", e)
   1003  */
   1004 static void
   1005 xfmtexp(char *p, int e, int ucase)
   1006 {
   1007 	char se[9];
   1008 	int i;
   1009 
   1010 	*p++ = ucase ? 'E' : 'e';
   1011 	if(e < 0) {
   1012 		*p++ = '-';
   1013 		e = -e;
   1014 	} else
   1015 		*p++ = '+';
   1016 	i = 0;
   1017 	while(e) {
   1018 		se[i++] = e % 10 + '0';
   1019 		e /= 10;
   1020 	}
   1021 	while(i < 2)
   1022 		se[i++] = '0';
   1023 	while(i > 0)
   1024 		*p++ = se[--i];
   1025 	*p++ = '\0';
   1026 }
   1027 
   1028 /*
   1029  * compute decimal integer m, exp such that:
   1030  *	f = m*10^exp
   1031  *	m is as short as possible with losing exactness
   1032  * assumes special cases (NaN, +Inf, -Inf) have been handled.
   1033  */
   1034 static void
   1035 xdtoa(double f, char *s, int *exp, int *neg, int *ns)
   1036 {
   1037 	int c, d, e2, e, ee, i, ndigit, oerrno;
   1038 	char tmp[NSIGNIF+10];
   1039 	double g;
   1040 
   1041 	oerrno = errno; /* in case strtod smashes errno */
   1042 
   1043 	/*
   1044 	 * make f non-negative.
   1045 	 */
   1046 	*neg = 0;
   1047 	if(f < 0) {
   1048 		f = -f;
   1049 		*neg = 1;
   1050 	}
   1051 
   1052 	/*
   1053 	 * must handle zero specially.
   1054 	 */
   1055 	if(f == 0){
   1056 		*exp = 0;
   1057 		s[0] = '0';
   1058 		s[1] = '\0';
   1059 		*ns = 1;
   1060 		return;
   1061 	}
   1062 		
   1063 	/*
   1064 	 * find g,e such that f = g*10^e.
   1065 	 * guess 10-exponent using 2-exponent, then fine tune.
   1066 	 */
   1067 	frexp(f, &e2);
   1068 	e = (int)(e2 * .301029995664);
   1069 	g = f * pow10(-e);
   1070 	while(g < 1) {
   1071 		e--;
   1072 		g = f * pow10(-e);
   1073 	}
   1074 	while(g >= 10) {
   1075 		e++;
   1076 		g = f * pow10(-e);
   1077 	}
   1078 
   1079 	/*
   1080 	 * convert NSIGNIF digits as a first approximation.
   1081 	 */
   1082 	for(i=0; i<NSIGNIF; i++) {
   1083 		d = (int)g;
   1084 		s[i] = d+'0';
   1085 		g = (g-d) * 10;
   1086 	}
   1087 	s[i] = 0;
   1088 
   1089 	/*
   1090 	 * adjust e because s is 314159... not 3.14159...
   1091 	 */
   1092 	e -= NSIGNIF-1;
   1093 	xfmtexp(s+NSIGNIF, e, 0);
   1094 
   1095 	/*
   1096 	 * adjust conversion until strtod(s) == f exactly.
   1097 	 */
   1098 	for(i=0; i<10; i++) {
   1099 		g = strtod(s, nil);
   1100 		if(f > g) {
   1101 			if(xadd1(s, NSIGNIF)) {
   1102 				/* gained a digit */
   1103 				e--;
   1104 				xfmtexp(s+NSIGNIF, e, 0);
   1105 			}
   1106 			continue;
   1107 		}
   1108 		if(f < g) {
   1109 			if(xsub1(s, NSIGNIF)) {
   1110 				/* lost a digit */
   1111 				e++;
   1112 				xfmtexp(s+NSIGNIF, e, 0);
   1113 			}
   1114 			continue;
   1115 		}
   1116 		break;
   1117 	}
   1118 
   1119 	/*
   1120 	 * play with the decimal to try to simplify.
   1121 	 */
   1122 
   1123 	/*
   1124 	 * bump last few digits up to 9 if we can
   1125 	 */
   1126 	for(i=NSIGNIF-1; i>=NSIGNIF-3; i--) {
   1127 		c = s[i];
   1128 		if(c != '9') {
   1129 			s[i] = '9';
   1130 			g = strtod(s, nil);
   1131 			if(g != f) {
   1132 				s[i] = c;
   1133 				break;
   1134 			}
   1135 		}
   1136 	}
   1137 
   1138 	/*
   1139 	 * add 1 in hopes of turning 9s to 0s
   1140 	 */
   1141 	if(s[NSIGNIF-1] == '9') {
   1142 		strcpy(tmp, s);
   1143 		ee = e;
   1144 		if(xadd1(tmp, NSIGNIF)) {
   1145 			ee--;
   1146 			xfmtexp(tmp+NSIGNIF, ee, 0);
   1147 		}
   1148 		g = strtod(tmp, nil);
   1149 		if(g == f) {
   1150 			strcpy(s, tmp);
   1151 			e = ee;
   1152 		}
   1153 	}
   1154 	
   1155 	/*
   1156 	 * bump last few digits down to 0 as we can.
   1157 	 */
   1158 	for(i=NSIGNIF-1; i>=NSIGNIF-3; i--) {
   1159 		c = s[i];
   1160 		if(c != '0') {
   1161 			s[i] = '0';
   1162 			g = strtod(s, nil);
   1163 			if(g != f) {
   1164 				s[i] = c;
   1165 				break;
   1166 			}
   1167 		}
   1168 	}
   1169 
   1170 	/*
   1171 	 * remove trailing zeros.
   1172 	 */
   1173 	ndigit = NSIGNIF;
   1174 	while(ndigit > 1 && s[ndigit-1] == '0'){
   1175 		e++;
   1176 		--ndigit;
   1177 	}
   1178 	s[ndigit] = 0;
   1179 	*exp = e;
   1180 	*ns = ndigit;
   1181 	errno = oerrno;
   1182 }
   1183 
   1184 #ifdef PLAN9PORT
   1185 static char *special[] = { "NaN", "NaN", "+Inf", "+Inf", "-Inf", "-Inf" };
   1186 #else
   1187 static char *special[] = { "nan", "NAN", "inf", "INF", "-inf", "-INF" };
   1188 #endif
   1189 
   1190 int
   1191 __efgfmt(Fmt *fmt)
   1192 {
   1193 	char buf[NSIGNIF+10], *dot, *digits, *p, *s, suf[10], *t;
   1194 	double f;
   1195 	int c, chr, dotwid, e, exp, fl, ndigits, neg, newndigits;
   1196 	int pad, point, prec, realchr, sign, sufwid, ucase, wid, z1, z2;
   1197 	Rune r, *rs, *rt;
   1198 	
   1199 	f = va_arg(fmt->args, double);
   1200 	
   1201 	/* 
   1202 	 * extract formatting flags
   1203 	 */
   1204 	fl = fmt->flags;
   1205 	fmt->flags = 0;
   1206 	prec = FDEFLT;
   1207 	if(fl & FmtPrec)
   1208 		prec = fmt->prec;
   1209 	chr = fmt->r;
   1210 	ucase = 0;
   1211 	switch(chr) {
   1212 	case 'A':
   1213 	case 'E':
   1214 	case 'F':
   1215 	case 'G':
   1216 		chr += 'a'-'A';
   1217 		ucase = 1;
   1218 		break;
   1219 	}
   1220 
   1221 	/*
   1222 	 * pick off special numbers.
   1223 	 */
   1224 	if(__isNaN(f)) {
   1225 		s = special[0+ucase];
   1226 	special:
   1227 		fmt->flags = fl & (FmtWidth|FmtLeft);
   1228 		return __fmtcpy(fmt, s, strlen(s), strlen(s));
   1229 	}
   1230 	if(__isInf(f, 1)) {
   1231 		s = special[2+ucase];
   1232 		goto special;
   1233 	}
   1234 	if(__isInf(f, -1)) {
   1235 		s = special[4+ucase];
   1236 		goto special;
   1237 	}
   1238 
   1239 	/*
   1240 	 * get exact representation.
   1241 	 */
   1242 	digits = buf;
   1243 	xdtoa(f, digits, &exp, &neg, &ndigits);
   1244 
   1245 	/*
   1246 	 * get locale's decimal point.
   1247 	 */
   1248 	dot = fmt->decimal;
   1249 	if(dot == nil)
   1250 		dot = ".";
   1251 	dotwid = utflen(dot);
   1252 
   1253 	/*
   1254 	 * now the formatting fun begins.
   1255 	 * compute parameters for actual fmt:
   1256 	 *
   1257 	 *	pad: number of spaces to insert before/after field.
   1258 	 *	z1: number of zeros to insert before digits
   1259 	 *	z2: number of zeros to insert after digits
   1260 	 *	point: number of digits to print before decimal point
   1261 	 *	ndigits: number of digits to use from digits[]
   1262 	 *	suf: trailing suffix, like "e-5"
   1263 	 */
   1264 	realchr = chr;
   1265 	switch(chr){
   1266 	case 'g':
   1267 		/*
   1268 		 * convert to at most prec significant digits. (prec=0 means 1)
   1269 		 */
   1270 		if(prec == 0)
   1271 			prec = 1;
   1272 		if(ndigits > prec) {
   1273 			if(digits[prec] >= '5' && xadd1(digits, prec))
   1274 				exp++;
   1275 			exp += ndigits-prec;
   1276 			ndigits = prec;
   1277 		}
   1278 		
   1279 		/*
   1280 		 * extra rules for %g (implemented below):
   1281 		 *	trailing zeros removed after decimal unless FmtSharp.
   1282 		 *	decimal point only if digit follows.
   1283 		 */
   1284 
   1285 		/* fall through to %e */
   1286 	default:
   1287 	case 'e':
   1288 		/* 
   1289 		 * one significant digit before decimal, no leading zeros.
   1290 		 */
   1291 		point = 1;
   1292 		z1 = 0;
   1293 		
   1294 		/*
   1295 		 * decimal point is after ndigits digits right now.
   1296 		 * slide to be after first.
   1297 		 */
   1298 		e  = exp + (ndigits-1);
   1299 
   1300 		/*
   1301 		 * if this is %g, check exponent and convert prec
   1302 		 */
   1303 		if(realchr == 'g') {
   1304 			if(-4 <= e && e < prec)
   1305 				goto casef;
   1306 			prec--;	/* one digit before decimal; rest after */
   1307 		}
   1308 
   1309 		/*
   1310 		 * compute trailing zero padding or truncate digits.
   1311 		 */
   1312 		if(1+prec >= ndigits)
   1313 			z2 = 1+prec - ndigits;
   1314 		else {
   1315 			/*
   1316 			 * truncate digits
   1317 			 */
   1318 			assert(realchr != 'g');
   1319 			newndigits = 1+prec;
   1320 			if(digits[newndigits] >= '5' && xadd1(digits, newndigits)) {
   1321 				/*
   1322 				 * had 999e4, now have 100e5
   1323 				 */
   1324 				e++;
   1325 			}
   1326 			ndigits = newndigits;
   1327 			z2 = 0;
   1328 		}
   1329 		xfmtexp(suf, e, ucase);
   1330 		sufwid = strlen(suf);
   1331 		break;
   1332 
   1333 	casef:
   1334 	case 'f':
   1335 		/*
   1336 		 * determine where digits go with respect to decimal point
   1337 		 */
   1338 		if(ndigits+exp > 0) {
   1339 			point = ndigits+exp;
   1340 			z1 = 0;
   1341 		} else {
   1342 			point = 1;
   1343 			z1 = 1 + -(ndigits+exp);
   1344 		}
   1345 
   1346 		/*
   1347 		 * %g specifies prec = number of significant digits
   1348 		 * convert to number of digits after decimal point
   1349 		 */
   1350 		if(realchr == 'g')
   1351 			prec += z1 - point;
   1352 
   1353 		/*
   1354 		 * compute trailing zero padding or truncate digits.
   1355 		 */
   1356 		if(point+prec >= z1+ndigits)
   1357 			z2 = point+prec - (z1+ndigits);
   1358 		else {
   1359 			/*
   1360 			 * truncate digits
   1361 			 */
   1362 			assert(realchr != 'g');
   1363 			newndigits = point+prec - z1;
   1364 			if(newndigits < 0) {
   1365 				z1 += newndigits;
   1366 				newndigits = 0;
   1367 			} else if(newndigits == 0) {
   1368 				/* perhaps round up */
   1369 				if(digits[0] >= '5'){
   1370 					digits[0] = '1';
   1371 					newndigits = 1;
   1372 					goto newdigit;
   1373 				}
   1374 			} else if(digits[newndigits] >= '5' && xadd1(digits, newndigits)) {
   1375 				/*
   1376 				 * digits was 999, is now 100; make it 1000
   1377 				 */
   1378 				digits[newndigits++] = '0';
   1379 			newdigit:
   1380 				/*
   1381 				 * account for new digit
   1382 				 */
   1383 				if(z1)	/* 0.099 => 0.100 or 0.99 => 1.00*/
   1384 					z1--;
   1385 				else	/* 9.99 => 10.00 */
   1386 					point++;
   1387 			}
   1388 			z2 = 0;
   1389 			ndigits = newndigits;
   1390 		}	
   1391 		sufwid = 0;
   1392 		break;
   1393 	}
   1394 	
   1395 	/*
   1396 	 * if %g is given without FmtSharp, remove trailing zeros.
   1397 	 * must do after truncation, so that e.g. print %.3g 1.001
   1398 	 * produces 1, not 1.00.  sorry, but them's the rules.
   1399 	 */
   1400 	if(realchr == 'g' && !(fl & FmtSharp)) {
   1401 		if(z1+ndigits+z2 >= point) {
   1402 			if(z1+ndigits < point)
   1403 				z2 = point - (z1+ndigits);
   1404 			else{
   1405 				z2 = 0;
   1406 				while(z1+ndigits > point && digits[ndigits-1] == '0')
   1407 					ndigits--;
   1408 			}
   1409 		}
   1410 	}
   1411 
   1412 	/*
   1413 	 * compute width of all digits and decimal point and suffix if any
   1414 	 */
   1415 	wid = z1+ndigits+z2;
   1416 	if(wid > point)
   1417 		wid += dotwid;
   1418 	else if(wid == point){
   1419 		if(fl & FmtSharp)
   1420 			wid += dotwid;
   1421 		else
   1422 			point++;	/* do not print any decimal point */
   1423 	}
   1424 	wid += sufwid;
   1425 
   1426 	/*
   1427 	 * determine sign
   1428 	 */
   1429 	sign = 0;
   1430 	if(neg)
   1431 		sign = '-';
   1432 	else if(fl & FmtSign)
   1433 		sign = '+';
   1434 	else if(fl & FmtSpace)
   1435 		sign = ' ';
   1436 	if(sign)
   1437 		wid++;
   1438 
   1439 	/*
   1440 	 * compute padding
   1441 	 */
   1442 	pad = 0;
   1443 	if((fl & FmtWidth) && fmt->width > wid)
   1444 		pad = fmt->width - wid;
   1445 	if(pad && !(fl & FmtLeft) && (fl & FmtZero)){
   1446 		z1 += pad;
   1447 		point += pad;
   1448 		pad = 0;
   1449 	}
   1450 
   1451 	/*
   1452 	 * format the actual field.  too bad about doing this twice.
   1453 	 */
   1454 	if(fmt->runes){
   1455 		if(pad && !(fl & FmtLeft) && __rfmtpad(fmt, pad) < 0)
   1456 			return -1;
   1457 		rt = (Rune*)fmt->to;
   1458 		rs = (Rune*)fmt->stop;
   1459 		if(sign)
   1460 			FMTRCHAR(fmt, rt, rs, sign);
   1461 		while(z1>0 || ndigits>0 || z2>0) {
   1462 			if(z1 > 0){
   1463 				z1--;
   1464 				c = '0';
   1465 			}else if(ndigits > 0){
   1466 				ndigits--;
   1467 				c = *digits++;
   1468 			}else{
   1469 				z2--;
   1470 				c = '0';
   1471 			}
   1472 			FMTRCHAR(fmt, rt, rs, c);
   1473 			if(--point == 0) {
   1474 				for(p = dot; *p; ){
   1475 					p += chartorune(&r, p);
   1476 					FMTRCHAR(fmt, rt, rs, r);
   1477 				}
   1478 			}
   1479 		}
   1480 		fmt->nfmt += rt - (Rune*)fmt->to;
   1481 		fmt->to = rt;
   1482 		if(sufwid && __fmtcpy(fmt, suf, sufwid, sufwid) < 0)
   1483 			return -1;
   1484 		if(pad && (fl & FmtLeft) && __rfmtpad(fmt, pad) < 0)
   1485 			return -1;
   1486 	}else{
   1487 		if(pad && !(fl & FmtLeft) && __fmtpad(fmt, pad) < 0)
   1488 			return -1;
   1489 		t = (char*)fmt->to;
   1490 		s = (char*)fmt->stop;
   1491 		if(sign)
   1492 			FMTCHAR(fmt, t, s, sign);
   1493 		while(z1>0 || ndigits>0 || z2>0) {
   1494 			if(z1 > 0){
   1495 				z1--;
   1496 				c = '0';
   1497 			}else if(ndigits > 0){
   1498 				ndigits--;
   1499 				c = *digits++;
   1500 			}else{
   1501 				z2--;
   1502 				c = '0';
   1503 			}
   1504 			FMTCHAR(fmt, t, s, c);
   1505 			if(--point == 0)
   1506 				for(p=dot; *p; p++)
   1507 					FMTCHAR(fmt, t, s, *p);
   1508 		}
   1509 		fmt->nfmt += t - (char*)fmt->to;
   1510 		fmt->to = t;
   1511 		if(sufwid && __fmtcpy(fmt, suf, sufwid, sufwid) < 0)
   1512 			return -1;
   1513 		if(pad && (fl & FmtLeft) && __fmtpad(fmt, pad) < 0)
   1514 			return -1;
   1515 	}
   1516 	return 0;
   1517 }
   1518 
   1519 /* -------------- fmt.c --------------- */
   1520 /* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
   1521 // #include <stdarg.h>
   1522 // #include <string.h>
   1523 // #include "plan9.h"
   1524 // #include "fmt.h"
   1525 // #include "fmtdef.h"
   1526 
   1527 enum
   1528 {
   1529 	Maxfmt = 64
   1530 };
   1531 
   1532 typedef struct Convfmt Convfmt;
   1533 struct Convfmt
   1534 {
   1535 	int	c;
   1536 	volatile	Fmts	fmt;	/* for spin lock in fmtfmt; avoids race due to write order */
   1537 };
   1538 
   1539 static struct
   1540 {
   1541 	/* lock by calling __fmtlock, __fmtunlock */
   1542 	int	nfmt;
   1543 	Convfmt	fmt[Maxfmt];
   1544 } fmtalloc;
   1545 
   1546 static Convfmt knownfmt[] = {
   1547 	{ ' ',	__flagfmt },
   1548 	{ '#',	__flagfmt },
   1549 	{ '%',	__percentfmt },
   1550 	{ '\'',	__flagfmt },
   1551 	{ '+',	__flagfmt },
   1552 	{ ',',	__flagfmt },
   1553 	{ '-',	__flagfmt },
   1554 	{ 'C',	__runefmt },	/* Plan 9 addition */
   1555 	{ 'E',	__efgfmt },
   1556 #ifndef PLAN9PORT
   1557 	{ 'F',	__efgfmt },	/* ANSI only */
   1558 #endif
   1559 	{ 'G',	__efgfmt },
   1560 #ifndef PLAN9PORT
   1561 	{ 'L',	__flagfmt },	/* ANSI only */
   1562 #endif
   1563 	{ 'S',	__runesfmt },	/* Plan 9 addition */
   1564 	{ 'X',	__ifmt },
   1565 	{ 'b',	__ifmt },		/* Plan 9 addition */
   1566 	{ 'c',	__charfmt },
   1567 	{ 'd',	__ifmt },
   1568 	{ 'e',	__efgfmt },
   1569 	{ 'f',	__efgfmt },
   1570 	{ 'g',	__efgfmt },
   1571 	{ 'h',	__flagfmt },
   1572 #ifndef PLAN9PORT
   1573 	{ 'i',	__ifmt },		/* ANSI only */
   1574 #endif
   1575 	{ 'l',	__flagfmt },
   1576 	{ 'n',	__countfmt },
   1577 	{ 'o',	__ifmt },
   1578 	{ 'p',	__ifmt },
   1579 	{ 'r',	__errfmt },
   1580 	{ 's',	__strfmt },
   1581 #ifdef PLAN9PORT
   1582 	{ 'u',	__flagfmt },
   1583 #else
   1584 	{ 'u',	__ifmt },
   1585 #endif
   1586 	{ 'x',	__ifmt },
   1587 	{ 0,	nil }
   1588 };
   1589 
   1590 
   1591 int	(*fmtdoquote)(int);
   1592 
   1593 /*
   1594  * __fmtlock() must be set
   1595  */
   1596 static int
   1597 __fmtinstall(int c, Fmts f)
   1598 {
   1599 	Convfmt *p, *ep;
   1600 
   1601 	if(c<=0 || c>=65536)
   1602 		return -1;
   1603 	if(!f)
   1604 		f = __badfmt;
   1605 
   1606 	ep = &fmtalloc.fmt[fmtalloc.nfmt];
   1607 	for(p=fmtalloc.fmt; p<ep; p++)
   1608 		if(p->c == c)
   1609 			break;
   1610 
   1611 	if(p == &fmtalloc.fmt[Maxfmt])
   1612 		return -1;
   1613 
   1614 	p->fmt = f;
   1615 	if(p == ep){	/* installing a new format character */
   1616 		fmtalloc.nfmt++;
   1617 		p->c = c;
   1618 	}
   1619 
   1620 	return 0;
   1621 }
   1622 
   1623 int
   1624 fmtinstall(int c, int (*f)(Fmt*))
   1625 {
   1626 	int ret;
   1627 
   1628 	__fmtlock();
   1629 	ret = __fmtinstall(c, f);
   1630 	__fmtunlock();
   1631 	return ret;
   1632 }
   1633 
   1634 static Fmts
   1635 fmtfmt(int c)
   1636 {
   1637 	Convfmt *p, *ep;
   1638 
   1639 	ep = &fmtalloc.fmt[fmtalloc.nfmt];
   1640 	for(p=fmtalloc.fmt; p<ep; p++)
   1641 		if(p->c == c){
   1642 			while(p->fmt == nil)	/* loop until value is updated */
   1643 				;
   1644 			return p->fmt;
   1645 		}
   1646 
   1647 	/* is this a predefined format char? */
   1648 	__fmtlock();
   1649 	for(p=knownfmt; p->c; p++)
   1650 		if(p->c == c){
   1651 			__fmtinstall(p->c, p->fmt);
   1652 			__fmtunlock();
   1653 			return p->fmt;
   1654 		}
   1655 	__fmtunlock();
   1656 
   1657 	return __badfmt;
   1658 }
   1659 
   1660 void*
   1661 __fmtdispatch(Fmt *f, void *fmt, int isrunes)
   1662 {
   1663 	Rune rune, r;
   1664 	int i, n;
   1665 
   1666 	f->flags = 0;
   1667 	f->width = f->prec = 0;
   1668 
   1669 	for(;;){
   1670 		if(isrunes){
   1671 			r = *(Rune*)fmt;
   1672 			fmt = (Rune*)fmt + 1;
   1673 		}else{
   1674 			fmt = (char*)fmt + chartorune(&rune, (char*)fmt);
   1675 			r = rune;
   1676 		}
   1677 		f->r = r;
   1678 		switch(r){
   1679 		case '\0':
   1680 			return nil;
   1681 		case '.':
   1682 			f->flags |= FmtWidth|FmtPrec;
   1683 			continue;
   1684 		case '0':
   1685 			if(!(f->flags & FmtWidth)){
   1686 				f->flags |= FmtZero;
   1687 				continue;
   1688 			}
   1689 			/* fall through */
   1690 		case '1': case '2': case '3': case '4':
   1691 		case '5': case '6': case '7': case '8': case '9':
   1692 			i = 0;
   1693 			while(r >= '0' && r <= '9'){
   1694 				i = i * 10 + r - '0';
   1695 				if(isrunes){
   1696 					r = *(Rune*)fmt;
   1697 					fmt = (Rune*)fmt + 1;
   1698 				}else{
   1699 					r = *(char*)fmt;
   1700 					fmt = (char*)fmt + 1;
   1701 				}
   1702 			}
   1703 			if(isrunes)
   1704 				fmt = (Rune*)fmt - 1;
   1705 			else
   1706 				fmt = (char*)fmt - 1;
   1707 		numflag:
   1708 			if(f->flags & FmtWidth){
   1709 				f->flags |= FmtPrec;
   1710 				f->prec = i;
   1711 			}else{
   1712 				f->flags |= FmtWidth;
   1713 				f->width = i;
   1714 			}
   1715 			continue;
   1716 		case '*':
   1717 			i = va_arg(f->args, int);
   1718 			if(i < 0){
   1719 				/*
   1720 				 * negative precision =>
   1721 				 * ignore the precision.
   1722 				 */
   1723 				if(f->flags & FmtPrec){
   1724 					f->flags &= ~FmtPrec;
   1725 					f->prec = 0;
   1726 					continue;
   1727 				}
   1728 				i = -i;
   1729 				f->flags |= FmtLeft;
   1730 			}
   1731 			goto numflag;
   1732 		}
   1733 		n = (*fmtfmt(r))(f);
   1734 		if(n < 0)
   1735 			return nil;
   1736 		if(n == 0)
   1737 			return fmt;
   1738 	}
   1739 }
   1740 /* -------------- fmtfd.c --------------- */
   1741 /* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
   1742 // #include <stdarg.h>
   1743 // #include <string.h>
   1744 // #include "plan9.h"
   1745 // #include "fmt.h"
   1746 // #include "fmtdef.h"
   1747 
   1748 /*
   1749  * public routine for final flush of a formatting buffer
   1750  * to a file descriptor; returns total char count.
   1751  */
   1752 int
   1753 fmtfdflush(Fmt *f)
   1754 {
   1755 	if(__fmtFdFlush(f) <= 0)
   1756 		return -1;
   1757 	return f->nfmt;
   1758 }
   1759 
   1760 /*
   1761  * initialize an output buffer for buffered printing
   1762  */
   1763 int
   1764 fmtfdinit(Fmt *f, int fd, char *buf, int size)
   1765 {
   1766 	f->runes = 0;
   1767 	f->start = buf;
   1768 	f->to = buf;
   1769 	f->stop = buf + size;
   1770 	f->flush = __fmtFdFlush;
   1771 	f->farg = (void*)(uintptr_t)fd;
   1772 	f->flags = 0;
   1773 	f->nfmt = 0;
   1774 	fmtlocaleinit(f, nil, nil, nil);
   1775 	return 0;
   1776 }
   1777 /* -------------- fmtfdflush.c --------------- */
   1778 /* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
   1779 // #include <stdarg.h>
   1780 // #include <unistd.h>
   1781 // #include "plan9.h"
   1782 // #include "fmt.h"
   1783 // #include "fmtdef.h"
   1784 
   1785 /*
   1786  * generic routine for flushing a formatting buffer
   1787  * to a file descriptor
   1788  */
   1789 int
   1790 __fmtFdFlush(Fmt *f)
   1791 {
   1792 	int n;
   1793 
   1794 	n = (char*)f->to - (char*)f->start;
   1795 	if(n && write((uintptr)f->farg, f->start, n) != n)
   1796 		return 0;
   1797 	f->to = f->start;
   1798 	return 1;
   1799 }
   1800 /* -------------- fmtlocale.c --------------- */
   1801 /* Copyright (c) 2004 Google Inc.; see LICENSE */
   1802 
   1803 // #include <stdarg.h>
   1804 // #include <string.h>
   1805 // #include "plan9.h"
   1806 // #include "fmt.h"
   1807 // #include "fmtdef.h"
   1808 
   1809 /*
   1810  * Fill in the internationalization stuff in the State structure.
   1811  * For nil arguments, provide the sensible defaults:
   1812  *	decimal is a period
   1813  *	thousands separator is a comma
   1814  *	thousands are marked every three digits
   1815  */
   1816 void
   1817 fmtlocaleinit(Fmt *f, char *decimal, char *thousands, char *grouping)
   1818 {
   1819 	if(decimal == nil || decimal[0] == '\0')
   1820 		decimal = ".";
   1821 	if(thousands == nil)
   1822 		thousands = ",";
   1823 	if(grouping == nil)
   1824 		grouping = "\3";
   1825 	f->decimal = decimal;
   1826 	f->thousands = thousands;
   1827 	f->grouping = grouping;
   1828 }
   1829 
   1830 /*
   1831  * We are about to emit a digit in e.g. %'d.  If that digit would
   1832  * overflow a thousands (e.g.) grouping, tell the caller to emit
   1833  * the thousands separator.  Always advance the digit counter
   1834  * and pointer into the grouping descriptor.
   1835  */
   1836 int
   1837 __needsep(int *ndig, char **grouping)
   1838 {
   1839 	int group;
   1840 	
   1841 	(*ndig)++;
   1842 	group = *(unsigned char*)*grouping;
   1843 	/* CHAR_MAX means no further grouping. \0 means we got the empty string */
   1844 	if(group == 0xFF || group == 0x7f || group == 0x00)
   1845 		return 0;
   1846 	if(*ndig > group){
   1847 		/* if we're at end of string, continue with this grouping; else advance */
   1848 		if((*grouping)[1] != '\0')
   1849 			(*grouping)++;
   1850 		*ndig = 1;
   1851 		return 1;
   1852 	}
   1853 	return 0;
   1854 }
   1855 
   1856 /* -------------- fmtlock.c --------------- */
   1857 /* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
   1858 // #include <stdarg.h>
   1859 // #include "plan9.h"
   1860 // #include "fmt.h"
   1861 // #include "fmtdef.h"
   1862 
   1863 void
   1864 __fmtlock(void)
   1865 {
   1866 }
   1867 
   1868 void
   1869 __fmtunlock(void)
   1870 {
   1871 }
   1872 /* -------------- fmtnull.c --------------- */
   1873 /* Copyright (c) 2004 Google Inc.; see LICENSE */
   1874 // #include <stdarg.h>
   1875 // #include <string.h>
   1876 // #include "plan9.h"
   1877 // #include "fmt.h"
   1878 // #include "fmtdef.h"
   1879 
   1880 /*
   1881  * Absorb output without using resources.
   1882  */
   1883 static Rune nullbuf[32];
   1884 
   1885 static int
   1886 __fmtnullflush(Fmt *f)
   1887 {
   1888 	f->to = nullbuf;
   1889 	f->nfmt = 0;
   1890 	return 0;
   1891 }
   1892 
   1893 int
   1894 fmtnullinit(Fmt *f)
   1895 {
   1896 	memset(f, 0, sizeof *f);
   1897 	f->runes = 1;
   1898 	f->start = nullbuf;
   1899 	f->to = nullbuf;
   1900 	f->stop = nullbuf+nelem(nullbuf);
   1901 	f->flush = __fmtnullflush;
   1902 	fmtlocaleinit(f, nil, nil, nil);
   1903 	return 0;
   1904 }
   1905 
   1906 /* -------------- fmtprint.c --------------- */
   1907 /* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
   1908 // #include <stdarg.h>
   1909 // #include <string.h>
   1910 // #include "plan9.h"
   1911 // #include "fmt.h"
   1912 // #include "fmtdef.h"
   1913 
   1914 /*
   1915  * format a string into the output buffer
   1916  * designed for formats which themselves call fmt,
   1917  * but ignore any width flags
   1918  */
   1919 int
   1920 fmtprint(Fmt *f, char *fmt, ...)
   1921 {
   1922 	va_list va;
   1923 	int n;
   1924 
   1925 	f->flags = 0;
   1926 	f->width = 0;
   1927 	f->prec = 0;
   1928 	VA_COPY(va, f->args);
   1929 	VA_END(f->args);
   1930 	va_start(f->args, fmt);
   1931 	n = dofmt(f, fmt);
   1932 	va_end(f->args);
   1933 	f->flags = 0;
   1934 	f->width = 0;
   1935 	f->prec = 0;
   1936 	VA_COPY(f->args,va);
   1937 	VA_END(va);
   1938 	if(n >= 0)
   1939 		return 0;
   1940 	return n;
   1941 }
   1942 
   1943 /* -------------- fmtquote.c --------------- */
   1944 /* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
   1945 // #include <stdarg.h>
   1946 // #include <string.h>
   1947 // #include "plan9.h"
   1948 // #include "fmt.h"
   1949 // #include "fmtdef.h"
   1950 
   1951 /*
   1952  * How many bytes of output UTF will be produced by quoting (if necessary) this string?
   1953  * How many runes? How much of the input will be consumed?
   1954  * The parameter q is filled in by __quotesetup.
   1955  * The string may be UTF or Runes (s or r).
   1956  * Return count does not include NUL.
   1957  * Terminate the scan at the first of:
   1958  *	NUL in input
   1959  *	count exceeded in input
   1960  *	count exceeded on output
   1961  * *ninp is set to number of input bytes accepted.
   1962  * nin may be <0 initially, to avoid checking input by count.
   1963  */
   1964 void
   1965 __quotesetup(char *s, Rune *r, int nin, int nout, Quoteinfo *q, int sharp, int runesout)
   1966 {
   1967 	int w;
   1968 	Rune c;
   1969 
   1970 	q->quoted = 0;
   1971 	q->nbytesout = 0;
   1972 	q->nrunesout = 0;
   1973 	q->nbytesin = 0;
   1974 	q->nrunesin = 0;
   1975 	if(sharp || nin==0 || (s && *s=='\0') || (r && *r=='\0')){
   1976 		if(nout < 2)
   1977 			return;
   1978 		q->quoted = 1;
   1979 		q->nbytesout = 2;
   1980 		q->nrunesout = 2;
   1981 	}
   1982 	for(; nin!=0; nin--){
   1983 		if(s)
   1984 			w = chartorune(&c, s);
   1985 		else{
   1986 			c = *r;
   1987 			w = runelen(c);
   1988 		}
   1989 
   1990 		if(c == '\0')
   1991 			break;
   1992 		if(runesout){
   1993 			if(q->nrunesout+1 > nout)
   1994 				break;
   1995 		}else{
   1996 			if(q->nbytesout+w > nout)
   1997 				break;
   1998 		}
   1999 
   2000 		if((c <= L' ') || (c == L'\'') || (fmtdoquote!=nil && fmtdoquote(c))){
   2001 			if(!q->quoted){
   2002 				if(runesout){
   2003 					if(1+q->nrunesout+1+1 > nout)	/* no room for quotes */
   2004 						break;
   2005 				}else{
   2006 					if(1+q->nbytesout+w+1 > nout)	/* no room for quotes */
   2007 						break;
   2008 				}
   2009 				q->nrunesout += 2;	/* include quotes */
   2010 				q->nbytesout += 2;	/* include quotes */
   2011 				q->quoted = 1;
   2012 			}
   2013 			if(c == '\'')	{
   2014 				if(runesout){
   2015 					if(1+q->nrunesout+1 > nout)	/* no room for quotes */
   2016 						break;
   2017 				}else{
   2018 					if(1+q->nbytesout+w > nout)	/* no room for quotes */
   2019 						break;
   2020 				}
   2021 				q->nbytesout++;
   2022 				q->nrunesout++;	/* quotes reproduce as two characters */
   2023 			}
   2024 		}
   2025 
   2026 		/* advance input */
   2027 		if(s)
   2028 			s += w;
   2029 		else
   2030 			r++;
   2031 		q->nbytesin += w;
   2032 		q->nrunesin++;
   2033 
   2034 		/* advance output */
   2035 		q->nbytesout += w;
   2036 		q->nrunesout++;
   2037 
   2038 #ifndef PLAN9PORT
   2039 		/* ANSI requires precision in bytes, not Runes. */
   2040 		nin-= w-1;	/* and then n-- in the loop */
   2041 #endif
   2042 	}
   2043 }
   2044 
   2045 static int
   2046 qstrfmt(char *sin, Rune *rin, Quoteinfo *q, Fmt *f)
   2047 {
   2048 	Rune r, *rm, *rme;
   2049 	char *t, *s, *m, *me;
   2050 	Rune *rt, *rs;
   2051 	ulong fl;
   2052 	int nc, w;
   2053 
   2054 	m = sin;
   2055 	me = m + q->nbytesin;
   2056 	rm = rin;
   2057 	rme = rm + q->nrunesin;
   2058 
   2059 	fl = f->flags;
   2060 	w = 0;
   2061 	if(fl & FmtWidth)
   2062 		w = f->width;
   2063 	if(f->runes){
   2064 		if(!(fl & FmtLeft) && __rfmtpad(f, w - q->nrunesout) < 0)
   2065 			return -1;
   2066 	}else{
   2067 		if(!(fl & FmtLeft) && __fmtpad(f, w - q->nbytesout) < 0)
   2068 			return -1;
   2069 	}
   2070 	t = (char*)f->to;
   2071 	s = (char*)f->stop;
   2072 	rt = (Rune*)f->to;
   2073 	rs = (Rune*)f->stop;
   2074 	if(f->runes)
   2075 		FMTRCHAR(f, rt, rs, '\'');
   2076 	else
   2077 		FMTRUNE(f, t, s, '\'');
   2078 	for(nc = q->nrunesin; nc > 0; nc--){
   2079 		if(sin){
   2080 			r = *(uchar*)m;
   2081 			if(r < Runeself)
   2082 				m++;
   2083 			else if((me - m) >= UTFmax || fullrune(m, me-m))
   2084 				m += chartorune(&r, m);
   2085 			else
   2086 				break;
   2087 		}else{
   2088 			if(rm >= rme)
   2089 				break;
   2090 			r = *(uchar*)rm++;
   2091 		}
   2092 		if(f->runes){
   2093 			FMTRCHAR(f, rt, rs, r);
   2094 			if(r == '\'')
   2095 				FMTRCHAR(f, rt, rs, r);
   2096 		}else{
   2097 			FMTRUNE(f, t, s, r);
   2098 			if(r == '\'')
   2099 				FMTRUNE(f, t, s, r);
   2100 		}
   2101 	}
   2102 
   2103 	if(f->runes){
   2104 		FMTRCHAR(f, rt, rs, '\'');
   2105 		USED(rs);
   2106 		f->nfmt += rt - (Rune *)f->to;
   2107 		f->to = rt;
   2108 		if(fl & FmtLeft && __rfmtpad(f, w - q->nrunesout) < 0)
   2109 			return -1;
   2110 	}else{
   2111 		FMTRUNE(f, t, s, '\'');
   2112 		USED(s);
   2113 		f->nfmt += t - (char *)f->to;
   2114 		f->to = t;
   2115 		if(fl & FmtLeft && __fmtpad(f, w - q->nbytesout) < 0)
   2116 			return -1;
   2117 	}
   2118 	return 0;
   2119 }
   2120 
   2121 int
   2122 __quotestrfmt(int runesin, Fmt *f)
   2123 {
   2124 	int nin, outlen;
   2125 	Rune *r;
   2126 	char *s;
   2127 	Quoteinfo q;
   2128 
   2129 	nin = -1;
   2130 	if(f->flags&FmtPrec)
   2131 		nin = f->prec;
   2132 	if(runesin){
   2133 		r = va_arg(f->args, Rune *);
   2134 		s = nil;
   2135 	}else{
   2136 		s = va_arg(f->args, char *);
   2137 		r = nil;
   2138 	}
   2139 	if(!s && !r)
   2140 		return __fmtcpy(f, (void*)"<nil>", 5, 5);
   2141 
   2142 	if(f->flush)
   2143 		outlen = 0x7FFFFFFF;	/* if we can flush, no output limit */
   2144 	else if(f->runes)
   2145 		outlen = (Rune*)f->stop - (Rune*)f->to;
   2146 	else
   2147 		outlen = (char*)f->stop - (char*)f->to;
   2148 
   2149 	__quotesetup(s, r, nin, outlen, &q, f->flags&FmtSharp, f->runes);
   2150 /*print("bytes in %d bytes out %d runes in %d runesout %d\n", q.nbytesin, q.nbytesout, q.nrunesin, q.nrunesout); */
   2151 
   2152 	if(runesin){
   2153 		if(!q.quoted)
   2154 			return __fmtrcpy(f, r, q.nrunesin);
   2155 		return qstrfmt(nil, r, &q, f);
   2156 	}
   2157 
   2158 	if(!q.quoted)
   2159 		return __fmtcpy(f, s, q.nrunesin, q.nbytesin);
   2160 	return qstrfmt(s, nil, &q, f);
   2161 }
   2162 
   2163 int
   2164 quotestrfmt(Fmt *f)
   2165 {
   2166 	return __quotestrfmt(0, f);
   2167 }
   2168 
   2169 int
   2170 quoterunestrfmt(Fmt *f)
   2171 {
   2172 	return __quotestrfmt(1, f);
   2173 }
   2174 
   2175 void
   2176 quotefmtinstall(void)
   2177 {
   2178 	fmtinstall('q', quotestrfmt);
   2179 	fmtinstall('Q', quoterunestrfmt);
   2180 }
   2181 
   2182 int
   2183 __needsquotes(char *s, int *quotelenp)
   2184 {
   2185 	Quoteinfo q;
   2186 
   2187 	__quotesetup(s, nil, -1, 0x7FFFFFFF, &q, 0, 0);
   2188 	*quotelenp = q.nbytesout;
   2189 
   2190 	return q.quoted;
   2191 }
   2192 
   2193 int
   2194 __runeneedsquotes(Rune *r, int *quotelenp)
   2195 {
   2196 	Quoteinfo q;
   2197 
   2198 	__quotesetup(nil, r, -1, 0x7FFFFFFF, &q, 0, 0);
   2199 	*quotelenp = q.nrunesout;
   2200 
   2201 	return q.quoted;
   2202 }
   2203 /* -------------- fmtrune.c --------------- */
   2204 /* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
   2205 // #include <stdarg.h>
   2206 // #include <string.h>
   2207 // #include "plan9.h"
   2208 // #include "fmt.h"
   2209 // #include "fmtdef.h"
   2210 
   2211 int
   2212 fmtrune(Fmt *f, int r)
   2213 {
   2214 	Rune *rt;
   2215 	char *t;
   2216 	int n;
   2217 
   2218 	if(f->runes){
   2219 		rt = (Rune*)f->to;
   2220 		FMTRCHAR(f, rt, f->stop, r);
   2221 		f->to = rt;
   2222 		n = 1;
   2223 	}else{
   2224 		t = (char*)f->to;
   2225 		FMTRUNE(f, t, f->stop, r);
   2226 		n = t - (char*)f->to;
   2227 		f->to = t;
   2228 	}
   2229 	f->nfmt += n;
   2230 	return 0;
   2231 }
   2232 /* -------------- fmtstr.c --------------- */
   2233 /* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
   2234 // #include <stdlib.h>
   2235 // #include <stdarg.h>
   2236 // #include "plan9.h"
   2237 // #include "fmt.h"
   2238 // #include "fmtdef.h"
   2239 
   2240 char*
   2241 fmtstrflush(Fmt *f)
   2242 {
   2243 	if(f->start == nil)
   2244 		return nil;
   2245 	*(char*)f->to = '\0';
   2246 	f->to = f->start;
   2247 	return (char*)f->start;
   2248 }
   2249 /* -------------- fmtvprint.c --------------- */
   2250 /* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
   2251 // #include <stdarg.h>
   2252 // #include <string.h>
   2253 // #include "plan9.h"
   2254 // #include "fmt.h"
   2255 // #include "fmtdef.h"
   2256 
   2257 
   2258 /*
   2259  * format a string into the output buffer
   2260  * designed for formats which themselves call fmt,
   2261  * but ignore any width flags
   2262  */
   2263 int
   2264 fmtvprint(Fmt *f, char *fmt, va_list args)
   2265 {
   2266 	va_list va;
   2267 	int n;
   2268 
   2269 	f->flags = 0;
   2270 	f->width = 0;
   2271 	f->prec = 0;
   2272 	VA_COPY(va,f->args);
   2273 	VA_END(f->args);
   2274 	VA_COPY(f->args,args);
   2275 	n = dofmt(f, fmt);
   2276 	f->flags = 0;
   2277 	f->width = 0;
   2278 	f->prec = 0;
   2279 	VA_END(f->args);
   2280 	VA_COPY(f->args,va);
   2281 	VA_END(va);
   2282 	if(n >= 0)
   2283 		return 0;
   2284 	return n;
   2285 }
   2286 
   2287 /* -------------- fprint.c --------------- */
   2288 /* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
   2289 // #include <stdarg.h>
   2290 // #include "plan9.h"
   2291 // #include "fmt.h"
   2292 // #include "fmtdef.h"
   2293 
   2294 int
   2295 fprint(int fd, char *fmt, ...)
   2296 {
   2297 	int n;
   2298 	va_list args;
   2299 
   2300 	va_start(args, fmt);
   2301 	n = vfprint(fd, fmt, args);
   2302 	va_end(args);
   2303 	return n;
   2304 }
   2305 /* -------------- nan64.c --------------- */
   2306 /*
   2307  * 64-bit IEEE not-a-number routines.
   2308  * This is big/little-endian portable assuming that 
   2309  * the 64-bit doubles and 64-bit integers have the
   2310  * same byte ordering.
   2311  */
   2312 
   2313 // #include "plan9.h"
   2314 // #include "fmt.h"
   2315 // #include "fmtdef.h"
   2316 
   2317 #if defined (__APPLE__) || (__powerpc__)
   2318 #define _NEEDLL
   2319 #endif
   2320 
   2321 static uvlong uvnan    = ((uvlong)0x7FF00000<<32)|0x00000001;
   2322 static uvlong uvinf    = ((uvlong)0x7FF00000<<32)|0x00000000;
   2323 static uvlong uvneginf = ((uvlong)0xFFF00000<<32)|0x00000000;
   2324 
   2325 double
   2326 __NaN(void)
   2327 {
   2328 	uvlong *p;
   2329 
   2330 	/* gcc complains about "return *(double*)&uvnan;" */
   2331 	p = &uvnan;
   2332 	return *(double*)p;
   2333 }
   2334 
   2335 int
   2336 __isNaN(double d)
   2337 {
   2338 	uvlong x;
   2339 	double *p;
   2340 
   2341 	p = &d;
   2342 	x = *(uvlong*)p;
   2343 	return (ulong)(x>>32)==0x7FF00000 && !__isInf(d, 0);
   2344 }
   2345 
   2346 double
   2347 __Inf(int sign)
   2348 {
   2349 	uvlong *p;
   2350 
   2351 	if(sign < 0)
   2352 		p = &uvinf;
   2353 	else
   2354 		p = &uvneginf;
   2355 	return *(double*)p;
   2356 }
   2357 
   2358 int
   2359 __isInf(double d, int sign)
   2360 {
   2361 	uvlong x;
   2362 	double *p;
   2363 
   2364 	p = &d;
   2365 	x = *(uvlong*)p;
   2366 	if(sign == 0)
   2367 		return x==uvinf || x==uvneginf;
   2368 	else if(sign > 0)
   2369 		return x==uvinf;
   2370 	else
   2371 		return x==uvneginf;
   2372 }
   2373 /* -------------- pow10.c --------------- */
   2374 /* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
   2375 // #include <stdarg.h>
   2376 // #include <string.h>
   2377 // #include "plan9.h"
   2378 // #include "fmt.h"
   2379 // #include "fmtdef.h"
   2380 
   2381 /*
   2382  * this table might overflow 127-bit exponent representations.
   2383  * in that case, truncate it after 1.0e38.
   2384  * it is important to get all one can from this
   2385  * routine since it is used in atof to scale numbers.
   2386  * the presumption is that C converts fp numbers better
   2387  * than multipication of lower powers of 10.
   2388  */
   2389 
   2390 static
   2391 double	tab[] =
   2392 {
   2393 	1.0e0, 1.0e1, 1.0e2, 1.0e3, 1.0e4, 1.0e5, 1.0e6, 1.0e7, 1.0e8, 1.0e9,
   2394 	1.0e10,1.0e11,1.0e12,1.0e13,1.0e14,1.0e15,1.0e16,1.0e17,1.0e18,1.0e19,
   2395 	1.0e20,1.0e21,1.0e22,1.0e23,1.0e24,1.0e25,1.0e26,1.0e27,1.0e28,1.0e29,
   2396 	1.0e30,1.0e31,1.0e32,1.0e33,1.0e34,1.0e35,1.0e36,1.0e37,1.0e38,1.0e39,
   2397 	1.0e40,1.0e41,1.0e42,1.0e43,1.0e44,1.0e45,1.0e46,1.0e47,1.0e48,1.0e49,
   2398 	1.0e50,1.0e51,1.0e52,1.0e53,1.0e54,1.0e55,1.0e56,1.0e57,1.0e58,1.0e59,
   2399 	1.0e60,1.0e61,1.0e62,1.0e63,1.0e64,1.0e65,1.0e66,1.0e67,1.0e68,1.0e69,
   2400 };
   2401 
   2402 double
   2403 __fmtpow10(int n)
   2404 {
   2405 	int m;
   2406 
   2407 	if(n < 0) {
   2408 		n = -n;
   2409 		if(n < (int)(sizeof(tab)/sizeof(tab[0])))
   2410 			return 1/tab[n];
   2411 		m = n/2;
   2412 		return __fmtpow10(-m) * __fmtpow10(m-n);
   2413 	}
   2414 	if(n < (int)(sizeof(tab)/sizeof(tab[0])))
   2415 		return tab[n];
   2416 	m = n/2;
   2417 	return __fmtpow10(m) * __fmtpow10(n-m);
   2418 }
   2419 /* -------------- print.c --------------- */
   2420 /* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
   2421 // #include <stdarg.h>
   2422 // #include "plan9.h"
   2423 // #include "fmt.h"
   2424 // #include "fmtdef.h"
   2425 
   2426 /*
   2427 int
   2428 print(char *fmt, ...)
   2429 {
   2430 	int n;
   2431 	va_list args;
   2432 
   2433 	va_start(args, fmt);
   2434 	n = vfprint(1, fmt, args);
   2435 	va_end(args);
   2436 	return n;
   2437 }
   2438 */
   2439 
   2440 /* -------------- runefmtstr.c --------------- */
   2441 /* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
   2442 // #include <stdarg.h>
   2443 // #include <stdlib.h>
   2444 // #include "plan9.h"
   2445 // #include "fmt.h"
   2446 // #include "fmtdef.h"
   2447 
   2448 Rune*
   2449 runefmtstrflush(Fmt *f)
   2450 {
   2451 	if(f->start == nil)
   2452 		return nil;
   2453 	*(Rune*)f->to = '\0';
   2454 	f->to = f->start;
   2455 	return f->start;
   2456 }
   2457 /* -------------- runeseprint.c --------------- */
   2458 /* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
   2459 // #include <stdarg.h>
   2460 // #include <string.h>
   2461 // #include "plan9.h"
   2462 // #include "fmt.h"
   2463 // #include "fmtdef.h"
   2464 
   2465 Rune*
   2466 runeseprint(Rune *buf, Rune *e, char *fmt, ...)
   2467 {
   2468 	Rune *p;
   2469 	va_list args;
   2470 
   2471 	va_start(args, fmt);
   2472 	p = runevseprint(buf, e, fmt, args);
   2473 	va_end(args);
   2474 	return p;
   2475 }
   2476 /* -------------- runesmprint.c --------------- */
   2477 /* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
   2478 // #include <stdarg.h>
   2479 // #include <string.h>
   2480 // #include "plan9.h"
   2481 // #include "fmt.h"
   2482 // #include "fmtdef.h"
   2483 
   2484 Rune*
   2485 runesmprint(char *fmt, ...)
   2486 {
   2487 	va_list args;
   2488 	Rune *p;
   2489 
   2490 	va_start(args, fmt);
   2491 	p = runevsmprint(fmt, args);
   2492 	va_end(args);
   2493 	return p;
   2494 }
   2495 /* -------------- runesnprint.c --------------- */
   2496 /* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
   2497 // #include <stdarg.h>
   2498 // #include <string.h>
   2499 // #include "plan9.h"
   2500 // #include "fmt.h"
   2501 // #include "fmtdef.h"
   2502 
   2503 int
   2504 runesnprint(Rune *buf, int len, char *fmt, ...)
   2505 {
   2506 	int n;
   2507 	va_list args;
   2508 
   2509 	va_start(args, fmt);
   2510 	n = runevsnprint(buf, len, fmt, args);
   2511 	va_end(args);
   2512 	return n;
   2513 }
   2514 
   2515 /* -------------- runesprint.c --------------- */
   2516 /* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
   2517 // #include <stdarg.h>
   2518 // #include <string.h>
   2519 // #include "plan9.h"
   2520 // #include "fmt.h"
   2521 // #include "fmtdef.h"
   2522 
   2523 int
   2524 runesprint(Rune *buf, char *fmt, ...)
   2525 {
   2526 	int n;
   2527 	va_list args;
   2528 
   2529 	va_start(args, fmt);
   2530 	n = runevsnprint(buf, 256, fmt, args);
   2531 	va_end(args);
   2532 	return n;
   2533 }
   2534 /* -------------- runevseprint.c --------------- */
   2535 /* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
   2536 // #include <stdarg.h>
   2537 // #include <string.h>
   2538 // #include "plan9.h"
   2539 // #include "fmt.h"
   2540 // #include "fmtdef.h"
   2541 
   2542 Rune*
   2543 runevseprint(Rune *buf, Rune *e, char *fmt, va_list args)
   2544 {
   2545 	Fmt f;
   2546 
   2547 	if(e <= buf)
   2548 		return nil;
   2549 	f.runes = 1;
   2550 	f.start = buf;
   2551 	f.to = buf;
   2552 	f.stop = e - 1;
   2553 	f.flush = nil;
   2554 	f.farg = nil;
   2555 	f.nfmt = 0;
   2556 	VA_COPY(f.args,args);
   2557 	fmtlocaleinit(&f, nil, nil, nil);
   2558 	dofmt(&f, fmt);
   2559 	VA_END(f.args);
   2560 	*(Rune*)f.to = '\0';
   2561 	return (Rune*)f.to;
   2562 }
   2563 
   2564 /* -------------- runevsmprint.c --------------- */
   2565 /* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
   2566 /*
   2567  * Plan 9 port version must include libc.h in order to 
   2568  * get Plan 9 debugging malloc, which sometimes returns
   2569  * different pointers than the standard malloc. 
   2570  */
   2571 #ifdef PLAN9PORT
   2572 // #include <u.h>
   2573 // #include <libc.h>
   2574 // #include "fmtdef.h"
   2575 #else
   2576 // #include <stdlib.h>
   2577 // #include <string.h>
   2578 // #include "plan9.h"
   2579 // #include "fmt.h"
   2580 // #include "fmtdef.h"
   2581 #endif
   2582 
   2583 static int
   2584 runeFmtStrFlush(Fmt *f)
   2585 {
   2586 	Rune *s;
   2587 	int n;
   2588 
   2589 	if(f->start == nil)
   2590 		return 0;
   2591 	n = (uintptr)f->farg;
   2592 	n *= 2;
   2593 	s = (Rune*)f->start;
   2594 	f->start = realloc(s, sizeof(Rune)*n);
   2595 	if(f->start == nil){
   2596 		f->farg = nil;
   2597 		f->to = nil;
   2598 		f->stop = nil;
   2599 		free(s);
   2600 		return 0;
   2601 	}
   2602 	f->farg = (void*)(uintptr)n;
   2603 	f->to = (Rune*)f->start + ((Rune*)f->to - s);
   2604 	f->stop = (Rune*)f->start + n - 1;
   2605 	return 1;
   2606 }
   2607 
   2608 int
   2609 runefmtstrinit(Fmt *f)
   2610 {
   2611 	int n;
   2612 
   2613 	memset(f, 0, sizeof *f);
   2614 	f->runes = 1;
   2615 	n = 32;
   2616 	f->start = malloc(sizeof(Rune)*n);
   2617 	if(f->start == nil)
   2618 		return -1;
   2619 	f->to = f->start;
   2620 	f->stop = (Rune*)f->start + n - 1;
   2621 	f->flush = runeFmtStrFlush;
   2622 	f->farg = (void*)(uintptr)n;
   2623 	f->nfmt = 0;
   2624 	fmtlocaleinit(f, nil, nil, nil);
   2625 	return 0;
   2626 }
   2627 
   2628 /*
   2629  * print into an allocated string buffer
   2630  */
   2631 Rune*
   2632 runevsmprint(char *fmt, va_list args)
   2633 {
   2634 	Fmt f;
   2635 	int n;
   2636 
   2637 	if(runefmtstrinit(&f) < 0)
   2638 		return nil;
   2639 	VA_COPY(f.args,args);
   2640 	n = dofmt(&f, fmt);
   2641 	VA_END(f.args);
   2642 	if(f.start == nil)
   2643 		return nil;
   2644 	if(n < 0){
   2645 		free(f.start);
   2646 		return nil;
   2647 	}
   2648 	*(Rune*)f.to = '\0';
   2649 	return (Rune*)f.start;
   2650 }
   2651 /* -------------- runevsnprint.c --------------- */
   2652 /* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
   2653 // #include <stdarg.h>
   2654 // #include <string.h>
   2655 // #include "plan9.h"
   2656 // #include "fmt.h"
   2657 // #include "fmtdef.h"
   2658 
   2659 int
   2660 runevsnprint(Rune *buf, int len, char *fmt, va_list args)
   2661 {
   2662 	Fmt f;
   2663 
   2664 	if(len <= 0)
   2665 		return -1;
   2666 	f.runes = 1;
   2667 	f.start = buf;
   2668 	f.to = buf;
   2669 	f.stop = buf + len - 1;
   2670 	f.flush = nil;
   2671 	f.farg = nil;
   2672 	f.nfmt = 0;
   2673 	VA_COPY(f.args,args);
   2674 	fmtlocaleinit(&f, nil, nil, nil);
   2675 	dofmt(&f, fmt);
   2676 	VA_END(f.args);
   2677 	*(Rune*)f.to = '\0';
   2678 	return (Rune*)f.to - buf;
   2679 }
   2680 /* -------------- seprint.c --------------- */
   2681 /* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
   2682 // #include <stdarg.h>
   2683 // #include "plan9.h"
   2684 // #include "fmt.h"
   2685 // #include "fmtdef.h"
   2686 
   2687 char*
   2688 seprint(char *buf, char *e, char *fmt, ...)
   2689 {
   2690 	char *p;
   2691 	va_list args;
   2692 
   2693 	va_start(args, fmt);
   2694 	p = vseprint(buf, e, fmt, args);
   2695 	va_end(args);
   2696 	return p;
   2697 }
   2698 /* -------------- smprint.c --------------- */
   2699 /* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
   2700 // #include <stdarg.h>
   2701 // #include "plan9.h"
   2702 // #include "fmt.h"
   2703 // #include "fmtdef.h"
   2704 
   2705 char*
   2706 smprint(char *fmt, ...)
   2707 {
   2708 	va_list args;
   2709 	char *p;
   2710 
   2711 	va_start(args, fmt);
   2712 	p = vsmprint(fmt, args);
   2713 	va_end(args);
   2714 	return p;
   2715 }
   2716 /* -------------- snprint.c --------------- */
   2717 /* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
   2718 // #include <stdarg.h>
   2719 // #include "plan9.h"
   2720 // #include "fmt.h"
   2721 // #include "fmtdef.h"
   2722 
   2723 int
   2724 snprint(char *buf, int len, char *fmt, ...)
   2725 {
   2726 	int n;
   2727 	va_list args;
   2728 
   2729 	va_start(args, fmt);
   2730 	n = vsnprint(buf, len, fmt, args);
   2731 	va_end(args);
   2732 	return n;
   2733 }
   2734 
   2735 /* -------------- sprint.c --------------- */
   2736 /* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
   2737 // #include <stdarg.h>
   2738 // #include <fmt.h>
   2739 // #include "plan9.h"
   2740 // #include "fmt.h"
   2741 // #include "fmtdef.h"
   2742 
   2743 int
   2744 sprint(char *buf, char *fmt, ...)
   2745 {
   2746 	int n;
   2747 	va_list args;
   2748 
   2749 	va_start(args, fmt);
   2750 	n = vsnprint(buf, 65536, fmt, args);
   2751 	va_end(args);
   2752 	return n;
   2753 }
   2754 /* -------------- strtod.c --------------- */
   2755 /* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
   2756 // #include <stdlib.h>
   2757 // #include <math.h>
   2758 // #include <ctype.h>
   2759 // #include <stdlib.h>
   2760 // #include <string.h>
   2761 // #include <errno.h>
   2762 // #include "plan9.h"
   2763 // #include "fmt.h"
   2764 // #include "fmtdef.h"
   2765 
   2766 static ulong
   2767 umuldiv(ulong a, ulong b, ulong c)
   2768 {
   2769 	double d;
   2770 
   2771 	d = ((double)a * (double)b) / (double)c;
   2772 	if(d >= 4294967295.)
   2773 		d = 4294967295.;
   2774 	return (ulong)d;
   2775 }
   2776 
   2777 /*
   2778  * This routine will convert to arbitrary precision
   2779  * floating point entirely in multi-precision fixed.
   2780  * The answer is the closest floating point number to
   2781  * the given decimal number. Exactly half way are
   2782  * rounded ala ieee rules.
   2783  * Method is to scale input decimal between .500 and .999...
   2784  * with external power of 2, then binary search for the
   2785  * closest mantissa to this decimal number.
   2786  * Nmant is is the required precision. (53 for ieee dp)
   2787  * Nbits is the max number of bits/word. (must be <= 28)
   2788  * Prec is calculated - the number of words of fixed mantissa.
   2789  */
   2790 enum
   2791 {
   2792 	Nbits	= 28,				/* bits safely represented in a ulong */
   2793 	Nmant	= 53,				/* bits of precision required */
   2794 	Prec	= (Nmant+Nbits+1)/Nbits,	/* words of Nbits each to represent mantissa */
   2795 	Sigbit	= 1<<(Prec*Nbits-Nmant),	/* first significant bit of Prec-th word */
   2796 	Ndig	= 1500,
   2797 	One	= (ulong)(1<<Nbits),
   2798 	Half	= (ulong)(One>>1),
   2799 	Maxe	= 310,
   2800 
   2801 	Fsign	= 1<<0,		/* found - */
   2802 	Fesign	= 1<<1,		/* found e- */
   2803 	Fdpoint	= 1<<2,		/* found . */
   2804 
   2805 	S0	= 0,		/* _		_S0	+S1	#S2	.S3 */
   2806 	S1,			/* _+		#S2	.S3 */
   2807 	S2,			/* _+#		#S2	.S4	eS5 */
   2808 	S3,			/* _+.		#S4 */
   2809 	S4,			/* _+#.#	#S4	eS5 */
   2810 	S5,			/* _+#.#e	+S6	#S7 */
   2811 	S6,			/* _+#.#e+	#S7 */
   2812 	S7			/* _+#.#e+#	#S7 */
   2813 };
   2814 
   2815 static	int	xcmp(char*, char*);
   2816 static	int	fpcmp(char*, ulong*);
   2817 static	void	frnorm(ulong*);
   2818 static	void	divascii(char*, int*, int*, int*);
   2819 static	void	mulascii(char*, int*, int*, int*);
   2820 
   2821 typedef	struct	Tab	Tab;
   2822 struct	Tab
   2823 {
   2824 	int	bp;
   2825 	int	siz;
   2826 	char*	cmp;
   2827 };
   2828 
   2829 double
   2830 fmtstrtod(const char *as, char **aas)
   2831 {
   2832 	int na, ex, dp, bp, c, i, flag, state;
   2833 	ulong low[Prec], hig[Prec], mid[Prec];
   2834 	double d;
   2835 	char *s, a[Ndig];
   2836 
   2837 	flag = 0;	/* Fsign, Fesign, Fdpoint */
   2838 	na = 0;		/* number of digits of a[] */
   2839 	dp = 0;		/* na of decimal point */
   2840 	ex = 0;		/* exonent */
   2841 
   2842 	state = S0;
   2843 	for(s=(char*)as;; s++) {
   2844 		c = *s;
   2845 		if(c >= '0' && c <= '9') {
   2846 			switch(state) {
   2847 			case S0:
   2848 			case S1:
   2849 			case S2:
   2850 				state = S2;
   2851 				break;
   2852 			case S3:
   2853 			case S4:
   2854 				state = S4;
   2855 				break;
   2856 
   2857 			case S5:
   2858 			case S6:
   2859 			case S7:
   2860 				state = S7;
   2861 				ex = ex*10 + (c-'0');
   2862 				continue;
   2863 			}
   2864 			if(na == 0 && c == '0') {
   2865 				dp--;
   2866 				continue;
   2867 			}
   2868 			if(na < Ndig-50)
   2869 				a[na++] = c;
   2870 			continue;
   2871 		}
   2872 		switch(c) {
   2873 		case '\t':
   2874 		case '\n':
   2875 		case '\v':
   2876 		case '\f':
   2877 		case '\r':
   2878 		case ' ':
   2879 			if(state == S0)
   2880 				continue;
   2881 			break;
   2882 		case '-':
   2883 			if(state == S0)
   2884 				flag |= Fsign;
   2885 			else
   2886 				flag |= Fesign;
   2887 		case '+':
   2888 			if(state == S0)
   2889 				state = S1;
   2890 			else
   2891 			if(state == S5)
   2892 				state = S6;
   2893 			else
   2894 				break;	/* syntax */
   2895 			continue;
   2896 		case '.':
   2897 			flag |= Fdpoint;
   2898 			dp = na;
   2899 			if(state == S0 || state == S1) {
   2900 				state = S3;
   2901 				continue;
   2902 			}
   2903 			if(state == S2) {
   2904 				state = S4;
   2905 				continue;
   2906 			}
   2907 			break;
   2908 		case 'e':
   2909 		case 'E':
   2910 			if(state == S2 || state == S4) {
   2911 				state = S5;
   2912 				continue;
   2913 			}
   2914 			break;
   2915 		}
   2916 		break;
   2917 	}
   2918 
   2919 	/*
   2920 	 * clean up return char-pointer
   2921 	 */
   2922 	switch(state) {
   2923 	case S0:
   2924 		if(xcmp(s, "nan") == 0) {
   2925 			if(aas != nil)
   2926 				*aas = s+3;
   2927 			goto retnan;
   2928 		}
   2929 	case S1:
   2930 		if(xcmp(s, "infinity") == 0) {
   2931 			if(aas != nil)
   2932 				*aas = s+8;
   2933 			goto retinf;
   2934 		}
   2935 		if(xcmp(s, "inf") == 0) {
   2936 			if(aas != nil)
   2937 				*aas = s+3;
   2938 			goto retinf;
   2939 		}
   2940 	case S3:
   2941 		if(aas != nil)
   2942 			*aas = (char*)as;
   2943 		goto ret0;	/* no digits found */
   2944 	case S6:
   2945 		s--;		/* back over +- */
   2946 	case S5:
   2947 		s--;		/* back over e */
   2948 		break;
   2949 	}
   2950 	if(aas != nil)
   2951 		*aas = s;
   2952 
   2953 	if(flag & Fdpoint)
   2954 	while(na > 0 && a[na-1] == '0')
   2955 		na--;
   2956 	if(na == 0)
   2957 		goto ret0;	/* zero */
   2958 	a[na] = 0;
   2959 	if(!(flag & Fdpoint))
   2960 		dp = na;
   2961 	if(flag & Fesign)
   2962 		ex = -ex;
   2963 	dp += ex;
   2964 	if(dp < -Maxe){
   2965 		errno = ERANGE;
   2966 		goto ret0;	/* underflow by exp */
   2967 	} else
   2968 	if(dp > +Maxe)
   2969 		goto retinf;	/* overflow by exp */
   2970 
   2971 	/*
   2972 	 * normalize the decimal ascii number
   2973 	 * to range .[5-9][0-9]* e0
   2974 	 */
   2975 	bp = 0;		/* binary exponent */
   2976 	while(dp > 0)
   2977 		divascii(a, &na, &dp, &bp);
   2978 	while(dp < 0 || a[0] < '5')
   2979 		mulascii(a, &na, &dp, &bp);
   2980 
   2981 	/* close approx by naive conversion */
   2982 	mid[0] = 0;
   2983 	mid[1] = 1;
   2984 	for(i=0; (c=a[i]) != '\0'; i++) {
   2985 		mid[0] = mid[0]*10 + (c-'0');
   2986 		mid[1] = mid[1]*10;
   2987 		if(i >= 8)
   2988 			break;
   2989 	}
   2990 	low[0] = umuldiv(mid[0], One, mid[1]);
   2991 	hig[0] = umuldiv(mid[0]+1, One, mid[1]);
   2992 	for(i=1; i<Prec; i++) {
   2993 		low[i] = 0;
   2994 		hig[i] = One-1;
   2995 	}
   2996 
   2997 	/* binary search for closest mantissa */
   2998 	for(;;) {
   2999 		/* mid = (hig + low) / 2 */
   3000 		c = 0;
   3001 		for(i=0; i<Prec; i++) {
   3002 			mid[i] = hig[i] + low[i];
   3003 			if(c)
   3004 				mid[i] += One;
   3005 			c = mid[i] & 1;
   3006 			mid[i] >>= 1;
   3007 		}
   3008 		frnorm(mid);
   3009 
   3010 		/* compare */
   3011 		c = fpcmp(a, mid);
   3012 		if(c > 0) {
   3013 			c = 1;
   3014 			for(i=0; i<Prec; i++)
   3015 				if(low[i] != mid[i]) {
   3016 					c = 0;
   3017 					low[i] = mid[i];
   3018 				}
   3019 			if(c)
   3020 				break;	/* between mid and hig */
   3021 			continue;
   3022 		}
   3023 		if(c < 0) {
   3024 			for(i=0; i<Prec; i++)
   3025 				hig[i] = mid[i];
   3026 			continue;
   3027 		}
   3028 
   3029 		/* only hard part is if even/odd roundings wants to go up */
   3030 		c = mid[Prec-1] & (Sigbit-1);
   3031 		if(c == Sigbit/2 && (mid[Prec-1]&Sigbit) == 0)
   3032 			mid[Prec-1] -= c;
   3033 		break;	/* exactly mid */
   3034 	}
   3035 
   3036 	/* normal rounding applies */
   3037 	c = mid[Prec-1] & (Sigbit-1);
   3038 	mid[Prec-1] -= c;
   3039 	if(c >= Sigbit/2) {
   3040 		mid[Prec-1] += Sigbit;
   3041 		frnorm(mid);
   3042 	}
   3043 	goto out;
   3044 
   3045 ret0:
   3046 	return 0;
   3047 
   3048 retnan:
   3049 	return __NaN();
   3050 
   3051 retinf:
   3052 	/*
   3053 	 * Unix strtod requires these.  Plan 9 would return Inf(0) or Inf(-1). */
   3054 	errno = ERANGE;
   3055 	if(flag & Fsign)
   3056 		return -HUGE_VAL;
   3057 	return HUGE_VAL;
   3058 
   3059 out:
   3060 	d = 0;
   3061 	for(i=0; i<Prec; i++)
   3062 		d = d*One + mid[i];
   3063 	if(flag & Fsign)
   3064 		d = -d;
   3065 	d = ldexp(d, bp - Prec*Nbits);
   3066 	if(d == 0){	/* underflow */
   3067 		errno = ERANGE;
   3068 	}
   3069 	return d;
   3070 }
   3071 
   3072 static void
   3073 frnorm(ulong *f)
   3074 {
   3075 	int i, c;
   3076 
   3077 	c = 0;
   3078 	for(i=Prec-1; i>0; i--) {
   3079 		f[i] += c;
   3080 		c = f[i] >> Nbits;
   3081 		f[i] &= One-1;
   3082 	}
   3083 	f[0] += c;
   3084 }
   3085 
   3086 static int
   3087 fpcmp(char *a, ulong* f)
   3088 {
   3089 	ulong tf[Prec];
   3090 	int i, d, c;
   3091 
   3092 	for(i=0; i<Prec; i++)
   3093 		tf[i] = f[i];
   3094 
   3095 	for(;;) {
   3096 		/* tf *= 10 */
   3097 		for(i=0; i<Prec; i++)
   3098 			tf[i] = tf[i]*10;
   3099 		frnorm(tf);
   3100 		d = (tf[0] >> Nbits) + '0';
   3101 		tf[0] &= One-1;
   3102 
   3103 		/* compare next digit */
   3104 		c = *a;
   3105 		if(c == 0) {
   3106 			if('0' < d)
   3107 				return -1;
   3108 			if(tf[0] != 0)
   3109 				goto cont;
   3110 			for(i=1; i<Prec; i++)
   3111 				if(tf[i] != 0)
   3112 					goto cont;
   3113 			return 0;
   3114 		}
   3115 		if(c > d)
   3116 			return +1;
   3117 		if(c < d)
   3118 			return -1;
   3119 		a++;
   3120 	cont:;
   3121 	}
   3122 }
   3123 
   3124 static void
   3125 divby(char *a, int *na, int b)
   3126 {
   3127 	int n, c;
   3128 	char *p;
   3129 
   3130 	p = a;
   3131 	n = 0;
   3132 	while(n>>b == 0) {
   3133 		c = *a++;
   3134 		if(c == 0) {
   3135 			while(n) {
   3136 				c = n*10;
   3137 				if(c>>b)
   3138 					break;
   3139 				n = c;
   3140 			}
   3141 			goto xx;
   3142 		}
   3143 		n = n*10 + c-'0';
   3144 		(*na)--;
   3145 	}
   3146 	for(;;) {
   3147 		c = n>>b;
   3148 		n -= c<<b;
   3149 		*p++ = c + '0';
   3150 		c = *a++;
   3151 		if(c == 0)
   3152 			break;
   3153 		n = n*10 + c-'0';
   3154 	}
   3155 	(*na)++;
   3156 xx:
   3157 	while(n) {
   3158 		n = n*10;
   3159 		c = n>>b;
   3160 		n -= c<<b;
   3161 		*p++ = c + '0';
   3162 		(*na)++;
   3163 	}
   3164 	*p = 0;
   3165 }
   3166 
   3167 static	Tab	tab1[] =
   3168 {
   3169 	{  1,  0, "" },
   3170 	{  3,  1, "7" },
   3171 	{  6,  2, "63" },
   3172 	{  9,  3, "511" },
   3173 	{ 13,  4, "8191" },
   3174 	{ 16,  5, "65535" },
   3175 	{ 19,  6, "524287" },
   3176 	{ 23,  7, "8388607" },
   3177 	{ 26,  8, "67108863" },
   3178 	{ 27,  9, "134217727" },
   3179 };
   3180 
   3181 static void
   3182 divascii(char *a, int *na, int *dp, int *bp)
   3183 {
   3184 	int b, d;
   3185 	Tab *t;
   3186 
   3187 	d = *dp;
   3188 	if(d >= (int)(nelem(tab1)))
   3189 		d = (int)(nelem(tab1))-1;
   3190 	t = tab1 + d;
   3191 	b = t->bp;
   3192 	if(memcmp(a, t->cmp, t->siz) > 0)
   3193 		d--;
   3194 	*dp -= d;
   3195 	*bp += b;
   3196 	divby(a, na, b);
   3197 }
   3198 
   3199 static void
   3200 mulby(char *a, char *p, char *q, int b)
   3201 {
   3202 	int n, c;
   3203 
   3204 	n = 0;
   3205 	*p = 0;
   3206 	for(;;) {
   3207 		q--;
   3208 		if(q < a)
   3209 			break;
   3210 		c = *q - '0';
   3211 		c = (c<<b) + n;
   3212 		n = c/10;
   3213 		c -= n*10;
   3214 		p--;
   3215 		*p = c + '0';
   3216 	}
   3217 	while(n) {
   3218 		c = n;
   3219 		n = c/10;
   3220 		c -= n*10;
   3221 		p--;
   3222 		*p = c + '0';
   3223 	}
   3224 }
   3225 
   3226 static	Tab	tab2[] =
   3227 {
   3228 	{  1,  1, "" },				/* dp = 0-0 */
   3229 	{  3,  3, "125" },
   3230 	{  6,  5, "15625" },
   3231 	{  9,  7, "1953125" },
   3232 	{ 13, 10, "1220703125" },
   3233 	{ 16, 12, "152587890625" },
   3234 	{ 19, 14, "19073486328125" },
   3235 	{ 23, 17, "11920928955078125" },
   3236 	{ 26, 19, "1490116119384765625" },
   3237 	{ 27, 19, "7450580596923828125" },		/* dp 8-9 */
   3238 };
   3239 
   3240 static void
   3241 mulascii(char *a, int *na, int *dp, int *bp)
   3242 {
   3243 	char *p;
   3244 	int d, b;
   3245 	Tab *t;
   3246 
   3247 	d = -*dp;
   3248 	if(d >= (int)(nelem(tab2)))
   3249 		d = (int)(nelem(tab2))-1;
   3250 	t = tab2 + d;
   3251 	b = t->bp;
   3252 	if(memcmp(a, t->cmp, t->siz) < 0)
   3253 		d--;
   3254 	p = a + *na;
   3255 	*bp -= b;
   3256 	*dp += d;
   3257 	*na += d;
   3258 	mulby(a, p+d, p, b);
   3259 }
   3260 
   3261 static int
   3262 xcmp(char *a, char *b)
   3263 {
   3264 	int c1, c2;
   3265 
   3266 	while((c1 = *b++) != '\0') {
   3267 		c2 = *a++;
   3268 		if(isupper(c2))
   3269 			c2 = tolower(c2);
   3270 		if(c1 != c2)
   3271 			return 1;
   3272 	}
   3273 	return 0;
   3274 }
   3275 /* -------------- vfprint.c --------------- */
   3276 /* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
   3277 // #include <stdarg.h>
   3278 // #include "plan9.h"
   3279 // #include "fmt.h"
   3280 // #include "fmtdef.h"
   3281 
   3282 int
   3283 vfprint(int fd, char *fmt, va_list args)
   3284 {
   3285 	Fmt f;
   3286 	char buf[256];
   3287 	int n;
   3288 
   3289 	fmtfdinit(&f, fd, buf, sizeof(buf));
   3290 	VA_COPY(f.args,args);
   3291 	n = dofmt(&f, fmt);
   3292 	VA_END(f.args);
   3293 	if(n > 0 && __fmtFdFlush(&f) == 0)
   3294 		return -1;
   3295 	return n;
   3296 }
   3297 /* -------------- vseprint.c --------------- */
   3298 /* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
   3299 // #include <stdarg.h>
   3300 // #include "plan9.h"
   3301 // #include "fmt.h"
   3302 // #include "fmtdef.h"
   3303 
   3304 char*
   3305 vseprint(char *buf, char *e, char *fmt, va_list args)
   3306 {
   3307 	Fmt f;
   3308 
   3309 	if(e <= buf)
   3310 		return nil;
   3311 	f.runes = 0;
   3312 	f.start = buf;
   3313 	f.to = buf;
   3314 	f.stop = e - 1;
   3315 	f.flush = 0;
   3316 	f.farg = nil;
   3317 	f.nfmt = 0;
   3318 	VA_COPY(f.args,args);
   3319 	fmtlocaleinit(&f, nil, nil, nil);
   3320 	dofmt(&f, fmt);
   3321 	VA_END(f.args);
   3322 	*(char*)f.to = '\0';
   3323 	return (char*)f.to;
   3324 }
   3325 
   3326 /* -------------- vsmprint.c --------------- */
   3327 /* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
   3328 /*
   3329  * Plan 9 port version must include libc.h in order to 
   3330  * get Plan 9 debugging malloc, which sometimes returns
   3331  * different pointers than the standard malloc. 
   3332  */
   3333 #ifdef PLAN9PORT
   3334 // #include <u.h>
   3335 // #include <libc.h>
   3336 // #include "fmtdef.h"
   3337 #else
   3338 // #include <stdlib.h>
   3339 // #include <string.h>
   3340 // #include "plan9.h"
   3341 // #include "fmt.h"
   3342 // #include "fmtdef.h"
   3343 #endif
   3344 
   3345 static int
   3346 fmtStrFlush(Fmt *f)
   3347 {
   3348 	char *s;
   3349 	int n;
   3350 
   3351 	if(f->start == nil)
   3352 		return 0;
   3353 	n = (uintptr)f->farg;
   3354 	n *= 2;
   3355 	s = (char*)f->start;
   3356 	f->start = realloc(s, n);
   3357 	if(f->start == nil){
   3358 		f->farg = nil;
   3359 		f->to = nil;
   3360 		f->stop = nil;
   3361 		free(s);
   3362 		return 0;
   3363 	}
   3364 	f->farg = (void*)(uintptr)n;
   3365 	f->to = (char*)f->start + ((char*)f->to - s);
   3366 	f->stop = (char*)f->start + n - 1;
   3367 	return 1;
   3368 }
   3369 
   3370 int
   3371 fmtstrinit(Fmt *f)
   3372 {
   3373 	int n;
   3374 
   3375 	memset(f, 0, sizeof *f);
   3376 	f->runes = 0;
   3377 	n = 32;
   3378 	f->start = malloc(n);
   3379 	if(f->start == nil)
   3380 		return -1;
   3381 	f->to = f->start;
   3382 	f->stop = (char*)f->start + n - 1;
   3383 	f->flush = fmtStrFlush;
   3384 	f->farg = (void*)(uintptr)n;
   3385 	f->nfmt = 0;
   3386 	fmtlocaleinit(f, nil, nil, nil);
   3387 	return 0;
   3388 }
   3389 
   3390 /*
   3391  * print into an allocated string buffer
   3392  */
   3393 char*
   3394 vsmprint(char *fmt, va_list args)
   3395 {
   3396 	Fmt f;
   3397 	int n;
   3398 
   3399 	if(fmtstrinit(&f) < 0)
   3400 		return nil;
   3401 	VA_COPY(f.args,args);
   3402 	n = dofmt(&f, fmt);
   3403 	VA_END(f.args);
   3404 	if(n < 0){
   3405 		free(f.start);
   3406 		return nil;
   3407 	}
   3408 	return fmtstrflush(&f);
   3409 }
   3410 /* -------------- vsnprint.c --------------- */
   3411 /* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
   3412 // #include <stdlib.h>
   3413 // #include <stdarg.h>
   3414 // #include "plan9.h"
   3415 // #include "fmt.h"
   3416 // #include "fmtdef.h"
   3417 
   3418 int
   3419 vsnprint(char *buf, int len, char *fmt, va_list args)
   3420 {
   3421 	Fmt f;
   3422 
   3423 	if(len <= 0)
   3424 		return -1;
   3425 	f.runes = 0;
   3426 	f.start = buf;
   3427 	f.to = buf;
   3428 	f.stop = buf + len - 1;
   3429 	f.flush = 0;
   3430 	f.farg = nil;
   3431 	f.nfmt = 0;
   3432 	VA_COPY(f.args,args);
   3433 	fmtlocaleinit(&f, nil, nil, nil);
   3434 	dofmt(&f, fmt);
   3435 	VA_END(f.args);
   3436 	*(char*)f.to = '\0';
   3437 	return (char*)f.to - buf;
   3438 }
   3439 
   3440 int
   3441 __errfmt(Fmt *f)
   3442 {
   3443 	char *s;
   3444 
   3445 	s = strerror(errno);
   3446 	return fmtstrcpy(f, s);
   3447 }