ソースを参照

Merge branch 'working'

Sean Barrett 8 年 前
コミット
fab4c61d45
1 ファイル変更92 行追加24 行削除
  1. 92 24
      stb_sprintf.h

+ 92 - 24
stb_sprintf.h

@@ -8,6 +8,7 @@
 // Contributors (bugfixes):
 //    github:d26435
 //    github:trex78
+//    Jari Komppa (SI suffixes)
 //
 // LICENSE:
 //
@@ -99,8 +100,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.
@@ -222,6 +226,35 @@ STBSP__PUBLICDEF void STB_SPRINTF_DECORATE( set_separators )( char pcomma, char
   stbsp__comma=pcomma;
 }
 
+#define STBSP__LEFTJUST 1
+#define STBSP__LEADINGPLUS 2
+#define STBSP__LEADINGSPACE 4
+#define STBSP__LEADING_0X 8
+#define STBSP__LEADINGZERO 16
+#define STBSP__INTMAX 32
+#define STBSP__TRIPLET_COMMA 64
+#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
+
+static void stbsp__lead_sign(stbsp__uint32 fl, char *sign)
+{
+  sign[0] = 0;
+  if (fl&STBSP__NEGATIVE) {
+    sign[0]=1;
+    sign[1]='-';
+  } else if (fl&STBSP__LEADINGSPACE) {
+    sign[0]=1;
+    sign[1]=' ';
+  } else if (fl&STBSP__LEADINGPLUS) {
+    sign[0]=1;
+    sign[1]='+';
+  }
+}
+  
 STBSP__PUBLICDEF int STB_SPRINTF_DECORATE( vsprintfcb )( STBSP_SPRINTFCB * callback, void * user, char * buf, char const * fmt, va_list va )
 {
   static char hex[]="0123456789abcdefxp";
@@ -236,17 +269,6 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE( vsprintfcb )( STBSP_SPRINTFCB * callb
   {
     stbsp__int32 fw,pr,tz; stbsp__uint32 fl;
 
-    #define STBSP__LEFTJUST 1
-    #define STBSP__LEADINGPLUS 2
-    #define STBSP__LEADINGSPACE 4
-    #define STBSP__LEADING_0X 8
-    #define STBSP__LEADINGZERO 16
-    #define STBSP__INTMAX 32
-    #define STBSP__TRIPLET_COMMA 64
-    #define STBSP__NEGATIVE 128
-    #define STBSP__METRIC_SUFFIX 256
-    #define STBSP__HALFWIDTH 512
- 
     // 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_buf(bytes) { if ( callback ) { stbsp__chk_cb_bufL(bytes); } }
@@ -296,8 +318,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;
@@ -416,8 +456,7 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE( vsprintfcb )( STBSP_SPRINTFCB * callb
   
         s = num+64;
 
-        // sign
-        lead[0]=0; if (fl&STBSP__NEGATIVE) { lead[0]=1; lead[1]='-'; } else if (fl&STBSP__LEADINGSPACE) { lead[0]=1; lead[1]=' '; } else if (fl&STBSP__LEADINGPLUS) { lead[0]=1; lead[1]='+'; };
+        stbsp__lead_sign(fl, lead);
 
         if (dp==-1023) dp=(n64)?-1022:0; else n64|=(((stbsp__uint64)1)<<52);
         n64<<=(64-56);
@@ -491,7 +530,7 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE( vsprintfcb )( STBSP_SPRINTFCB * callb
           fl |= STBSP__NEGATIVE;
        doexpfromg: 
         tail[0]=0; 
-        lead[0]=0; if (fl&STBSP__NEGATIVE) { lead[0]=1; lead[1]='-'; } else if (fl&STBSP__LEADINGSPACE) { lead[0]=1; lead[1]=' '; } else if (fl&STBSP__LEADINGPLUS) { lead[0]=1; lead[1]='+'; };
+        stbsp__lead_sign(fl, lead);
         if ( dp == STBSP__SPECIAL ) { s=(char*)sn; cs=0; pr=0; goto scopy; }
         s=num+64; 
         // handle leading chars
@@ -522,15 +561,20 @@ 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 ) )
           fl |= STBSP__NEGATIVE;
         dofloatfromg:
         tail[0]=0;
-        // sign
-        lead[0]=0; if (fl&STBSP__NEGATIVE) { lead[0]=1; lead[1]='-'; } else if (fl&STBSP__LEADINGSPACE) { lead[0]=1; lead[1]=' '; } else if (fl&STBSP__LEADINGPLUS) { lead[0]=1; lead[1]='+'; };
+        stbsp__lead_sign(fl, lead);
         if ( dp == STBSP__SPECIAL ) { s=(char*)sn; cs=0; pr=0; goto scopy; }
         s=num+64; 
 
@@ -575,7 +619,32 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE( vsprintfcb )( STBSP_SPRINTFCB * callb
         pr = 0;
         
         // handle k,m,g,t
-        if (fl&STBSP__METRIC_SUFFIX) { tail[0]=1; tail[1]=' '; { if (fl>>24) { tail[2]="_kmgt"[fl>>24]; tail[0]=2; } } };
+        if (fl&STBSP__METRIC_SUFFIX) 
+        { 
+            char idx;
+            idx=1;
+            if (fl&STBSP__METRIC_NOSPACE)
+                idx=0;
+            tail[0]=idx; 
+            tail[1]=' '; 
+            { 
+                if (fl>>24) 
+                {   // 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;
+                } 
+            } 
+        };
 
         flt_lead:
         // get the length that we copied
@@ -669,8 +738,7 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE( vsprintfcb )( STBSP_SPRINTFCB * callb
         }
 
         tail[0]=0;
-        // sign
-        lead[0]=0; if (fl&STBSP__NEGATIVE) { lead[0]=1; lead[1]='-'; } else if (fl&STBSP__LEADINGSPACE) { lead[0]=1; lead[1]=' '; } else if (fl&STBSP__LEADINGPLUS) { lead[0]=1; lead[1]='+'; };
+        stbsp__lead_sign(fl, lead);
 
         // get the length that we copied
         l = (stbsp__uint32) ( (num+STBSP__NUMSZ) - s ); if ( l == 0 ) { *--s='0'; l = 1; }