Fixed a buffer overflow if there is given a not null terminated string with a precision parameter.

Reduced some overhead for outputing strings.
Added handling of the precision parameter for counted strings.
Return the outputed character count (or an error) in __vf(w)printf.

svn path=/trunk/; revision=3492
This commit is contained in:
Hartmut Birr 2002-09-13 18:48:42 +00:00
parent 3f316cde99
commit eec75375c4
2 changed files with 661 additions and 252 deletions

View file

@ -20,6 +20,9 @@ vfprintf(FILE *f, const char *fmt, va_list ap)
int len;
char localbuf[BUFSIZ];
#if 0
__fileno_lock(fileno(f));
#endif
if (f->_flag & _IONBF)
{
f->_flag &= ~_IONBF;
@ -34,6 +37,9 @@ vfprintf(FILE *f, const char *fmt, va_list ap)
}
else
len = __vfprintf(f,fmt, ap);
#if 0
__fileno_unlock(fileno(f));
#endif
return (ferror(f) ? EOF : len);
}
@ -91,18 +97,18 @@ static int do_div(long long *n,int base)
}
static void number(FILE * f, long long num, int base, int size, int precision ,int type)
static int number(FILE * f, long long num, int base, int size, int precision ,int type)
{
char c,sign,tmp[66];
const char *digits="0123456789abcdefghijklmnopqrstuvwxyz";
int i;
int i, done = 0;
if (type & LARGE)
digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
if (type & LEFT)
type &= ~ZEROPAD;
if (base < 2 || base > 36)
return;
return done;
c = (type & ZEROPAD) ? '0' : ' ';
sign = 0;
if (type & SIGN) {
@ -134,32 +140,62 @@ static void number(FILE * f, long long num, int base, int size, int precision ,i
size -= precision;
if (!(type&(ZEROPAD+LEFT)))
while(size-->0)
putc(' ',f);
{
if (putc(' ',f) == EOF)
return -1;
done++;
}
if (sign)
putc(sign,f);
{
if (putc(sign,f) == EOF)
return -1;
done++;
}
if (type & SPECIAL) {
if (base==8) {
putc('0',f);
if (putc('0',f) == EOF)
return -1;
done++;
}
else if (base==16) {
putc('0', f);
putc(digits[33],f);
if (putc('0', f) == EOF)
return -1;
done++;
if (putc(digits[33],f) == EOF)
return -1;
done++;
}
}
if (!(type & LEFT))
while (size-- > 0)
putc(c,f);
{
if (putc(c,f) == EOF)
return -1;
done++;
}
while (i < precision--)
putc('0', f);
{
if (putc('0', f) == EOF)
return -1;
done++;
}
while (i-- > 0)
putc(tmp[i],f);
{
if (putc(tmp[i],f) == EOF)
return -1;
done++;
}
while (size-- > 0)
putc(' ', f);
return;
{
if (putc(' ', f) == EOF)
return -1;
done++;
}
return done;
}
static void numberf(FILE * f, double __n, char exp_sign, int size, int precision, int type)
static int numberf(FILE * f, double __n, char exp_sign, int size, int precision, int type)
{
double exponent = 0.0;
double e;
@ -176,6 +212,7 @@ static void numberf(FILE * f, double __n, char exp_sign, int size, int precisio
char sign;
char c;
char ro = 0;
int result, done = 0;
double_t *n = (double_t *)&__n;
@ -197,16 +234,24 @@ static void numberf(FILE * f, double __n, char exp_sign, int size, int precisio
else if ( frac < -0.5 )
e--;
numberf(f,__n/pow(10.0L,e),'f',size-4, precision, type);
putc( exp_sign,f);
result = numberf(f,__n/pow(10.0L,e),'f',size-4, precision, type);
if (result < 0)
return -1;
done += result;
if (putc( exp_sign,f) == EOF)
return -1;
done++;
size--;
ie = (long)e;
type = LEFT | PLUS;
if ( ie < 0 )
type |= SIGN;
number(f,ie, 10,2, 2,type );
return;
result = number(f,ie, 10,2, 2,type );
if (result < 0)
return -1;
done += result;
return done;
}
if ( exp_sign == 'f' ) {
@ -293,19 +338,35 @@ static void numberf(FILE * f, double __n, char exp_sign, int size, int precisio
size -= precision;
if (!(type&(ZEROPAD+LEFT)))
while(size-->0)
putc(' ',f);
{
if (putc(' ',f) == EOF)
return -1;
done++;
}
if (sign)
putc( sign,f);
{
if (putc( sign,f) == EOF)
return -1;
done++;
}
if (!(type&(ZEROPAD+LEFT)))
while(size-->0)
putc(' ',f);
{
if (putc(' ',f) == EOF)
return -1;
done++;
}
if (type & SPECIAL) {
}
if (!(type & LEFT))
while (size-- > 0)
putc(c,f);
{
if (putc(c,f) == EOF)
return -1;
done++;
}
tmp = buf;
if ( type & ZEROTRUNC && ((type & SPECIAL) != SPECIAL) ) {
@ -319,14 +380,23 @@ static void numberf(FILE * f, double __n, char exp_sign, int size, int precisio
// while (i < precision--)
// putc('0', f);
while (i-- > 0)
putc(tmp[i],f);
{
if (putc(tmp[i],f) == EOF)
return -1;
done++;
}
while (size-- > 0)
putc(' ', f);
{
if (putc(' ', f) == EOF)
return -1;
done++;
}
}
return done;
}
static void numberfl(FILE * f, long double __n, char exp_sign, int size, int precision, int type)
static int numberfl(FILE * f, long double __n, char exp_sign, int size, int precision, int type)
{
long double exponent = 0.0;
long double e;
@ -344,6 +414,8 @@ static void numberfl(FILE * f, long double __n, char exp_sign, int size, int pr
char c;
char ro = 0;
int result, done = 0;
long_double_t *n = (long_double_t *)&__n;
if ( exp_sign == 'g' || exp_sign == 'G' || exp_sign == 'e' || exp_sign == 'E' ) {
@ -364,16 +436,24 @@ static void numberfl(FILE * f, long double __n, char exp_sign, int size, int pr
else if ( frac < -0.5 )
e--;
numberf(f,__n/powl(10.0L,e),'f',size-4, precision, type);
putc( exp_sign,f);
result = numberf(f,__n/powl(10.0L,e),'f',size-4, precision, type);
if (result < 0)
return -1;
done += result;
if (putc( exp_sign,f) == EOF)
return -1;
done++;
size--;
ie = (long)e;
type = LEFT | PLUS;
if ( ie < 0 )
type |= SIGN;
number(f,ie, 10,2, 2,type );
return;
result = number(f,ie, 10,2, 2,type );
if (result < 0)
return -1;
done += result;
return done;
}
if ( exp_sign == 'f' ) {
@ -461,20 +541,35 @@ static void numberfl(FILE * f, long double __n, char exp_sign, int size, int pr
size -= precision;
if (!(type&(ZEROPAD+LEFT)))
while(size-->0)
putc(' ',f);
{
if (putc(' ',f) == EOF)
return -1;
done++;
}
if (sign)
putc(sign,f);
{
if (putc(sign,f) == EOF)
return -1;
done++;
}
if (!(type&(ZEROPAD+LEFT)))
while(size-->0)
putc(' ',f);
{
if (putc(' ',f) == EOF)
return -1;
done++;
}
if (type & SPECIAL) {
}
if (!(type & LEFT))
while (size-- > 0)
putc(c,f);
{
if (putc(c,f) == EOF)
return -1;
done++;
}
tmp = buf;
if ( type & ZEROTRUNC && ((type & SPECIAL) != SPECIAL) ) {
j = 0;
@ -487,12 +582,108 @@ static void numberfl(FILE * f, long double __n, char exp_sign, int size, int pr
// while (i < precision--)
// putc( '0', f);
while (i-- > 0)
putc(tmp[i],f);
{
if ( putc(tmp[i],f) == EOF)
return -1;
done++;
}
while (size-- > 0)
putc(' ', f);
{
if (putc(' ', f) == EOF)
return -1;
done++;
}
}
return done;
}
static int string(FILE *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 (s[len] && (unsigned int)len < (unsigned int)precision)
len++;
}
else
{
if ((unsigned int)len > (unsigned int)precision)
len = precision;
}
}
if (!(flags & LEFT))
while (len < field_width--)
{
if (putc(' ', f) == EOF)
return -1;
done++;
}
for (i = 0; i < len; ++i)
{
if (putc(*s++, f) == EOF)
return -1;
done++;
}
while (len < field_width--)
{
if (putc(' ', f) == EOF)
return -1;
done++;
}
return done;
}
static int stringw(FILE *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 (sw[len] && (unsigned int)len < (unsigned int)precision)
len++;
}
else
{
if ((unsigned int)len > (unsigned int)precision)
len = precision;
}
}
if (!(flags & LEFT))
while (len < field_width--)
{
if (putc(' ', f) == EOF)
return -1;
done++;
}
for (i = 0; i < len; ++i)
{
if (putc((unsigned char)(*sw++), f) == EOF)
return -1;
done++;
}
while (len < field_width--)
{
if (putc(' ', f) == EOF)
return -1;
done++;
}
return done;
}
int __vfprintf(FILE *f, const char *fmt, va_list args)
{
@ -503,6 +694,7 @@ int __vfprintf(FILE *f, const char *fmt, va_list args)
double _double;
const char *s;
const short int* sw;
int result, done = 0;
int flags; /* flags to number() */
@ -513,7 +705,9 @@ int __vfprintf(FILE *f, const char *fmt, va_list args)
for (; *fmt ; ++fmt) {
if (*fmt != '%') {
putc(*fmt,f);
if (putc(*fmt,f) == EOF)
return -1;
done++;
continue;
}
@ -597,101 +791,87 @@ int __vfprintf(FILE *f, const char *fmt, va_list args)
case 'c':
if (!(flags & LEFT))
while (--field_width > 0)
putc(' ', f);
{
if (putc(' ', f) == EOF)
return -1;
done++;
}
if (qualifier == 'l' || qualifier == 'w')
putc((unsigned char)(wchar_t) va_arg(args, int), f);
{
if (putc((unsigned char)(wchar_t) va_arg(args, int), f) == EOF)
return -1;
done++;
}
else
putc((unsigned char) va_arg(args, int), f);
{
if (putc((unsigned char) va_arg(args, int), f) == EOF)
return -1;
done++;
}
while (--field_width > 0)
putc(' ', f);
{
if (putc(' ', f) == EOF)
return -1;
done++;
}
continue;
case 'C':
if (!(flags & LEFT))
while (--field_width > 0)
putc(' ', f);
{
if (putc(' ', f) == EOF)
return -1;
done++;
}
if (qualifier == 'h')
putc((unsigned char) va_arg(args, int), f);
{
if (putc((unsigned char) va_arg(args, int), f) == EOF)
return -1;
done++;
}
else
putc((unsigned char)(wchar_t) va_arg(args, int), f);
{
if (putc((unsigned char)(wchar_t) va_arg(args, int), f) == EOF)
return -1;
done++;
}
while (--field_width > 0)
putc(' ', f);
{
if (putc(' ', f) == EOF)
return -1;
done++;
}
continue;
case 's':
if (qualifier == 'l' || qualifier == 'w') {
/* print unicode string */
sw = va_arg(args, wchar_t *);
if (sw == NULL)
sw = L"<NULL>";
len = wcslen (sw);
if ((unsigned int)len > (unsigned int)precision)
len = precision;
if (!(flags & LEFT))
while (len < field_width--)
putc(' ', f);
for (i = 0; i < len; ++i)
putc((unsigned char)(*sw++), f);
while (len < field_width--)
putc(' ', f);
result = stringw(f, sw, -1, field_width, precision, flags);
} else {
/* print ascii string */
s = va_arg(args, char *);
if (s == NULL)
s = "<NULL>";
len = strlen (s);
if ((unsigned int)len > (unsigned int)precision)
len = precision;
if (!(flags & LEFT))
while (len < field_width--)
putc(' ', f);
for (i = 0; i < len; ++i)
putc(*s++, f);
while (len < field_width--)
putc(' ', f);
result = string(f, s, -1, field_width, precision, flags);
}
if (result < 0)
return -1;
done += result;
continue;
case 'S':
if (qualifier == 'h') {
/* print ascii string */
s = va_arg(args, char *);
if (s == NULL)
s = "<NULL>";
len = strlen (s);
if ((unsigned int)len > (unsigned int)precision)
len = precision;
if (!(flags & LEFT))
while (len < field_width--)
putc(' ', f);
for (i = 0; i < len; ++i)
putc(*s++, f);
while (len < field_width--)
putc(' ', f);
result = string(f, s, -1, field_width, precision, flags);
} else {
/* print unicode string */
sw = va_arg(args, wchar_t *);
if (sw == NULL)
sw = L"<NULL>";
len = wcslen (sw);
if ((unsigned int)len > (unsigned int)precision)
len = precision;
if (!(flags & LEFT))
while (len < field_width--)
putc(' ', f);
for (i = 0; i < len; ++i)
putc((unsigned char)(*sw++), f);
while (len < field_width--)
putc(' ', f);
result = stringw(f, sw, -1, field_width, precision, flags);
}
if (result < 0)
return -1;
done += result;
continue;
case 'Z':
@ -699,25 +879,28 @@ int __vfprintf(FILE *f, const char *fmt, va_list args)
/* print counted unicode string */
PUNICODE_STRING pus = va_arg(args, PUNICODE_STRING);
if ((pus == NULL) || (pus->Buffer == NULL)) {
s = "<NULL>";
while ((*s) != 0)
putc(*s++, f);
sw = NULL;
len = -1;
} else {
for (i = 0; pus->Buffer[i] && i < pus->Length / sizeof(WCHAR); i++)
putc((unsigned char)(pus->Buffer[i]), f);
sw = pus->Buffer;
len = pus->Length / sizeof(WCHAR);
}
result = stringw(f, sw, len, field_width, precision, flags);
} else {
/* print counted ascii string */
PANSI_STRING pus = va_arg(args, PANSI_STRING);
if ((pus == NULL) || (pus->Buffer == NULL)) {
s = "<NULL>";
while ((*s) != 0)
putc(*s++, f);
PANSI_STRING pas = va_arg(args, PANSI_STRING);
if ((pas == NULL) || (pas->Buffer == NULL)) {
s = NULL;
len = -1;
} else {
for (i = 0; pus->Buffer[i] && i < pus->Length; i++)
putc(pus->Buffer[i], f);
s = pas->Buffer;
len = pas->Length;
}
result = string(f, s, -1, field_width, precision, flags);
}
if (result < 0)
return -1;
done += result;
continue;
case 'e':
@ -732,7 +915,9 @@ int __vfprintf(FILE *f, const char *fmt, va_list args)
s = "Nan";
len = 3;
while ( len > 0 ) {
putc(*s++,f);
if (putc(*s++,f) == EOF)
return -1;
done++;
len --;
}
}
@ -740,7 +925,9 @@ int __vfprintf(FILE *f, const char *fmt, va_list args)
s = "-Inf";
len = 4;
while ( len > 0 ) {
putc(*s++,f);
if (putc(*s++,f) == EOF)
return -1;
done++;
len --;
}
}
@ -748,13 +935,18 @@ int __vfprintf(FILE *f, const char *fmt, va_list args)
s = "+Inf";
len = 4;
while ( len > 0 ) {
putc(*s++,f);
if (putc(*s++,f) == EOF)
return -1;
done++;
len --;
}
} else {
if ( precision == -1 )
precision = 6;
numberfl(f,_ldouble,*fmt,field_width,precision,flags);
result = numberfl(f,_ldouble,*fmt,field_width,precision,flags);
if (result < 0)
return -1;
done += result;
}
} else {
_double = (double)va_arg(args, double);
@ -763,27 +955,36 @@ int __vfprintf(FILE *f, const char *fmt, va_list args)
s = "Nan";
len = 3;
while ( len > 0 ) {
putc(*s++,f);
if (putc(*s++,f) == EOF)
return -1;
done++;
len --;
}
} else if ( _isinf(_double) < 0 ) {
s = "-Inf";
len = 4;
while ( len > 0 ) {
putc(*s++,f);
if (putc(*s++,f) == EOF)
return -1;
done++;
len --;
}
} else if ( _isinf(_double) > 0 ) {
s = "+Inf";
len = 4;
while ( len > 0 ) {
putc(*s++,f);
if (putc(*s++,f) == EOF)
return -1;
done++;
len --;
}
} else {
if ( precision == -1 )
precision = 6;
numberf(f,_double,*fmt,field_width,precision,flags);
result = numberf(f,_double,*fmt,field_width,precision,flags);
if (result < 0)
return -1;
done += result;
}
}
continue;
@ -793,9 +994,12 @@ int __vfprintf(FILE *f, const char *fmt, va_list args)
field_width = 2*sizeof(void *);
flags |= ZEROPAD;
}
number(f,
(unsigned long) va_arg(args, void *), 16,
field_width, precision, flags);
result = number(f,
(unsigned long) va_arg(args, void *), 16,
field_width, precision, flags);
if (result < 0)
return -1;
done += result;
continue;
case 'n':
@ -831,9 +1035,17 @@ int __vfprintf(FILE *f, const char *fmt, va_list args)
default:
if (*fmt != '%')
putc('%', f);
{
if (putc('%', f) == EOF)
return -1;
done++;
}
if (*fmt)
putc(*fmt, f);
{
if (putc(*fmt, f) == EOF)
return -1;
done++;
}
else
--fmt;
continue;
@ -853,10 +1065,13 @@ int __vfprintf(FILE *f, const char *fmt, va_list args)
num = va_arg(args, int);
else
num = va_arg(args, unsigned int);
number(f, num, base, field_width, precision, flags);
result = number(f, num, base, field_width, precision, flags);
if (result < 0)
return -1;
done += result;
}
//putc('\0',f);
return 0;
return done;
}
/* EOF */

View file

@ -20,6 +20,9 @@ vfwprintf(FILE *f, const wchar_t *fmt, va_list ap)
int len;
wchar_t localbuf[BUFSIZ];
#if 0
__fileno_lock(fileno(f));
#endif
if (f->_flag & _IONBF) {
f->_flag &= ~_IONBF;
f->_ptr = f->_base = (char *)localbuf;
@ -32,7 +35,9 @@ vfwprintf(FILE *f, const wchar_t *fmt, va_list ap)
f->_cnt = 0;
} else
len = __vfwprintf(f,fmt,ap);
#if 0
__fileno_unlock(fileno(f));
#endif
return (ferror(f) ? EOF : len);
}
@ -91,18 +96,18 @@ static int do_div(long long *n,int base)
}
static void number(FILE * f, long long num, int base, int size, int precision ,int type)
static int number(FILE * f, long long num, int base, int size, int precision ,int type)
{
wchar_t c,sign,tmp[66];
const wchar_t *digits=L"0123456789abcdefghijklmnopqrstuvwxyz";
int i;
int i, done = 0;
if (type & LARGE)
digits = L"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
if (type & LEFT)
type &= ~ZEROPAD;
if (base < 2 || base > 36)
return;
return done;
c = (type & ZEROPAD) ? L'0' : L' ';
sign = 0;
if (type & SIGN) {
@ -134,32 +139,63 @@ static void number(FILE * f, long long num, int base, int size, int precision ,i
size -= precision;
if (!(type&(ZEROPAD+LEFT)))
while(size-->0)
putwc(L' ',f);
{
if (putwc(L' ',f) == WEOF)
return -1;
done++;
}
if (sign)
putwc(sign,f);
{
if (putwc(sign,f) == WEOF)
return -1;
done++;
}
if (type & SPECIAL) {
if (base==8) {
putwc(L'0',f);
if (putwc(L'0',f) == WEOF)
return -1;
done++;
}
else if (base==16) {
putwc(L'0', f);
putwc(digits[33],f);
if (putwc(L'0', f) == WEOF)
return -1;
done++;
if (putwc(digits[33],f) == WEOF)
return -1;
done++;
}
}
if (!(type & LEFT))
while (size-- > 0)
putwc(c,f);
{
if (putwc(c,f) == WEOF)
return -1;
done++;
}
while (i < precision--)
putwc(L'0', f);
{
if (putwc(L'0', f) == WEOF)
return -1;
done++;
}
while (i-- > 0)
putwc(tmp[i],f);
{
if (putwc(tmp[i],f) == WEOF)
return -1;
done++;
}
while (size-- > 0)
putwc(L' ', f);
return;
{
if (putwc(L' ', f) == WEOF)
return -1;
done++;
}
return done;
}
static void numberf(FILE * f, double __n, wchar_t exp_sign, int size, int precision, int type)
static int numberf(FILE * f, double __n, wchar_t exp_sign, int size, int precision, int type)
{
double exponent = 0.0;
double e;
@ -176,6 +212,7 @@ static void numberf(FILE * f, double __n, wchar_t exp_sign, int size, int preci
wchar_t sign;
wchar_t c;
char ro = 0;
int result, done = 0;
double_t *n = (double_t *)&__n;
@ -197,16 +234,24 @@ static void numberf(FILE * f, double __n, wchar_t exp_sign, int size, int preci
else if ( frac < -0.5 )
e--;
numberf(f,__n/pow(10.0L,e),L'f',size-4, precision, type);
putwc( exp_sign,f);
result = numberf(f,__n/pow(10.0L,e),L'f',size-4, precision, type);
if (result < 0)
return -1;
done += result;
if (putwc( exp_sign,f) == WEOF)
return -1;
done++;
size--;
ie = (long)e;
type = LEFT | PLUS;
if ( ie < 0 )
type |= SIGN;
number(f,ie, 10,2, 2,type );
return;
result = number(f,ie, 10,2, 2,type );
if (result < 0)
return -1;
done += result;
return done;
}
if ( exp_sign == 'f' ) {
@ -293,19 +338,35 @@ static void numberf(FILE * f, double __n, wchar_t exp_sign, int size, int preci
size -= precision;
if (!(type&(ZEROPAD+LEFT)))
while(size-->0)
putwc(L' ',f);
{
if (putwc(L' ',f) == WEOF)
return -1;
done++;
}
if (sign)
putwc( sign,f);
{
if (putwc( sign,f) == WEOF)
return -1;
done++;
}
if (!(type&(ZEROPAD+LEFT)))
while(size-->0)
putwc(L' ',f);
{
if (putwc(L' ',f) == WEOF)
return -1;
done++;
}
if (type & SPECIAL) {
}
if (!(type & LEFT))
while (size-- > 0)
putwc(c,f);
{
if (putwc(c,f) == WEOF)
return -1;
done++;
}
tmp = buf;
if ( type & ZEROTRUNC && ((type & SPECIAL) != SPECIAL) ) {
@ -319,14 +380,23 @@ static void numberf(FILE * f, double __n, wchar_t exp_sign, int size, int preci
// while (i < precision--)
// putwc(L'0', f);
while (i-- > 0)
putwc(tmp[i],f);
{
if (putwc(tmp[i],f) == WEOF)
return -1;
done++;
}
while (size-- > 0)
putwc(L' ', f);
{
if (putwc(L' ', f) == WEOF)
return -1;
done++;
}
}
return done;
}
static void numberfl(FILE * f, long double __n, wchar_t exp_sign, int size, int precision, int type)
static int numberfl(FILE * f, long double __n, wchar_t exp_sign, int size, int precision, int type)
{
long double exponent = 0.0;
long double e;
@ -344,6 +414,8 @@ static void numberfl(FILE * f, long double __n, wchar_t exp_sign, int size, int
wchar_t c;
char ro = 0;
int result, done = 0;
long_double_t *n = (long_double_t *)&__n;
if ( exp_sign == L'g' || exp_sign == L'G' || exp_sign == L'e' || exp_sign == L'E' ) {
@ -364,16 +436,24 @@ static void numberfl(FILE * f, long double __n, wchar_t exp_sign, int size, int
else if ( frac < -0.5 )
e--;
numberf(f,__n/powl(10.0L,e),L'f',size-4, precision, type);
putwc( exp_sign,f);
result = numberf(f,__n/powl(10.0L,e),L'f',size-4, precision, type);
if (result < 0)
return -1;
done += result;
if (putwc( exp_sign,f) == WEOF)
return -1;
done++;
size--;
ie = (long)e;
type = LEFT | PLUS;
if ( ie < 0 )
type |= SIGN;
number(f,ie, 10,2, 2,type );
return;
result = number(f,ie, 10,2, 2,type );
if (result < 0)
return -1;
done += result;
return done;
}
if ( exp_sign == L'f' ) {
@ -486,12 +566,108 @@ static void numberfl(FILE * f, long double __n, wchar_t exp_sign, int size, int
// while (i < precision--)
// putc( '0', f);
while (i-- > 0)
putwc(tmp[i],f);
{
if (putwc(tmp[i],f) == WEOF)
return -1;
done++;
}
while (size-- > 0)
putwc(L' ', f);
{
if (putwc(L' ', f) == WEOF)
return -1;
done++;
}
}
return done;
}
static int string(FILE *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 (s[len] && (unsigned int)len < (unsigned int)precision)
len++;
}
else
{
if ((unsigned int)len > (unsigned int)precision)
len = precision;
}
}
if (!(flags & LEFT))
while (len < field_width--)
{
if (putwc(L' ', f) == WEOF)
return -1;
done++;
}
for (i = 0; i < len; ++i)
{
if (putwc(*s++, f) == WEOF)
return -1;
done++;
}
while (len < field_width--)
{
if (putwc(L' ', f) == WEOF)
return -1;
done++;
}
return done;
}
static int stringw(FILE *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 (sw[len] && (unsigned int)len < (unsigned int)precision)
len++;
}
else
{
if ((unsigned int)len > (unsigned int)precision)
len = precision;
}
}
if (!(flags & LEFT))
while (len < field_width--)
{
if (putwc(L' ', f) == WEOF)
return -1;
done++;
}
for (i = 0; i < len; ++i)
{
if (putwc(*sw++, f) == WEOF)
return -1;
done++;
}
while (len < field_width--)
{
if (putwc(L' ', f) == WEOF)
return -1;
done++;
}
return done;
}
int __vfwprintf(FILE *f, const wchar_t *fmt, va_list args)
{
@ -502,6 +678,7 @@ int __vfwprintf(FILE *f, const wchar_t *fmt, va_list args)
double _double;
const char *s;
const wchar_t* sw;
int result, done = 0;
int flags; /* flags to number() */
@ -512,7 +689,9 @@ int __vfwprintf(FILE *f, const wchar_t *fmt, va_list args)
for (; *fmt ; ++fmt) {
if (*fmt != L'%') {
putwc(*fmt,f);
if (putwc(*fmt,f) == WEOF)
return -1;
done++;
continue;
}
@ -596,130 +775,113 @@ int __vfwprintf(FILE *f, const wchar_t *fmt, va_list args)
case L'c': /* finished */
if (!(flags & LEFT))
while (--field_width > 0)
putwc(L' ', f);
{
if (putwc(L' ', f) == WEOF)
return -1;
done++;
}
if (qualifier == L'h')
putwc((wchar_t) va_arg(args, int), f);
{
if (putwc((wchar_t) va_arg(args, int), f) == WEOF)
return -1;
}
else
putwc((wchar_t) va_arg(args, int), f);
{
if (putwc((wchar_t) va_arg(args, int), f) == WEOF)
return -1;
}
done++;
while (--field_width > 0)
putwc(L' ', f);
{
if (putwc(L' ', f) == WEOF)
return -1;
done++;
}
continue;
case L'C': /* finished */
if (!(flags & LEFT))
while (--field_width > 0)
putwc(L' ', f);
{
if (putwc(L' ', f) == WEOF)
return -1;
done;
}
if (qualifier == L'l' || qualifier == L'w')
putwc((unsigned char) va_arg(args, int), f);
{
if (putwc((unsigned char) va_arg(args, int), f) == WEOF)
return -1;
}
else
putwc((unsigned char) va_arg(args, int), f);
{
if (putwc((unsigned char) va_arg(args, int), f) == WEOF)
return -1;
}
done++;
while (--field_width > 0)
putwc(L' ', f);
{
if (putwc(L' ', f) == WEOF)
return -1;
done++;
}
continue;
case L's': /* finished */
if (qualifier == L'h') {
/* print ascii string */
s = va_arg(args, char *);
if (s == NULL)
s = "<NULL>";
len = strlen (s);
if ((unsigned int)len > (unsigned int)precision)
len = precision;
if (!(flags & LEFT))
while (len < field_width--)
putwc(L' ', f);
for (i = 0; i < len; ++i)
putwc((wchar_t)(*s++), f);
while (len < field_width--)
putwc(L' ', f);
result = string(f, s, -1, field_width, precision, flags);
} else {
/* print unicode string */
sw = va_arg(args, wchar_t *);
if (sw == NULL)
sw = L"<NULL>";
len = wcslen (sw);
if ((unsigned int)len > (unsigned int)precision)
len = precision;
if (!(flags & LEFT))
while (len < field_width--)
putwc(L' ', f);
for (i = 0; i < len; ++i)
putwc(*sw++, f);
while (len < field_width--)
putwc(L' ', f);
result = stringw(f, sw, -1, field_width, precision, flags);
}
if (result < 0)
return -1;
done += result;
continue;
case L'S':
if (qualifier == L'l' || qualifier == L'w') {
/* print unicode string */
sw = va_arg(args, wchar_t *);
if (sw == NULL)
sw = L"<NULL>";
len = wcslen (sw);
if ((unsigned int)len > (unsigned int)precision)
len = precision;
if (!(flags & LEFT))
while (len < field_width--)
putwc(L' ', f);
for (i = 0; i < len; ++i)
putwc(*sw++, f);
while (len < field_width--)
putwc(L' ', f);
result = stringw(f, sw, -1, field_width, precision, flags);
} else {
/* print ascii string */
s = va_arg(args, char *);
if (s == NULL)
s = "<NULL>";
len = strlen (s);
if ((unsigned int)len > (unsigned int)precision)
len = precision;
if (!(flags & LEFT))
while (len < field_width--)
putwc(L' ', f);
for (i = 0; i < len; ++i)
putwc((wchar_t)(*s++), f);
while (len < field_width--)
putwc(L' ', f);
}
if (result < 0)
return -1;
done += result;
continue;
#if 0
case L'Z': /* finished */
if (qualifier == L'w') {
/* print counted unicode string */
PUNICODE_STRING pus = va_arg(args, PUNICODE_STRING);
if ((pus == NULL) || (pus->Buffer)) {
sw = L"<NULL>";
while ((*sw) != 0)
putwc(*sw++, f);
sw = NULL;
len = -1;
} else {
for (i = 0; pus->Buffer[i] && i < pus->Length; i++)
putwc(pus->Buffer[i], f);
sw = pus->Buffer;
}
result = stringw(f, sw, len, field_width, precision, flags);
} else {
/* print counted ascii string */
PANSI_STRING pus = va_arg(args, PANSI_STRING);
if ((pus == NULL) || (pus->Buffer)) {
sw = L"<NULL>";
while ((*sw) != 0)
putwc(*sw++, f);
s = NULL;
len = -1;
} else {
for (i = 0; pus->Buffer[i] && i < pus->Length; i++)
putwc((wchar_t)pus->Buffer[i], f);
s = pus->Buffer;
len = pus->Length;
}
result = string(f, s, len, field_width, precision, flags);
}
if (result < 0)
return -1;
done += result;
continue;
#endif
case L'e': /* finished */
case L'E':
@ -733,7 +895,9 @@ int __vfwprintf(FILE *f, const wchar_t *fmt, va_list args)
sw = L"Nan";
len = 3;
while ( len > 0 ) {
putwc(*sw++,f);
if (putwc(*sw++,f) == WEOF)
return -1;
done++;
len --;
}
}
@ -741,7 +905,9 @@ int __vfwprintf(FILE *f, const wchar_t *fmt, va_list args)
sw = L"-Inf";
len = 4;
while ( len > 0 ) {
putwc(*sw++,f);
if (putwc(*sw++,f) == WEOF)
return -1;
done++;
len --;
}
}
@ -749,13 +915,18 @@ int __vfwprintf(FILE *f, const wchar_t *fmt, va_list args)
sw = L"+Inf";
len = 4;
while ( len > 0 ) {
putwc(*sw++,f);
if (putwc(*sw++,f) == WEOF)
return -1;
done++;
len --;
}
} else {
if ( precision == -1 )
precision = 6;
numberfl(f,_ldouble,*fmt,field_width,precision,flags);
result = numberfl(f,_ldouble,*fmt,field_width,precision,flags);
if (result < 0)
return -1;
done += result;
}
} else {
_double = (double)va_arg(args, double);
@ -764,27 +935,36 @@ int __vfwprintf(FILE *f, const wchar_t *fmt, va_list args)
sw = L"Nan";
len = 3;
while ( len > 0 ) {
putwc(*sw++,f);
if (putwc(*sw++,f) == WEOF)
return -1;
done++;
len --;
}
} else if ( _isinf(_double) < 0 ) {
sw = L"-Inf";
len = 4;
while ( len > 0 ) {
putwc(*sw++,f);
if (putwc(*sw++,f) == WEOF)
return -1;
done++;
len --;
}
} else if ( _isinf(_double) > 0 ) {
sw = L"+Inf";
len = 4;
while ( len > 0 ) {
putwc(*sw++,f);
if (putwc(*sw++,f) == WEOF)
return -1;
done++;
len --;
}
} else {
if ( precision == -1 )
precision = 6;
numberf(f,_double,*fmt,field_width,precision,flags);
result = numberf(f,_double,*fmt,field_width,precision,flags);
if (result < 0)
return -1;
done += result;
}
}
continue;
@ -794,9 +974,12 @@ int __vfwprintf(FILE *f, const wchar_t *fmt, va_list args)
field_width = 2*sizeof(void *);
flags |= ZEROPAD;
}
number(f,
(unsigned long) va_arg(args, void *), 16,
field_width, precision, flags);
result = number(f,
(unsigned long) va_arg(args, void *), 16,
field_width, precision, flags);
if (result < 0)
return -1;
done += result;
continue;
case L'n':
@ -832,9 +1015,17 @@ int __vfwprintf(FILE *f, const wchar_t *fmt, va_list args)
default:
if (*fmt != L'%')
putwc(L'%', f);
{
if (putwc(L'%', f) == WEOF)
return -1;
done++;
}
if (*fmt)
putwc(*fmt, f);
{
if (putwc(*fmt, f) == WEOF)
return -1;
done++;
}
else
--fmt;
continue;
@ -854,10 +1045,13 @@ int __vfwprintf(FILE *f, const wchar_t *fmt, va_list args)
num = va_arg(args, int);
else
num = va_arg(args, unsigned int);
number(f, num, base, field_width, precision, flags);
result = number(f, num, base, field_width, precision, flags);
if (result < 0)
return -1;
done += result;
}
//putwc(L'\0',f);
return 0;
return done;
}
/* EOF */