fix compile problems with msvc6
[reactos.git] / reactos / tools / rbuild / ssprintf.cpp
index d8c415f..36a190c 100644 (file)
-// ssprintf.cpp\r
-\r
-#include "pch.h"\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
-#ifdef _MSC_VER\r
-typedef __int64 LONGLONG;\r
-typedef unsigned __int64 ULONGLONG;\r
-#else\r
-typedef long long LONGLONG;\r
-typedef unsigned long long ULONGLONG;\r
-#endif\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\r
-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\r
-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\r
-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\r
-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\r
-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\r
-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\r
-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\r
-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\r
-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\r
-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\r
-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\r
-do_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\r
-do_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\r
-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\r
-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\r
-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 wchar_t* 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 = do_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 = do_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\r
-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 = do_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 = do_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
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "pch.h"
+
+#include <malloc.h>
+#include <math.h>
+#include <float.h>
+#include <assert.h>
+#include "ssprintf.h"
+
+#ifdef _MSC_VER
+#define alloca _alloca
+#endif//_MSC_VER
+
+#ifdef _MSC_VER
+typedef __int64 LONGLONG;
+typedef unsigned __int64 ULONGLONG;
+#else
+typedef long long LONGLONG;
+typedef unsigned long long ULONGLONG;
+#endif
+
+typedef struct {
+    unsigned int mantissa:23;
+    unsigned int exponent:8;
+    unsigned int sign:1;
+} ieee_float_t;
+
+typedef struct {
+    unsigned int mantissal:32;
+    unsigned int mantissah:20;
+    unsigned int exponent:11;
+    unsigned int sign:1;
+} ieee_double_t;
+
+typedef struct {
+    unsigned int mantissal:32;
+    unsigned int mantissah:32;
+    unsigned int exponent:15;
+    unsigned int sign:1;
+    unsigned int empty:16;
+} ieee_long_double_t;
+
+std::string
+ssprintf ( const char* fmt, ... )
+{
+       va_list arg;
+       va_start(arg, fmt);
+       std::string f = ssvprintf ( fmt, arg );
+       va_end(arg);
+       return f;
+}
+
+std::wstring
+sswprintf ( const wchar_t* fmt, ... )
+{
+       va_list arg;
+       va_start(arg, fmt);
+       std::wstring f = sswvprintf ( fmt, arg );
+       va_end(arg);
+       return f;
+}
+
+#define ZEROPAD                1       /* pad with zero */
+#define SIGN           2       /* unsigned/signed long */
+#define PLUS           4       /* show plus */
+#define SPACE          8       /* space if plus */
+#define LEFT           16      /* left justified */
+#define SPECIAL                32      /* 0x */
+#define LARGE          64      /* use 'ABCDEF' instead of 'abcdef' */
+#define ZEROTRUNC      128     /* truncate zero 's */
+
+
+static int
+skip_atoi(const char **s)
+{
+       int i=0;
+
+       while (isdigit(**s))
+               i = i*10 + *((*s)++) - '0';
+       return i;
+}
+
+static int
+skip_wtoi(const wchar_t **s)
+{
+       int i=0;
+
+       while (iswdigit(**s))
+               i = i*10 + *((*s)++) - L'0';
+       return i;
+}
+
+
+static int
+do_div(LONGLONG *n,int base)
+{
+       int __res = ((ULONGLONG) *n) % (unsigned) base;
+       *n = ((ULONGLONG) *n) / (unsigned) base;
+       return __res;
+}
+
+
+static bool
+number(std::string& f, LONGLONG num, int base, int size, int precision ,int type)
+{
+       char c,sign,tmp[66];
+       const char *digits="0123456789abcdefghijklmnopqrstuvwxyz";
+       int i;
+
+       if (type & LARGE)
+               digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+       if (type & LEFT)
+               type &= ~ZEROPAD;
+       if (base < 2 || base > 36)
+               return false;
+       c = (type & ZEROPAD) ? '0' : ' ';
+       sign = 0;
+       if (type & SIGN) {
+               if (num < 0) {
+                       sign = '-';
+                       num = -num;
+                       size--;
+               } else if (type & PLUS) {
+                       sign = '+';
+                       size--;
+               } else if (type & SPACE) {
+                       sign = ' ';
+                       size--;
+               }
+       }
+       if (type & SPECIAL) {
+               if (base == 16)
+                       size -= 2;
+               else if (base == 8)
+                       size--;
+       }
+       i = 0;
+       if (num == 0)
+               tmp[i++]='0';
+       else while (num != 0)
+               tmp[i++] = digits[do_div(&num,base)];
+       if (i > precision)
+               precision = i;
+       size -= precision;
+       if (!(type&(ZEROPAD+LEFT)))
+               while(size-->0)
+                       f += ' ';
+       if (sign)
+               f += sign;
+       if (type & SPECIAL)
+       {
+               if (base==8)
+                       f += '0';
+               else if (base==16)
+               {
+                       f += '0';
+                       f += digits[33];
+               }
+       }
+       if (!(type & LEFT))
+       {
+               while (size-- > 0)
+                       f += c;
+       }
+       while (i < precision--)
+       {
+               f += '0';
+       }
+       while (i-- > 0)
+       {
+               f += tmp[i];
+       }
+       while (size-- > 0)
+       {
+               f += ' ';
+       }
+       return true;
+}
+
+static bool
+wnumber(std::wstring& f, LONGLONG num, int base, int size, int precision ,int type)
+{
+       wchar_t c,sign,tmp[66];
+       const wchar_t *digits = L"0123456789abcdefghijklmnopqrstuvwxyz";
+       int i;
+
+       if (type & LARGE)
+               digits = L"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+       if (type & LEFT)
+               type &= ~ZEROPAD;
+       if (base < 2 || base > 36)
+               return 0;
+       c = (type & ZEROPAD) ? L'0' : L' ';
+       sign = false;
+       if (type & SIGN) {
+               if (num < 0) {
+                       sign = L'-';
+                       num = -num;
+                       size--;
+               } else if (type & PLUS) {
+                       sign = L'+';
+                       size--;
+               } else if (type & SPACE) {
+                       sign = L' ';
+                       size--;
+               }
+       }
+       if (type & SPECIAL) {
+               if (base == 16)
+                       size -= 2;
+               else if (base == 8)
+                       size--;
+       }
+       i = 0;
+       if (num == 0)
+               tmp[i++]=L'0';
+       else while (num != 0)
+               tmp[i++] = digits[do_div(&num,base)];
+       if (i > precision)
+               precision = i;
+       size -= precision;
+       if (!(type&(ZEROPAD+LEFT)))
+               while(size-->0)
+                       f += L' ';
+       if (sign)
+               f += sign;
+       if (type & SPECIAL)
+       {
+               if (base==8)
+                       f += L'0';
+               else if (base==16)
+               {
+                       f += L'0';
+                       f += digits[33];
+               }
+       }
+       if (!(type & LEFT))
+       {
+               while (size-- > 0)
+                       f += c;
+       }
+       while (i < precision--)
+       {
+               f += L'0';
+       }
+       while (i-- > 0)
+       {
+               f += tmp[i];
+       }
+       while (size-- > 0)
+       {
+               f += L' ';
+       }
+       return true;
+}
+
+
+static bool
+numberf(std::string& f, double __n, char exp_sign,  int size, int precision, int type)
+{
+       double exponent = 0.0;
+       double e;
+       long ie;
+
+       //int x;
+       char *buf, *tmp;
+       int i = 0;
+       int j = 0;
+       //int k = 0;
+
+       double frac, intr;
+       double p;
+       char sign;
+       char c;
+       char ro = 0;
+       int result;
+
+       union
+       {
+               double*  __n;
+               ieee_double_t*  n;
+       } n;
+       
+       n.__n = &__n;
+
+       if ( exp_sign == 'g' || exp_sign == 'G' || exp_sign == 'e' || exp_sign == 'E' ) {
+               ie = ((unsigned int)n.n->exponent - (unsigned int)0x3ff);
+               exponent = ie/3.321928;
+       }
+
+       if ( exp_sign == 'g' || exp_sign == 'G' ) {
+               type |= ZEROTRUNC;
+               if ( exponent < -4 || fabs(exponent) >= precision )
+                       exp_sign -= 2; // g -> e and G -> E
+               else
+                       exp_sign = 'f';
+       }
+
+       if ( exp_sign == 'e' ||  exp_sign == 'E' ) {
+               frac = modf(exponent,&e);
+               if ( frac > 0.5 )
+                       e++;
+               else if (  frac < -0.5  )
+                       e--;
+
+               result = numberf(f,__n/pow(10.0L,(long double)e),'f',size-4, precision, type);
+               if (result < 0)
+                       return false;
+               f += exp_sign;
+               size--;
+               ie = (long)e;
+               type = LEFT | PLUS;
+               if ( ie < 0 )
+                       type |= SIGN;
+
+               result = number(f,ie, 10,2, 2,type );
+               if (result < 0)
+                       return false;
+               return true;
+       }
+
+       if ( exp_sign == 'f' ) {
+               buf = (char*)alloca(4096);
+               if (type & LEFT) {
+                       type &= ~ZEROPAD;
+               }
+
+               c = (type & ZEROPAD) ? '0' : ' ';
+               sign = 0;
+               if (type & SIGN) {
+                       if (__n < 0) {
+                               sign = '-';
+                               __n = fabs(__n);
+                               size--;
+                       } else if (type & PLUS) {
+                               sign = '+';
+                               size--;
+                       } else if (type & SPACE) {
+                               sign = ' ';
+                               size--;
+                       }
+               }
+
+               frac = modf(__n,&intr);
+
+               // # flags forces a . and prevents trucation of trailing zero's
+
+               if ( precision > 0 ) {
+                       //frac = modfl(__n,&intr);
+                       i = precision-1;
+                       while (  i >= 0  ) {
+                               frac*=10.0L;
+                               frac = modf(frac, &p);
+                               buf[i] = (int)p + '0';
+                               i--;
+                       }
+                       i = precision;
+                       size -= precision;
+
+                       ro = 0;
+                       if ( frac > 0.5 ) {
+                               ro = 1;
+                       }
+
+                       if ( precision >= 1 || type & SPECIAL) {
+                               buf[i++] = '.';
+                               size--;
+                       }
+               }
+
+               if ( intr == 0.0 ) {
+                       buf[i++] = '0';
+                       size--;
+               }
+               else {
+                       while ( intr > 0.0 ) {
+                               p = intr;
+                               intr/=10.0L;
+                               modf(intr, &intr);
+
+                               p -= 10.0*intr;
+
+                               buf[i++] = (int)p + '0';
+                               size--;
+                       }
+               }
+
+               j = 0;
+               while ( j < i && ro == 1) {
+                       if ( buf[j] >= '0' && buf[j] <= '8' ) {
+                               buf[j]++;
+                               ro = 0;
+                       }
+                       else if ( buf[j] == '9' ) {
+                               buf[j] = '0';
+                       }
+                       j++;
+               }
+               if ( ro == 1 )
+                       buf[i++] = '1';
+
+               buf[i] = 0;
+
+               size -= precision;
+               if (!(type&(ZEROPAD+LEFT)))
+               {
+                       while(size-->0)
+                               f += ' ';
+               }
+               if (sign)
+               {
+                       f += sign;
+               }
+
+               if (!(type&(ZEROPAD+LEFT)))
+                       while(size-->0)
+                       {
+                               f += ' ';
+                       }
+               if (type & SPECIAL) {
+               }
+
+               if (!(type & LEFT))
+                       while (size-- > 0)
+                       {
+                               f += c;
+                       }
+
+               tmp = buf;
+               if ( type & ZEROTRUNC && ((type & SPECIAL) != SPECIAL) )
+               {
+                       j = 0;
+                       while ( j < i && ( *tmp == '0' || *tmp == '.' ))
+                       {
+                               tmp++;
+                               i--;
+                       }
+               }
+//             else
+//                     while (i < precision--)
+//                             putc('0', f);
+               while (i-- > 0)
+               {
+                       f += tmp[i];
+               }
+               while (size-- > 0)
+               {
+                       f += ' ';
+               }
+       }
+       return true;
+}
+
+static bool
+wnumberf(std::wstring& f, double __n, wchar_t exp_sign,  int size, int precision, int type)
+{
+       double exponent = 0.0;
+       double e;
+       long ie;
+
+       int i = 0;
+       int j = 0;
+
+       double frac, intr;
+       double p;
+       wchar_t *buf, *tmp, sign, c, ro = 0;
+       int result;
+
+       union
+       {
+               double*  __n;
+               ieee_double_t*  n;
+       } n;
+       
+       n.__n = &__n;
+
+       if ( exp_sign == L'g' || exp_sign == L'G' || exp_sign == L'e' || exp_sign == L'E' ) {
+               ie = ((unsigned int)n.n->exponent - (unsigned int)0x3ff);
+               exponent = ie/3.321928;
+       }
+
+       if ( exp_sign == L'g' || exp_sign == L'G' )
+       {
+               type |= ZEROTRUNC;
+               if ( exponent < -4 || fabs(exponent) >= precision )
+                       exp_sign -= 2; // g -> e and G -> E
+               else
+                       exp_sign = L'f';
+       }
+
+       if ( exp_sign == L'e' ||  exp_sign == L'E' )
+       {
+               frac = modf(exponent,&e);
+               if ( frac > 0.5 )
+                       e++;
+               else if (  frac < -0.5  )
+                       e--;
+
+               result = wnumberf(f,__n/pow(10.0L,(long double) e),L'f',size-4, precision, type);
+               if (result < 0)
+                       return false;
+               f += exp_sign;
+               size--;
+               ie = (long)e;
+               type = LEFT | PLUS;
+               if ( ie < 0 )
+                       type |= SIGN;
+
+               result = wnumber(f,ie, 10,2, 2,type );
+               if (result < 0)
+                       return false;
+               return true;
+       }
+
+       if ( exp_sign == L'f' )
+       {
+               buf = (wchar_t*)alloca(4096*sizeof(wchar_t));
+               if (type & LEFT)
+                       type &= ~ZEROPAD;
+
+               c = (type & ZEROPAD) ? L'0' : L' ';
+               sign = 0;
+               if (type & SIGN)
+               {
+                       if (__n < 0)
+                       {
+                               sign = L'-';
+                               __n = fabs(__n);
+                               size--;
+                       }
+                       else if (type & PLUS)
+                       {
+                               sign = L'+';
+                               size--;
+                       }
+                       else if (type & SPACE)
+                       {
+                               sign = L' ';
+                               size--;
+                       }
+               }
+
+               frac = modf(__n,&intr);
+
+               // # flags forces a . and prevents trucation of trailing zero's
+
+               if ( precision > 0 ) {
+                       //frac = modfl(__n,&intr);
+                       i = precision-1;
+                       while (  i >= 0  ) {
+                               frac*=10.0L;
+                               frac = modf(frac, &p);
+                               buf[i] = (int)p + L'0';
+                               i--;
+                       }
+                       i = precision;
+                       size -= precision;
+
+                       ro = 0;
+                       if ( frac > 0.5 ) {
+                               ro = 1;
+                       }
+
+                       if ( precision >= 1 || type & SPECIAL) {
+                               buf[i++] = L'.';
+                               size--;
+                       }
+               }
+
+               if ( intr == 0.0 ) {
+                       buf[i++] = L'0';
+                       size--;
+               }
+               else {
+                       while ( intr > 0.0 ) {
+                               p = intr;
+                               intr/=10.0L;
+                               modf(intr, &intr);
+
+                               p -= 10.0*intr;
+
+                               buf[i++] = (int)p + L'0';
+                               size--;
+                       }
+               }
+
+               j = 0;
+               while ( j < i && ro == 1) {
+                       if ( buf[j] >= L'0' && buf[j] <= L'8' ) {
+                               buf[j]++;
+                               ro = 0;
+                       }
+                       else if ( buf[j] == L'9' ) {
+                               buf[j] = L'0';
+                       }
+                       j++;
+               }
+               if ( ro == 1 )
+                       buf[i++] = L'1';
+
+               buf[i] = 0;
+
+               size -= precision;
+               if (!(type&(ZEROPAD+LEFT)))
+               {
+                       while(size-->0)
+                               f += L' ';
+               }
+               if (sign)
+               {
+                       f += sign;
+               }
+
+               if (!(type&(ZEROPAD+LEFT)))
+                       while(size-->0)
+                       {
+                               f += L' ';
+                       }
+               if (type & SPECIAL) {
+               }
+
+               if (!(type & LEFT))
+                       while (size-- > 0)
+                       {
+                               f += c;
+                       }
+
+               tmp = buf;
+               if ( type & ZEROTRUNC && ((type & SPECIAL) != SPECIAL) )
+               {
+                       j = 0;
+                       while ( j < i && ( *tmp == L'0' || *tmp == L'.' ))
+                       {
+                               tmp++;
+                               i--;
+                       }
+               }
+               while (i-- > 0)
+               {
+                       f += tmp[i];
+               }
+               while (size-- > 0)
+               {
+                       f += L' ';
+               }
+       }
+       return true;
+}
+
+static bool
+numberfl(std::string& f, long double __n, char exp_sign,  int size, int precision, int type)
+{
+       long double exponent = 0.0;
+       long double e;
+       long ie;
+
+       //int x;
+       char *buf, *tmp;
+       int i = 0;
+       int j = 0;
+       //int k = 0;
+
+       long double frac, intr;
+       long double p;
+       char sign;
+       char c;
+       char ro = 0;
+
+       int result;
+
+       union
+       {
+           long double*   __n;
+           ieee_long_double_t*   n;
+       } n;
+
+       n.__n = &__n;
+
+       if ( exp_sign == 'g' || exp_sign == 'G' || exp_sign == 'e' || exp_sign == 'E' ) {
+               ie = ((unsigned int)n.n->exponent - (unsigned int)0x3fff);
+               exponent = ie/3.321928;
+       }
+
+       if ( exp_sign == 'g' || exp_sign == 'G' ) {
+               type |= ZEROTRUNC;
+               if ( exponent < -4 || fabs(exponent) >= precision ) 
+                       exp_sign -= 2; // g -> e and G -> E
+               else
+                       exp_sign = 'f';
+       }
+
+       if ( exp_sign == 'e' || exp_sign == 'E' ) {
+               frac = modfl(exponent,&e);
+               if ( frac > 0.5 )
+                       e++;
+               else if ( frac < -0.5 )
+                       e--;
+
+               result = numberf(f,__n/powl(10.0L,e),'f',size-4, precision, type);
+               if (result < 0)
+                       return false;
+               f += exp_sign;
+               size--;
+               ie = (long)e;
+               type = LEFT | PLUS;
+               if ( ie < 0 )
+                       type |= SIGN;
+
+               result = number(f,ie, 10,2, 2,type );
+               if (result < 0)
+                       return false;
+               return true;
+       }
+
+       if ( exp_sign == 'f' )
+       {
+               
+               buf = (char*)alloca(4096);
+               if (type & LEFT)
+               {
+                       type &= ~ZEROPAD;
+               }
+
+               c = (type & ZEROPAD) ? '0' : ' ';
+               sign = 0;
+               if (type & SIGN)
+               {
+                       if (__n < 0)
+                       {
+                               sign = '-';
+                               __n = fabs(__n);
+                               size--;
+                       } else if (type & PLUS)
+                       {
+                               sign = '+';
+                               size--;
+                       } else if (type & SPACE)
+                       {
+                               sign = ' ';
+                               size--;
+                       }
+               }
+
+               frac = modfl(__n,&intr);
+
+               // # flags forces a . and prevents trucation of trailing zero's
+               if ( precision > 0 )
+               {
+                       //frac = modfl(__n,&intr);
+
+                       i = precision-1;
+                       while ( i >= 0  )
+                       {
+                               frac*=10.0L;
+                               frac = modfl((long double)frac, &p);
+                               buf[i] = (int)p + '0';
+                               i--;
+                       }
+                       i = precision;
+                       size -= precision;
+
+                       ro = 0;
+                       if ( frac > 0.5 )
+                       {
+                               ro = 1;
+                       }
+
+                       if ( precision >= 1 || type & SPECIAL)
+                       {
+                               buf[i++] = '.';
+                               size--;
+                       }
+               }
+
+               if ( intr == 0.0 )
+               {
+                       buf[i++] = '0';
+                       size--;
+               }
+               else
+               {
+                       while ( intr > 0.0 )
+                       {
+                               p=intr;
+                               intr/=10.0L;
+                               modfl(intr, &intr);
+
+                               p -= 10.0L*intr;
+
+                               buf[i++] = (int)p + '0';
+                               size--;
+                       }
+               }
+
+               j = 0;
+               while ( j < i && ro == 1) {
+                       if ( buf[j] >= '0' && buf[j] <= '8' )
+                       {
+                               buf[j]++;
+                               ro = 0;
+                       }
+                       else if ( buf[j] == '9' )
+                       {
+                               buf[j] = '0';
+                       }
+                       j++;
+               }
+               if ( ro == 1 )
+                       buf[i++] = '1';
+
+               buf[i] = 0;
+
+               size -= precision;
+               if (!(type&(ZEROPAD+LEFT)))
+               {
+                       while(size-->0)
+                               f += ' ';
+               }
+               if (sign)
+               {
+                       f += sign;
+               }
+
+               if (!(type&(ZEROPAD+LEFT)))
+               {
+                       while(size-->0)
+                               f += ' ';
+               }
+               if (type & SPECIAL) {
+               }
+
+               if (!(type & LEFT))
+                       while (size-- > 0)
+                       {
+                               f += c;
+                       }
+               tmp = buf;
+               if ( type & ZEROTRUNC && ((type & SPECIAL) != SPECIAL) )
+               {
+                       j = 0;
+                       while ( j < i && ( *tmp == '0' || *tmp == '.' ))
+                       {
+                               tmp++;
+                               i--;
+                       }
+               }
+               while (i-- > 0)
+               {
+                       f += tmp[i];
+               }
+               while (size-- > 0)
+               {
+                       f += ' ';
+               }
+       }
+       return true;
+}
+
+static bool
+wnumberfl(std::wstring& f, long double __n, wchar_t exp_sign,  int size, int precision, int type)
+{
+       long double exponent = 0.0;
+       long double e;
+       long ie;
+
+       wchar_t *buf, *tmp, sign, c, ro = 0;
+       int i = 0;
+       int j = 0;
+
+       long double frac, intr;
+       long double p;
+
+       int result;
+
+       union
+       {
+           long double*   __n;
+           ieee_long_double_t*   n;
+       } n;
+
+       n.__n = &__n;
+
+       if ( exp_sign == L'g' || exp_sign == L'G' || exp_sign == L'e' || exp_sign == L'E' ) {
+               ie = ((unsigned int)n.n->exponent - (unsigned int)0x3fff);
+               exponent = ie/3.321928;
+       }
+
+       if ( exp_sign == L'g' || exp_sign == L'G' ) {
+               type |= ZEROTRUNC;
+               if ( exponent < -4 || fabs(exponent) >= precision ) 
+                       exp_sign -= 2; // g -> e and G -> E
+               else
+                       exp_sign = 'f';
+       }
+
+       if ( exp_sign == L'e' || exp_sign == L'E' ) {
+               frac = modfl(exponent,&e);
+               if ( frac > 0.5 )
+                       e++;
+               else if ( frac < -0.5 )
+                       e--;
+
+               result = wnumberf(f,__n/powl(10.0L,e),L'f',size-4, precision, type);
+               if (result < 0)
+                       return false;
+               f += exp_sign;
+               size--;
+               ie = (long)e;
+               type = LEFT | PLUS;
+               if ( ie < 0 )
+                       type |= SIGN;
+
+               result = wnumber(f,ie, 10,2, 2,type );
+               if (result < 0)
+                       return false;
+               return true;
+       }
+
+       if ( exp_sign == L'f' )
+       {
+               
+               buf = (wchar_t*)alloca(4096*sizeof(wchar_t));
+               if (type & LEFT)
+               {
+                       type &= ~ZEROPAD;
+               }
+
+               c = (type & ZEROPAD) ? L'0' : L' ';
+               sign = 0;
+               if (type & SIGN)
+               {
+                       if (__n < 0)
+                       {
+                               sign = L'-';
+                               __n = fabs(__n);
+                               size--;
+                       } else if (type & PLUS)
+                       {
+                               sign = L'+';
+                               size--;
+                       } else if (type & SPACE)
+                       {
+                               sign = L' ';
+                               size--;
+                       }
+               }
+
+               frac = modfl(__n,&intr);
+
+               // # flags forces a . and prevents trucation of trailing zero's
+               if ( precision > 0 )
+               {
+                       //frac = modfl(__n,&intr);
+
+                       i = precision-1;
+                       while ( i >= 0  )
+                       {
+                               frac*=10.0L;
+                               frac = modfl((long double)frac, &p);
+                               buf[i] = (int)p + L'0';
+                               i--;
+                       }
+                       i = precision;
+                       size -= precision;
+
+                       ro = 0;
+                       if ( frac > 0.5 )
+                       {
+                               ro = 1;
+                       }
+
+                       if ( precision >= 1 || type & SPECIAL)
+                       {
+                               buf[i++] = L'.';
+                               size--;
+                       }
+               }
+
+               if ( intr == 0.0 )
+               {
+                       buf[i++] = L'0';
+                       size--;
+               }
+               else
+               {
+                       while ( intr > 0.0 )
+                       {
+                               p=intr;
+                               intr/=10.0L;
+                               modfl(intr, &intr);
+
+                               p -= 10.0L*intr;
+
+                               buf[i++] = (int)p + L'0';
+                               size--;
+                       }
+               }
+
+               j = 0;
+               while ( j < i && ro == 1) {
+                       if ( buf[j] >= L'0' && buf[j] <= L'8' )
+                       {
+                               buf[j]++;
+                               ro = 0;
+                       }
+                       else if ( buf[j] == L'9' )
+                       {
+                               buf[j] = L'0';
+                       }
+                       j++;
+               }
+               if ( ro == 1 )
+                       buf[i++] = L'1';
+
+               buf[i] = 0;
+
+               size -= precision;
+               if (!(type&(ZEROPAD+LEFT)))
+               {
+                       while(size-->0)
+                               f += L' ';
+               }
+               if (sign)
+               {
+                       f += sign;
+               }
+
+               if (!(type&(ZEROPAD+LEFT)))
+               {
+                       while(size-->0)
+                               f += L' ';
+               }
+               if (type & SPECIAL) {
+               }
+
+               if (!(type & LEFT))
+                       while (size-- > 0)
+                       {
+                               f += c;
+                       }
+               tmp = buf;
+               if ( type & ZEROTRUNC && ((type & SPECIAL) != SPECIAL) )
+               {
+                       j = 0;
+                       while ( j < i && ( *tmp == L'0' || *tmp == L'.' ))
+                       {
+                               tmp++;
+                               i--;
+                       }
+               }
+               while (i-- > 0)
+               {
+                       f += tmp[i];
+               }
+               while (size-- > 0)
+               {
+                       f += L' ';
+               }
+       }
+       return true;
+}
+
+static int
+do_string(std::string& f, const char* s, int len, int field_width, int precision, int flags)
+{
+       int i, done = 0;
+       if (s == NULL)
+       {
+               s = "<NULL>";
+               len = 6;
+       }
+       else
+       {
+               if (len == -1)
+               {
+                       len = 0;
+                       while ((unsigned int)len < (unsigned int)precision && s[len])
+                               len++;
+               }
+               else
+               {
+                       if ((unsigned int)len > (unsigned int)precision)
+                               len = precision;
+               }
+       }
+       if (!(flags & LEFT))
+               while (len < field_width--)
+               {
+                       f += ' ';
+                       done++;
+               }
+       for (i = 0; i < len; ++i)
+       {
+               f += *s++;
+               done++;
+       }
+       while (len < field_width--)
+       {
+               f += ' ';
+               done++;
+       }
+       return done;
+}
+
+static int
+do_wstring(std::wstring& f, const wchar_t* s, int len, int field_width, int precision, int flags)
+{
+       int i, done = 0;
+       if (s == NULL)
+       {
+               s = L"<NULL>";
+               len = 6;
+       }
+       else
+       {
+               if (len == -1)
+               {
+                       len = 0;
+                       while ((unsigned int)len < (unsigned int)precision && s[len])
+                               len++;
+               }
+               else
+               {
+                       if ((unsigned int)len > (unsigned int)precision)
+                               len = precision;
+               }
+       }
+       if (!(flags & LEFT))
+               while (len < field_width--)
+               {
+                       f += L' ';
+                       done++;
+               }
+       for (i = 0; i < len; ++i)
+       {
+               f += *s++;
+               done++;
+       }
+       while (len < field_width--)
+       {
+               f += L' ';
+               done++;
+       }
+       return done;
+}
+
+static int
+stringw(std::string& f, const wchar_t* sw, int len, int field_width, int precision, int flags)
+{
+       int i, done = 0;
+       if (sw == NULL)
+       {
+               sw = L"<NULL>";
+               len = 6;
+       }
+       else
+       {
+               if (len == -1)
+               {
+                       len = 0;
+                       while ((unsigned int)len < (unsigned int)precision && sw[len])
+                               len++;
+               }
+               else
+               {
+                       if ((unsigned int)len > (unsigned int)precision)
+                               len = precision;
+               }
+       }
+       if (!(flags & LEFT))
+               while (len < field_width--)
+               {
+                       f += ' ';
+                       done++;
+               }
+       for (i = 0; i < len; ++i)
+       {
+#define MY_MB_CUR_MAX 1
+               char mb[MY_MB_CUR_MAX];
+               int mbcount, j;
+               mbcount = wctomb(mb, *sw++);
+               if (mbcount <= 0)
+               {
+                       break;
+               }
+               for (j = 0; j < mbcount; j++)
+               {
+                       f += mb[j];
+                       done++;
+               }
+       }
+       while (len < field_width--)
+       {
+               f += ' ';
+               done++;
+       }
+       return done;
+}
+
+static int
+wstringa(std::wstring& f, const char* sa, int len, int field_width, int precision, int flags)
+{
+       int i, done = 0;
+       if (sa == NULL)
+       {
+               sa = "<NULL>";
+               len = 6;
+       }
+       else
+       {
+               if (len == -1)
+               {
+                       len = 0;
+                       while ((unsigned int)len < (unsigned int)precision && sa[len])
+                               len++;
+               }
+               else
+               {
+                       if ((unsigned int)len > (unsigned int)precision)
+                               len = precision;
+               }
+       }
+       if (!(flags & LEFT))
+               while (len < field_width--)
+               {
+                       f += L' ';
+                       done++;
+               }
+       for (i = 0; i < len;)
+       {
+               wchar_t w;
+               int mbcount;
+               mbcount = mbtowc(&w, sa, len-i);
+               if (mbcount <= 0)
+                       break;
+               f += w;
+               done++;
+               i += mbcount;
+       }
+       while (len < field_width--)
+       {
+               f += L' ';
+               done++;
+       }
+       return done;
+}
+
+#define _isnanl _isnan
+#define _finitel _finite
+
+std::string
+ssvprintf ( const char *fmt, va_list args )
+{
+       ULONGLONG num;
+       int base;
+       long double _ldouble;
+       double _double;
+       const char *s;
+       const wchar_t* sw;
+       int result;
+       std::string f;
+
+       int flags;              /* flags to number() */
+
+       int field_width;        /* width of output field */
+       int precision;          /* min. # of digits for integers; max
+                                  number of chars for from string */
+       int qualifier = 0;      /* 'h', 'l', 'L' or 'I64' for integer fields */
+
+       for (; *fmt ; ++fmt)
+       {
+               if (*fmt != '%')
+               {
+                       f += *fmt;
+                       continue;
+               }
+
+               /* process flags */
+               flags = 0;
+               repeat:
+                       ++fmt;          /* this also skips first '%' */
+                       switch (*fmt) {
+                               case '-': flags |= LEFT; goto repeat;
+                               case '+': flags |= PLUS; goto repeat;
+                               case ' ': flags |= SPACE; goto repeat;
+                               case '#': flags |= SPECIAL; goto repeat;
+                               case '0': flags |= ZEROPAD; goto repeat;
+                               }
+
+               /* get field width */
+               field_width = -1;
+               if (isdigit(*fmt))
+                       field_width = skip_atoi(&fmt);
+               else if (*fmt == '*') {
+                       ++fmt;
+                       /* it's the next argument */
+                       field_width = va_arg(args, int);
+                       if (field_width < 0) {
+                               field_width = -field_width;
+                               flags |= LEFT;
+                       }
+               }
+
+               /* get the precision */
+               precision = -1;
+               if (*fmt == '.') {
+                       ++fmt;
+                       if (isdigit(*fmt))
+                               precision = skip_atoi(&fmt);
+                       else if (*fmt == '*') {
+                               ++fmt;
+                               /* it's the next argument */
+                               precision = va_arg(args, int);
+                       }
+                       if (precision < 0)
+                               precision = 0;
+               }
+
+               /* get the conversion qualifier */
+               qualifier = 0;
+               // %Z can be just stand alone or as size_t qualifier
+               if ( *fmt == 'Z' ) {
+                       qualifier = *fmt;
+                       switch ( *(fmt+1)) {
+                               case 'o':
+                               case 'b':
+                               case 'X':
+                               case 'x':
+                               case 'd':
+                               case 'i':
+                               case 'u':
+                                       ++fmt;
+                                       break;
+                               default:
+                                       break;
+                       }
+               } else if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt == 'w') {
+                       qualifier = *fmt;
+                       ++fmt;
+               } else if (*fmt == 'I' && *(fmt+1) == '6' && *(fmt+2) == '4') {
+                       qualifier = *fmt;
+                       fmt += 3;
+               }
+
+               // go fine with ll instead of L
+               if ( *fmt == 'l' ) {
+                       ++fmt;
+                       qualifier = 'L';
+               }
+
+               /* default base */
+               base = 10;
+
+               switch (*fmt) {
+               case 'c':
+                       if (!(flags & LEFT))
+                               while (--field_width > 0)
+                               {
+                                       f += ' ';
+                               }
+                       if (qualifier == 'l' || qualifier == 'w')
+                       {
+                               f += (char)(unsigned char)(wchar_t) va_arg(args,int);
+                       }
+                       else
+                       {
+                               f += (char)(unsigned char) va_arg(args,int);
+                       }
+                       while (--field_width > 0)
+                       {
+                               f += ' ';
+                       }
+                       continue;
+
+               case 'C':
+                       if (!(flags & LEFT))
+                               while (--field_width > 0)
+                               {
+                                       f += ' ';
+                               }
+                       if (qualifier == 'h')
+                       {
+                               f += (char)(unsigned char) va_arg(args,int);
+                       }
+                       else
+                       {
+                               f += (char)(unsigned char)(wchar_t) va_arg(args,int);
+                       }
+                       while (--field_width > 0)
+                       {
+                               f += ' ';
+                       }
+                       continue;
+
+               case 's':
+                       if (qualifier == 'l' || qualifier == 'w') {
+                               /* print unicode string */
+                               sw = va_arg(args, wchar_t *);
+                               result = stringw(f, sw, -1, field_width, precision, flags);
+                       } else {
+                               /* print ascii string */
+                               s = va_arg(args, char *);
+                               result = do_string(f, s, -1, field_width, precision, flags);
+                       }
+                       if (result < 0)
+                       {
+                               assert(!"TODO FIXME handle error better");
+                               return f;
+                       }
+                       continue;
+
+               case 'S':
+                       if (qualifier == 'h') {
+                               /* print ascii string */
+                               s = va_arg(args, char *);
+                               result = do_string(f, s, -1, field_width, precision, flags);
+                       } else {
+                               /* print unicode string */
+                               sw = va_arg(args, wchar_t *);
+                               result = stringw(f, sw, -1, field_width, precision, flags);
+                       }
+                       if (result < 0)
+                       {
+                               assert(!"TODO FIXME handle error better");
+                               return f;
+                       }
+                       continue;
+
+               /*case 'Z':
+                       if (qualifier == 'w') {
+                               // print counted unicode string
+                               PUNICODE_STRING pus = va_arg(args, PUNICODE_STRING);
+                               if ((pus == NULL) || (pus->Buffer == NULL)) {
+                                       sw = NULL;
+                                       len = -1;
+                               } else {
+                                       sw = pus->Buffer;
+                                       len = pus->Length / sizeof(WCHAR);
+                               }
+                               result = stringw(f, sw, len, field_width, precision, flags);
+                       } else {
+                               // print counted ascii string
+                               PANSI_STRING pas = va_arg(args, PANSI_STRING);
+                               if ((pas == NULL) || (pas->Buffer == NULL)) {
+                                       s = NULL;
+                                       len = -1;
+                               } else {
+                                       s = pas->Buffer;
+                                       len = pas->Length;
+                               }
+                               result = string(f, s, -1, field_width, precision, flags);
+                       }
+                       if (result < 0)
+                               return -1;
+                       continue;*/
+
+               case 'e':
+               case 'E':
+               case 'f':
+               case 'g':
+               case 'G':
+                       if (qualifier == 'l' || qualifier == 'L' ) {
+                               _ldouble = va_arg(args, long double);
+                       
+                               if ( _isnanl(_ldouble) )
+                               {
+                                       f += "Nan";
+                               }
+                               else if ( !_finitel(_ldouble) )
+                               {
+                                       if ( _ldouble < 0 )
+                                               f += "-Inf";
+                                       else
+                                               f += "+Inf";
+                               } else {
+                                       if ( precision == -1 )
+                                               precision = 6;
+                                       result = numberfl(f,_ldouble,*fmt,field_width,precision,flags);
+                                       if (result < 0)
+                                       {
+                                               assert(!"TODO FIXME handle error better");
+                                               return f;
+                                       }
+                               }
+                       } else {
+                               _double = (double)va_arg(args, double);
+
+                               if ( _isnan(_double) )
+                               {
+                                       f += "Nan";
+                               }
+                               else if ( !_finite(_double) )
+                               {
+                                       if ( _double < 0 )
+                                               f += "-Inf";
+                                       else
+                                               f += "+Inf";
+                               }
+                               else
+                               {
+                                       if ( precision == -1 )
+                                               precision = 6;
+                                       result = numberf(f,_double,*fmt,field_width,precision,flags);
+                                       if (result < 0)
+                                       {
+                                               assert(!"TODO FIXME handle error better");
+                                               return f;
+                                       }
+                               }
+                       }
+                       continue;
+
+               case 'p':
+                       if (field_width == -1) {
+                               field_width = 2*sizeof(void *);
+                               flags |= ZEROPAD;
+                       }
+                       result = number(f,
+                                       (unsigned long) va_arg(args, void *), 16,
+                                       field_width, precision, flags);
+                       if (result < 0)
+                       {
+                               assert(!"TODO FIXME handle error better");
+                               return f;
+                       }
+                       continue;
+
+               case 'n':
+                       if (qualifier == 'l') {
+                               long * ip = va_arg(args, long *);
+                               *ip = 0;
+                       } else {
+                               int * ip = va_arg(args, int *);
+                               *ip = 0;
+                       }
+                       continue;
+
+               /* integer number formats - set up the flags and "break" */
+               case 'o':
+                       base = 8;
+                       break;
+
+               case 'b':
+                       base = 2;
+                       break;
+
+               case 'X':
+                       flags |= LARGE;
+               case 'x':
+                       base = 16;
+                       break;
+
+               case 'd':
+               case 'i':
+                       flags |= SIGN;
+               case 'u':
+                       break;
+
+               default:
+                       if (*fmt != '%')
+                       {
+                               f += '%';
+                       }
+                       if (*fmt)
+                       {
+                               f += *fmt;
+                       }
+                       else
+                               --fmt;
+                       continue;
+               }
+
+               if (qualifier == 'I')
+                       num = va_arg(args, ULONGLONG);
+               else if (qualifier == 'l') {
+                       if (flags & SIGN)
+                               num = va_arg(args, long);
+                       else
+                               num = va_arg(args, unsigned long);
+               }
+               else if (qualifier == 'h') {
+                       if (flags & SIGN)
+                               num = va_arg(args, int);
+                       else
+                               num = va_arg(args, unsigned int);
+               }
+               else if (flags & SIGN)
+                       num = va_arg(args, int);
+               else
+                       num = va_arg(args, unsigned int);
+               result = number(f, num, base, field_width, precision, flags);
+               if (result < 0)
+               {
+                       assert(!"TODO FIXME handle error better");
+                       return f;
+               }
+       }
+       //putc('\0',f);
+       return f;
+}
+
+std::wstring
+sswvprintf ( const wchar_t* fmt, va_list args )
+{
+       ULONGLONG num;
+       int base;
+       long double _ldouble;
+       double _double;
+       const wchar_t* s;
+       const char* sa;
+       int result;
+       std::wstring f;
+
+       int flags;              /* flags to number() */
+
+       int field_width;        /* width of output field */
+       int precision;          /* min. # of digits for integers; max
+                                  number of chars for from string */
+       int qualifier = 0;      /* 'h', 'l', 'L' or 'I64' for integer fields */
+
+       for (; *fmt ; ++fmt)
+       {
+               if (*fmt != L'%')
+               {
+                       f += *fmt;
+                       continue;
+               }
+
+               /* process flags */
+               flags = 0;
+               repeat:
+                       ++fmt;          /* this also skips first '%' */
+                       switch (*fmt) {
+                               case L'-': flags |= LEFT; goto repeat;
+                               case L'+': flags |= PLUS; goto repeat;
+                               case L' ': flags |= SPACE; goto repeat;
+                               case L'#': flags |= SPECIAL; goto repeat;
+                               case L'0': flags |= ZEROPAD; goto repeat;
+                               }
+
+               /* get field width */
+               field_width = -1;
+               if (isdigit(*fmt))
+                       field_width = skip_wtoi(&fmt);
+               else if (*fmt == L'*') {
+                       ++fmt;
+                       /* it's the next argument */
+                       field_width = va_arg(args, int);
+                       if (field_width < 0) {
+                               field_width = -field_width;
+                               flags |= LEFT;
+                       }
+               }
+
+               /* get the precision */
+               precision = -1;
+               if (*fmt == L'.') {
+                       ++fmt;
+                       if (iswdigit(*fmt))
+                               precision = skip_wtoi(&fmt);
+                       else if (*fmt == L'*') {
+                               ++fmt;
+                               /* it's the next argument */
+                               precision = va_arg(args, int);
+                       }
+                       if (precision < 0)
+                               precision = 0;
+               }
+
+               /* get the conversion qualifier */
+               qualifier = 0;
+               // %Z can be just stand alone or as size_t qualifier
+               if ( *fmt == L'Z' ) {
+                       qualifier = *fmt;
+                       switch ( *(fmt+1)) {
+                               case L'o':
+                               case L'b':
+                               case L'X':
+                               case L'x':
+                               case L'd':
+                               case L'i':
+                               case L'u':
+                                       ++fmt;
+                                       break;
+                               default:
+                                       break;
+                       }
+               } else if (*fmt == L'h' || *fmt == L'l' || *fmt == L'L' || *fmt == L'w') {
+                       qualifier = *fmt;
+                       ++fmt;
+               } else if (*fmt == L'I' && *(fmt+1) == L'6' && *(fmt+2) == L'4') {
+                       qualifier = *fmt;
+                       fmt += 3;
+               }
+
+               // go fine with ll instead of L
+               if ( *fmt == L'l' ) {
+                       ++fmt;
+                       qualifier = L'L';
+               }
+
+               /* default base */
+               base = 10;
+
+               switch (*fmt) {
+               case L'c':
+                       if (!(flags & LEFT))
+                               while (--field_width > 0)
+                               {
+                                       f += L' ';
+                               }
+                       if ( qualifier == L'h' )
+                       {
+                               f += (wchar_t)(char)(unsigned char) va_arg(args,int);
+                       }
+                       else
+                       {
+                               f += (wchar_t) va_arg(args,int);
+                       }
+                       while (--field_width > 0)
+                       {
+                               f += ' ';
+                       }
+                       continue;
+
+               case 'C':
+                       if (!(flags & LEFT))
+                               while (--field_width > 0)
+                               {
+                                       f += L' ';
+                               }
+                       if (qualifier == L'l' || qualifier == L'w')
+                       {
+                               f += (wchar_t) va_arg(args,int);
+                       }
+                       else
+                       {
+                               f += (wchar_t)(char)(unsigned char) va_arg(args,int);
+                       }
+                       while (--field_width > 0)
+                       {
+                               f += L' ';
+                       }
+                       continue;
+
+               case 's':
+                       if (qualifier == L'h') {
+                               /* print ascii string */
+                               sa = va_arg(args, char *);
+                               result = wstringa(f, sa, -1, field_width, precision, flags);
+                       } else {
+                               /* print unicode string */
+                               s = va_arg(args, wchar_t *);
+                               result = do_wstring(f, s, -1, field_width, precision, flags);
+                       }
+                       if (result < 0)
+                       {
+                               assert(!"TODO FIXME handle error better");
+                               return f;
+                       }
+                       continue;
+
+               case 'S':
+                       if (qualifier == L'l' || qualifier == L'w') {
+                               /* print unicode string */
+                               s = va_arg(args, wchar_t *);
+                               result = do_wstring(f, s, -1, field_width, precision, flags);
+                       } else {
+                               /* print ascii string */
+                               sa = va_arg(args, char *);
+                               result = wstringa(f, sa, -1, field_width, precision, flags);
+                       }
+                       if (result < 0)
+                       {
+                               assert(!"TODO FIXME handle error better");
+                               return f;
+                       }
+                       continue;
+
+               case L'e':
+               case L'E':
+               case L'f':
+               case L'g':
+               case L'G':
+                       if (qualifier == L'l' || qualifier == L'L' )
+                       {
+                               _ldouble = va_arg(args, long double);
+                       
+                               if ( _isnanl(_ldouble) )
+                               {
+                                       f += L"Nan";
+                               }
+                               else if ( !_finitel(_ldouble) )
+                               {
+                                       if ( _ldouble < 0 )
+                                               f += L"-Inf";
+                                       else
+                                               f += L"+Inf";
+                               } else {
+                                       if ( precision == -1 )
+                                               precision = 6;
+                                       result = wnumberfl(f,_ldouble,*fmt,field_width,precision,flags);
+                                       if (result < 0)
+                                       {
+                                               assert(!"TODO FIXME handle error better");
+                                               return f;
+                                       }
+                               }
+                       } else {
+                               _double = (double)va_arg(args, double);
+
+                               if ( _isnan(_double) )
+                               {
+                                       f += L"Nan";
+                               }
+                               else if ( !_finite(_double) )
+                               {
+                                       if ( _double < 0 )
+                                               f += L"-Inf";
+                                       else
+                                               f += L"+Inf";
+                               }
+                               else
+                               {
+                                       if ( precision == -1 )
+                                               precision = 6;
+                                       result = wnumberf(f,_double,*fmt,field_width,precision,flags);
+                                       if (result < 0)
+                                       {
+                                               assert(!"TODO FIXME handle error better");
+                                               return f;
+                                       }
+                               }
+                       }
+                       continue;
+
+               case L'p':
+                       if (field_width == -1) {
+                               field_width = 2*sizeof(void *);
+                               flags |= ZEROPAD;
+                       }
+                       result = wnumber(f,
+                                       (unsigned long) va_arg(args, void *), 16,
+                                       field_width, precision, flags);
+                       if (result < 0)
+                       {
+                               assert(!"TODO FIXME handle error better");
+                               return f;
+                       }
+                       continue;
+
+               case L'n':
+                       if (qualifier == L'l') {
+                               long * ip = va_arg(args, long *);
+                               *ip = 0;
+                       } else {
+                               int * ip = va_arg(args, int *);
+                               *ip = 0;
+                       }
+                       continue;
+
+               /* integer number formats - set up the flags and "break" */
+               case L'o':
+                       base = 8;
+                       break;
+
+               case L'b':
+                       base = 2;
+                       break;
+
+               case L'X':
+                       flags |= LARGE;
+               case L'x':
+                       base = 16;
+                       break;
+
+               case L'd':
+               case L'i':
+                       flags |= SIGN;
+               case L'u':
+                       break;
+
+               default:
+                       if (*fmt != L'%')
+                       {
+                               f += L'%';
+                       }
+                       if (*fmt)
+                       {
+                               f += *fmt;
+                       }
+                       else
+                               --fmt;
+                       continue;
+               }
+
+               if (qualifier == L'I')
+                       num = va_arg(args, ULONGLONG);
+               else if (qualifier == L'l') {
+                       if (flags & SIGN)
+                               num = va_arg(args, long);
+                       else
+                               num = va_arg(args, unsigned long);
+               }
+               else if (qualifier == L'h') {
+                       if (flags & SIGN)
+                               num = va_arg(args, int);
+                       else
+                               num = va_arg(args, unsigned int);
+               }
+               else if (flags & SIGN)
+                       num = va_arg(args, int);
+               else
+                       num = va_arg(args, unsigned int);
+               result = wnumber(f, num, base, field_width, precision, flags);
+               if (result < 0)
+               {
+                       assert(!"TODO FIXME handle error better");
+                       return f;
+               }
+       }
+       //putc('\0',f);
+       return f;
+}