progress on stb_sprintf.h

This commit is contained in:
ed
2025-02-09 05:40:33 -05:00
parent 0485058938
commit 5798526a54
+269 -165
View File
@@ -562,61 +562,70 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(vsprintfcb)(STBSP_SPRINTFCB *callback,
fl |= STBSP__HALFWIDTH; fl |= STBSP__HALFWIDTH;
++ f; ++ f;
if (f[0] == 'h') if (f[0] == 'h')
++f; // QUARTERWIDTH ++ f; // QUARTERWIDTH
break; break;
// are we 64-bit (unix style) // are we 64-bit (unix style)
case 'l': case 'l':
fl |= ((sizeof(long) == 8) ? STBSP__INTMAX : 0); fl |= ((sizeof(long) == 8) ? STBSP__INTMAX : 0);
++f; ++ f;
if (f[0] == 'l') { if (f[0] == 'l') {
fl |= STBSP__INTMAX; fl |= STBSP__INTMAX;
++f; ++f;
} }
break; break;
// are we 64-bit on intmax? (c99) // are we 64-bit on intmax? (c99)
case 'j': case 'j':
fl |= (sizeof(size_t) == 8) ? STBSP__INTMAX : 0; fl |= (sizeof(size_t) == 8) ? STBSP__INTMAX : 0;
++f; ++ f;
break; break;
// are we 64-bit on size_t or ptrdiff_t? (c99) // are we 64-bit on size_t or ptrdiff_t? (c99)
case 'z': case 'z':
fl |= (sizeof(ptrdiff_t) == 8) ? STBSP__INTMAX : 0; fl |= (sizeof(ptrdiff_t) == 8) ? STBSP__INTMAX : 0;
++f; ++ f;
break; break;
case 't': case 't':
fl |= (sizeof(ptrdiff_t) == 8) ? STBSP__INTMAX : 0; fl |= (sizeof(ptrdiff_t) == 8) ? STBSP__INTMAX : 0;
++f; ++ f;
break; break;
// are we 64-bit (msft style) // are we 64-bit (msft style)
case 'I': case 'I':
if ((f[1] == '6') && (f[2] == '4')) { if ((f[1] == '6') && (f[2] == '4')) {
fl |= STBSP__INTMAX; fl |= STBSP__INTMAX;
f += 3; f += 3;
} else if ((f[1] == '3') && (f[2] == '2')) { }
else if ((f[1] == '3') && (f[2] == '2')) {
f += 3; f += 3;
} else { }
else {
fl |= ((sizeof(void *) == 8) ? STBSP__INTMAX : 0); fl |= ((sizeof(void *) == 8) ? STBSP__INTMAX : 0);
++f; ++ f;
} }
break; break;
default: break; default: break;
} }
// handle each replacement // handle each replacement
switch (f[0]) { switch (f[0])
{
#define STBSP__NUMSZ 512 // big enough for e308 (with commas) or e-307 #define STBSP__NUMSZ 512 // big enough for e308 (with commas) or e-307
char num[STBSP__NUMSZ]; char num[STBSP__NUMSZ];
char lead[8]; char lead[8];
char tail[8]; char tail[8];
char *s; char* s;
char const *h; char const* h;
stbsp__uint32 l, n, cs; stbsp__uint32 l, n, cs;
stbsp__uint64 n64; stbsp__uint64 n64;
#ifndef STB_SPRINTF_NOFLOAT #ifndef STB_SPRINTF_NOFLOAT
double fv; double fv;
#endif #endif
stbsp__int32 dp; stbsp__int32 dp;
char const *sn; char const* sn;
case 's': case 's':
// get the string // get the string
@@ -652,7 +661,8 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(vsprintfcb)(STBSP_SPRINTFCB *callback,
pr = 0; pr = 0;
dp = 0; dp = 0;
cs = 0; cs = 0;
}goto scopy; }
goto scopy;
case 'm': case 'm':
case 'M': case 'M':
@@ -663,44 +673,38 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(vsprintfcb)(STBSP_SPRINTFCB *callback,
static const U64 one_tib = 1ull * 1024 * 1024 * 1024 * 1024; static const U64 one_tib = 1ull * 1024 * 1024 * 1024 * 1024;
U64 size; U64 size;
if(f[0] == 'M') if (f[0] == 'M') {
{
size = va_arg(va, U64); size = va_arg(va, U64);
} }
else else {
{
size = va_arg(va, U32); size = va_arg(va, U32);
} }
U64 lo = 0; U64 lo = 0;
U64 hi = 0; U64 hi = 0;
char *units = ""; char* units = "";
if(size < one_kib) if (size < one_kib) {
{
hi = size; hi = size;
units = "Bytes"; units = "Bytes";
} }
else if(size < one_mib) else if (size < one_mib)
{ {
hi = size / one_kib; hi = size / one_kib;
lo = ((size * 100) / one_kib) % 100; lo = ((size * 100) / one_kib) % 100;
units = "KiB"; units = "KiB";
} }
else if(size < one_gib) else if (size < one_gib) {
{
hi = size / one_mib; hi = size / one_mib;
lo = ((size * 100) / one_mib) % 100; lo = ((size * 100) / one_mib) % 100;
units = "MiB"; units = "MiB";
} }
else if(size < one_tib) else if(size < one_tib) {
{
hi = size / one_gib; hi = size / one_gib;
lo = ((size * 100) / one_gib) % 100; lo = ((size * 100) / one_gib) % 100;
units = "GiB"; units = "GiB";
} }
else else {
{
assert(size <= MAX_U64 / 100ull); assert(size <= MAX_U64 / 100ull);
hi = size / one_tib; hi = size / one_tib;
lo = ((size * 100) / one_tib) % 100; lo = ((size * 100) / one_tib) % 100;
@@ -708,63 +712,60 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(vsprintfcb)(STBSP_SPRINTFCB *callback,
} }
// format high part // format high part
if(hi > 0) if (hi > 0)
{ {
s = num; s = num;
for(U64 n = hi; n > 0; n /= 10ull) for (U64 n = hi; n > 0; n /= 10ull)
{ {
*s = (char)(n % 10ull) + '0'; *s = (char)(n % 10ull) + '0';
++s; ++s;
} }
for(S64 i = (S64)(s-num)-1; i >= 0; --i) for (S64 i = (S64)(s-num)-1; i >= 0; --i)
{ {
*bf = num[i]; *bf = num[i];
++bf; ++ bf;
} }
} }
else else
{ {
*bf = '0'; *bf = '0';
++bf; ++ bf;
} }
// format low part // format low part
if(lo > 0) if (lo > 0)
{ {
*bf = '.'; *bf = '.';
++bf; ++ bf;
s = num; s = num;
for(U64 n = lo; n > 0; n /= 10ull) for (U64 n = lo; n > 0; n /= 10ull) {
{
*s = (char)(n % 10ull) + '0'; *s = (char)(n % 10ull) + '0';
++s; ++ s;
} }
U64 lead_zero_count = 3 - (U64)(s-num); U64 lead_zero_count = 3 - (U64)(s-num);
for(U64 i = 1; i < lead_zero_count; ++i) for (U64 i = 1; i < lead_zero_count; ++i) {
{
*bf = '0'; *bf = '0';
++bf; ++ bf;
} }
for(S64 i = (S64)(s-num)-1; i >= 0; --i) for (S64 i = (S64)(s-num)-1; i >= 0; --i) {
{
*bf = num[i]; *bf = num[i];
++bf; ++ bf;
} }
} }
*bf = ' '; *bf = ' ';
++bf; ++ bf;
// copy units // copy units
for(U64 i = 0; units[i] != 0; ++i) for(U64 i = 0; units[i] != 0; ++i) {
{
*bf = units[i]; *bf = units[i];
++bf; ++ bf;
} }
}break; }
break;
// //
// NOTE(rjf): DEBUGGER PROJECT ADDITION ^^^ // NOTE(rjf): DEBUGGER PROJECT ADDITION ^^^
//- //-
@@ -785,9 +786,11 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(vsprintfcb)(STBSP_SPRINTFCB *callback,
case 'n': // weird write-bytes specifier case 'n': // weird write-bytes specifier
{ {
int *d = va_arg(va, int *); int*
d = va_arg(va, int *);
*d = tlen + (int)(bf - buf); *d = tlen + (int)(bf - buf);
} break; }
break;
#ifdef STB_SPRINTF_NOFLOAT #ifdef STB_SPRINTF_NOFLOAT
case 'A': // float case 'A': // float
@@ -809,10 +812,13 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(vsprintfcb)(STBSP_SPRINTFCB *callback,
#else #else
case 'A': // hex float case 'A': // hex float
case 'a': // hex float case 'a': // hex float
{
h = (f[0] == 'A') ? hexu : hex; h = (f[0] == 'A') ? hexu : hex;
fv = va_arg(va, double); fv = va_arg(va, double);
if (pr == -1) if (pr == -1)
pr = 6; // default is 6 pr = 6; // default is 6
// read the double into a string // read the double into a string
if (stbsp__real_to_parts((stbsp__int64 *)&n64, &dp, fv)) if (stbsp__real_to_parts((stbsp__int64 *)&n64, &dp, fv))
fl |= STBSP__NEGATIVE; fl |= STBSP__NEGATIVE;
@@ -825,34 +831,42 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(vsprintfcb)(STBSP_SPRINTFCB *callback,
dp = (n64) ? -1022 : 0; dp = (n64) ? -1022 : 0;
else else
n64 |= (((stbsp__uint64)1) << 52); n64 |= (((stbsp__uint64)1) << 52);
n64 <<= (64 - 56); n64 <<= (64 - 56);
if (pr < 15) if (pr < 15)
n64 += ((((stbsp__uint64)8) << 56) >> (pr * 4)); n64 += ((((stbsp__uint64)8) << 56) >> (pr * 4));
// add leading chars // add leading chars
#ifdef STB_SPRINTF_MSVC_MODE #ifdef STB_SPRINTF_MSVC_MODE
*s++ = '0'; *s ++ = '0';
*s++ = 'x'; *s ++ = 'x';
#else #else
lead[1 + lead[0]] = '0'; lead[1 + lead[0]] = '0';
lead[2 + lead[0]] = 'x'; lead[2 + lead[0]] = 'x';
lead[0] += 2; lead[0 ] += 2;
#endif #endif
*s++ = h[(n64 >> 60) & 15];
*s ++ = h[(n64 >> 60) & 15];
n64 <<= 4; n64 <<= 4;
if (pr) if (pr)
*s++ = stbsp__period; *s++ = stbsp__period;
sn = s; sn = s;
// print the bits // print the bits
n = pr; n = pr;
if (n > 13) if (n > 13)
n = 13; n = 13;
if (pr > (stbsp__int32)n) if (pr > (stbsp__int32)n)
tz = pr - n; tz = pr - n;
pr = 0; pr = 0;
while (n--) { while (n--) {
*s++ = h[(n64 >> 60) & 15]; *s ++ = h[(n64 >> 60) & 15];
n64 <<= 4; n64 <<= 4;
} }
@@ -861,15 +875,20 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(vsprintfcb)(STBSP_SPRINTFCB *callback,
if (dp < 0) { if (dp < 0) {
tail[2] = '-'; tail[2] = '-';
dp = -dp; dp = -dp;
} else }
else
tail[2] = '+'; tail[2] = '+';
n = (dp >= 1000) ? 6 : ((dp >= 100) ? 5 : ((dp >= 10) ? 4 : 3)); n = (dp >= 1000) ? 6 : ((dp >= 100) ? 5 : ((dp >= 10) ? 4 : 3));
tail[0] = (char)n; tail[0] = (char)n;
for (;;) {
for (;;)
{
tail[n] = '0' + dp % 10; tail[n] = '0' + dp % 10;
if (n <= 3)
break; if (n <= 3) break;
--n; -- n;
dp /= 10; dp /= 10;
} }
@@ -878,15 +897,19 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(vsprintfcb)(STBSP_SPRINTFCB *callback,
s = num + 64; s = num + 64;
cs = 1 + (3 << 24); cs = 1 + (3 << 24);
goto scopy; goto scopy;
}
case 'G': // float case 'G': // float
case 'g': // float case 'g': // float
{
h = (f[0] == 'G') ? hexu : hex; h = (f[0] == 'G') ? hexu : hex;
fv = va_arg(va, double); fv = va_arg(va, double);
if (pr == -1) if (pr == -1)
pr = 6; pr = 6;
else if (pr == 0) else if (pr == 0)
pr = 1; // default is 6 pr = 1; // default is 6
// read the double into a string // read the double into a string
if (stbsp__real_to_str(&sn, &l, num, &dp, fv, (pr - 1) | 0x80000000)) if (stbsp__real_to_str(&sn, &l, num, &dp, fv, (pr - 1) | 0x80000000))
fl |= STBSP__NEGATIVE; fl |= STBSP__NEGATIVE;
@@ -915,16 +938,21 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(vsprintfcb)(STBSP_SPRINTFCB *callback,
pr = -dp + ((pr > (stbsp__int32)l) ? (stbsp__int32) l : pr); pr = -dp + ((pr > (stbsp__int32)l) ? (stbsp__int32) l : pr);
} }
goto dofloatfromg; goto dofloatfromg;
}
case 'E': // float case 'E': // float
case 'e': // float case 'e': // float
{
h = (f[0] == 'E') ? hexu : hex; h = (f[0] == 'E') ? hexu : hex;
fv = va_arg(va, double); fv = va_arg(va, double);
if (pr == -1) if (pr == -1)
pr = 6; // default is 6 pr = 6; // default is 6
// read the double into a string // read the double into a string
if (stbsp__real_to_str(&sn, &l, num, &dp, fv, pr | 0x80000000)) if (stbsp__real_to_str(&sn, &l, num, &dp, fv, pr | 0x80000000))
fl |= STBSP__NEGATIVE; fl |= STBSP__NEGATIVE;
doexpfromg: doexpfromg:
tail[0] = 0; tail[0] = 0;
stbsp__lead_sign(fl, lead); stbsp__lead_sign(fl, lead);
@@ -936,52 +964,62 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(vsprintfcb)(STBSP_SPRINTFCB *callback,
} }
s = num + 64; s = num + 64;
// handle leading chars // handle leading chars
*s++ = sn[0]; *s ++ = sn[0];
if (pr) if (pr)
*s++ = stbsp__period; *s ++ = stbsp__period;
// handle after decimal // handle after decimal
if ((l - 1) > (stbsp__uint32)pr) if ((l - 1) > (stbsp__uint32)pr)
l = pr + 1; l = pr + 1;
for (n = 1; n < l; n++) for (n = 1; n < l; n++)
*s++ = sn[n]; *s++ = sn[n];
// trailing zeros // trailing zeros
tz = pr - (l - 1); tz = pr - (l - 1);
pr = 0; pr = 0;
// dump expo // dump expo
tail[1] = h[0xe]; tail[1] = h[0xe];
dp -= 1; dp -= 1;
if (dp < 0) { if (dp < 0) {
tail[2] = '-'; tail[2] = '-';
dp = -dp; dp = -dp;
} else }
else
tail[2] = '+'; tail[2] = '+';
#ifdef STB_SPRINTF_MSVC_MODE #ifdef STB_SPRINTF_MSVC_MODE
n = 5; n = 5;
#else #else
n = (dp >= 100) ? 5 : 4; n = (dp >= 100) ? 5 : 4;
#endif #endif
tail[0] = (char)n; tail[0] = (char)n;
for (;;) { for (;;) {
tail[n] = '0' + dp % 10; tail[n] = '0' + dp % 10;
if (n <= 3) if (n <= 3)
break; break;
--n; -- n;
dp /= 10; dp /= 10;
} }
cs = 1 + (3 << 24); // how many tens cs = 1 + (3 << 24); // how many tens
goto flt_lead; goto flt_lead;
}
case 'f': // float case 'f': // float
{
fv = va_arg(va, double); fv = va_arg(va, double);
doafloat: doafloat:
// do kilos // do kilos
if (fl & STBSP__METRIC_SUFFIX) { if (fl & STBSP__METRIC_SUFFIX) {
double divisor; double divisor;
divisor = 1000.0f; divisor = 1000.0f;
if (fl & STBSP__METRIC_1024) if (fl & STBSP__METRIC_1024)
divisor = 1024.0; divisor = 1024.0;
while (fl < 0x4000000) { while (fl < 0x4000000) {
if ((fv < divisor) && (fv > -divisor)) if ((fv < divisor) && (fv > -divisor))
break; break;
@@ -989,11 +1027,14 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(vsprintfcb)(STBSP_SPRINTFCB *callback,
fl += 0x1000000; fl += 0x1000000;
} }
} }
if (pr == -1) if (pr == -1)
pr = 6; // default is 6 pr = 6; // default is 6
// read the double into a string // read the double into a string
if (stbsp__real_to_str(&sn, &l, num, &dp, fv, pr)) if (stbsp__real_to_str(&sn, &l, num, &dp, fv, pr))
fl |= STBSP__NEGATIVE; fl |= STBSP__NEGATIVE;
dofloatfromg: dofloatfromg:
tail[0] = 0; tail[0] = 0;
stbsp__lead_sign(fl, lead); stbsp__lead_sign(fl, lead);
@@ -1006,64 +1047,86 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(vsprintfcb)(STBSP_SPRINTFCB *callback,
s = num + 64; s = num + 64;
// handle the three decimal varieties // handle the three decimal varieties
if (dp <= 0) { if (dp <= 0)
{
stbsp__int32 i; stbsp__int32 i;
// handle 0.000*000xxxx // handle 0.000*000xxxx
*s++ = '0'; *s ++ = '0';
if (pr) if (pr)
*s++ = stbsp__period; *s ++ = stbsp__period;
n = -dp; n = -dp;
if ((stbsp__int32)n > pr) if ((stbsp__int32)n > pr)
n = pr; n = pr;
i = n; i = n;
while (i) {
while (i)
{
if ((((stbsp__uintptr)s) & 3) == 0) if ((((stbsp__uintptr)s) & 3) == 0)
break; break;
*s++ = '0'; *s ++ = '0';
--i; -- i;
} }
while (i >= 4) {
while (i >= 4)
{
*(stbsp__uint32 *)s = 0x30303030; *(stbsp__uint32 *)s = 0x30303030;
s += 4; s += 4;
i -= 4; i -= 4;
} }
while (i) {
*s++ = '0'; while (i)
{
*s ++ = '0';
--i; --i;
} }
if ((stbsp__int32)(l + n) > pr) if ((stbsp__int32)(l + n) > pr)
l = pr - n; l = pr - n;
i = l; i = l;
while (i) {
*s++ = *sn++; while (i)
--i; {
*s ++ = *sn++;
-- i;
} }
tz = pr - (n + l); tz = pr - (n + l);
cs = 1 + (3 << 24); // how many tens did we write (for commas below) cs = 1 + (3 << 24); // how many tens did we write (for commas below)
} else { }
else
{
cs = (fl & STBSP__TRIPLET_COMMA) ? ((600 - (stbsp__uint32)dp) % 3) : 0; cs = (fl & STBSP__TRIPLET_COMMA) ? ((600 - (stbsp__uint32)dp) % 3) : 0;
if ((stbsp__uint32)dp >= l) {
if ((stbsp__uint32)dp >= l)
{
// handle xxxx000*000.0 // handle xxxx000*000.0
n = 0; n = 0;
for (;;) {
for (;;)
{
if ((fl & STBSP__TRIPLET_COMMA) && (++cs == 4)) { if ((fl & STBSP__TRIPLET_COMMA) && (++cs == 4)) {
cs = 0; cs = 0;
*s++ = stbsp__comma; *s ++ = stbsp__comma;
} else { }
*s++ = sn[n]; else {
++n; *s ++ = sn[n];
++ n;
if (n >= l) if (n >= l)
break; break;
} }
} }
if (n < (stbsp__uint32)dp) { if (n < (stbsp__uint32)dp)
{
n = dp - n; n = dp - n;
if ((fl & STBSP__TRIPLET_COMMA) == 0) { if ((fl & STBSP__TRIPLET_COMMA) == 0)
{
while (n) { while (n) {
if ((((stbsp__uintptr)s) & 3) == 0) if ((((stbsp__uintptr)s) & 3) == 0)
break; break;
*s++ = '0'; *s ++ = '0';
--n; -- n;
} }
while (n >= 4) { while (n >= 4) {
*(stbsp__uint32 *)s = 0x30303030; *(stbsp__uint32 *)s = 0x30303030;
@@ -1071,69 +1134,89 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(vsprintfcb)(STBSP_SPRINTFCB *callback,
n -= 4; n -= 4;
} }
} }
while (n) { while (n)
{
if ((fl & STBSP__TRIPLET_COMMA) && (++cs == 4)) { if ((fl & STBSP__TRIPLET_COMMA) && (++cs == 4)) {
cs = 0; cs = 0;
*s++ = stbsp__comma; *s ++ = stbsp__comma;
} else { }
*s++ = '0'; else {
*s ++ = '0';
--n; --n;
} }
} }
} }
cs = (int)(s - (num + 64)) + (3 << 24); // cs is how many tens cs = (int)(s - (num + 64)) + (3 << 24); // cs is how many tens
if (pr) { if (pr) {
*s++ = stbsp__period; *s ++ = stbsp__period;
tz = pr; tz = pr;
} }
} else { }
else
{
// handle xxxxx.xxxx000*000 // handle xxxxx.xxxx000*000
n = 0; n = 0;
for (;;) { for (;;)
{
if ((fl & STBSP__TRIPLET_COMMA) && (++cs == 4)) { if ((fl & STBSP__TRIPLET_COMMA) && (++cs == 4)) {
cs = 0; cs = 0;
*s++ = stbsp__comma; *s++ = stbsp__comma;
} else { }
*s++ = sn[n]; else {
++n; *s ++ = sn[n];
++ n;
if (n >= (stbsp__uint32)dp) if (n >= (stbsp__uint32)dp)
break; break;
} }
} }
cs = (int)(s - (num + 64)) + (3 << 24); // cs is how many tens cs = (int)(s - (num + 64)) + (3 << 24); // cs is how many tens
if (pr) if (pr)
*s++ = stbsp__period; *s ++ = stbsp__period;
if ((l - dp) > (stbsp__uint32)pr) if ((l - dp) > (stbsp__uint32)pr)
l = pr + dp; l = pr + dp;
while (n < l) { while (n < l) {
*s++ = sn[n]; *s ++ = sn[n];
++n; ++ n;
} }
tz = pr - (l - dp); tz = pr - (l - dp);
} }
} }
pr = 0; pr = 0;
// handle k,m,g,t // handle k,m,g,t
if (fl & STBSP__METRIC_SUFFIX) { if (fl & STBSP__METRIC_SUFFIX)
{
char idx; char idx;
idx = 1; idx = 1;
if (fl & STBSP__METRIC_NOSPACE) if (fl & STBSP__METRIC_NOSPACE)
idx = 0; idx = 0;
tail[0] = idx; tail[0] = idx;
tail[1] = ' '; tail[1] = ' ';
{ {
if (fl >> 24) { // SI kilo is 'k', JEDEC and SI kibits are 'K'. if (fl >> 24)
{
// SI kilo is 'k', JEDEC and SI kibits are 'K'.
if (fl & STBSP__METRIC_1024) if (fl & STBSP__METRIC_1024)
tail[idx + 1] = "_KMGT"[fl >> 24]; tail[idx + 1] = "_KMGT"[fl >> 24];
else else
tail[idx + 1] = "_kMGT"[fl >> 24]; tail[idx + 1] = "_kMGT"[fl >> 24];
idx++; idx++;
// If printing kibits and not in jedec, add the 'i'. // If printing kibits and not in jedec, add the 'i'.
if (fl & STBSP__METRIC_1024 && !(fl & STBSP__METRIC_JEDEC)) { if (fl & STBSP__METRIC_1024 && !(fl & STBSP__METRIC_JEDEC)) {
tail[idx + 1] = 'i'; tail[idx + 1] = 'i';
idx++; idx ++;
} }
tail[0] = idx; tail[0] = idx;
} }
} }
@@ -1144,27 +1227,33 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(vsprintfcb)(STBSP_SPRINTFCB *callback,
l = (stbsp__uint32)(s - (num + 64)); l = (stbsp__uint32)(s - (num + 64));
s = num + 64; s = num + 64;
goto scopy; goto scopy;
}
// ifdef STB_SPRINTF_NOFLOAT
#endif #endif
case 'B': // upper binary case 'B': // upper binary
case 'b': // lower binary case 'b': // lower binary
h = (f[0] == 'B') ? hexu : hex; h = (f[0] == 'B') ? hexu : hex;
lead[0] = 0; lead[0] = 0;
if (fl & STBSP__LEADING_0X) { if (fl & STBSP__LEADING_0X) {
lead[0] = 2; lead[0] = 2;
lead[1] = '0'; lead[1] = '0';
lead[2] = h[0xb]; lead[2] = h[0xb];
} }
l = (8 << 4) | (1 << 8); l = (8 << 4) | (1 << 8);
goto radixnum; goto radixnum;
case 'o': // octal case 'o': // octal
h = hexu; h = hexu;
lead[0] = 0; lead[0] = 0;
if (fl & STBSP__LEADING_0X) { if (fl & STBSP__LEADING_0X) {
lead[0] = 1; lead[0] = 1;
lead[1] = '0'; lead[1] = '0';
} }
l = (3 << 4) | (3 << 8); l = (3 << 4) | (3 << 8);
goto radixnum; goto radixnum;
@@ -1176,6 +1265,7 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(vsprintfcb)(STBSP_SPRINTFCB *callback,
case 'X': // upper hex case 'X': // upper hex
case 'x': // lower hex case 'x': // lower hex
{
h = (f[0] == 'X') ? hexu : hex; h = (f[0] == 'X') ? hexu : hex;
l = (4 << 4) | (4 << 8); l = (4 << 4) | (4 << 8);
lead[0] = 0; lead[0] = 0;
@@ -1223,21 +1313,30 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(vsprintfcb)(STBSP_SPRINTFCB *callback,
l = (stbsp__uint32)((num + STBSP__NUMSZ) - s); l = (stbsp__uint32)((num + STBSP__NUMSZ) - s);
// copy it // copy it
goto scopy; goto scopy;
}
case 'u': // unsigned case 'u': // unsigned
case 'i': case 'i':
case 'd': // integer case 'd': // integer
// get the integer and abs it // get the integer and abs it
if (fl & STBSP__INTMAX) { if (fl & STBSP__INTMAX)
stbsp__int64 i64 = va_arg(va, stbsp__int64); {
stbsp__int64
i64 = va_arg(va, stbsp__int64);
n64 = (stbsp__uint64)i64; n64 = (stbsp__uint64)i64;
if ((f[0] != 'u') && (i64 < 0)) {
n64 = (stbsp__uint64)-i64; if ((f[0] != 'u') && (i64 < 0))
{
n64 = (stbsp__uint64) - i64;
fl |= STBSP__NEGATIVE; fl |= STBSP__NEGATIVE;
} }
} else { }
stbsp__int32 i = va_arg(va, stbsp__int32); else
{
stbsp__int32
i = va_arg(va, stbsp__int32);
n64 = (stbsp__uint32)i; n64 = (stbsp__uint32)i;
if ((f[0] != 'u') && (i < 0)) { if ((f[0] != 'u') && (i < 0)) {
n64 = (stbsp__uint32)-i; n64 = (stbsp__uint32)-i;
fl |= STBSP__NEGATIVE; fl |= STBSP__NEGATIVE;
@@ -1245,11 +1344,13 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(vsprintfcb)(STBSP_SPRINTFCB *callback,
} }
#ifndef STB_SPRINTF_NOFLOAT #ifndef STB_SPRINTF_NOFLOAT
if (fl & STBSP__METRIC_SUFFIX) { if (fl & STBSP__METRIC_SUFFIX)
{
if (n64 < 1024) if (n64 < 1024)
pr = 0; pr = 0;
else if (pr == -1) else if (pr == -1)
pr = 1; pr = 1;
fv = (double)(stbsp__int64)n64; fv = (double)(stbsp__int64)n64;
goto doafloat; goto doafloat;
} }
@@ -1259,7 +1360,8 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(vsprintfcb)(STBSP_SPRINTFCB *callback,
s = num + STBSP__NUMSZ; s = num + STBSP__NUMSZ;
l = 0; l = 0;
for (;;) { for (;;)
{
// do in 32-bit chunks (avoid lots of 64-bit divides even with constant denominators) // do in 32-bit chunks (avoid lots of 64-bit divides even with constant denominators)
char *o = s - 8; char *o = s - 8;
if (n64 >= 100000000) { if (n64 >= 100000000) {
@@ -1336,7 +1438,8 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(vsprintfcb)(STBSP_SPRINTFCB *callback,
} }
// copy the spaces and/or zeros // copy the spaces and/or zeros
if (fw + pr) { if (fw + pr)
{
stbsp__int32 i; stbsp__int32 i;
stbsp__uint32 c; stbsp__uint32 c;
@@ -1422,10 +1525,13 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(vsprintfcb)(STBSP_SPRINTFCB *callback,
// copy the string // copy the string
n = l; n = l;
while (n) { while (n)
{
stbsp__int32 i; stbsp__int32 i;
stbsp__cb_buf_clamp(i, n); stbsp__cb_buf_clamp(i, n);
n -= i; n -= i;
STBSP__UNALIGNED(while (i >= 4) { STBSP__UNALIGNED(while (i >= 4) {
*(stbsp__uint32 volatile *)bf = *(stbsp__uint32 volatile *)s; *(stbsp__uint32 volatile *)bf = *(stbsp__uint32 volatile *)s;
bf += 4; bf += 4;
@@ -1433,31 +1539,34 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(vsprintfcb)(STBSP_SPRINTFCB *callback,
i -= 4; i -= 4;
}) })
while (i) { while (i) {
*bf++ = *s++; *bf ++ = *s++;
--i; -- i;
} }
stbsp__chk_cb_buf(1); stbsp__chk_cb_buf(1);
} }
// copy trailing zeros // copy trailing zeros
while (tz) { while (tz)
{
stbsp__int32 i; stbsp__int32 i;
stbsp__cb_buf_clamp(i, tz); stbsp__cb_buf_clamp(i, tz);
tz -= i; tz -= i;
while (i) { while (i) {
if ((((stbsp__uintptr)bf) & 3) == 0) if ((((stbsp__uintptr)bf) & 3) == 0)
break; break;
*bf++ = '0'; *bf ++ = '0';
--i; -- i;
} }
while (i >= 4) { while (i >= 4) {
*(stbsp__uint32 *)bf = 0x30303030; *(stbsp__uint32 *)bf = 0x30303030;
bf += 4; bf += 4;
i -= 4; i -= 4;
} }
while (i) { while (i) {
*bf++ = '0'; *bf ++ = '0';
--i; -- i;
} }
stbsp__chk_cb_buf(1); stbsp__chk_cb_buf(1);
} }
@@ -1476,17 +1585,20 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(vsprintfcb)(STBSP_SPRINTFCB *callback,
} }
// handle the left justify // handle the left justify
if (fl & STBSP__LEFTJUST) if (fl & STBSP__LEFTJUST) if (fw > 0)
if (fw > 0) { {
while (fw) { while (fw)
{
stbsp__int32 i; stbsp__int32 i;
stbsp__cb_buf_clamp(i, fw); stbsp__cb_buf_clamp(i, fw);
fw -= i; fw -= i;
while (i) { while (i) {
if ((((stbsp__uintptr)bf) & 3) == 0) if ((((stbsp__uintptr)bf) & 3) == 0)
break; break;
*bf++ = ' '; *bf ++ = ' ';
--i; -- i;
} }
while (i >= 4) { while (i >= 4) {
*(stbsp__uint32 *)bf = 0x20202020; *(stbsp__uint32 *)bf = 0x20202020;
@@ -1494,7 +1606,8 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(vsprintfcb)(STBSP_SPRINTFCB *callback,
i -= 4; i -= 4;
} }
while (i--) while (i--)
*bf++ = ' '; *bf ++ = ' ';
stbsp__chk_cb_buf(1); stbsp__chk_cb_buf(1);
} }
} }
@@ -1504,7 +1617,8 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(vsprintfcb)(STBSP_SPRINTFCB *callback,
s = num + STBSP__NUMSZ - 1; s = num + STBSP__NUMSZ - 1;
*s = f[0]; *s = f[0];
l = 1; l = 1;
fw = fl = 0; fw = 0;
fl = 0;
lead[0] = 0; lead[0] = 0;
tail[0] = 0; tail[0] = 0;
pr = 0; pr = 0;
@@ -1514,7 +1628,8 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(vsprintfcb)(STBSP_SPRINTFCB *callback,
} }
++f; ++f;
} }
endfmt:
endfmt:
if (!callback) if (!callback)
*bf = 0; *bf = 0;
@@ -1628,22 +1743,16 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE( vsnprintf )( char * buf, int count, c
return c.length; return c.length;
} }
STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(snprintf)(char *buf, int count, char const *fmt, ...) STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(snprintf)(char *buf, int count, char const *fmt, ...) {
{
int result; int result;
va_list va; va_list va;
va_start(va, fmt); va_start(va, fmt);
result = STB_SPRINTF_DECORATE(vsnprintf)(buf, count, fmt, va); result = STB_SPRINTF_DECORATE(vsnprintf)(buf, count, fmt, va);
va_end(va); va_end(va);
return result; return result;
} }
STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(vsprintf)(char *buf, char const *fmt, va_list va) STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(vsprintf)(char *buf, char const *fmt, va_list va) { return STB_SPRINTF_DECORATE(vsprintfcb)(0, 0, buf, fmt, va); }
{
return STB_SPRINTF_DECORATE(vsprintfcb)(0, 0, buf, fmt, va);
}
// ======================================================================= // =======================================================================
// low level float utility functions // low level float utility functions
@@ -1653,9 +1762,9 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(vsprintf)(char *buf, char const *fmt,
// copies d to bits w/ strict aliasing (this compiles to nothing on /Ox) // copies d to bits w/ strict aliasing (this compiles to nothing on /Ox)
#define STBSP__COPYFP(dest, src) \ #define STBSP__COPYFP(dest, src) \
{ \ { \
int cn; \ int cn; \
for (cn = 0; cn < 8; cn++) \ for (cn = 0; cn < 8; cn++) \
((char *)&dest)[cn] = ((char *)&src)[cn]; \ ((char *)&dest)[cn] = ((char *)&src)[cn]; \
} }
// get float info // get float info
@@ -1666,7 +1775,6 @@ static stbsp__int32 stbsp__real_to_parts(stbsp__int64 *bits, stbsp__int32 *expo,
// load value and round at the frac_digits // load value and round at the frac_digits
d = value; d = value;
STBSP__COPYFP(b, d); STBSP__COPYFP(b, d);
*bits = b & ((((stbsp__uint64)1) << 52) - 1); *bits = b & ((((stbsp__uint64)1) << 52) - 1);
@@ -1769,41 +1877,37 @@ static stbsp__uint64 const stbsp__powten[20] = {
#define stbsp__ddmulthi(oh, ol, xh, yh) \ #define stbsp__ddmulthi(oh, ol, xh, yh) \
{ \ { \
double ahi = 0, alo, bhi = 0, blo; \ double ahi = 0; \
stbsp__int64 bt; \ double alo; \
oh = xh * yh; \ double bhi = 0; \
STBSP__COPYFP(bt, xh); \ double blo; \
bt &= ((~(stbsp__uint64)0) << 27); \ stbsp__int64 bt; \
STBSP__COPYFP(ahi, bt); \ oh = xh * yh; STBSP__COPYFP(bt, xh); bt &= ((~(stbsp__uint64)0) << 27); STBSP__COPYFP(ahi, bt); \
alo = xh - ahi; \ alo = xh - ahi; STBSP__COPYFP(bt, yh); bt &= ((~(stbsp__uint64)0) << 27); STBSP__COPYFP(bhi, bt); \
STBSP__COPYFP(bt, yh); \ blo = yh - bhi; \
bt &= ((~(stbsp__uint64)0) << 27); \ ol = ((ahi * bhi - oh) + ahi * blo + alo * bhi) + alo * blo; \
STBSP__COPYFP(bhi, bt); \
blo = yh - bhi; \
ol = ((ahi * bhi - oh) + ahi * blo + alo * bhi) + alo * blo; \
} }
#define stbsp__ddtoS64(ob, xh, xl) \ #define stbsp__ddtoS64(ob, xh, xl) \
{ \ { \
double ahi = 0, alo, vh, t; \ double ahi = 0, alo, vh, t; \
ob = (stbsp__int64)xh; \ ob = (stbsp__int64)xh; \
vh = (double)ob; \ vh = (double)ob; \
ahi = (xh - vh); \ ahi = (xh - vh); \
t = (ahi - xh); \ t = (ahi - xh); \
alo = (xh - (ahi - t)) - (vh + t); \ alo = (xh - (ahi - t)) - (vh + t); \
ob += (stbsp__int64)(ahi + alo + xl); \ ob += (stbsp__int64)(ahi + alo + xl); \
} }
#define stbsp__ddrenorm(oh, ol) \ #define stbsp__ddrenorm(oh, ol) \
{ \ { \
double s; \ double s; \
s = oh + ol; \ s = oh + ol; \
ol = ol - (s - oh); \ ol = ol - (s - oh); \
oh = s; \ oh = s; \
} }
#define stbsp__ddmultlo(oh, ol, xh, xl, yh, yl) ol = ol + (xh * yl + xl * yh); #define stbsp__ddmultlo (oh, ol, xh, xl, yh, yl) ol = ol + (xh * yl + xl * yh);
#define stbsp__ddmultlos(oh, ol, xh, yl) ol = ol + (xh * yl); #define stbsp__ddmultlos(oh, ol, xh, yl) ol = ol + (xh * yl);
static void stbsp__raise_to_power10(double *ohi, double *olo, double d, stbsp__int32 power) // power can be -323 to +350 static void stbsp__raise_to_power10(double *ohi, double *olo, double d, stbsp__int32 power) // power can be -323 to +350