Forráskód Böngészése

A bit more involved change: support for both 1000 and 1024 divisors, and SI and JEDEC suffixes, as well as removing the space between number and suffix.

jarikomppa 8 éve
szülő
commit
0e63382be0
1 módosított fájl, 53 hozzáadás és 17 törlés
  1. 53 17
      stb_sprintf.h

+ 53 - 17
stb_sprintf.h

@@ -91,8 +91,11 @@ would print 12,345.
 
 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
-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 
 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()
 
-// Uncomment for old-school prefixes (KB, MB instead of KiB, MiB) with the $ format
-//#define STBSP__JEDEC_PREFIX
-
 #ifndef STB_SPRINTF_MIN
 #define STB_SPRINTF_MIN 512 // how many characters per callback
 #endif
@@ -232,6 +232,9 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE( vsprintfcb )( STBSP_SPRINTFCB * callb
     #define STBSP__NEGATIVE 128
     #define STBSP__METRIC_SUFFIX 256
     #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
     #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; 
         // if we have thousand commas
         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
         case '0': fl|=STBSP__LEADINGZERO; ++f; 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);
        doafloat: 
         // 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
         // read the double into a string
         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
         if (fl&STBSP__METRIC_SUFFIX) 
         { 
-            tail[0]=1; 
+            char idx;
+            idx=1;
+            if (fl&STBSP__METRIC_NOSPACE)
+                idx=0;
+            tail[0]=idx; 
             tail[1]=' '; 
             { 
                 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;
                 } 
             } 
         };