39 int v = 0, n_s, base, fmt,
flags;
41 char *sp, *ssp, *endsp, *ep, *endep;
42 int dot, width, precis, n, n_output = 0;
57 char decimal = 0, thousand = 0;
59#define SFputc(f,c) do { \
60 if (putc((c), (f)) == EOF) { \
64#define SFnputc(f,c,n) do { \
65 for (int i_ = 0; i_ < (n); ++i_) { \
66 if (putc((c), (f)) == EOF) { \
72#define SFwrite(f,s,n) do { \
73 if ((n) > 0 && fwrite((s), (size_t)(n), 1, (f)) < 1) { \
89 const char *form = argv.
ft->
form;
96 while (form[form_len] !=
'\0' && form[form_len] !=
'%')
105 size = width = precis = base = n_s = -1;
108 endsp = sp = buf + (
sizeof(buf) - 1);
113 switch ((fmt = *form++)) {
137 n_str = (form - 1) - t_str;
142 n = ft->
extf(&argv, ft);
146 if ((t_str = argv.
s) && (n_str = (
int)ft->
size) < 0)
147 n_str = (ssize_t)strlen(t_str);
184 }
else if (
dot == 2) {
186 if (*form ==
'c' || *form ==
's')
189 (form[1] ==
'c' || form[1] ==
's')) {
202 }
else if (*form !=
'*')
211 if (ft->
extf(&argv, ft) < 0)
227 for (v = fmt -
'0';
gv_isdigit(*form); ++form)
228 v = v * 10 + (*form -
'0');
231 if ((width = v) < 0) {
246 size = size * 10 + (n -
'0');
247 }
else if (*form ==
'*') {
251 FMTSET(ft, form,
'I',
sizeof(
int), 0, 0, 0, 0,
NULL, 0);
252 if (ft->
extf(&argv, ft) < 0)
261 flags &= ~SFFMT_TYPES;
270 flags &= ~SFFMT_TYPES;
315 FMTSET(ft, form, fmt, size,
flags, width, precis, base, t_str, n_str);
316 v = ft->
extf(&argv, ft);
321 FMTGET(ft, form, fmt, size,
flags, width, precis, base);
336 if (!(ls = argv.
sp) || !ls[0])
345 if ((v = size) >= 0) {
346 if (precis >= 0 && v > precis)
348 }
else if (precis < 0)
351 for (v = 0; v < precis; ++v)
355 if ((n = width - v) > 0) {
376 if (!(sp = argv.
s) || !sp[0])
411 if (
sizeof(
void*) >
sizeof(int)) {
412 lv = (
long long)(intptr_t)argv.
vp;
415 v = (int)(intptr_t)argv.
vp;
425 ssp =
"0123456789ABCDEF";
443 if ((base & (n_s = base - 1)) == 0) {
445 n = base < 4 ? 1 : 2;
447 n = base < 16 ? 3 : 4;
449 n = base < 64 ? 5 : 6;
451 n_s = base == 10 ? -1 : 0;
454 if ((
sizeof(
long) >
sizeof(int) ||
sizeof(
void*) >
sizeof(int))
455 &&
FMTCMP(size,
long long,
long long)) {
458 }
else if ((
sizeof(
long) >
sizeof(
int) ||
sizeof(
void*) >
sizeof(
int))
459 &&
FMTCMP(size,
long,
long long)) {
461 lv = (
long long)argv.
l;
463 lv = (
long long)(
ulong)argv.
l;
465 if (lv == 0 && precis == 0)
467 if (lv < 0 && fmt ==
'd') {
469 if ((
unsigned long long)lv ==
HIGHBITL) {
470 lv = (
long long)(
HIGHBITL / (
unsigned long long)base);
472 (
unsigned long long)lv * (
unsigned long long)base];
478 const int nv = snprintf(scratch,
sizeof(scratch),
"%lld", lv);
480 memcpy(sp, scratch, (
size_t)nv);
481 }
else if (n_s > 0) {
483 *--sp = ssp[lv & n_s];
484 }
while ((lv = (
unsigned long long)lv >> n));
487 *--sp = ssp[(
unsigned long long)lv % (
unsigned long long)base];
488 }
while ((lv = (
unsigned long long)lv / (
unsigned long long)base));
491 if (
sizeof(
short) <
sizeof(int) &&
FMTCMP(size,
short,
long long)) {
494 v = (int) ((
short) argv.
h);
499 v = (int) ((
short) argv.
i);
504 }
else if (size ==
sizeof(
char)) {
507 v = (int) ((
char) argv.
c);
509 v = (int) ((
uchar) argv.
c);
512 v = (int) ((
char) argv.
i);
514 v = (int) ((
uchar) argv.
i);
520 if (v == 0 && precis == 0)
522 if (v < 0 && fmt ==
'd') {
525 v = (int)(
HIGHBITI / (
unsigned)base);
532 const int nv = snprintf(scratch,
sizeof(scratch),
"%d", v);
534 memcpy(sp, scratch, (
size_t)nv);
535 }
else if (n_s > 0) {
537 *--sp = ssp[v & n_s];
538 }
while ((v = (
unsigned)v >> n));
541 *--sp = ssp[(unsigned)v % (
unsigned)base];
542 }
while ((v = (
unsigned)v / (
unsigned)base));
547 && (n = endsp - sp) > 3) {
550 for (ep = buf +
SLACK, endep = ep + n;;) {
564 if (precis > 0 && (precis -= (endsp - sp)) < (sp - buf) - 64)
574 if (fmt ==
'x' || fmt ==
'X')
579 n = base < 10 ? 2 : 3;
581 n = width - (n + (endsp - sp));
585 if (fmt ==
'x' || fmt ==
'X') {
588 }
else if (
dot >= 2) {
591 *--sp = (char) (
'0' + base);
593 *--sp =
_Sfdec[(base <<= 1) + 1];
610 dval = (double) argv.
f;
612 if (fmt ==
'e' || fmt ==
'E') {
613 n = (precis = precis < 0 ?
FPRECIS : precis) + 1;
619 }
else if (fmt ==
'f' || fmt ==
'F') {
620 precis = precis < 0 ?
FPRECIS : precis;
629 precis = precis < 0 ?
FPRECIS : precis == 0 ? 1 : precis;
640 if ((n =
sfslen()) > precis)
642 while ((n -= 1) >= 1 && ep[n] ==
'0');
647 if (decpt < -3 || decpt > precis) {
658 sp = endsp = buf + 1;
659 *endsp++ = *ep ? *ep++ :
'0';
666 while ((*endsp++ = *ep++) && ep <= endep);
667 precis -= (endsp -= 1) - ssp;
670 ep = endep = buf + (
sizeof(buf) - 1);
672 if ((n = decpt - 1) < 0)
677 *--ep = (char) (
'0' + (v - n * 10));
681 *--ep = (char) (
'0' + n);
686 *--ep = (decpt > 0 || dval == 0.) ?
'+' :
'-';
694 endsp = (sp = ep) +
sfslen();
701 endsp = sp = buf + 1;
704 if ((n = decpt % 3) == 0)
706 while (ep < endep && (*endsp++ = *ep++)) {
707 if (--n == 0 && (ep <= endep - 3)) {
713 while (ep < endep && (*endsp++ = *ep++));
721 if ((n = -decpt) > 0) {
722 ssp = endsp +
imin(n, precis);
730 while ((*endsp++ = *ep++) && ep <= endep);
731 precis -= (endsp -= 1) - ssp;
740 if (
flags == 0 && width <= 0)
748 n = (endsp - sp) + (endep - ep) + (precis <= 0 ? 0 : precis) +
750 if ((v = width - n) <= 0)
757 flags &= ~SFFMT_PREFIX;
778 if ((n = endsp - sp) > 0)
782 if ((n = precis) > 0)
786 if ((n = endep - (sp = ep)) > 0)
#define FMTGET(ft, frm, fv, sz, flgs, wid, pr, bs)
#define FMTSET(ft, frm, fv, sz, flgs, wid, pr, bs, ts, ns)