ssprintf() family of functions for std::string + printf functionality
authorRoyce Mitchell III <royce3@ev1.net>
Tue, 4 Jan 2005 18:38:31 +0000 (18:38 +0000)
committerRoyce Mitchell III <royce3@ev1.net>
Tue, 4 Jan 2005 18:38:31 +0000 (18:38 +0000)
svn path=/branches/xmlbuildsystem/; revision=12794

reactos/tools/rbuild/ssprintf.cpp [new file with mode: 0644]
reactos/tools/rbuild/ssprintf.h [new file with mode: 0644]

diff --git a/reactos/tools/rbuild/ssprintf.cpp b/reactos/tools/rbuild/ssprintf.cpp
new file mode 100644 (file)
index 0000000..5b0e713
--- /dev/null
@@ -0,0 +1,1893 @@
+// ssprintf.cpp\r
+\r
+#include <malloc.h>\r
+#include <math.h>\r
+#include <float.h>\r
+#include <assert.h>\r
+#include "ssprintf.h"\r
+\r
+#ifdef _MSC_VER\r
+#define alloca _alloca\r
+#endif//_MSC_VER\r
+\r
+typedef __int64 LONGLONG;\r
+typedef unsigned __int64 ULONGLONG;\r
+\r
+typedef struct {\r
+    unsigned int mantissa:23;\r
+    unsigned int exponent:8;\r
+    unsigned int sign:1;\r
+} ieee_float_t;\r
+\r
+typedef struct {\r
+    unsigned int mantissal:32;\r
+    unsigned int mantissah:20;\r
+    unsigned int exponent:11;\r
+    unsigned int sign:1;\r
+} ieee_double_t;\r
+\r
+typedef struct {\r
+    unsigned int mantissal:32;\r
+    unsigned int mantissah:32;\r
+    unsigned int exponent:15;\r
+    unsigned int sign:1;\r
+    unsigned int empty:16;\r
+} ieee_long_double_t;\r
+\r
+std::string ssprintf ( const char* fmt, ... )\r
+{\r
+       va_list arg;\r
+       va_start(arg, fmt);\r
+       std::string f = ssvprintf ( fmt, arg );\r
+       va_end(arg);\r
+       return f;\r
+}\r
+\r
+std::wstring sswprintf ( const wchar_t* fmt, ... )\r
+{\r
+       va_list arg;\r
+       va_start(arg, fmt);\r
+       std::wstring f = sswvprintf ( fmt, arg );\r
+       va_end(arg);\r
+       return f;\r
+}\r
+\r
+#define ZEROPAD                1       /* pad with zero */\r
+#define SIGN           2       /* unsigned/signed long */\r
+#define PLUS           4       /* show plus */\r
+#define SPACE          8       /* space if plus */\r
+#define LEFT           16      /* left justified */\r
+#define SPECIAL                32      /* 0x */\r
+#define LARGE          64      /* use 'ABCDEF' instead of 'abcdef' */\r
+#define ZEROTRUNC      128     /* truncate zero 's */\r
+\r
+\r
+static int skip_atoi(const char **s)\r
+{\r
+       int i=0;\r
+\r
+       while (isdigit(**s))\r
+               i = i*10 + *((*s)++) - '0';\r
+       return i;\r
+}\r
+\r
+static int skip_wtoi(const wchar_t **s)\r
+{\r
+       int i=0;\r
+\r
+       while (iswdigit(**s))\r
+               i = i*10 + *((*s)++) - L'0';\r
+       return i;\r
+}\r
+\r
+\r
+static int do_div(LONGLONG *n,int base)\r
+{\r
+       int __res = ((ULONGLONG) *n) % (unsigned) base;\r
+       *n = ((ULONGLONG) *n) / (unsigned) base;\r
+       return __res;\r
+}\r
+\r
+\r
+static bool number(std::string& f, LONGLONG num, int base, int size, int precision ,int type)\r
+{\r
+       char c,sign,tmp[66];\r
+       const char *digits="0123456789abcdefghijklmnopqrstuvwxyz";\r
+       int i;\r
+\r
+       if (type & LARGE)\r
+               digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";\r
+       if (type & LEFT)\r
+               type &= ~ZEROPAD;\r
+       if (base < 2 || base > 36)\r
+               return 0;\r
+       c = (type & ZEROPAD) ? '0' : ' ';\r
+       sign = 0;\r
+       if (type & SIGN) {\r
+               if (num < 0) {\r
+                       sign = '-';\r
+                       num = -num;\r
+                       size--;\r
+               } else if (type & PLUS) {\r
+                       sign = '+';\r
+                       size--;\r
+               } else if (type & SPACE) {\r
+                       sign = ' ';\r
+                       size--;\r
+               }\r
+       }\r
+       if (type & SPECIAL) {\r
+               if (base == 16)\r
+                       size -= 2;\r
+               else if (base == 8)\r
+                       size--;\r
+       }\r
+       i = 0;\r
+       if (num == 0)\r
+               tmp[i++]='0';\r
+       else while (num != 0)\r
+               tmp[i++] = digits[do_div(&num,base)];\r
+       if (i > precision)\r
+               precision = i;\r
+       size -= precision;\r
+       if (!(type&(ZEROPAD+LEFT)))\r
+               while(size-->0)\r
+                       f += ' ';\r
+       if (sign)\r
+               f += sign;\r
+       if (type & SPECIAL)\r
+       {\r
+               if (base==8)\r
+                       f += '0';\r
+               else if (base==16)\r
+               {\r
+                       f += '0';\r
+                       f += digits[33];\r
+               }\r
+       }\r
+       if (!(type & LEFT))\r
+       {\r
+               while (size-- > 0)\r
+                       f += c;\r
+       }\r
+       while (i < precision--)\r
+       {\r
+               f += '0';\r
+       }\r
+       while (i-- > 0)\r
+       {\r
+               f += tmp[i];\r
+       }\r
+       while (size-- > 0)\r
+       {\r
+               f += ' ';\r
+       }\r
+       return true;\r
+}\r
+\r
+static bool wnumber(std::wstring& f, LONGLONG num, int base, int size, int precision ,int type)\r
+{\r
+       wchar_t c,sign,tmp[66];\r
+       const wchar_t *digits = L"0123456789abcdefghijklmnopqrstuvwxyz";\r
+       int i;\r
+\r
+       if (type & LARGE)\r
+               digits = L"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";\r
+       if (type & LEFT)\r
+               type &= ~ZEROPAD;\r
+       if (base < 2 || base > 36)\r
+               return 0;\r
+       c = (type & ZEROPAD) ? L'0' : L' ';\r
+       sign = 0;\r
+       if (type & SIGN) {\r
+               if (num < 0) {\r
+                       sign = L'-';\r
+                       num = -num;\r
+                       size--;\r
+               } else if (type & PLUS) {\r
+                       sign = L'+';\r
+                       size--;\r
+               } else if (type & SPACE) {\r
+                       sign = L' ';\r
+                       size--;\r
+               }\r
+       }\r
+       if (type & SPECIAL) {\r
+               if (base == 16)\r
+                       size -= 2;\r
+               else if (base == 8)\r
+                       size--;\r
+       }\r
+       i = 0;\r
+       if (num == 0)\r
+               tmp[i++]=L'0';\r
+       else while (num != 0)\r
+               tmp[i++] = digits[do_div(&num,base)];\r
+       if (i > precision)\r
+               precision = i;\r
+       size -= precision;\r
+       if (!(type&(ZEROPAD+LEFT)))\r
+               while(size-->0)\r
+                       f += L' ';\r
+       if (sign)\r
+               f += sign;\r
+       if (type & SPECIAL)\r
+       {\r
+               if (base==8)\r
+                       f += L'0';\r
+               else if (base==16)\r
+               {\r
+                       f += L'0';\r
+                       f += digits[33];\r
+               }\r
+       }\r
+       if (!(type & LEFT))\r
+       {\r
+               while (size-- > 0)\r
+                       f += c;\r
+       }\r
+       while (i < precision--)\r
+       {\r
+               f += L'0';\r
+       }\r
+       while (i-- > 0)\r
+       {\r
+               f += tmp[i];\r
+       }\r
+       while (size-- > 0)\r
+       {\r
+               f += L' ';\r
+       }\r
+       return true;\r
+}\r
+\r
+\r
+static bool numberf(std::string& f, double __n, char exp_sign,  int size, int precision, int type)\r
+{\r
+       double exponent = 0.0;\r
+       double e;\r
+       long ie;\r
+\r
+       //int x;\r
+       char *buf, *tmp;\r
+       int i = 0;\r
+       int j = 0;\r
+       //int k = 0;\r
+\r
+       double frac, intr;\r
+       double p;\r
+       char sign;\r
+       char c;\r
+       char ro = 0;\r
+       int result;\r
+\r
+       union\r
+       {\r
+               double*  __n;\r
+               ieee_double_t*  n;\r
+       } n;\r
+       \r
+       n.__n = &__n;\r
+\r
+       if ( exp_sign == 'g' || exp_sign == 'G' || exp_sign == 'e' || exp_sign == 'E' ) {\r
+               ie = ((unsigned int)n.n->exponent - (unsigned int)0x3ff);\r
+               exponent = ie/3.321928;\r
+       }\r
+\r
+       if ( exp_sign == 'g' || exp_sign == 'G' ) {\r
+               type |= ZEROTRUNC;\r
+               if ( exponent < -4 || fabs(exponent) >= precision )\r
+                        exp_sign -= 2; // g -> e and G -> E\r
+       }\r
+\r
+       if ( exp_sign == 'e' ||  exp_sign == 'E' ) {\r
+               frac = modf(exponent,&e);\r
+               if ( frac > 0.5 )\r
+                       e++;\r
+               else if (  frac < -0.5  )\r
+                       e--;\r
+\r
+               result = numberf(f,__n/pow(10.0L,e),'f',size-4, precision, type);\r
+               if (result < 0)\r
+                       return false;\r
+               f += exp_sign;\r
+               size--;\r
+               ie = (long)e;\r
+               type = LEFT | PLUS;\r
+               if ( ie < 0 )\r
+                       type |= SIGN;\r
+\r
+               result = number(f,ie, 10,2, 2,type );\r
+               if (result < 0)\r
+                       return false;\r
+               return true;\r
+       }\r
+\r
+       if ( exp_sign == 'f' ) {\r
+               buf = (char*)alloca(4096);\r
+               if (type & LEFT) {\r
+                       type &= ~ZEROPAD;\r
+               }\r
+\r
+               c = (type & ZEROPAD) ? '0' : ' ';\r
+               sign = 0;\r
+               if (type & SIGN) {\r
+                       if (__n < 0) {\r
+                               sign = '-';\r
+                               __n = fabs(__n);\r
+                               size--;\r
+                       } else if (type & PLUS) {\r
+                               sign = '+';\r
+                               size--;\r
+                       } else if (type & SPACE) {\r
+                               sign = ' ';\r
+                               size--;\r
+                       }\r
+               }\r
+\r
+               frac = modf(__n,&intr);\r
+\r
+               // # flags forces a . and prevents trucation of trailing zero's\r
+\r
+               if ( precision > 0 ) {\r
+                       //frac = modfl(__n,&intr);\r
+                       i = precision-1;\r
+                       while (  i >= 0  ) {\r
+                               frac*=10.0L;\r
+                               frac = modf(frac, &p);\r
+                               buf[i] = (int)p + '0';\r
+                               i--;\r
+                       }\r
+                       i = precision;\r
+                       size -= precision;\r
+\r
+                       ro = 0;\r
+                       if ( frac > 0.5 ) {\r
+                               ro = 1;\r
+                       }\r
+\r
+                       if ( precision >= 1 || type & SPECIAL) {\r
+                               buf[i++] = '.';\r
+                               size--;\r
+                       }\r
+               }\r
+\r
+               if ( intr == 0.0 ) {\r
+                       buf[i++] = '0';\r
+                       size--;\r
+               }\r
+               else {\r
+                       while ( intr > 0.0 ) {\r
+                               p = intr;\r
+                               intr/=10.0L;\r
+                               modf(intr, &intr);\r
+\r
+                               p -= 10.0*intr;\r
+\r
+                               buf[i++] = (int)p + '0';\r
+                               size--;\r
+                       }\r
+               }\r
+\r
+               j = 0;\r
+               while ( j < i && ro == 1) {\r
+                       if ( buf[j] >= '0' && buf[j] <= '8' ) {\r
+                               buf[j]++;\r
+                               ro = 0;\r
+                       }\r
+                       else if ( buf[j] == '9' ) {\r
+                               buf[j] = '0';\r
+                       }\r
+                       j++;\r
+               }\r
+               if ( ro == 1 )\r
+                       buf[i++] = '1';\r
+\r
+               buf[i] = 0;\r
+\r
+               size -= precision;\r
+               if (!(type&(ZEROPAD+LEFT)))\r
+               {\r
+                       while(size-->0)\r
+                               f += ' ';\r
+               }\r
+               if (sign)\r
+               {\r
+                       f += sign;\r
+               }\r
+\r
+               if (!(type&(ZEROPAD+LEFT)))\r
+                       while(size-->0)\r
+                       {\r
+                               f += ' ';\r
+                       }\r
+               if (type & SPECIAL) {\r
+               }\r
+\r
+               if (!(type & LEFT))\r
+                       while (size-- > 0)\r
+                       {\r
+                               f += c;\r
+                       }\r
+\r
+               tmp = buf;\r
+               if ( type & ZEROTRUNC && ((type & SPECIAL) != SPECIAL) )\r
+               {\r
+                       j = 0;\r
+                       while ( j < i && ( *tmp == '0' || *tmp == '.' ))\r
+                       {\r
+                               tmp++;\r
+                               i--;\r
+                       }\r
+               }\r
+//             else\r
+//                     while (i < precision--)\r
+//                             putc('0', f);\r
+               while (i-- > 0)\r
+               {\r
+                       f += tmp[i];\r
+               }\r
+               while (size-- > 0)\r
+               {\r
+                       f += ' ';\r
+               }\r
+       }\r
+       return true;\r
+}\r
+\r
+static bool wnumberf(std::wstring& f, double __n, wchar_t exp_sign,  int size, int precision, int type)\r
+{\r
+       double exponent = 0.0;\r
+       double e;\r
+       long ie;\r
+\r
+       int i = 0;\r
+       int j = 0;\r
+\r
+       double frac, intr;\r
+       double p;\r
+       wchar_t *buf, *tmp, sign, c, ro = 0;\r
+       int result;\r
+\r
+       union\r
+       {\r
+               double*  __n;\r
+               ieee_double_t*  n;\r
+       } n;\r
+       \r
+       n.__n = &__n;\r
+\r
+       if ( exp_sign == L'g' || exp_sign == L'G' || exp_sign == L'e' || exp_sign == L'E' ) {\r
+               ie = ((unsigned int)n.n->exponent - (unsigned int)0x3ff);\r
+               exponent = ie/3.321928;\r
+       }\r
+\r
+       if ( exp_sign == L'g' || exp_sign == L'G' )\r
+       {\r
+               type |= ZEROTRUNC;\r
+               if ( exponent < -4 || fabs(exponent) >= precision )\r
+                        exp_sign -= 2; // g -> e and G -> E\r
+       }\r
+\r
+       if ( exp_sign == L'e' ||  exp_sign == L'E' )\r
+       {\r
+               frac = modf(exponent,&e);\r
+               if ( frac > 0.5 )\r
+                       e++;\r
+               else if (  frac < -0.5  )\r
+                       e--;\r
+\r
+               result = wnumberf(f,__n/pow(10.0L,e),L'f',size-4, precision, type);\r
+               if (result < 0)\r
+                       return false;\r
+               f += exp_sign;\r
+               size--;\r
+               ie = (long)e;\r
+               type = LEFT | PLUS;\r
+               if ( ie < 0 )\r
+                       type |= SIGN;\r
+\r
+               result = wnumber(f,ie, 10,2, 2,type );\r
+               if (result < 0)\r
+                       return false;\r
+               return true;\r
+       }\r
+\r
+       if ( exp_sign == L'f' )\r
+       {\r
+               buf = (wchar_t*)alloca(4096*sizeof(wchar_t));\r
+               if (type & LEFT)\r
+                       type &= ~ZEROPAD;\r
+\r
+               c = (type & ZEROPAD) ? L'0' : L' ';\r
+               sign = 0;\r
+               if (type & SIGN)\r
+               {\r
+                       if (__n < 0)\r
+                       {\r
+                               sign = L'-';\r
+                               __n = fabs(__n);\r
+                               size--;\r
+                       }\r
+                       else if (type & PLUS)\r
+                       {\r
+                               sign = L'+';\r
+                               size--;\r
+                       }\r
+                       else if (type & SPACE)\r
+                       {\r
+                               sign = L' ';\r
+                               size--;\r
+                       }\r
+               }\r
+\r
+               frac = modf(__n,&intr);\r
+\r
+               // # flags forces a . and prevents trucation of trailing zero's\r
+\r
+               if ( precision > 0 ) {\r
+                       //frac = modfl(__n,&intr);\r
+                       i = precision-1;\r
+                       while (  i >= 0  ) {\r
+                               frac*=10.0L;\r
+                               frac = modf(frac, &p);\r
+                               buf[i] = (int)p + L'0';\r
+                               i--;\r
+                       }\r
+                       i = precision;\r
+                       size -= precision;\r
+\r
+                       ro = 0;\r
+                       if ( frac > 0.5 ) {\r
+                               ro = 1;\r
+                       }\r
+\r
+                       if ( precision >= 1 || type & SPECIAL) {\r
+                               buf[i++] = L'.';\r
+                               size--;\r
+                       }\r
+               }\r
+\r
+               if ( intr == 0.0 ) {\r
+                       buf[i++] = L'0';\r
+                       size--;\r
+               }\r
+               else {\r
+                       while ( intr > 0.0 ) {\r
+                               p = intr;\r
+                               intr/=10.0L;\r
+                               modf(intr, &intr);\r
+\r
+                               p -= 10.0*intr;\r
+\r
+                               buf[i++] = (int)p + L'0';\r
+                               size--;\r
+                       }\r
+               }\r
+\r
+               j = 0;\r
+               while ( j < i && ro == 1) {\r
+                       if ( buf[j] >= L'0' && buf[j] <= L'8' ) {\r
+                               buf[j]++;\r
+                               ro = 0;\r
+                       }\r
+                       else if ( buf[j] == L'9' ) {\r
+                               buf[j] = L'0';\r
+                       }\r
+                       j++;\r
+               }\r
+               if ( ro == 1 )\r
+                       buf[i++] = L'1';\r
+\r
+               buf[i] = 0;\r
+\r
+               size -= precision;\r
+               if (!(type&(ZEROPAD+LEFT)))\r
+               {\r
+                       while(size-->0)\r
+                               f += L' ';\r
+               }\r
+               if (sign)\r
+               {\r
+                       f += sign;\r
+               }\r
+\r
+               if (!(type&(ZEROPAD+LEFT)))\r
+                       while(size-->0)\r
+                       {\r
+                               f += L' ';\r
+                       }\r
+               if (type & SPECIAL) {\r
+               }\r
+\r
+               if (!(type & LEFT))\r
+                       while (size-- > 0)\r
+                       {\r
+                               f += c;\r
+                       }\r
+\r
+               tmp = buf;\r
+               if ( type & ZEROTRUNC && ((type & SPECIAL) != SPECIAL) )\r
+               {\r
+                       j = 0;\r
+                       while ( j < i && ( *tmp == L'0' || *tmp == L'.' ))\r
+                       {\r
+                               tmp++;\r
+                               i--;\r
+                       }\r
+               }\r
+               while (i-- > 0)\r
+               {\r
+                       f += tmp[i];\r
+               }\r
+               while (size-- > 0)\r
+               {\r
+                       f += L' ';\r
+               }\r
+       }\r
+       return true;\r
+}\r
+\r
+static bool numberfl(std::string& f, long double __n, char exp_sign,  int size, int precision, int type)\r
+{\r
+       long double exponent = 0.0;\r
+       long double e;\r
+       long ie;\r
+\r
+       //int x;\r
+       char *buf, *tmp;\r
+       int i = 0;\r
+       int j = 0;\r
+       //int k = 0;\r
+\r
+       long double frac, intr;\r
+       long double p;\r
+       char sign;\r
+       char c;\r
+       char ro = 0;\r
+\r
+       int result;\r
+\r
+       union\r
+       {\r
+           long double*   __n;\r
+           ieee_long_double_t*   n;\r
+       } n;\r
+\r
+       n.__n = &__n;\r
+\r
+       if ( exp_sign == 'g' || exp_sign == 'G' || exp_sign == 'e' || exp_sign == 'E' ) {\r
+               ie = ((unsigned int)n.n->exponent - (unsigned int)0x3fff);\r
+               exponent = ie/3.321928;\r
+       }\r
+\r
+       if ( exp_sign == 'g' || exp_sign == 'G' ) {\r
+               type |= ZEROTRUNC;\r
+               if ( exponent < -4 || fabs(exponent) >= precision ) \r
+                        exp_sign -= 2; // g -> e and G -> E\r
+       }\r
+\r
+       if ( exp_sign == 'e' || exp_sign == 'E' ) {\r
+               frac = modfl(exponent,&e);\r
+               if ( frac > 0.5 )\r
+                       e++;\r
+               else if ( frac < -0.5 )\r
+                       e--;\r
+\r
+               result = numberf(f,__n/powl(10.0L,e),'f',size-4, precision, type);\r
+               if (result < 0)\r
+                       return false;\r
+               f += exp_sign;\r
+               size--;\r
+               ie = (long)e;\r
+               type = LEFT | PLUS;\r
+               if ( ie < 0 )\r
+                       type |= SIGN;\r
+\r
+               result = number(f,ie, 10,2, 2,type );\r
+               if (result < 0)\r
+                       return false;\r
+               return true;\r
+       }\r
+\r
+       if ( exp_sign == 'f' )\r
+       {\r
+               \r
+               buf = (char*)alloca(4096);\r
+               if (type & LEFT)\r
+               {\r
+                       type &= ~ZEROPAD;\r
+               }\r
+\r
+               c = (type & ZEROPAD) ? '0' : ' ';\r
+               sign = 0;\r
+               if (type & SIGN)\r
+               {\r
+                       if (__n < 0)\r
+                       {\r
+                               sign = '-';\r
+                               __n = fabs(__n);\r
+                               size--;\r
+                       } else if (type & PLUS)\r
+                       {\r
+                               sign = '+';\r
+                               size--;\r
+                       } else if (type & SPACE)\r
+                       {\r
+                               sign = ' ';\r
+                               size--;\r
+                       }\r
+               }\r
+\r
+               frac = modfl(__n,&intr);\r
+\r
+               // # flags forces a . and prevents trucation of trailing zero's\r
+               if ( precision > 0 )\r
+               {\r
+                       //frac = modfl(__n,&intr);\r
+\r
+                       i = precision-1;\r
+                       while ( i >= 0  )\r
+                       {\r
+                               frac*=10.0L;\r
+                               frac = modfl((long double)frac, &p);\r
+                               buf[i] = (int)p + '0';\r
+                               i--;\r
+                       }\r
+                       i = precision;\r
+                       size -= precision;\r
+\r
+                       ro = 0;\r
+                       if ( frac > 0.5 )\r
+                       {\r
+                               ro = 1;\r
+                       }\r
+\r
+                       if ( precision >= 1 || type & SPECIAL)\r
+                       {\r
+                               buf[i++] = '.';\r
+                               size--;\r
+                       }\r
+               }\r
+\r
+               if ( intr == 0.0 )\r
+               {\r
+                       buf[i++] = '0';\r
+                       size--;\r
+               }\r
+               else\r
+               {\r
+                       while ( intr > 0.0 )\r
+                       {\r
+                               p=intr;\r
+                               intr/=10.0L;\r
+                               modfl(intr, &intr);\r
+\r
+                               p -= 10.0L*intr;\r
+\r
+                               buf[i++] = (int)p + '0';\r
+                               size--;\r
+                       }\r
+               }\r
+\r
+               j = 0;\r
+               while ( j < i && ro == 1) {\r
+                       if ( buf[j] >= '0' && buf[j] <= '8' )\r
+                       {\r
+                               buf[j]++;\r
+                               ro = 0;\r
+                       }\r
+                       else if ( buf[j] == '9' )\r
+                       {\r
+                               buf[j] = '0';\r
+                       }\r
+                       j++;\r
+               }\r
+               if ( ro == 1 )\r
+                       buf[i++] = '1';\r
+\r
+               buf[i] = 0;\r
+\r
+               size -= precision;\r
+               if (!(type&(ZEROPAD+LEFT)))\r
+               {\r
+                       while(size-->0)\r
+                               f += ' ';\r
+               }\r
+               if (sign)\r
+               {\r
+                       f += sign;\r
+               }\r
+\r
+               if (!(type&(ZEROPAD+LEFT)))\r
+               {\r
+                       while(size-->0)\r
+                               f += ' ';\r
+               }\r
+               if (type & SPECIAL) {\r
+               }\r
+\r
+               if (!(type & LEFT))\r
+                       while (size-- > 0)\r
+                       {\r
+                               f += c;\r
+                       }\r
+               tmp = buf;\r
+               if ( type & ZEROTRUNC && ((type & SPECIAL) != SPECIAL) )\r
+               {\r
+                       j = 0;\r
+                       while ( j < i && ( *tmp == '0' || *tmp == '.' ))\r
+                       {\r
+                               tmp++;\r
+                               i--;\r
+                       }\r
+               }\r
+               while (i-- > 0)\r
+               {\r
+                       f += tmp[i];\r
+               }\r
+               while (size-- > 0)\r
+               {\r
+                       f += ' ';\r
+               }\r
+       }\r
+       return true;\r
+}\r
+\r
+static bool wnumberfl(std::wstring& f, long double __n, wchar_t exp_sign,  int size, int precision, int type)\r
+{\r
+       long double exponent = 0.0;\r
+       long double e;\r
+       long ie;\r
+\r
+       wchar_t *buf, *tmp, sign, c, ro = 0;\r
+       int i = 0;\r
+       int j = 0;\r
+\r
+       long double frac, intr;\r
+       long double p;\r
+\r
+       int result;\r
+\r
+       union\r
+       {\r
+           long double*   __n;\r
+           ieee_long_double_t*   n;\r
+       } n;\r
+\r
+       n.__n = &__n;\r
+\r
+       if ( exp_sign == L'g' || exp_sign == L'G' || exp_sign == L'e' || exp_sign == L'E' ) {\r
+               ie = ((unsigned int)n.n->exponent - (unsigned int)0x3fff);\r
+               exponent = ie/3.321928;\r
+       }\r
+\r
+       if ( exp_sign == L'g' || exp_sign == L'G' ) {\r
+               type |= ZEROTRUNC;\r
+               if ( exponent < -4 || fabs(exponent) >= precision ) \r
+                        exp_sign -= 2; // g -> e and G -> E\r
+       }\r
+\r
+       if ( exp_sign == L'e' || exp_sign == L'E' ) {\r
+               frac = modfl(exponent,&e);\r
+               if ( frac > 0.5 )\r
+                       e++;\r
+               else if ( frac < -0.5 )\r
+                       e--;\r
+\r
+               result = wnumberf(f,__n/powl(10.0L,e),L'f',size-4, precision, type);\r
+               if (result < 0)\r
+                       return false;\r
+               f += exp_sign;\r
+               size--;\r
+               ie = (long)e;\r
+               type = LEFT | PLUS;\r
+               if ( ie < 0 )\r
+                       type |= SIGN;\r
+\r
+               result = wnumber(f,ie, 10,2, 2,type );\r
+               if (result < 0)\r
+                       return false;\r
+               return true;\r
+       }\r
+\r
+       if ( exp_sign == L'f' )\r
+       {\r
+               \r
+               buf = (wchar_t*)alloca(4096*sizeof(wchar_t));\r
+               if (type & LEFT)\r
+               {\r
+                       type &= ~ZEROPAD;\r
+               }\r
+\r
+               c = (type & ZEROPAD) ? L'0' : L' ';\r
+               sign = 0;\r
+               if (type & SIGN)\r
+               {\r
+                       if (__n < 0)\r
+                       {\r
+                               sign = L'-';\r
+                               __n = fabs(__n);\r
+                               size--;\r
+                       } else if (type & PLUS)\r
+                       {\r
+                               sign = L'+';\r
+                               size--;\r
+                       } else if (type & SPACE)\r
+                       {\r
+                               sign = L' ';\r
+                               size--;\r
+                       }\r
+               }\r
+\r
+               frac = modfl(__n,&intr);\r
+\r
+               // # flags forces a . and prevents trucation of trailing zero's\r
+               if ( precision > 0 )\r
+               {\r
+                       //frac = modfl(__n,&intr);\r
+\r
+                       i = precision-1;\r
+                       while ( i >= 0  )\r
+                       {\r
+                               frac*=10.0L;\r
+                               frac = modfl((long double)frac, &p);\r
+                               buf[i] = (int)p + L'0';\r
+                               i--;\r
+                       }\r
+                       i = precision;\r
+                       size -= precision;\r
+\r
+                       ro = 0;\r
+                       if ( frac > 0.5 )\r
+                       {\r
+                               ro = 1;\r
+                       }\r
+\r
+                       if ( precision >= 1 || type & SPECIAL)\r
+                       {\r
+                               buf[i++] = L'.';\r
+                               size--;\r
+                       }\r
+               }\r
+\r
+               if ( intr == 0.0 )\r
+               {\r
+                       buf[i++] = L'0';\r
+                       size--;\r
+               }\r
+               else\r
+               {\r
+                       while ( intr > 0.0 )\r
+                       {\r
+                               p=intr;\r
+                               intr/=10.0L;\r
+                               modfl(intr, &intr);\r
+\r
+                               p -= 10.0L*intr;\r
+\r
+                               buf[i++] = (int)p + L'0';\r
+                               size--;\r
+                       }\r
+               }\r
+\r
+               j = 0;\r
+               while ( j < i && ro == 1) {\r
+                       if ( buf[j] >= L'0' && buf[j] <= L'8' )\r
+                       {\r
+                               buf[j]++;\r
+                               ro = 0;\r
+                       }\r
+                       else if ( buf[j] == L'9' )\r
+                       {\r
+                               buf[j] = L'0';\r
+                       }\r
+                       j++;\r
+               }\r
+               if ( ro == 1 )\r
+                       buf[i++] = L'1';\r
+\r
+               buf[i] = 0;\r
+\r
+               size -= precision;\r
+               if (!(type&(ZEROPAD+LEFT)))\r
+               {\r
+                       while(size-->0)\r
+                               f += L' ';\r
+               }\r
+               if (sign)\r
+               {\r
+                       f += sign;\r
+               }\r
+\r
+               if (!(type&(ZEROPAD+LEFT)))\r
+               {\r
+                       while(size-->0)\r
+                               f += L' ';\r
+               }\r
+               if (type & SPECIAL) {\r
+               }\r
+\r
+               if (!(type & LEFT))\r
+                       while (size-- > 0)\r
+                       {\r
+                               f += c;\r
+                       }\r
+               tmp = buf;\r
+               if ( type & ZEROTRUNC && ((type & SPECIAL) != SPECIAL) )\r
+               {\r
+                       j = 0;\r
+                       while ( j < i && ( *tmp == L'0' || *tmp == L'.' ))\r
+                       {\r
+                               tmp++;\r
+                               i--;\r
+                       }\r
+               }\r
+               while (i-- > 0)\r
+               {\r
+                       f += tmp[i];\r
+               }\r
+               while (size-- > 0)\r
+               {\r
+                       f += L' ';\r
+               }\r
+       }\r
+       return true;\r
+}\r
+\r
+static int string(std::string& f, const char* s, int len, int field_width, int precision, int flags)\r
+{\r
+       int i, done = 0;\r
+       if (s == NULL)\r
+       {\r
+               s = "<NULL>";\r
+               len = 6;\r
+       }\r
+       else\r
+       {\r
+               if (len == -1)\r
+               {\r
+                       len = 0;\r
+                       while ((unsigned int)len < (unsigned int)precision && s[len])\r
+                               len++;\r
+               }\r
+               else\r
+               {\r
+                       if ((unsigned int)len > (unsigned int)precision)\r
+                               len = precision;\r
+               }\r
+       }\r
+       if (!(flags & LEFT))\r
+               while (len < field_width--)\r
+               {\r
+                       f += ' ';\r
+                       done++;\r
+               }\r
+       for (i = 0; i < len; ++i)\r
+       {\r
+               f += *s++;\r
+               done++;\r
+       }\r
+       while (len < field_width--)\r
+       {\r
+               f += ' ';\r
+               done++;\r
+       }\r
+       return done;\r
+}\r
+\r
+static int wstring(std::wstring& f, const wchar_t* s, int len, int field_width, int precision, int flags)\r
+{\r
+       int i, done = 0;\r
+       if (s == NULL)\r
+       {\r
+               s = L"<NULL>";\r
+               len = 6;\r
+       }\r
+       else\r
+       {\r
+               if (len == -1)\r
+               {\r
+                       len = 0;\r
+                       while ((unsigned int)len < (unsigned int)precision && s[len])\r
+                               len++;\r
+               }\r
+               else\r
+               {\r
+                       if ((unsigned int)len > (unsigned int)precision)\r
+                               len = precision;\r
+               }\r
+       }\r
+       if (!(flags & LEFT))\r
+               while (len < field_width--)\r
+               {\r
+                       f += L' ';\r
+                       done++;\r
+               }\r
+       for (i = 0; i < len; ++i)\r
+       {\r
+               f += *s++;\r
+               done++;\r
+       }\r
+       while (len < field_width--)\r
+       {\r
+               f += L' ';\r
+               done++;\r
+       }\r
+       return done;\r
+}\r
+\r
+static int stringw(std::string& f, const wchar_t* sw, int len, int field_width, int precision, int flags)\r
+{\r
+       int i, done = 0;\r
+       if (sw == NULL)\r
+       {\r
+               sw = L"<NULL>";\r
+               len = 6;\r
+       }\r
+       else\r
+       {\r
+               if (len == -1)\r
+               {\r
+                       len = 0;\r
+                       while ((unsigned int)len < (unsigned int)precision && sw[len])\r
+                               len++;\r
+               }\r
+               else\r
+               {\r
+                       if ((unsigned int)len > (unsigned int)precision)\r
+                               len = precision;\r
+               }\r
+       }\r
+       if (!(flags & LEFT))\r
+               while (len < field_width--)\r
+               {\r
+                       f += ' ';\r
+                       done++;\r
+               }\r
+       for (i = 0; i < len; ++i)\r
+       {\r
+#define MY_MB_CUR_MAX 1\r
+               char mb[MY_MB_CUR_MAX];\r
+               int mbcount, j;\r
+               mbcount = wctomb(mb, *sw++);\r
+               if (mbcount <= 0)\r
+               {\r
+                       break;\r
+               }\r
+               for (j = 0; j < mbcount; j++)\r
+               {\r
+                       f += mb[j];\r
+                       done++;\r
+               }\r
+       }\r
+       while (len < field_width--)\r
+       {\r
+               f += ' ';\r
+               done++;\r
+       }\r
+       return done;\r
+}\r
+\r
+static int wstringa(std::wstring& f, const char* sa, int len, int field_width, int precision, int flags)\r
+{\r
+       int i, done = 0;\r
+       if (sa == NULL)\r
+       {\r
+               sa = "<NULL>";\r
+               len = 6;\r
+       }\r
+       else\r
+       {\r
+               if (len == -1)\r
+               {\r
+                       len = 0;\r
+                       while ((unsigned int)len < (unsigned int)precision && sa[len])\r
+                               len++;\r
+               }\r
+               else\r
+               {\r
+                       if ((unsigned int)len > (unsigned int)precision)\r
+                               len = precision;\r
+               }\r
+       }\r
+       if (!(flags & LEFT))\r
+               while (len < field_width--)\r
+               {\r
+                       f += L' ';\r
+                       done++;\r
+               }\r
+       for (i = 0; i < len;)\r
+       {\r
+               wchar_t w;\r
+               int mbcount;\r
+               mbcount = mbtowc(&w, sa, len-i);\r
+               if (mbcount <= 0)\r
+                       break;\r
+               f += w;\r
+               done++;\r
+               i += mbcount;\r
+       }\r
+       while (len < field_width--)\r
+       {\r
+               f += L' ';\r
+               done++;\r
+       }\r
+       return done;\r
+}\r
+\r
+#define _isnanl _isnan\r
+#define _finitel _finite\r
+\r
+std::string ssvprintf ( const char *fmt, va_list args )\r
+{\r
+       ULONGLONG num;\r
+       int base;\r
+       long double _ldouble;\r
+       double _double;\r
+       const char *s;\r
+       const unsigned short* sw;\r
+       int result;\r
+       std::string f;\r
+\r
+       int flags;              /* flags to number() */\r
+\r
+       int field_width;        /* width of output field */\r
+       int precision;          /* min. # of digits for integers; max\r
+                                  number of chars for from string */\r
+       int qualifier = 0;      /* 'h', 'l', 'L' or 'I64' for integer fields */\r
+\r
+       for (; *fmt ; ++fmt)\r
+       {\r
+               if (*fmt != '%')\r
+               {\r
+                       f += *fmt;\r
+                       continue;\r
+               }\r
+\r
+               /* process flags */\r
+               flags = 0;\r
+               repeat:\r
+                       ++fmt;          /* this also skips first '%' */\r
+                       switch (*fmt) {\r
+                               case '-': flags |= LEFT; goto repeat;\r
+                               case '+': flags |= PLUS; goto repeat;\r
+                               case ' ': flags |= SPACE; goto repeat;\r
+                               case '#': flags |= SPECIAL; goto repeat;\r
+                               case '0': flags |= ZEROPAD; goto repeat;\r
+                               }\r
+\r
+               /* get field width */\r
+               field_width = -1;\r
+               if (isdigit(*fmt))\r
+                       field_width = skip_atoi(&fmt);\r
+               else if (*fmt == '*') {\r
+                       ++fmt;\r
+                       /* it's the next argument */\r
+                       field_width = va_arg(args, int);\r
+                       if (field_width < 0) {\r
+                               field_width = -field_width;\r
+                               flags |= LEFT;\r
+                       }\r
+               }\r
+\r
+               /* get the precision */\r
+               precision = -1;\r
+               if (*fmt == '.') {\r
+                       ++fmt;\r
+                       if (isdigit(*fmt))\r
+                               precision = skip_atoi(&fmt);\r
+                       else if (*fmt == '*') {\r
+                               ++fmt;\r
+                               /* it's the next argument */\r
+                               precision = va_arg(args, int);\r
+                       }\r
+                       if (precision < 0)\r
+                               precision = 0;\r
+               }\r
+\r
+               /* get the conversion qualifier */\r
+               qualifier = 0;\r
+               // %Z can be just stand alone or as size_t qualifier\r
+               if ( *fmt == 'Z' ) {\r
+                       qualifier = *fmt;\r
+                       switch ( *(fmt+1)) {\r
+                               case 'o':\r
+                               case 'b':\r
+                               case 'X':\r
+                               case 'x':\r
+                               case 'd':\r
+                               case 'i':\r
+                               case 'u':\r
+                                       ++fmt;\r
+                                       break;\r
+                               default:\r
+                                       break;\r
+                       }\r
+               } else if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt == 'w') {\r
+                       qualifier = *fmt;\r
+                       ++fmt;\r
+               } else if (*fmt == 'I' && *(fmt+1) == '6' && *(fmt+2) == '4') {\r
+                       qualifier = *fmt;\r
+                       fmt += 3;\r
+               }\r
+\r
+               // go fine with ll instead of L\r
+               if ( *fmt == 'l' ) {\r
+                       ++fmt;\r
+                       qualifier = 'L';\r
+               }\r
+\r
+               /* default base */\r
+               base = 10;\r
+\r
+               switch (*fmt) {\r
+               case 'c':\r
+                       if (!(flags & LEFT))\r
+                               while (--field_width > 0)\r
+                               {\r
+                                       f += ' ';\r
+                               }\r
+                       if (qualifier == 'l' || qualifier == 'w')\r
+                       {\r
+                               f += (char)(unsigned char)(wchar_t) va_arg(args,int);\r
+                       }\r
+                       else\r
+                       {\r
+                               f += (char)(unsigned char) va_arg(args,int);\r
+                       }\r
+                       while (--field_width > 0)\r
+                       {\r
+                               f += ' ';\r
+                       }\r
+                       continue;\r
+\r
+               case 'C':\r
+                       if (!(flags & LEFT))\r
+                               while (--field_width > 0)\r
+                               {\r
+                                       f += ' ';\r
+                               }\r
+                       if (qualifier == 'h')\r
+                       {\r
+                               f += (char)(unsigned char) va_arg(args,int);\r
+                       }\r
+                       else\r
+                       {\r
+                               f += (char)(unsigned char)(wchar_t) va_arg(args,int);\r
+                       }\r
+                       while (--field_width > 0)\r
+                       {\r
+                               f += ' ';\r
+                       }\r
+                       continue;\r
+\r
+               case 's':\r
+                       if (qualifier == 'l' || qualifier == 'w') {\r
+                               /* print unicode string */\r
+                               sw = va_arg(args, wchar_t *);\r
+                               result = stringw(f, sw, -1, field_width, precision, flags);\r
+                       } else {\r
+                               /* print ascii string */\r
+                               s = va_arg(args, char *);\r
+                               result = string(f, s, -1, field_width, precision, flags);\r
+                       }\r
+                       if (result < 0)\r
+                       {\r
+                               assert(!"TODO FIXME handle error better");\r
+                               return f;\r
+                       }\r
+                       continue;\r
+\r
+               case 'S':\r
+                       if (qualifier == 'h') {\r
+                               /* print ascii string */\r
+                               s = va_arg(args, char *);\r
+                               result = string(f, s, -1, field_width, precision, flags);\r
+                       } else {\r
+                               /* print unicode string */\r
+                               sw = va_arg(args, wchar_t *);\r
+                               result = stringw(f, sw, -1, field_width, precision, flags);\r
+                       }\r
+                       if (result < 0)\r
+                       {\r
+                               assert(!"TODO FIXME handle error better");\r
+                               return f;\r
+                       }\r
+                       continue;\r
+\r
+               /*case 'Z':\r
+                       if (qualifier == 'w') {\r
+                               // print counted unicode string\r
+                               PUNICODE_STRING pus = va_arg(args, PUNICODE_STRING);\r
+                               if ((pus == NULL) || (pus->Buffer == NULL)) {\r
+                                       sw = NULL;\r
+                                       len = -1;\r
+                               } else {\r
+                                       sw = pus->Buffer;\r
+                                       len = pus->Length / sizeof(WCHAR);\r
+                               }\r
+                               result = stringw(f, sw, len, field_width, precision, flags);\r
+                       } else {\r
+                               // print counted ascii string\r
+                               PANSI_STRING pas = va_arg(args, PANSI_STRING);\r
+                               if ((pas == NULL) || (pas->Buffer == NULL)) {\r
+                                       s = NULL;\r
+                                       len = -1;\r
+                               } else {\r
+                                       s = pas->Buffer;\r
+                                       len = pas->Length;\r
+                               }\r
+                               result = string(f, s, -1, field_width, precision, flags);\r
+                       }\r
+                       if (result < 0)\r
+                               return -1;\r
+                       continue;*/\r
+\r
+               case 'e':\r
+               case 'E':\r
+               case 'f':\r
+               case 'g':\r
+               case 'G':\r
+                       if (qualifier == 'l' || qualifier == 'L' ) {\r
+                               _ldouble = va_arg(args, long double);\r
+                       \r
+                               if ( _isnanl(_ldouble) )\r
+                               {\r
+                                       f += "Nan";\r
+                               }\r
+                               else if ( !_finitel(_ldouble) )\r
+                               {\r
+                                       if ( _ldouble < 0 )\r
+                                               f += "-Inf";\r
+                                       else\r
+                                               f += "+Inf";\r
+                               } else {\r
+                                       if ( precision == -1 )\r
+                                               precision = 6;\r
+                                       result = numberfl(f,_ldouble,*fmt,field_width,precision,flags);\r
+                                       if (result < 0)\r
+                                       {\r
+                                               assert(!"TODO FIXME handle error better");\r
+                                               return f;\r
+                                       }\r
+                               }\r
+                       } else {\r
+                               _double = (double)va_arg(args, double);\r
+\r
+                               if ( _isnan(_double) )\r
+                               {\r
+                                       f += "Nan";\r
+                               }\r
+                               else if ( !_finite(_double) )\r
+                               {\r
+                                       if ( _double < 0 )\r
+                                               f += "-Inf";\r
+                                       else\r
+                                               f += "+Inf";\r
+                               }\r
+                               else\r
+                               {\r
+                                       if ( precision == -1 )\r
+                                               precision = 6;\r
+                                       result = numberf(f,_double,*fmt,field_width,precision,flags);\r
+                                       if (result < 0)\r
+                                       {\r
+                                               assert(!"TODO FIXME handle error better");\r
+                                               return f;\r
+                                       }\r
+                               }\r
+                       }\r
+                       continue;\r
+\r
+               case 'p':\r
+                       if (field_width == -1) {\r
+                               field_width = 2*sizeof(void *);\r
+                               flags |= ZEROPAD;\r
+                       }\r
+                       result = number(f,\r
+                                       (unsigned long) va_arg(args, void *), 16,\r
+                                       field_width, precision, flags);\r
+                       if (result < 0)\r
+                       {\r
+                               assert(!"TODO FIXME handle error better");\r
+                               return f;\r
+                       }\r
+                       continue;\r
+\r
+               case 'n':\r
+                       if (qualifier == 'l') {\r
+                               long * ip = va_arg(args, long *);\r
+                               *ip = 0;\r
+                       } else {\r
+                               int * ip = va_arg(args, int *);\r
+                               *ip = 0;\r
+                       }\r
+                       continue;\r
+\r
+               /* integer number formats - set up the flags and "break" */\r
+               case 'o':\r
+                       base = 8;\r
+                       break;\r
+\r
+               case 'b':\r
+                       base = 2;\r
+                       break;\r
+\r
+               case 'X':\r
+                       flags |= LARGE;\r
+               case 'x':\r
+                       base = 16;\r
+                       break;\r
+\r
+               case 'd':\r
+               case 'i':\r
+                       flags |= SIGN;\r
+               case 'u':\r
+                       break;\r
+\r
+               default:\r
+                       if (*fmt != '%')\r
+                       {\r
+                               f += '%';\r
+                       }\r
+                       if (*fmt)\r
+                       {\r
+                               f += *fmt;\r
+                       }\r
+                       else\r
+                               --fmt;\r
+                       continue;\r
+               }\r
+\r
+               if (qualifier == 'I')\r
+                       num = va_arg(args, ULONGLONG);\r
+               else if (qualifier == 'l') {\r
+                       if (flags & SIGN)\r
+                               num = va_arg(args, long);\r
+                       else\r
+                               num = va_arg(args, unsigned long);\r
+               }\r
+               else if (qualifier == 'h') {\r
+                       if (flags & SIGN)\r
+                               num = va_arg(args, int);\r
+                       else\r
+                               num = va_arg(args, unsigned int);\r
+               }\r
+               else if (flags & SIGN)\r
+                       num = va_arg(args, int);\r
+               else\r
+                       num = va_arg(args, unsigned int);\r
+               result = number(f, num, base, field_width, precision, flags);\r
+               if (result < 0)\r
+               {\r
+                       assert(!"TODO FIXME handle error better");\r
+                       return f;\r
+               }\r
+       }\r
+       //putc('\0',f);\r
+       return f;\r
+}\r
+\r
+std::wstring sswvprintf ( const wchar_t* fmt, va_list args )\r
+{\r
+       ULONGLONG num;\r
+       int base;\r
+       long double _ldouble;\r
+       double _double;\r
+       const wchar_t* s;\r
+       const char* sa;\r
+       int result;\r
+       std::wstring f;\r
+\r
+       int flags;              /* flags to number() */\r
+\r
+       int field_width;        /* width of output field */\r
+       int precision;          /* min. # of digits for integers; max\r
+                                  number of chars for from string */\r
+       int qualifier = 0;      /* 'h', 'l', 'L' or 'I64' for integer fields */\r
+\r
+       for (; *fmt ; ++fmt)\r
+       {\r
+               if (*fmt != L'%')\r
+               {\r
+                       f += *fmt;\r
+                       continue;\r
+               }\r
+\r
+               /* process flags */\r
+               flags = 0;\r
+               repeat:\r
+                       ++fmt;          /* this also skips first '%' */\r
+                       switch (*fmt) {\r
+                               case L'-': flags |= LEFT; goto repeat;\r
+                               case L'+': flags |= PLUS; goto repeat;\r
+                               case L' ': flags |= SPACE; goto repeat;\r
+                               case L'#': flags |= SPECIAL; goto repeat;\r
+                               case L'0': flags |= ZEROPAD; goto repeat;\r
+                               }\r
+\r
+               /* get field width */\r
+               field_width = -1;\r
+               if (isdigit(*fmt))\r
+                       field_width = skip_wtoi(&fmt);\r
+               else if (*fmt == L'*') {\r
+                       ++fmt;\r
+                       /* it's the next argument */\r
+                       field_width = va_arg(args, int);\r
+                       if (field_width < 0) {\r
+                               field_width = -field_width;\r
+                               flags |= LEFT;\r
+                       }\r
+               }\r
+\r
+               /* get the precision */\r
+               precision = -1;\r
+               if (*fmt == L'.') {\r
+                       ++fmt;\r
+                       if (iswdigit(*fmt))\r
+                               precision = skip_wtoi(&fmt);\r
+                       else if (*fmt == L'*') {\r
+                               ++fmt;\r
+                               /* it's the next argument */\r
+                               precision = va_arg(args, int);\r
+                       }\r
+                       if (precision < 0)\r
+                               precision = 0;\r
+               }\r
+\r
+               /* get the conversion qualifier */\r
+               qualifier = 0;\r
+               // %Z can be just stand alone or as size_t qualifier\r
+               if ( *fmt == L'Z' ) {\r
+                       qualifier = *fmt;\r
+                       switch ( *(fmt+1)) {\r
+                               case L'o':\r
+                               case L'b':\r
+                               case L'X':\r
+                               case L'x':\r
+                               case L'd':\r
+                               case L'i':\r
+                               case L'u':\r
+                                       ++fmt;\r
+                                       break;\r
+                               default:\r
+                                       break;\r
+                       }\r
+               } else if (*fmt == L'h' || *fmt == L'l' || *fmt == L'L' || *fmt == L'w') {\r
+                       qualifier = *fmt;\r
+                       ++fmt;\r
+               } else if (*fmt == L'I' && *(fmt+1) == L'6' && *(fmt+2) == L'4') {\r
+                       qualifier = *fmt;\r
+                       fmt += 3;\r
+               }\r
+\r
+               // go fine with ll instead of L\r
+               if ( *fmt == L'l' ) {\r
+                       ++fmt;\r
+                       qualifier = L'L';\r
+               }\r
+\r
+               /* default base */\r
+               base = 10;\r
+\r
+               switch (*fmt) {\r
+               case L'c':\r
+                       if (!(flags & LEFT))\r
+                               while (--field_width > 0)\r
+                               {\r
+                                       f += L' ';\r
+                               }\r
+                       if ( qualifier == L'h' )\r
+                       {\r
+                               f += (wchar_t)(char)(unsigned char) va_arg(args,int);\r
+                       }\r
+                       else\r
+                       {\r
+                               f += (wchar_t) va_arg(args,int);\r
+                       }\r
+                       while (--field_width > 0)\r
+                       {\r
+                               f += ' ';\r
+                       }\r
+                       continue;\r
+\r
+               case 'C':\r
+                       if (!(flags & LEFT))\r
+                               while (--field_width > 0)\r
+                               {\r
+                                       f += L' ';\r
+                               }\r
+                       if (qualifier == L'l' || qualifier == L'w')\r
+                       {\r
+                               f += (wchar_t) va_arg(args,int);\r
+                       }\r
+                       else\r
+                       {\r
+                               f += (wchar_t)(char)(unsigned char) va_arg(args,int);\r
+                       }\r
+                       while (--field_width > 0)\r
+                       {\r
+                               f += L' ';\r
+                       }\r
+                       continue;\r
+\r
+               case 's':\r
+                       if (qualifier == L'h') {\r
+                               /* print ascii string */\r
+                               sa = va_arg(args, char *);\r
+                               result = wstringa(f, sa, -1, field_width, precision, flags);\r
+                       } else {\r
+                               /* print unicode string */\r
+                               s = va_arg(args, wchar_t *);\r
+                               result = wstring(f, s, -1, field_width, precision, flags);\r
+                       }\r
+                       if (result < 0)\r
+                       {\r
+                               assert(!"TODO FIXME handle error better");\r
+                               return f;\r
+                       }\r
+                       continue;\r
+\r
+               case 'S':\r
+                       if (qualifier == L'l' || qualifier == L'w') {\r
+                               /* print unicode string */\r
+                               s = va_arg(args, wchar_t *);\r
+                               result = wstring(f, s, -1, field_width, precision, flags);\r
+                       } else {\r
+                               /* print ascii string */\r
+                               sa = va_arg(args, char *);\r
+                               result = wstringa(f, sa, -1, field_width, precision, flags);\r
+                       }\r
+                       if (result < 0)\r
+                       {\r
+                               assert(!"TODO FIXME handle error better");\r
+                               return f;\r
+                       }\r
+                       continue;\r
+\r
+               case L'e':\r
+               case L'E':\r
+               case L'f':\r
+               case L'g':\r
+               case L'G':\r
+                       if (qualifier == L'l' || qualifier == L'L' )\r
+                       {\r
+                               _ldouble = va_arg(args, long double);\r
+                       \r
+                               if ( _isnanl(_ldouble) )\r
+                               {\r
+                                       f += L"Nan";\r
+                               }\r
+                               else if ( !_finitel(_ldouble) )\r
+                               {\r
+                                       if ( _ldouble < 0 )\r
+                                               f += L"-Inf";\r
+                                       else\r
+                                               f += L"+Inf";\r
+                               } else {\r
+                                       if ( precision == -1 )\r
+                                               precision = 6;\r
+                                       result = wnumberfl(f,_ldouble,*fmt,field_width,precision,flags);\r
+                                       if (result < 0)\r
+                                       {\r
+                                               assert(!"TODO FIXME handle error better");\r
+                                               return f;\r
+                                       }\r
+                               }\r
+                       } else {\r
+                               _double = (double)va_arg(args, double);\r
+\r
+                               if ( _isnan(_double) )\r
+                               {\r
+                                       f += L"Nan";\r
+                               }\r
+                               else if ( !_finite(_double) )\r
+                               {\r
+                                       if ( _double < 0 )\r
+                                               f += L"-Inf";\r
+                                       else\r
+                                               f += L"+Inf";\r
+                               }\r
+                               else\r
+                               {\r
+                                       if ( precision == -1 )\r
+                                               precision = 6;\r
+                                       result = wnumberf(f,_double,*fmt,field_width,precision,flags);\r
+                                       if (result < 0)\r
+                                       {\r
+                                               assert(!"TODO FIXME handle error better");\r
+                                               return f;\r
+                                       }\r
+                               }\r
+                       }\r
+                       continue;\r
+\r
+               case L'p':\r
+                       if (field_width == -1) {\r
+                               field_width = 2*sizeof(void *);\r
+                               flags |= ZEROPAD;\r
+                       }\r
+                       result = wnumber(f,\r
+                                       (unsigned long) va_arg(args, void *), 16,\r
+                                       field_width, precision, flags);\r
+                       if (result < 0)\r
+                       {\r
+                               assert(!"TODO FIXME handle error better");\r
+                               return f;\r
+                       }\r
+                       continue;\r
+\r
+               case L'n':\r
+                       if (qualifier == L'l') {\r
+                               long * ip = va_arg(args, long *);\r
+                               *ip = 0;\r
+                       } else {\r
+                               int * ip = va_arg(args, int *);\r
+                               *ip = 0;\r
+                       }\r
+                       continue;\r
+\r
+               /* integer number formats - set up the flags and "break" */\r
+               case L'o':\r
+                       base = 8;\r
+                       break;\r
+\r
+               case L'b':\r
+                       base = 2;\r
+                       break;\r
+\r
+               case L'X':\r
+                       flags |= LARGE;\r
+               case L'x':\r
+                       base = 16;\r
+                       break;\r
+\r
+               case L'd':\r
+               case L'i':\r
+                       flags |= SIGN;\r
+               case L'u':\r
+                       break;\r
+\r
+               default:\r
+                       if (*fmt != L'%')\r
+                       {\r
+                               f += L'%';\r
+                       }\r
+                       if (*fmt)\r
+                       {\r
+                               f += *fmt;\r
+                       }\r
+                       else\r
+                               --fmt;\r
+                       continue;\r
+               }\r
+\r
+               if (qualifier == L'I')\r
+                       num = va_arg(args, ULONGLONG);\r
+               else if (qualifier == L'l') {\r
+                       if (flags & SIGN)\r
+                               num = va_arg(args, long);\r
+                       else\r
+                               num = va_arg(args, unsigned long);\r
+               }\r
+               else if (qualifier == L'h') {\r
+                       if (flags & SIGN)\r
+                               num = va_arg(args, int);\r
+                       else\r
+                               num = va_arg(args, unsigned int);\r
+               }\r
+               else if (flags & SIGN)\r
+                       num = va_arg(args, int);\r
+               else\r
+                       num = va_arg(args, unsigned int);\r
+               result = wnumber(f, num, base, field_width, precision, flags);\r
+               if (result < 0)\r
+               {\r
+                       assert(!"TODO FIXME handle error better");\r
+                       return f;\r
+               }\r
+       }\r
+       //putc('\0',f);\r
+       return f;\r
+}\r
diff --git a/reactos/tools/rbuild/ssprintf.h b/reactos/tools/rbuild/ssprintf.h
new file mode 100644 (file)
index 0000000..8efdb87
--- /dev/null
@@ -0,0 +1,23 @@
+// ssprintf.h\r
+\r
+#ifndef SSPRINTF_H\r
+#define SSPRINTF_H\r
+\r
+#include <string>\r
+#include <stdarg.h>\r
+\r
+std::string ssprintf ( const char* fmt, ... );\r
+std::string ssvprintf ( const char* fmt, va_list args );\r
+\r
+std::wstring sswprintf ( const wchar_t* fmt, ... );\r
+std::wstring sswvprintf ( const wchar_t* fmt, va_list args );\r
+\r
+#ifdef _UNICODE\r
+#define sstprintf sswprintf\r
+#define sstvprintf sswvprintf\r
+#else\r
+#define sstprintf ssprintf\r
+#define sstvprintf ssvprintf\r
+#endif\r
+\r
+#endif//SSPRINTF_H\r