1 /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
8 #include <msvcrt/stdarg.h> // robd
9 #include <msvcrt/crttypes.h> // robd
11 #include <msvcrt/stdio.h>
12 #include <msvcrt/malloc.h>
13 #include <msvcrt/internal/file.h>
16 int _isnanl(double x
);
17 int _isinfl(double x
);
23 __vfwprintf(FILE *fp
, const wchar_t *fmt0
, va_list argp
);
30 vfwprintf(FILE *f
, const wchar_t *fmt
, va_list ap
)
33 wchar_t localbuf
[BUFSIZ
];
36 __fileno_lock(fileno(f
));
38 if (f
->_flag
& _IONBF
) {
40 f
->_ptr
= f
->_base
= (char *)localbuf
;
42 len
= __vfwprintf(f
,fmt
,ap
);
49 len
= __vfwprintf(f
,fmt
,ap
);
51 __fileno_unlock(fileno(f
));
53 return (ferror(f
) ? EOF
: len
);
59 * linux/lib/vsprintf.c
61 * Copyright (C) 1991, 1992 Linus Torvalds
64 /* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */
66 * Wirzenius wrote this portably, Torvalds fucked it up :-)
70 * Appropiated for the reactos kernel, March 1998 -- David Welch
73 #include <msvcrt/stdarg.h>
75 #include <msvcrt/ctype.h>
76 #include <msvcrt/string.h>
77 #include <msvcrt/stdio.h>
78 #include <msvcrt/string.h>
79 #include <msvcrt/math.h>
80 #include <msvcrt/internal/ieee.h>
83 #define ZEROPAD 1 /* pad with zero */
84 #define SIGN 2 /* unsigned/signed long */
85 #define PLUS 4 /* show plus */
86 #define SPACE 8 /* space if plus */
87 #define LEFT 16 /* left justified */
88 #define SPECIAL 32 /* 0x */
89 #define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */
90 #define ZEROTRUNC 128 /* truncate zero 's */
93 static int skip_wtoi(const wchar_t **s
)
98 i
= i
*10 + *((*s
)++) - L
'0';
103 static int do_div(LONGLONG
*n
,int base
)
105 int __res
= ((ULONGLONG
) *n
) % (unsigned) base
;
106 *n
= ((ULONGLONG
) *n
) / (unsigned) base
;
111 static int number(FILE * f
, LONGLONG num
, int base
, int size
, int precision
,int type
)
113 wchar_t c
,sign
,tmp
[66];
114 const wchar_t *digits
=L
"0123456789abcdefghijklmnopqrstuvwxyz";
118 digits
= L
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
121 if (base
< 2 || base
> 36)
123 c
= (type
& ZEROPAD
) ? L
'0' : L
' ';
130 } else if (type
& PLUS
) {
133 } else if (type
& SPACE
) {
138 if (type
& SPECIAL
) {
147 else while (num
!= 0)
148 tmp
[i
++] = digits
[do_div(&num
,base
)];
152 if (!(type
&(ZEROPAD
+LEFT
)))
155 if (putwc(L
' ',f
) == WEOF
)
162 if (putwc(sign
,f
) == WEOF
)
166 if (type
& SPECIAL
) {
168 if (putwc(L
'0',f
) == WEOF
)
173 if (putwc(L
'0', f
) == WEOF
)
176 if (putwc(digits
[33],f
) == WEOF
)
184 if (putwc(c
,f
) == WEOF
)
188 while (i
< precision
--)
190 if (putwc(L
'0', f
) == WEOF
)
196 if (putwc(tmp
[i
],f
) == WEOF
)
202 if (putwc(L
' ', f
) == WEOF
)
210 static int numberf(FILE * f
, double __n
, wchar_t exp_sign
, int size
, int precision
, int type
)
212 double exponent
= 0.0;
227 int result
, done
= 0;
237 if ( exp_sign
== L
'g' || exp_sign
== L
'G' || exp_sign
== L
'e' || exp_sign
== L
'E' ) {
238 ie
= ((unsigned int)n
.n
->exponent
- (unsigned int)0x3ff);
239 exponent
= ie
/3.321928;
242 if ( exp_sign
== L
'g' || exp_sign
== L
'G' ) {
244 if ( exponent
< -4 || fabs(exponent
) >= precision
)
245 exp_sign
-= 2; // g -> e and G -> E
248 if ( exp_sign
== L
'e' || exp_sign
== L
'E' ) {
249 frac
= modf(exponent
,&e
);
252 else if ( frac
< -0.5 )
255 result
= numberf(f
,__n
/pow(10.0L,e
),L
'f',size
-4, precision
, type
);
259 if (putwc( exp_sign
,f
) == WEOF
)
268 result
= number(f
,ie
, 10,2, 2,type
);
275 if ( exp_sign
== 'f' ) {
281 c
= (type
& ZEROPAD
) ? L
'0' : L
' ';
288 } else if (type
& PLUS
) {
291 } else if (type
& SPACE
) {
297 frac
= modf(__n
,&intr
);
299 // # flags forces a . and prevents trucation of trailing zero's
301 if ( precision
> 0 ) {
302 //frac = modfl(__n,&intr);
306 frac
= modf(frac
, &p
);
307 buf
[i
] = (int)p
+ L
'0';
318 if ( precision
>= 1 || type
& SPECIAL
) {
329 while ( intr
> 0.0 ) {
336 buf
[i
++] = (int)p
+ L
'0';
342 while ( j
< i
&& ro
== 1 ) {
343 if ( buf
[j
] >= L
'0' && buf
[j
] <= L
'8' ) {
347 else if ( buf
[j
] == L
'9' ) {
358 if (!(type
&(ZEROPAD
+LEFT
)))
361 if (putwc(L
' ',f
) == WEOF
)
367 if (putwc( sign
,f
) == WEOF
)
372 if (!(type
&(ZEROPAD
+LEFT
)))
375 if (putwc(L
' ',f
) == WEOF
)
379 if (type
& SPECIAL
) {
385 if (putwc(c
,f
) == WEOF
)
391 if ( type
& ZEROTRUNC
&& ((type
& SPECIAL
) != SPECIAL
) ) {
393 while ( j
< i
&& ( *tmp
== L
'0' || *tmp
== L
'.' )) {
399 // while (i < precision--)
403 if (putwc(tmp
[i
],f
) == WEOF
)
409 if (putwc(L
' ', f
) == WEOF
)
419 static int string(FILE *f
, const char* s
, int len
, int field_width
, int precision
, int flags
)
432 while ((unsigned int)len
< (unsigned int)precision
&& s
[len
])
437 if ((unsigned int)len
> (unsigned int)precision
)
442 while (len
< field_width
--)
444 if (putwc(L
' ', f
) == WEOF
)
448 for (i
= 0; i
< len
; ++i
)
450 if (putwc(*s
++, f
) == WEOF
)
454 while (len
< field_width
--)
456 if (putwc(L
' ', f
) == WEOF
)
463 static int stringw(FILE *f
, const wchar_t* sw
, int len
, int field_width
, int precision
, int flags
)
476 while ((unsigned int)len
< (unsigned int)precision
&& sw
[len
])
481 if ((unsigned int)len
> (unsigned int)precision
)
486 while (len
< field_width
--)
488 if (putwc(L
' ', f
) == WEOF
)
492 for (i
= 0; i
< len
; ++i
)
494 if (putwc(*sw
++, f
) == WEOF
)
498 while (len
< field_width
--)
500 if (putwc(L
' ', f
) == WEOF
)
507 int __vfwprintf(FILE *f
, const wchar_t *fmt
, va_list args
)
515 int result
, done
= 0;
517 int flags
; /* flags to number() */
519 int field_width
; /* width of output field */
520 int precision
; /* min. # of digits for integers; max
521 number of chars for from string */
522 int qualifier
= 0; /* 'h', 'l', 'L' or 'I64' for integer fields */
524 for (; *fmt
; ++fmt
) {
526 if (putwc(*fmt
,f
) == WEOF
)
535 ++fmt
; /* this also skips first '%' */
537 case L
'-': flags
|= LEFT
; goto repeat
;
538 case L
'+': flags
|= PLUS
; goto repeat
;
539 case L
' ': flags
|= SPACE
; goto repeat
;
540 case L
'#': flags
|= SPECIAL
; goto repeat
;
541 case L
'0': flags
|= ZEROPAD
; goto repeat
;
544 /* get field width */
547 field_width
= skip_wtoi(&fmt
);
548 else if (*fmt
== L
'*') {
550 /* it's the next argument */
551 field_width
= va_arg(args
, int);
552 if (field_width
< 0) {
553 field_width
= -field_width
;
558 /* get the precision */
563 precision
= skip_wtoi(&fmt
);
564 else if (*fmt
== L
'*') {
566 /* it's the next argument */
567 precision
= va_arg(args
, int);
573 /* get the conversion qualifier */
575 // %Z can be just stand alone or as size_t qualifier
591 } else if (*fmt
== L
'h' || *fmt
== L
'l' || *fmt
== L
'L' || *fmt
== L
'w') {
594 } else if (*fmt
== L
'I' && *(fmt
+1) == L
'6' && *(fmt
+2) == L
'4') {
599 // go fine with ll instead of L
600 if ( *fmt
== L
'l' ) {
609 case L
'c': /* finished */
611 while (--field_width
> 0)
613 if (putwc(L
' ', f
) == WEOF
)
617 if (qualifier
== L
'h')
619 if (putwc((wchar_t) va_arg(args
, int), f
) == WEOF
)
624 if (putwc((wchar_t) va_arg(args
, int), f
) == WEOF
)
628 while (--field_width
> 0)
630 if (putwc(L
' ', f
) == WEOF
)
636 case L
'C': /* finished */
638 while (--field_width
> 0)
640 if (putwc(L
' ', f
) == WEOF
)
644 if (qualifier
== L
'l' || qualifier
== L
'w')
646 if (putwc((unsigned char) va_arg(args
, int), f
) == WEOF
)
651 if (putwc((unsigned char) va_arg(args
, int), f
) == WEOF
)
655 while (--field_width
> 0)
657 if (putwc(L
' ', f
) == WEOF
)
663 case L
's': /* finished */
664 if (qualifier
== L
'h') {
665 /* print ascii string */
666 s
= va_arg(args
, char *);
667 result
= string(f
, s
, -1, field_width
, precision
, flags
);
669 /* print unicode string */
670 sw
= va_arg(args
, wchar_t *);
671 result
= stringw(f
, sw
, -1, field_width
, precision
, flags
);
679 if (qualifier
== L
'l' || qualifier
== L
'w') {
680 /* print unicode string */
681 sw
= va_arg(args
, wchar_t *);
682 result
= stringw(f
, sw
, -1, field_width
, precision
, flags
);
684 /* print ascii string */
685 s
= va_arg(args
, char *);
686 result
= string(f
, s
, -1, field_width
, precision
, flags
);
693 case L
'Z': /* finished */
694 if (qualifier
== L
'w') {
695 /* print counted unicode string */
696 PUNICODE_STRING pus
= va_arg(args
, PUNICODE_STRING
);
697 if ((pus
== NULL
) || (pus
->Buffer
)) {
703 result
= stringw(f
, sw
, len
, field_width
, precision
, flags
);
705 /* print counted ascii string */
706 PANSI_STRING pus
= va_arg(args
, PANSI_STRING
);
707 if ((pus
== NULL
) || (pus
->Buffer
)) {
714 result
= string(f
, s
, len
, field_width
, precision
, flags
);
721 case L
'e': /* finished */
726 _double
= (double)va_arg(args
, double);
728 if ( _isnan(_double
) ) {
732 if (putwc(*sw
++,f
) == WEOF
)
737 } else if ( _isinf(_double
) < 0 ) {
741 if (putwc(*sw
++,f
) == WEOF
)
746 } else if ( _isinf(_double
) > 0 ) {
750 if (putwc(*sw
++,f
) == WEOF
)
756 if ( precision
== -1 )
758 result
= numberf(f
,_double
,*fmt
,field_width
,precision
,flags
);
766 if (field_width
== -1) {
767 field_width
= 2*sizeof(void *);
771 (unsigned long) va_arg(args
, void *), 16,
772 field_width
, precision
, flags
);
779 if (qualifier
== L
'l') {
780 long * ip
= va_arg(args
, long *);
783 int * ip
= va_arg(args
, int *);
788 /* integer number formats - set up the flags and "break" */
812 if (putwc(L
'%', f
) == WEOF
)
818 if (putwc(*fmt
, f
) == WEOF
)
827 if (qualifier
== L
'I')
828 num
= va_arg(args
, ULONGLONG
);
829 else if (qualifier
== L
'l') {
831 num
= va_arg(args
, long);
833 num
= va_arg(args
, unsigned long);
835 else if (qualifier
== L
'h') {
837 num
= va_arg(args
, int);
839 num
= va_arg(args
, unsigned int);
841 else if (flags
& SIGN
)
842 num
= va_arg(args
, int);
844 num
= va_arg(args
, unsigned int);
845 result
= number(f
, num
, base
, field_width
, precision
, flags
);