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