1 /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
8 #include <internal/file.h>
12 int _isnanl(double x
);
13 int _isinfl(double x
);
19 __vfwprintf(FILE *fp
, const wchar_t *fmt0
, va_list argp
);
26 vfwprintf(FILE *f
, const wchar_t *fmt
, va_list ap
)
29 wchar_t localbuf
[BUFSIZ
];
32 __fileno_lock(_fileno(f
));
34 if (f
->_flag
& _IONBF
) {
36 f
->_ptr
= f
->_base
= (char *)localbuf
;
38 len
= __vfwprintf(f
,fmt
,ap
);
45 len
= __vfwprintf(f
,fmt
,ap
);
47 __fileno_unlock(_fileno(f
));
49 return (ferror(f
) ? EOF
: len
);
55 * linux/lib/vsprintf.c
57 * Copyright (C) 1991, 1992 Linus Torvalds
60 /* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */
62 * Wirzenius wrote this portably, Torvalds fucked it up :-)
66 * Appropiated for the reactos kernel, March 1998 -- David Welch
75 #include <internal/ieee.h>
78 #define ZEROPAD 1 /* pad with zero */
79 #define SIGN 2 /* unsigned/signed long */
80 #define PLUS 4 /* show plus */
81 #define SPACE 8 /* space if plus */
82 #define LEFT 16 /* left justified */
83 #define SPECIAL 32 /* 0x */
84 #define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */
85 #define ZEROTRUNC 128 /* truncate zero 's */
88 static int skip_wtoi(const wchar_t **s
)
93 i
= i
*10 + *((*s
)++) - L
'0';
98 static int do_div(LONGLONG
*n
,int base
)
100 int __res
= ((ULONGLONG
) *n
) % (unsigned) base
;
101 *n
= ((ULONGLONG
) *n
) / (unsigned) base
;
106 static int number(FILE * f
, LONGLONG num
, int base
, int size
, int precision
,int type
)
108 wchar_t c
,sign
,tmp
[66];
109 const wchar_t *digits
=L
"0123456789abcdefghijklmnopqrstuvwxyz";
113 digits
= L
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
116 if (base
< 2 || base
> 36)
118 c
= (type
& ZEROPAD
) ? L
'0' : L
' ';
125 } else if (type
& PLUS
) {
128 } else if (type
& SPACE
) {
133 if (type
& SPECIAL
) {
142 else while (num
!= 0)
143 tmp
[i
++] = digits
[do_div(&num
,base
)];
147 if (!(type
&(ZEROPAD
+LEFT
)))
150 if (putwc(L
' ',f
) == WEOF
)
157 if (putwc(sign
,f
) == WEOF
)
161 if (type
& SPECIAL
) {
163 if (putwc(L
'0',f
) == WEOF
)
168 if (putwc(L
'0', f
) == WEOF
)
171 if (putwc(digits
[33],f
) == WEOF
)
179 if (putwc(c
,f
) == WEOF
)
183 while (i
< precision
--)
185 if (putwc(L
'0', f
) == WEOF
)
191 if (putwc(tmp
[i
],f
) == WEOF
)
197 if (putwc(L
' ', f
) == WEOF
)
205 static int numberf(FILE * f
, double __n
, wchar_t exp_sign
, int size
, int precision
, int type
)
207 double exponent
= 0.0;
222 int result
, done
= 0;
232 if ( exp_sign
== L
'g' || exp_sign
== L
'G' || exp_sign
== L
'e' || exp_sign
== L
'E' ) {
233 ie
= ((unsigned int)n
.n
->exponent
- (unsigned int)0x3ff);
234 exponent
= ie
/3.321928;
237 if ( exp_sign
== L
'g' || exp_sign
== L
'G' ) {
239 if ( exponent
< -4 || fabs(exponent
) >= precision
)
240 exp_sign
-= 2; // g -> e and G -> E
243 if ( exp_sign
== L
'e' || exp_sign
== L
'E' ) {
244 frac
= modf(exponent
,&e
);
247 else if ( frac
< -0.5 )
250 result
= numberf(f
,__n
/pow(10.0L,e
),L
'f',size
-4, precision
, type
);
254 if (putwc( exp_sign
,f
) == WEOF
)
263 result
= number(f
,ie
, 10,2, 2,type
);
270 if ( exp_sign
== 'f' ) {
276 c
= (type
& ZEROPAD
) ? L
'0' : L
' ';
283 } else if (type
& PLUS
) {
286 } else if (type
& SPACE
) {
292 frac
= modf(__n
,&intr
);
294 // # flags forces a . and prevents trucation of trailing zero's
296 if ( precision
> 0 ) {
297 //frac = modfl(__n,&intr);
301 frac
= modf(frac
, &p
);
302 buf
[i
] = (int)p
+ L
'0';
313 if ( precision
>= 1 || type
& SPECIAL
) {
324 while ( intr
> 0.0 ) {
331 buf
[i
++] = (int)p
+ L
'0';
337 while ( j
< i
&& ro
== 1 ) {
338 if ( buf
[j
] >= L
'0' && buf
[j
] <= L
'8' ) {
342 else if ( buf
[j
] == L
'9' ) {
353 if (!(type
&(ZEROPAD
+LEFT
)))
356 if (putwc(L
' ',f
) == WEOF
)
362 if (putwc( sign
,f
) == WEOF
)
367 if (!(type
&(ZEROPAD
+LEFT
)))
370 if (putwc(L
' ',f
) == WEOF
)
374 if (type
& SPECIAL
) {
380 if (putwc(c
,f
) == WEOF
)
386 if ( type
& ZEROTRUNC
&& ((type
& SPECIAL
) != SPECIAL
) ) {
388 while ( j
< i
&& ( *tmp
== L
'0' || *tmp
== L
'.' )) {
394 // while (i < precision--)
398 if (putwc(tmp
[i
],f
) == WEOF
)
404 if (putwc(L
' ', f
) == WEOF
)
414 static int string(FILE *f
, const char* s
, int len
, int field_width
, int precision
, int flags
)
427 while ((unsigned int)len
< (unsigned int)precision
&& s
[len
])
432 if ((unsigned int)len
> (unsigned int)precision
)
437 while (len
< field_width
--)
439 if (putwc(L
' ', f
) == WEOF
)
443 for (i
= 0; i
< len
; ++i
)
445 if (putwc(*s
++, f
) == WEOF
)
449 while (len
< field_width
--)
451 if (putwc(L
' ', f
) == WEOF
)
458 static int stringw(FILE *f
, const wchar_t* sw
, int len
, int field_width
, int precision
, int flags
)
471 while ((unsigned int)len
< (unsigned int)precision
&& sw
[len
])
476 if ((unsigned int)len
> (unsigned int)precision
)
481 while (len
< field_width
--)
483 if (putwc(L
' ', f
) == WEOF
)
487 for (i
= 0; i
< len
; ++i
)
489 if (putwc(*sw
++, f
) == WEOF
)
493 while (len
< field_width
--)
495 if (putwc(L
' ', f
) == WEOF
)
502 int __vfwprintf(FILE *f
, const wchar_t *fmt
, va_list args
)
510 int result
, done
= 0;
512 int flags
; /* flags to number() */
514 int field_width
; /* width of output field */
515 int precision
; /* min. # of digits for integers; max
516 number of chars for from string */
517 int qualifier
= 0; /* 'h', 'l', 'L' or 'I64' for integer fields */
519 for (; *fmt
; ++fmt
) {
521 if (putwc(*fmt
,f
) == WEOF
)
530 ++fmt
; /* this also skips first '%' */
532 case L
'-': flags
|= LEFT
; goto repeat
;
533 case L
'+': flags
|= PLUS
; goto repeat
;
534 case L
' ': flags
|= SPACE
; goto repeat
;
535 case L
'#': flags
|= SPECIAL
; goto repeat
;
536 case L
'0': flags
|= ZEROPAD
; goto repeat
;
539 /* get field width */
542 field_width
= skip_wtoi(&fmt
);
543 else if (*fmt
== L
'*') {
545 /* it's the next argument */
546 field_width
= va_arg(args
, int);
547 if (field_width
< 0) {
548 field_width
= -field_width
;
553 /* get the precision */
558 precision
= skip_wtoi(&fmt
);
559 else if (*fmt
== L
'*') {
561 /* it's the next argument */
562 precision
= va_arg(args
, int);
568 /* get the conversion qualifier */
570 // %Z can be just stand alone or as size_t qualifier
586 } else if (*fmt
== L
'h' || *fmt
== L
'l' || *fmt
== L
'L' || *fmt
== L
'w') {
589 } else if (*fmt
== L
'I' && *(fmt
+1) == L
'6' && *(fmt
+2) == L
'4') {
594 // go fine with ll instead of L
595 if ( *fmt
== L
'l' ) {
604 case L
'c': /* finished */
606 while (--field_width
> 0)
608 if (putwc(L
' ', f
) == WEOF
)
612 if (qualifier
== L
'h')
614 if (putwc((wchar_t) va_arg(args
, int), f
) == WEOF
)
619 if (putwc((wchar_t) va_arg(args
, int), f
) == WEOF
)
623 while (--field_width
> 0)
625 if (putwc(L
' ', f
) == WEOF
)
631 case L
'C': /* finished */
633 while (--field_width
> 0)
635 if (putwc(L
' ', f
) == WEOF
)
639 if (qualifier
== L
'l' || qualifier
== L
'w')
641 if (putwc((unsigned char) va_arg(args
, int), f
) == WEOF
)
646 if (putwc((unsigned char) va_arg(args
, int), f
) == WEOF
)
650 while (--field_width
> 0)
652 if (putwc(L
' ', f
) == WEOF
)
658 case L
's': /* finished */
659 if (qualifier
== L
'h') {
660 /* print ascii string */
661 s
= va_arg(args
, char *);
662 result
= string(f
, s
, -1, field_width
, precision
, flags
);
664 /* print unicode string */
665 sw
= va_arg(args
, wchar_t *);
666 result
= stringw(f
, sw
, -1, field_width
, precision
, flags
);
674 if (qualifier
== L
'l' || qualifier
== L
'w') {
675 /* print unicode string */
676 sw
= va_arg(args
, wchar_t *);
677 result
= stringw(f
, sw
, -1, field_width
, precision
, flags
);
679 /* print ascii string */
680 s
= va_arg(args
, char *);
681 result
= string(f
, s
, -1, field_width
, precision
, flags
);
688 case L
'Z': /* finished */
689 if (qualifier
== L
'w') {
690 /* print counted unicode string */
691 PUNICODE_STRING pus
= va_arg(args
, PUNICODE_STRING
);
692 if ((pus
== NULL
) || (pus
->Buffer
)) {
698 result
= stringw(f
, sw
, len
, field_width
, precision
, flags
);
700 /* print counted ascii string */
701 PANSI_STRING pus
= va_arg(args
, PANSI_STRING
);
702 if ((pus
== NULL
) || (pus
->Buffer
)) {
709 result
= string(f
, s
, len
, field_width
, precision
, flags
);
716 case L
'e': /* finished */
721 _double
= (double)va_arg(args
, double);
723 if ( _isnan(_double
) ) {
727 if (putwc(*sw
++,f
) == WEOF
)
732 } else if ( _isinf(_double
) < 0 ) {
736 if (putwc(*sw
++,f
) == WEOF
)
741 } else if ( _isinf(_double
) > 0 ) {
745 if (putwc(*sw
++,f
) == WEOF
)
751 if ( precision
== -1 )
753 result
= numberf(f
,_double
,*fmt
,field_width
,precision
,flags
);
761 if (field_width
== -1) {
762 field_width
= 2*sizeof(void *);
766 (unsigned long) va_arg(args
, void *), 16,
767 field_width
, precision
, flags
);
774 if (qualifier
== L
'l') {
775 long * ip
= va_arg(args
, long *);
778 int * ip
= va_arg(args
, int *);
783 /* integer number formats - set up the flags and "break" */
807 if (putwc(L
'%', f
) == WEOF
)
813 if (putwc(*fmt
, f
) == WEOF
)
822 if (qualifier
== L
'I')
823 num
= va_arg(args
, ULONGLONG
);
824 else if (qualifier
== L
'l') {
826 num
= va_arg(args
, long);
828 num
= va_arg(args
, unsigned long);
830 else if (qualifier
== L
'h') {
832 num
= va_arg(args
, int);
834 num
= va_arg(args
, unsigned int);
836 else if (flags
& SIGN
)
837 num
= va_arg(args
, int);
839 num
= va_arg(args
, unsigned int);
840 result
= number(f
, num
, base
, field_width
, precision
, flags
);