|
@@ -91,8 +91,11 @@ would print 12,345.
|
|
|
|
|
|
For integers and floats, you can use a "$" specifier and the number
|
|
For integers and floats, you can use a "$" specifier and the number
|
|
will be converted to float and then divided to get kilo, mega, giga or
|
|
will be converted to float and then divided to get kilo, mega, giga or
|
|
-tera and then printed, so "%$d" 1024 is "1.0 k", "%$.2d" 2536000 is
|
|
|
|
-"2.42 m", etc.
|
|
|
|
|
|
+tera and then printed, so "%$d" 1000 is "1.0 k", "%$.2d" 2536000 is
|
|
|
|
+"2.53 M", etc. For byte values, use two $:s, like "%$$d" to turn
|
|
|
|
+2536000 to "2.42 Mi". If you prefer JEDEC suffixes to SI ones, use three
|
|
|
|
+$:s: "%$$$d" -> "2.42 M". To remove the space between the number and the
|
|
|
|
+suffix, add "_" specifier: "%_$d" -> "2.53M".
|
|
|
|
|
|
In addition to octal and hexadecimal conversions, you can print
|
|
In addition to octal and hexadecimal conversions, you can print
|
|
integers in binary: "%b" for 256 would print 100.
|
|
integers in binary: "%b" for 256 would print 100.
|
|
@@ -133,9 +136,6 @@ PERFORMANCE vs MSVC 2008 32-/64-bit (GCC is even slower than MSVC):
|
|
|
|
|
|
#include <stdarg.h> // for va_list()
|
|
#include <stdarg.h> // for va_list()
|
|
|
|
|
|
-// Uncomment for old-school prefixes (KB, MB instead of KiB, MiB) with the $ format
|
|
|
|
-//#define STBSP__JEDEC_PREFIX
|
|
|
|
-
|
|
|
|
#ifndef STB_SPRINTF_MIN
|
|
#ifndef STB_SPRINTF_MIN
|
|
#define STB_SPRINTF_MIN 512 // how many characters per callback
|
|
#define STB_SPRINTF_MIN 512 // how many characters per callback
|
|
#endif
|
|
#endif
|
|
@@ -232,6 +232,9 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE( vsprintfcb )( STBSP_SPRINTFCB * callb
|
|
#define STBSP__NEGATIVE 128
|
|
#define STBSP__NEGATIVE 128
|
|
#define STBSP__METRIC_SUFFIX 256
|
|
#define STBSP__METRIC_SUFFIX 256
|
|
#define STBSP__HALFWIDTH 512
|
|
#define STBSP__HALFWIDTH 512
|
|
|
|
+ #define STBSP__METRIC_NOSPACE 1024
|
|
|
|
+ #define STBSP__METRIC_1024 2048
|
|
|
|
+ #define STBSP__METRIC_JEDEC 4096
|
|
|
|
|
|
// macros for the callback buffer stuff
|
|
// macros for the callback buffer stuff
|
|
#define stbsp__chk_cb_bufL(bytes) { int len = (int)(bf-buf); if ((len+(bytes))>=STB_SPRINTF_MIN) { tlen+=len; if (0==(bf=buf=callback(buf,user,len))) goto done; } }
|
|
#define stbsp__chk_cb_bufL(bytes) { int len = (int)(bf-buf); if ((len+(bytes))>=STB_SPRINTF_MIN) { tlen+=len; if (0==(bf=buf=callback(buf,user,len))) goto done; } }
|
|
@@ -279,8 +282,26 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE( vsprintfcb )( STBSP_SPRINTFCB * callb
|
|
case '#': fl|=STBSP__LEADING_0X; ++f; continue;
|
|
case '#': fl|=STBSP__LEADING_0X; ++f; continue;
|
|
// if we have thousand commas
|
|
// if we have thousand commas
|
|
case '\'': fl|=STBSP__TRIPLET_COMMA; ++f; continue;
|
|
case '\'': fl|=STBSP__TRIPLET_COMMA; ++f; continue;
|
|
- // if we have kilo marker
|
|
|
|
- case '$': fl|=STBSP__METRIC_SUFFIX; ++f; continue;
|
|
|
|
|
|
+ // if we have kilo marker (none->kilo->kibi->jedec)
|
|
|
|
+ case '$':
|
|
|
|
+ if (fl&STBSP__METRIC_SUFFIX)
|
|
|
|
+ {
|
|
|
|
+ if (fl&STBSP__METRIC_1024)
|
|
|
|
+ {
|
|
|
|
+ fl|=STBSP__METRIC_JEDEC;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ fl|=STBSP__METRIC_1024;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ fl|=STBSP__METRIC_SUFFIX;
|
|
|
|
+ }
|
|
|
|
+ ++f; continue;
|
|
|
|
+ // if we don't want space between metric suffix and number
|
|
|
|
+ case '_': fl|=STBSP__METRIC_NOSPACE; ++f; continue;
|
|
// if we have leading zero
|
|
// if we have leading zero
|
|
case '0': fl|=STBSP__LEADINGZERO; ++f; goto flags_done;
|
|
case '0': fl|=STBSP__LEADINGZERO; ++f; goto flags_done;
|
|
default: goto flags_done;
|
|
default: goto flags_done;
|
|
@@ -505,7 +526,13 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE( vsprintfcb )( STBSP_SPRINTFCB * callb
|
|
fv = va_arg(va,double);
|
|
fv = va_arg(va,double);
|
|
doafloat:
|
|
doafloat:
|
|
// do kilos
|
|
// do kilos
|
|
- if (fl&STBSP__METRIC_SUFFIX) {while(fl<0x4000000) { if ((fv<1024.0) && (fv>-1024.0)) break; fv/=1024.0; fl+=0x1000000; }}
|
|
|
|
|
|
+ if (fl&STBSP__METRIC_SUFFIX)
|
|
|
|
+ {
|
|
|
|
+ double divisor;
|
|
|
|
+ divisor=1000.0f;
|
|
|
|
+ if (fl&STBSP__METRIC_1024) divisor = 1024.0;
|
|
|
|
+ while(fl<0x4000000) { if ((fv<divisor) && (fv>-divisor)) break; fv/=divisor; fl+=0x1000000; }
|
|
|
|
+ }
|
|
if (pr==-1) pr=6; // default is 6
|
|
if (pr==-1) 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 ) )
|
|
@@ -560,18 +587,27 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE( vsprintfcb )( STBSP_SPRINTFCB * callb
|
|
// handle k,m,g,t
|
|
// handle k,m,g,t
|
|
if (fl&STBSP__METRIC_SUFFIX)
|
|
if (fl&STBSP__METRIC_SUFFIX)
|
|
{
|
|
{
|
|
- tail[0]=1;
|
|
|
|
|
|
+ char idx;
|
|
|
|
+ idx=1;
|
|
|
|
+ if (fl&STBSP__METRIC_NOSPACE)
|
|
|
|
+ idx=0;
|
|
|
|
+ tail[0]=idx;
|
|
tail[1]=' ';
|
|
tail[1]=' ';
|
|
{
|
|
{
|
|
if (fl>>24)
|
|
if (fl>>24)
|
|
- {
|
|
|
|
- tail[2]="_KMGT"[fl>>24];
|
|
|
|
-#ifdef STBSP__JEDEC_PREFIX
|
|
|
|
- tail[0]=2;
|
|
|
|
-#else // SI prefix
|
|
|
|
- tail[3]='i';
|
|
|
|
- tail[0]=3;
|
|
|
|
-#endif
|
|
|
|
|
|
+ { // SI kilo is 'k', JEDEC and SI kibits are 'K'.
|
|
|
|
+ if (fl&STBSP__METRIC_1024)
|
|
|
|
+ tail[idx+1]="_KMGT"[fl>>24];
|
|
|
|
+ else
|
|
|
|
+ tail[idx+1]="_kMGT"[fl>>24];
|
|
|
|
+ idx++;
|
|
|
|
+ // If printing kibits and not in jedec, add the 'i'.
|
|
|
|
+ if (fl&STBSP__METRIC_1024&&!(fl&STBSP__METRIC_JEDEC))
|
|
|
|
+ {
|
|
|
|
+ tail[idx+1]='i';
|
|
|
|
+ idx++;
|
|
|
|
+ }
|
|
|
|
+ tail[0]=idx;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
};
|