123 static const info fmtinfo[] = {
124 {
'd', 10,
"0123456789", 1, 0,
RADIX, },
125 {
's', 0, 0, 0, 0,
STRING, },
126 {
'S', 0, 0, 0, 0,
SEEIT, },
128 {
'c', 0, 0, 0, 0,
CHAR, },
129 {
'o', 8,
"01234567", 0,
"0",
RADIX, },
130 {
'u', 10,
"0123456789", 0, 0,
RADIX, },
131 {
'x', 16,
"0123456789abcdef", 0,
"x0",
RADIX, },
132 {
'X', 16,
"0123456789ABCDEF", 0,
"X0",
RADIX, },
133 {
'r', 10,
"0123456789", 0, 0,
ORDINAL, },
134 {
'f', 0, 0, 1, 0,
FLOAT, },
135 {
'e', 0,
"e", 1, 0,
EXP, },
136 {
'E', 0,
"E", 1, 0,
EXP, },
137 {
'g', 0,
"e", 1, 0,
GENERIC, },
138 {
'G', 0,
"E", 1, 0,
GENERIC, },
139 {
'i', 10,
"0123456789", 1, 0,
RADIX, },
140 {
'n', 0, 0, 0, 0,
SIZE, },
141 {
'S', 0, 0, 0, 0,
SEEIT, },
143 {
'b', 2,
"01", 0,
"b0",
RADIX, },
144 {
'p', 16,
"0123456789abcdef", 0,
"x0",
RADIX, },
145 {
'\'', 0, 0, 0, 0,
CHARLIT, },
147 #define NINFO (sizeof(fmtinfo)/sizeof(info))
153 #ifndef NOFLOATINGPOINT
167 static int getdigit(
long double *val,
int *cnt){
170 if( (*cnt)++ >=
MAXDIG )
return '0';
174 *val = (*val - d)*10.0;
217 void (*func)(const
char*,
int,
void*);
222 register const char *fmt;
224 register char *bufpt;
225 register int precision;
230 int flag_leftjustify;
233 int flag_alternateform;
237 unsigned long longvalue;
238 long double realvalue;
245 static const char spaces[] =
247 #define SPACESIZE (sizeof(spaces)-1)
248 #ifndef NOFLOATINGPOINT
260 for(; (c=(*fmt))!=0; ++fmt){
265 while( (c=(*++fmt))!=
'%' && c!=0 ) amt++;
266 (*func)(bufpt,amt,arg);
270 if( (c=(*++fmt))==0 ){
277 flag_leftjustify = flag_plussign = flag_blanksign =
278 flag_alternateform = flag_zeropad = flag_center = 0;
281 case '-': flag_leftjustify = 1; c = 0;
break;
282 case '+': flag_plussign = 1; c = 0;
break;
283 case ' ': flag_blanksign = 1; c = 0;
break;
284 case '#': flag_alternateform = 1; c = 0;
break;
285 case '0': flag_zeropad = 1; c = 0;
break;
286 case '=': flag_center = 1; c = 0;
break;
289 }
while( c==0 && (c=(*++fmt))!=0 );
290 if( flag_center ) flag_leftjustify = 0;
294 width = va_arg(ap,
int);
296 flag_leftjustify = 1;
302 width = width*10 + c -
'0';
314 precision = va_arg(ap,
int);
315 #ifndef COMPATIBILITY
317 if( precision<0 ) precision = -precision;
322 precision = precision*10 + c -
'0';
340 for(idx=0; idx<
NINFO; idx++){
341 if( c==fmtinfo[idx].fmttype ){
342 infop = &fmtinfo[idx];
352 flag_alternateform = 1;
353 width =
sizeof(uintptr_t)*2;
378 if( flag_long ) longvalue = va_arg(ap,
long);
379 else longvalue = va_arg(ap,
int);
383 if( longvalue==0 ) flag_alternateform = 0;
387 if( longvalue==0 && infop->
base==8 ) flag_alternateform = 0;
390 if( *(
long*)&longvalue<0 ){
391 longvalue = -*(
long*)&longvalue;
393 }
else if( flag_plussign ) prefix =
'+';
394 else if( flag_blanksign ) prefix =
' ';
397 if( flag_zeropad && precision<width-(prefix!=0) ){
398 precision = width-(prefix!=0);
406 if( a==0 || a>3 || (b>10 && b<14) ){
426 *(--bufpt) = cset[longvalue%base];
427 longvalue = longvalue/base;
428 }
while( longvalue>0 );
430 length = (int)(&buf[
BUFSIZE]-bufpt);
431 for(idx=precision-length; idx>0; idx--){
434 if( prefix ) *(--bufpt) = prefix;
435 if( flag_alternateform && infop->
prefix ){
438 if( *bufpt!=pre[0] ){
439 for(pre=infop->
prefix; (x=(*pre))!=0; pre++) *(--bufpt) = x;
442 length = (int)(&buf[
BUFSIZE]-bufpt);
447 realvalue = va_arg(ap,
double);
448 #ifndef NOFLOATINGPOINT
449 if( precision<0 ) precision = 6;
452 realvalue = -realvalue;
455 if( flag_plussign ) prefix =
'+';
456 else if( flag_blanksign ) prefix =
' ';
459 if( infop->
type==
GENERIC && precision>0 ) precision--;
463 for(idx=precision, rounder=0.4999; idx>0; idx--, rounder*=0.1);
467 else idx = precision;
468 for(rounder=0.5; idx>0; idx--, rounder*=0.1);
470 if( infop->
type==
FLOAT ) realvalue += rounder;
475 while( realvalue>=1e8 && k++<100 ){ realvalue *= 1e-8; exp+=8; }
476 while( realvalue>=10.0 && k++<100 ){ realvalue *= 0.1; exp++; }
477 while( realvalue<1e-8 && k++<100 ){ realvalue *= 1e8; exp-=8; }
478 while( realvalue<1.0 && k++<100 ){ realvalue *= 10.0; exp--; }
490 flag_exp = xtype==
EXP;
492 realvalue += rounder;
493 if( realvalue>=10.0 ){ realvalue *= 0.1; exp++; }
496 flag_rtz = !flag_alternateform;
497 if( exp<-4 || exp>precision ){
500 precision = precision -
exp;
512 flag_dp = (precision>0 || flag_alternateform);
513 if( prefix ) *(bufpt++) = prefix;
514 if( exp<0 ) *(bufpt++) =
'0';
515 else for(; exp>=0; exp--) *(bufpt++) = getdigit(&realvalue,&nsd);
516 if( flag_dp ) *(bufpt++) =
'.';
517 for(exp++; exp<0 && precision>0; precision--, exp++){
520 while( (precision--)>0 ) *(bufpt++) = getdigit(&realvalue,&nsd);
522 if( flag_rtz && flag_dp ){
523 while( bufpt>=buf && *bufpt==
'0' ) *(bufpt--) = 0;
524 if( bufpt>=buf && *bufpt==
'.' ) *(bufpt--) = 0;
528 flag_dp = (precision>0 || flag_alternateform);
529 if( prefix ) *(bufpt++) = prefix;
530 *(bufpt++) = getdigit(&realvalue,&nsd);
531 if( flag_dp ) *(bufpt++) =
'.';
532 while( (precision--)>0 ) *(bufpt++) = getdigit(&realvalue,&nsd);
534 if( flag_rtz && flag_dp ){
535 while( bufpt>=buf && *bufpt==
'0' ) *(bufpt--) = 0;
536 if( bufpt>=buf && *bufpt==
'.' ) *(bufpt--) = 0;
539 if( exp || flag_exp ){
540 *(bufpt++) = infop->
charset[0];
541 if( exp<0 ){ *(bufpt++) =
'-'; exp = -
exp; }
542 else { *(bufpt++) =
'+'; }
544 *(bufpt++) = (exp/100)+
'0';
547 *(bufpt++) = exp/10+
'0';
548 *(bufpt++) = exp%10+
'0';
554 length = (int)(bufpt-buf);
559 if( flag_zeropad && !flag_leftjustify && length < width){
561 int nPad = width - length;
562 for(i=width; i>=nPad; i--){
563 bufpt[i] = bufpt[i-nPad];
566 while( nPad-- ) bufpt[i++] =
'0';
572 *(va_arg(ap,
int*)) = count;
582 c = buf[0] = (xtype==
CHAR ? va_arg(ap,
int) : *++fmt);
584 for(idx=1; idx<precision; idx++) buf[idx] = c;
593 zMem = bufpt = va_arg(ap,
char*);
594 if( bufpt==0 ) bufpt =
"(null)";
595 length = strlen(bufpt);
596 if( precision>=0 && precision<length ) length = precision;
602 char *arg = va_arg(ap,
char*);
603 for(i=0; i<
BUFSIZE-1 && (c = *arg++)!=0; i++){
604 if( c<0x20 || c>=0x7f ){
606 buf[i] = (c&0x1f)+0x40;
613 if( precision>=0 && precision<length ) length = precision;
621 (*func)(
"%",idx,arg);
631 if( !flag_leftjustify ){
633 nspace = width-length;
638 flag_leftjustify = 1;
645 if( nspace>0 ) (*func)(spaces,nspace,arg);
649 (*func)(bufpt,length,arg);
655 if( flag_leftjustify ){
657 nspace = width-length;
664 if( nspace>0 ) (*func)(spaces,nspace,arg);
668 return errorflag ? -1 : count;
684 static void sout(txt,amt,arg)
690 register const char *t;
698 while( a-- >0 && head<tail ) *(head++) = *(t++);
700 while( a-- >0 ) *(head++) = *(t++);
706 int vsprintf(
char *buf,
const char *fmt,va_list ap){
713 int vsnprintf(
char *buf,
size_t n,
const char *fmt, va_list ap){
716 arg.
last = &buf[n-1];
737 static void mout(zNewText,nNewChar,arg)
753 memcpy(&pM->
zText[pM->
nChar], zNewText, nNewChar);
754 pM->
nChar += nNewChar;
772 int vasprintf(
char ** out,
const char *zFormat,va_list ap){
777 sMprintf.
zText = zBuf;
778 sMprintf.
nAlloc =
sizeof(zBuf);
779 sMprintf.
zBase = zBuf;
780 r =
vxprintf(mout,&sMprintf,zFormat,ap);
783 if( sMprintf.
zText ) strcpy(sMprintf.
zText,zBuf);
787 *out = sMprintf.
zText;
797 static void fout(zNewText,nNewChar,arg)
802 write(*(
int*)arg,zNewText,nNewChar);
806 int vdprintf(
int fd,
const char *zFormat, va_list ap){
807 return vxprintf(fout,&fd,zFormat,ap);