37 int v = 0, n_s, base, fmt,
flags;
39 char *sp, *ssp, *endsp, *ep, *endep;
40 int dot, width, precis, n, n_output = 0;
55 char decimal = 0, thousand = 0;
57#define SFputc(f,c) do { \
58 if (putc((c), (f)) == EOF) { \
62#define SFnputc(f,c,n) do { \
63 for (int i_ = 0; i_ < (n); ++i_) { \
64 if (putc((c), (f)) == EOF) { \
70#define SFwrite(f,s,n) do { \
71 if ((n) > 0 && fwrite((s), (size_t)(n), 1, (f)) < 1) { \
87 const char *form = argv.
ft->
form;
94 while (form[form_len] !=
'\0' && form[form_len] !=
'%')
103 size = width = precis = base = n_s = -1;
106 endsp = sp = buf + (
sizeof(buf) - 1);
111 switch ((fmt = *form++)) {
135 n_str = (form - 1) - t_str;
140 n = ft->
extf(&argv, ft);
144 if ((t_str = argv.
s) && (n_str = (
int)ft->
size) < 0)
145 n_str = (ssize_t)strlen(t_str);
182 }
else if (
dot == 2) {
184 if (*form ==
'c' || *form ==
's')
187 (form[1] ==
'c' || form[1] ==
's')) {
200 }
else if (*form !=
'*')
209 if (ft->
extf(&argv, ft) < 0)
225 for (v = fmt -
'0';
gv_isdigit(*form); ++form)
226 v = v * 10 + (*form -
'0');
229 if ((width = v) < 0) {
244 size = size * 10 + (n -
'0');
245 }
else if (*form ==
'*') {
249 FMTSET(ft, form,
'I',
sizeof(
int), 0, 0, 0, 0,
NULL, 0);
250 if (ft->
extf(&argv, ft) < 0)
259 flags &= ~SFFMT_TYPES;
268 flags &= ~SFFMT_TYPES;
313 FMTSET(ft, form, fmt, size,
flags, width, precis, base, t_str, n_str);
314 v = ft->
extf(&argv, ft);
319 FMTGET(ft, form, fmt, size,
flags, width, precis, base);
334 if (!(ls = argv.
sp) || !ls[0])
343 if ((v = size) >= 0) {
344 if (precis >= 0 && v > precis)
346 }
else if (precis < 0)
349 for (v = 0; v < precis; ++v)
353 if ((n = width - v) > 0) {
374 if (!(sp = argv.
s) || !sp[0])
409 if (
sizeof(
void*) >
sizeof(int)) {
410 lv = (
long long)(intptr_t)argv.
vp;
413 v = (int)(intptr_t)argv.
vp;
423 ssp =
"0123456789ABCDEF";
441 if ((base & (n_s = base - 1)) == 0) {
443 n = base < 4 ? 1 : 2;
445 n = base < 16 ? 3 : 4;
447 n = base < 64 ? 5 : 6;
449 n_s = base == 10 ? -1 : 0;
452 if ((
sizeof(
long) >
sizeof(int) ||
sizeof(
void*) >
sizeof(int))
453 &&
FMTCMP(size,
long long,
long long)) {
456 }
else if ((
sizeof(
long) >
sizeof(
int) ||
sizeof(
void*) >
sizeof(
int))
457 &&
FMTCMP(size,
long,
long long)) {
459 lv = (
long long)argv.
l;
461 lv = (
long long)(
ulong)argv.
l;
463 if (lv == 0 && precis == 0)
465 if (lv < 0 && fmt ==
'd') {
467 if ((
unsigned long long)lv ==
HIGHBITL) {
468 lv = (
long long)(
HIGHBITL / (
unsigned long long)base);
470 (
unsigned long long)lv * (
unsigned long long)base];
476 const int nv = snprintf(scratch,
sizeof(scratch),
"%lld", lv);
478 memcpy(sp, scratch, (
size_t)nv);
479 }
else if (n_s > 0) {
481 *--sp = ssp[lv & n_s];
482 }
while ((lv = (
unsigned long long)lv >> n));
485 *--sp = ssp[(
unsigned long long)lv % (
unsigned long long)base];
486 }
while ((lv = (
unsigned long long)lv / (
unsigned long long)base));
489 if (
sizeof(
short) <
sizeof(int) &&
FMTCMP(size,
short,
long long)) {
492 v = (int) ((
short) argv.
h);
497 v = (int) ((
short) argv.
i);
502 }
else if (size ==
sizeof(
char)) {
505 v = (int) ((
char) argv.
c);
507 v = (int) ((
uchar) argv.
c);
510 v = (int) ((
char) argv.
i);
512 v = (int) ((
uchar) argv.
i);
518 if (v == 0 && precis == 0)
520 if (v < 0 && fmt ==
'd') {
523 v = (int)(
HIGHBITI / (
unsigned)base);
530 const int nv = snprintf(scratch,
sizeof(scratch),
"%d", v);
532 memcpy(sp, scratch, (
size_t)nv);
533 }
else if (n_s > 0) {
535 *--sp = ssp[v & n_s];
536 }
while ((v = (
unsigned)v >> n));
539 *--sp = ssp[(unsigned)v % (
unsigned)base];
540 }
while ((v = (
unsigned)v / (
unsigned)base));
545 && (n = endsp - sp) > 3) {
548 for (ep = buf +
SLACK, endep = ep + n;;) {
562 if (precis > 0 && (precis -= (endsp - sp)) < (sp - buf) - 64)
572 if (fmt ==
'x' || fmt ==
'X')
577 n = base < 10 ? 2 : 3;
579 n = width - (n + (endsp - sp));
583 if (fmt ==
'x' || fmt ==
'X') {
586 }
else if (
dot >= 2) {
589 *--sp = (char) (
'0' + base);
591 *--sp =
_Sfdec[(base <<= 1) + 1];
608 dval = (double) argv.
f;
610 if (fmt ==
'e' || fmt ==
'E') {
611 n = (precis = precis < 0 ?
FPRECIS : precis) + 1;
617 }
else if (fmt ==
'f' || fmt ==
'F') {
618 precis = precis < 0 ?
FPRECIS : precis;
627 precis = precis < 0 ?
FPRECIS : precis == 0 ? 1 : precis;
638 if ((n =
sfslen()) > precis)
640 while ((n -= 1) >= 1 && ep[n] ==
'0');
645 if (decpt < -3 || decpt > precis) {
656 sp = endsp = buf + 1;
657 *endsp++ = *ep ? *ep++ :
'0';
664 while ((*endsp++ = *ep++) && ep <= endep);
665 precis -= (endsp -= 1) - ssp;
668 ep = endep = buf + (
sizeof(buf) - 1);
670 if ((n = decpt - 1) < 0)
675 *--ep = (char) (
'0' + (v - n * 10));
679 *--ep = (char) (
'0' + n);
684 *--ep = (decpt > 0 || dval == 0.) ?
'+' :
'-';
692 endsp = (sp = ep) +
sfslen();
699 endsp = sp = buf + 1;
702 if ((n = decpt % 3) == 0)
704 while (ep < endep && (*endsp++ = *ep++)) {
705 if (--n == 0 && (ep <= endep - 3)) {
711 while (ep < endep && (*endsp++ = *ep++));
719 if ((n = -decpt) > 0) {
720 ssp = endsp +
imin(n, precis);
728 while ((*endsp++ = *ep++) && ep <= endep);
729 precis -= (endsp -= 1) - ssp;
738 if (
flags == 0 && width <= 0)
746 n = (endsp - sp) + (endep - ep) + (precis <= 0 ? 0 : precis) +
748 if ((v = width - n) <= 0)
755 flags &= ~SFFMT_PREFIX;
776 if ((n = endsp - sp) > 0)
780 if ((n = precis) > 0)
784 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)