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
245 if ( exp_sign
== L
'e' || exp_sign
== L
'E' ) {
246 frac
= modf(exponent
,&e
);
249 else if ( frac
< -0.5 )
252 result
= numberf(f
,__n
/pow(10.0L,e
),L
'f',size
-4, precision
, type
);
256 if (putwc( exp_sign
,f
) == WEOF
)
265 result
= number(f
,ie
, 10,2, 2,type
);
272 if ( exp_sign
== 'f' ) {
278 c
= (type
& ZEROPAD
) ? L
'0' : L
' ';
285 } else if (type
& PLUS
) {
288 } else if (type
& SPACE
) {
294 frac
= modf(__n
,&intr
);
296 // # flags forces a . and prevents trucation of trailing zero's
298 if ( precision
> 0 ) {
299 //frac = modfl(__n,&intr);
303 frac
= modf(frac
, &p
);
304 buf
[i
] = (int)p
+ L
'0';
315 if ( precision
>= 1 || type
& SPECIAL
) {
326 while ( intr
> 0.0 ) {
333 buf
[i
++] = (int)p
+ L
'0';
339 while ( j
< i
&& ro
== 1 ) {
340 if ( buf
[j
] >= L
'0' && buf
[j
] <= L
'8' ) {
344 else if ( buf
[j
] == L
'9' ) {
355 if (!(type
&(ZEROPAD
+LEFT
)))
358 if (putwc(L
' ',f
) == WEOF
)
364 if (putwc( sign
,f
) == WEOF
)
369 if (!(type
&(ZEROPAD
+LEFT
)))
372 if (putwc(L
' ',f
) == WEOF
)
376 if (type
& SPECIAL
) {
382 if (putwc(c
,f
) == WEOF
)
388 if ( type
& ZEROTRUNC
&& ((type
& SPECIAL
) != SPECIAL
) ) {
390 while ( j
< i
&& ( *tmp
== L
'0' || *tmp
== L
'.' )) {
396 // while (i < precision--)
400 if (putwc(tmp
[i
],f
) == WEOF
)
406 if (putwc(L
' ', f
) == WEOF
)
416 static int string(FILE *f
, const char* s
, int len
, int field_width
, int precision
, int flags
)
429 while ((unsigned int)len
< (unsigned int)precision
&& s
[len
])
434 if ((unsigned int)len
> (unsigned int)precision
)
439 while (len
< field_width
--)
441 if (putwc(L
' ', f
) == WEOF
)
445 for (i
= 0; i
< len
; ++i
)
447 if (putwc(*s
++, f
) == WEOF
)
451 while (len
< field_width
--)
453 if (putwc(L
' ', f
) == WEOF
)
460 static int stringw(FILE *f
, const wchar_t* sw
, int len
, int field_width
, int precision
, int flags
)
473 while ((unsigned int)len
< (unsigned int)precision
&& sw
[len
])
478 if ((unsigned int)len
> (unsigned int)precision
)
483 while (len
< field_width
--)
485 if (putwc(L
' ', f
) == WEOF
)
489 for (i
= 0; i
< len
; ++i
)
491 if (putwc(*sw
++, f
) == WEOF
)
495 while (len
< field_width
--)
497 if (putwc(L
' ', f
) == WEOF
)
504 int __vfwprintf(FILE *f
, const wchar_t *fmt
, va_list args
)
512 int result
, done
= 0;
514 int flags
; /* flags to number() */
516 int field_width
; /* width of output field */
517 int precision
; /* min. # of digits for integers; max
518 number of chars for from string */
519 int qualifier
= 0; /* 'h', 'l', 'L' or 'I64' for integer fields */
521 for (; *fmt
; ++fmt
) {
523 if (putwc(*fmt
,f
) == WEOF
)
532 ++fmt
; /* this also skips first '%' */
534 case L
'-': flags
|= LEFT
; goto repeat
;
535 case L
'+': flags
|= PLUS
; goto repeat
;
536 case L
' ': flags
|= SPACE
; goto repeat
;
537 case L
'#': flags
|= SPECIAL
; goto repeat
;
538 case L
'0': flags
|= ZEROPAD
; goto repeat
;
541 /* get field width */
544 field_width
= skip_wtoi(&fmt
);
545 else if (*fmt
== L
'*') {
547 /* it's the next argument */
548 field_width
= va_arg(args
, int);
549 if (field_width
< 0) {
550 field_width
= -field_width
;
555 /* get the precision */
560 precision
= skip_wtoi(&fmt
);
561 else if (*fmt
== L
'*') {
563 /* it's the next argument */
564 precision
= va_arg(args
, int);
570 /* get the conversion qualifier */
572 // %Z can be just stand alone or as size_t qualifier
588 } else if (*fmt
== L
'h' || *fmt
== L
'l' || *fmt
== L
'L' || *fmt
== L
'w') {
591 } else if (*fmt
== L
'I' && *(fmt
+1) == L
'6' && *(fmt
+2) == L
'4') {
596 // go fine with ll instead of L
597 if ( *fmt
== L
'l' ) {
606 case L
'c': /* finished */
608 while (--field_width
> 0)
610 if (putwc(L
' ', f
) == WEOF
)
614 if (qualifier
== L
'h')
616 if (putwc((wchar_t) va_arg(args
, int), f
) == WEOF
)
621 if (putwc((wchar_t) va_arg(args
, int), f
) == WEOF
)
625 while (--field_width
> 0)
627 if (putwc(L
' ', f
) == WEOF
)
633 case L
'C': /* finished */
635 while (--field_width
> 0)
637 if (putwc(L
' ', f
) == WEOF
)
641 if (qualifier
== L
'l' || qualifier
== L
'w')
643 if (putwc((unsigned char) va_arg(args
, int), f
) == WEOF
)
648 if (putwc((unsigned char) va_arg(args
, int), f
) == WEOF
)
652 while (--field_width
> 0)
654 if (putwc(L
' ', f
) == WEOF
)
660 case L
's': /* finished */
661 if (qualifier
== L
'h') {
662 /* print ascii string */
663 s
= va_arg(args
, char *);
664 result
= string(f
, s
, -1, field_width
, precision
, flags
);
666 /* print unicode string */
667 sw
= va_arg(args
, wchar_t *);
668 result
= stringw(f
, sw
, -1, field_width
, precision
, flags
);
676 if (qualifier
== L
'l' || qualifier
== L
'w') {
677 /* print unicode string */
678 sw
= va_arg(args
, wchar_t *);
679 result
= stringw(f
, sw
, -1, field_width
, precision
, flags
);
681 /* print ascii string */
682 s
= va_arg(args
, char *);
683 result
= string(f
, s
, -1, field_width
, precision
, flags
);
690 case L
'Z': /* finished */
691 if (qualifier
== L
'w') {
692 /* print counted unicode string */
693 PUNICODE_STRING pus
= va_arg(args
, PUNICODE_STRING
);
694 if ((pus
== NULL
) || (pus
->Buffer
)) {
700 result
= stringw(f
, sw
, len
, field_width
, precision
, flags
);
702 /* print counted ascii string */
703 PANSI_STRING pus
= va_arg(args
, PANSI_STRING
);
704 if ((pus
== NULL
) || (pus
->Buffer
)) {
711 result
= string(f
, s
, len
, field_width
, precision
, flags
);
718 case L
'e': /* finished */
723 _double
= (double)va_arg(args
, double);
725 if ( _isnan(_double
) ) {
729 if (putwc(*sw
++,f
) == WEOF
)
734 } else if ( _isinf(_double
) < 0 ) {
738 if (putwc(*sw
++,f
) == WEOF
)
743 } else if ( _isinf(_double
) > 0 ) {
747 if (putwc(*sw
++,f
) == WEOF
)
753 if ( precision
== -1 )
755 result
= numberf(f
,_double
,*fmt
,field_width
,precision
,flags
);
763 if (field_width
== -1) {
764 field_width
= 2*sizeof(void *);
768 (unsigned long) va_arg(args
, void *), 16,
769 field_width
, precision
, flags
);
776 if (qualifier
== L
'l') {
777 long * ip
= va_arg(args
, long *);
780 int * ip
= va_arg(args
, int *);
785 /* integer number formats - set up the flags and "break" */
809 if (putwc(L
'%', f
) == WEOF
)
815 if (putwc(*fmt
, f
) == WEOF
)
824 if (qualifier
== L
'I')
825 num
= va_arg(args
, ULONGLONG
);
826 else if (qualifier
== L
'l') {
828 num
= va_arg(args
, long);
830 num
= va_arg(args
, unsigned long);
832 else if (qualifier
== L
'h') {
834 num
= va_arg(args
, int);
836 num
= va_arg(args
, unsigned int);
838 else if (flags
& SIGN
)
839 num
= va_arg(args
, int);
841 num
= va_arg(args
, unsigned int);
842 result
= number(f
, num
, base
, field_width
, precision
, flags
);