--- branches/xmlbuildsystem/reactos/tools/rbuild/ssprintf.cpp 2005-01-04 18:24:21 UTC (rev 12793)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/ssprintf.cpp 2005-01-04 18:38:31 UTC (rev 12794)
@@ -0,0 +1,1893 @@
+// ssprintf.cpp
+
+#include <malloc.h>
+#include <math.h>
+#include <float.h>
+#include <assert.h>
+#include "ssprintf.h"
+
+#ifdef _MSC_VER
+#define alloca _alloca
+#endif//_MSC_VER
+
+typedef __int64 LONGLONG;
+typedef unsigned __int64 ULONGLONG;
+
+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 0;
+ 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 = 0;
+ 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
+ }
+
+ 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,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
+ }
+
+ 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,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
+ }
+
+ 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
+ }
+
+ 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)
[truncated at 1000 lines; 926 more skipped]