1 /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
6 __vfwprintf(FILE *fp
, const wchar_t *fmt0
, va_list argp
);
13 vfwprintf(FILE *f
, const wchar_t *fmt
, va_list ap
)
16 wchar_t localbuf
[BUFSIZ
];
19 __fileno_lock(_fileno(f
));
21 if (f
->_flag
& _IONBF
) {
23 f
->_ptr
= f
->_base
= (char *)localbuf
;
25 len
= __vfwprintf(f
,fmt
,ap
);
32 len
= __vfwprintf(f
,fmt
,ap
);
34 __fileno_unlock(_fileno(f
));
36 return (ferror(f
) ? EOF
: len
);
42 * linux/lib/vsprintf.c
44 * Copyright (C) 1991, 1992 Linus Torvalds
47 /* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */
49 * Wirzenius wrote this portably, Torvalds fucked it up :-)
53 * Appropiated for the reactos kernel, March 1998 -- David Welch
57 #include <internal/ieee.h>
59 #define ZEROPAD 1 /* pad with zero */
60 #define SIGN 2 /* unsigned/signed long */
61 #define PLUS 4 /* show plus */
62 #define SPACE 8 /* space if plus */
63 #define LEFT 16 /* left justified */
64 #define SPECIAL 32 /* 0x */
65 #define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */
66 #define ZEROTRUNC 128 /* truncate zero 's */
69 static int skip_wtoi(const wchar_t **s
)
74 i
= i
*10 + *((*s
)++) - L
'0';
79 static int do_div(LONGLONG
*n
,int base
)
81 int __res
= ((ULONGLONG
) *n
) % (unsigned) base
;
82 *n
= ((ULONGLONG
) *n
) / (unsigned) base
;
87 static int number(FILE * f
, LONGLONG num
, int base
, int size
, int precision
,int type
)
89 wchar_t c
,sign
,tmp
[66];
90 const wchar_t *digits
=L
"0123456789abcdefghijklmnopqrstuvwxyz";
94 digits
= L
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
97 if (base
< 2 || base
> 36)
99 c
= (type
& ZEROPAD
) ? L
'0' : L
' ';
106 } else if (type
& PLUS
) {
109 } else if (type
& SPACE
) {
114 if (type
& SPECIAL
) {
123 else while (num
!= 0)
124 tmp
[i
++] = digits
[do_div(&num
,base
)];
128 if (!(type
&(ZEROPAD
+LEFT
)))
131 if (putwc(L
' ',f
) == WEOF
)
138 if (putwc(sign
,f
) == WEOF
)
142 if (type
& SPECIAL
) {
144 if (putwc(L
'0',f
) == WEOF
)
149 if (putwc(L
'0', f
) == WEOF
)
152 if (putwc(digits
[33],f
) == WEOF
)
160 if (putwc(c
,f
) == WEOF
)
164 while (i
< precision
--)
166 if (putwc(L
'0', f
) == WEOF
)
172 if (putwc(tmp
[i
],f
) == WEOF
)
178 if (putwc(L
' ', f
) == WEOF
)
186 static int numberf(FILE * f
, double __n
, wchar_t exp_sign
, int size
, int precision
, int type
)
188 double exponent
= 0.0;
203 int result
, done
= 0;
213 if ( exp_sign
== L
'g' || exp_sign
== L
'G' || exp_sign
== L
'e' || exp_sign
== L
'E' ) {
214 ie
= ((unsigned int)n
.n
->exponent
- (unsigned int)0x3ff);
215 exponent
= ie
/3.321928;
218 if ( exp_sign
== L
'g' || exp_sign
== L
'G' ) {
220 if ( exponent
< -4 || fabs(exponent
) >= precision
)
221 exp_sign
-= 2; // g -> e and G -> E
226 if ( exp_sign
== L
'e' || exp_sign
== L
'E' ) {
227 frac
= modf(exponent
,&e
);
230 else if ( frac
< -0.5 )
233 result
= numberf(f
,__n
/pow(10.0L,e
),L
'f',size
-4, precision
, type
);
237 if (putwc( exp_sign
,f
) == WEOF
)
246 result
= number(f
,ie
, 10,2, 2,type
);
253 if ( exp_sign
== 'f' ) {
259 c
= (type
& ZEROPAD
) ? L
'0' : L
' ';
266 } else if (type
& PLUS
) {
269 } else if (type
& SPACE
) {
275 frac
= modf(__n
,&intr
);
277 // # flags forces a . and prevents trucation of trailing zero's
279 if ( precision
> 0 ) {
280 //frac = modfl(__n,&intr);
284 frac
= modf(frac
, &p
);
285 buf
[i
] = (int)p
+ L
'0';
296 if ( precision
>= 1 || type
& SPECIAL
) {
307 while ( intr
> 0.0 ) {
314 buf
[i
++] = (int)p
+ L
'0';
320 while ( j
< i
&& ro
== 1 ) {
321 if ( buf
[j
] >= L
'0' && buf
[j
] <= L
'8' ) {
325 else if ( buf
[j
] == L
'9' ) {
336 if (!(type
&(ZEROPAD
+LEFT
)))
339 if (putwc(L
' ',f
) == WEOF
)
345 if (putwc( sign
,f
) == WEOF
)
350 if (!(type
&(ZEROPAD
+LEFT
)))
353 if (putwc(L
' ',f
) == WEOF
)
357 if (type
& SPECIAL
) {
363 if (putwc(c
,f
) == WEOF
)
369 if ( type
& ZEROTRUNC
&& ((type
& SPECIAL
) != SPECIAL
) ) {
371 while ( j
< i
&& *tmp
== L
'0' ) {
375 if ( j
< i
&& *tmp
== L
'.' ) {
381 // while (i < precision--)
385 if (putwc(tmp
[i
],f
) == WEOF
)
391 if (putwc(L
' ', f
) == WEOF
)
401 static int string(FILE *f
, const char* s
, int len
, int field_width
, int precision
, int flags
)
414 while ((unsigned int)len
< (unsigned int)precision
&& s
[len
])
419 if ((unsigned int)len
> (unsigned int)precision
)
424 while (len
< field_width
--)
426 if (putwc(L
' ', f
) == WEOF
)
430 for (i
= 0; i
< len
; ++i
)
432 if (putwc(*s
++, f
) == WEOF
)
436 while (len
< field_width
--)
438 if (putwc(L
' ', f
) == WEOF
)
445 static int stringw(FILE *f
, const wchar_t* sw
, int len
, int field_width
, int precision
, int flags
)
458 while ((unsigned int)len
< (unsigned int)precision
&& sw
[len
])
463 if ((unsigned int)len
> (unsigned int)precision
)
468 while (len
< field_width
--)
470 if (putwc(L
' ', f
) == WEOF
)
474 for (i
= 0; i
< len
; ++i
)
476 if (putwc(*sw
++, f
) == WEOF
)
480 while (len
< field_width
--)
482 if (putwc(L
' ', f
) == WEOF
)
489 int __vfwprintf(FILE *f
, const wchar_t *fmt
, va_list args
)
497 int result
, done
= 0;
499 int flags
; /* flags to number() */
501 int field_width
; /* width of output field */
502 int precision
; /* min. # of digits for integers; max
503 number of chars for from string */
504 int qualifier
= 0; /* 'h', 'l', 'L' or 'I64' for integer fields */
506 for (; *fmt
; ++fmt
) {
508 if (putwc(*fmt
,f
) == WEOF
)
517 ++fmt
; /* this also skips first '%' */
519 case L
'-': flags
|= LEFT
; goto repeat
;
520 case L
'+': flags
|= PLUS
; goto repeat
;
521 case L
' ': flags
|= SPACE
; goto repeat
;
522 case L
'#': flags
|= SPECIAL
; goto repeat
;
523 case L
'0': flags
|= ZEROPAD
; goto repeat
;
526 /* get field width */
529 field_width
= skip_wtoi(&fmt
);
530 else if (*fmt
== L
'*') {
532 /* it's the next argument */
533 field_width
= va_arg(args
, int);
534 if (field_width
< 0) {
535 field_width
= -field_width
;
540 /* get the precision */
545 precision
= skip_wtoi(&fmt
);
546 else if (*fmt
== L
'*') {
548 /* it's the next argument */
549 precision
= va_arg(args
, int);
555 /* get the conversion qualifier */
557 // %Z can be just stand alone or as size_t qualifier
573 } else if (*fmt
== L
'h' || *fmt
== L
'l' || *fmt
== L
'L' || *fmt
== L
'w') {
576 } else if (*fmt
== L
'I' && *(fmt
+1) == L
'6' && *(fmt
+2) == L
'4') {
581 // go fine with ll instead of L
582 if ( *fmt
== L
'l' ) {
591 case L
'c': /* finished */
593 while (--field_width
> 0)
595 if (putwc(L
' ', f
) == WEOF
)
599 if (qualifier
== L
'h')
601 if (putwc((wchar_t) va_arg(args
, int), f
) == WEOF
)
606 if (putwc((wchar_t) va_arg(args
, int), f
) == WEOF
)
610 while (--field_width
> 0)
612 if (putwc(L
' ', f
) == WEOF
)
618 case L
'C': /* finished */
620 while (--field_width
> 0)
622 if (putwc(L
' ', f
) == WEOF
)
626 if (qualifier
== L
'l' || qualifier
== L
'w')
628 if (putwc((unsigned char) va_arg(args
, int), f
) == WEOF
)
633 if (putwc((unsigned char) va_arg(args
, int), f
) == WEOF
)
637 while (--field_width
> 0)
639 if (putwc(L
' ', f
) == WEOF
)
645 case L
's': /* finished */
646 if (qualifier
== L
'h') {
647 /* print ascii string */
648 s
= va_arg(args
, char *);
649 result
= string(f
, s
, -1, field_width
, precision
, flags
);
651 /* print unicode string */
652 sw
= va_arg(args
, wchar_t *);
653 result
= stringw(f
, sw
, -1, field_width
, precision
, flags
);
661 if (qualifier
== L
'l' || qualifier
== L
'w') {
662 /* print unicode string */
663 sw
= va_arg(args
, wchar_t *);
664 result
= stringw(f
, sw
, -1, field_width
, precision
, flags
);
666 /* print ascii string */
667 s
= va_arg(args
, char *);
668 result
= string(f
, s
, -1, field_width
, precision
, flags
);
675 case L
'Z': /* finished */
676 if (qualifier
== L
'w') {
677 /* print counted unicode string */
678 PUNICODE_STRING pus
= va_arg(args
, PUNICODE_STRING
);
679 if ((pus
== NULL
) || (pus
->Buffer
)) {
685 result
= stringw(f
, sw
, len
, field_width
, precision
, flags
);
687 /* print counted ascii string */
688 PANSI_STRING pus
= va_arg(args
, PANSI_STRING
);
689 if ((pus
== NULL
) || (pus
->Buffer
)) {
696 result
= string(f
, s
, len
, field_width
, precision
, flags
);
703 case L
'e': /* finished */
708 _double
= (double)va_arg(args
, double);
710 if ( _isnan(_double
) ) {
714 if (putwc(*sw
++,f
) == WEOF
)
719 } else if ( _isinf(_double
) < 0 ) {
723 if (putwc(*sw
++,f
) == WEOF
)
728 } else if ( _isinf(_double
) > 0 ) {
732 if (putwc(*sw
++,f
) == WEOF
)
738 if ( precision
== -1 )
740 result
= numberf(f
,_double
,*fmt
,field_width
,precision
,flags
);
748 if (field_width
== -1) {
749 field_width
= 2*sizeof(void *);
753 (unsigned long) va_arg(args
, void *), 16,
754 field_width
, precision
, flags
);
761 if (qualifier
== L
'l') {
762 long * ip
= va_arg(args
, long *);
765 int * ip
= va_arg(args
, int *);
770 /* integer number formats - set up the flags and "break" */
794 if (putwc(L
'%', f
) == WEOF
)
800 if (putwc(*fmt
, f
) == WEOF
)
809 if (qualifier
== L
'I')
810 num
= va_arg(args
, ULONGLONG
);
811 else if (qualifier
== L
'l') {
813 num
= va_arg(args
, long);
815 num
= va_arg(args
, unsigned long);
817 else if (qualifier
== L
'h') {
819 num
= va_arg(args
, int);
821 num
= va_arg(args
, unsigned int);
823 else if (flags
& SIGN
)
824 num
= va_arg(args
, int);
826 num
= va_arg(args
, unsigned int);
827 result
= number(f
, num
, base
, field_width
, precision
, flags
);