1 /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
4 extern int __mb_cur_max
;
5 int __vfprintf(FILE*, const char*, va_list);
10 int vfprintf(FILE* f
, const char* fmt
, va_list ap
)
13 char localbuf
[BUFSIZ
];
16 __fileno_lock(_fileno(f
));
18 if (f
->_flag
& _IONBF
) {
20 f
->_ptr
= f
->_base
= localbuf
;
21 f
->_bufsiz
= f
->_cnt
= BUFSIZ
;
22 len
= __vfprintf(f
, fmt
, ap
);
29 len
= __vfprintf(f
,fmt
, ap
);
32 __fileno_unlock(_fileno(f
));
34 return (ferror(f
) ? EOF
: len
);
39 * linux/lib/vsprintf.c
41 * Copyright (C) 1991, 1992 Linus Torvalds
44 /* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */
46 * Wirzenius wrote this portably, Torvalds fucked it up :-)
50 * Appropiated for the reactos kernel, March 1998 -- David Welch
58 #include <internal/ieee.h>
61 #define ZEROPAD 1 /* pad with zero */
62 #define SIGN 2 /* unsigned/signed long */
63 #define PLUS 4 /* show plus */
64 #define SPACE 8 /* space if plus */
65 #define LEFT 16 /* left justified */
66 #define SPECIAL 32 /* 0x */
67 #define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */
68 #define ZEROTRUNC 128 /* truncate zero 's */
71 static int skip_atoi(const char **s
)
76 i
= i
*10 + *((*s
)++) - '0';
81 static int do_div(LONGLONG
*n
,int base
)
83 int __res
= ((ULONGLONG
) *n
) % (unsigned) base
;
84 *n
= ((ULONGLONG
) *n
) / (unsigned) base
;
89 static int number(FILE * f
, LONGLONG num
, int base
, int size
, int precision
,int type
)
92 const char *digits
="0123456789abcdefghijklmnopqrstuvwxyz";
96 digits
= "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
99 if (base
< 2 || base
> 36)
101 c
= (type
& ZEROPAD
) ? '0' : ' ';
108 } else if (type
& PLUS
) {
111 } else if (type
& SPACE
) {
116 if (type
& SPECIAL
) {
125 else while (num
!= 0)
126 tmp
[i
++] = digits
[do_div(&num
,base
)];
130 if (!(type
&(ZEROPAD
+LEFT
)))
133 if (putc(' ',f
) == EOF
)
139 if (putc(sign
,f
) == EOF
)
143 if (type
& SPECIAL
) {
145 if (putc('0',f
) == EOF
)
150 if (putc('0', f
) == EOF
)
153 if (putc(digits
[33],f
) == EOF
)
161 if (putc(c
,f
) == EOF
)
165 while (i
< precision
--)
167 if (putc('0', f
) == EOF
)
173 if (putc(tmp
[i
],f
) == EOF
)
179 if (putc(' ', f
) == EOF
)
187 static int numberf(FILE * f
, double __n
, char exp_sign
, int size
, int precision
, int type
)
189 double exponent
= 0.0;
204 int result
, done
= 0;
214 if ( exp_sign
== L
'g' || exp_sign
== L
'G' || exp_sign
== L
'e' || exp_sign
== L
'E' )
216 if ( 0 == n
.n
->mantissal
&& 0 == n
.n
->mantissah
&& 0 == n
.n
->exponent
)
222 ie
= ((unsigned int)n
.n
->exponent
- (unsigned int)0x3ff);
225 exponent
= ie
/3.321928;
229 if ( exp_sign
== 'g' || exp_sign
== 'G' ) {
231 if ( exponent
< -4 || fabs(exponent
) >= precision
)
232 exp_sign
-= 2; // g -> e and G -> E
237 if ( exp_sign
== 'e' || exp_sign
== 'E' ) {
238 frac
= modf(exponent
,&e
);
241 else if ( frac
< -0.5 )
244 result
= numberf(f
,__n
/pow(10.0L,e
),'f',size
-4, precision
, type
);
248 if (putc( exp_sign
,f
) == EOF
)
257 result
= number(f
,ie
, 10,2, 2,type
);
264 if ( exp_sign
== 'f' ) {
270 c
= (type
& ZEROPAD
) ? '0' : ' ';
277 } else if (type
& PLUS
) {
280 } else if (type
& SPACE
) {
286 frac
= modf(__n
,&intr
);
288 // # flags forces a . and prevents trucation of trailing zero's
290 if ( precision
> 0 ) {
291 //frac = modfl(__n,&intr);
295 frac
= modf(frac
, &p
);
296 buf
[i
] = (int)p
+ '0';
307 if ( precision
>= 1 || type
& SPECIAL
) {
318 while ( intr
> 0.0 ) {
325 buf
[i
++] = (int)p
+ '0';
331 while ( j
< i
&& ro
== 1) {
332 if ( buf
[j
] >= '0' && buf
[j
] <= '8' ) {
336 else if ( buf
[j
] == '9' ) {
347 if (!(type
&(ZEROPAD
+LEFT
)))
350 if (putc(' ',f
) == EOF
)
356 if (putc( sign
,f
) == EOF
)
361 if (!(type
&(ZEROPAD
+LEFT
)))
364 if (putc(' ',f
) == EOF
)
368 if (type
& SPECIAL
) {
374 if (putc(c
,f
) == EOF
)
381 if ( type
& ZEROTRUNC
&& ((type
& SPECIAL
) != SPECIAL
) ) {
383 while ( j
< i
&& *tmp
== L
'0' ) {
387 if ( j
< i
&& *tmp
== L
'.' ) {
395 // while (i < precision--)
399 if (putc(tmp
[i
],f
) == EOF
)
405 if (putc(' ', f
) == EOF
)
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 (putc(' ', f
) == EOF
)
445 for (i
= 0; i
< len
; ++i
)
447 if (putc(*s
++, f
) == EOF
)
451 while (len
< field_width
--)
453 if (putc(' ', f
) == EOF
)
460 static int stringw(FILE *f
, const wchar_t* sw
, int len
, int field_width
, int precision
, int flags
)
474 while ((unsigned int)len
< (unsigned int)precision
&& sw
[len
])
479 if ((unsigned int)len
> (unsigned int)precision
)
484 while (len
< field_width
--)
486 if (putc(' ', f
) == EOF
)
490 mb
= malloc(MB_CUR_MAX
* sizeof(char));
493 for (i
= 0; i
< len
; ++i
)
496 mbcount
= wctomb(mb
, *sw
++);
501 for (j
= 0; j
< mbcount
; j
++)
503 if (putc(mb
[j
], f
) == EOF
)
511 while (len
< field_width
--)
513 if (putc(' ', f
) == EOF
)
524 int __vfprintf(FILE *f
, const char *fmt
, va_list args
)
532 int result
, done
= 0;
534 int flags
; /* flags to number() */
536 int field_width
; /* width of output field */
537 int precision
; /* min. # of digits for integers; max
538 number of chars for from string */
539 int qualifier
= 0; /* 'h', 'l', 'L' or 'I64' for integer fields */
541 for (; *fmt
; ++fmt
) {
543 if (putc(*fmt
,f
) == EOF
)
552 ++fmt
; /* this also skips first '%' */
554 case '-': flags
|= LEFT
; goto repeat
;
555 case '+': flags
|= PLUS
; goto repeat
;
556 case ' ': flags
|= SPACE
; goto repeat
;
557 case '#': flags
|= SPECIAL
; goto repeat
;
558 case '0': flags
|= ZEROPAD
; goto repeat
;
561 /* get field width */
564 field_width
= skip_atoi(&fmt
);
565 else if (*fmt
== '*') {
567 /* it's the next argument */
568 field_width
= va_arg(args
, int);
569 if (field_width
< 0) {
570 field_width
= -field_width
;
575 /* get the precision */
580 precision
= skip_atoi(&fmt
);
581 else if (*fmt
== '*') {
583 /* it's the next argument */
584 precision
= va_arg(args
, int);
590 /* get the conversion qualifier */
592 // %Z can be just stand alone or as size_t qualifier
608 } else if (*fmt
== 'h' || *fmt
== 'l' || *fmt
== 'L' || *fmt
== 'w') {
611 } else if (*fmt
== 'I' && *(fmt
+1) == '6' && *(fmt
+2) == '4') {
616 // go fine with ll instead of L
628 while (--field_width
> 0)
630 if (putc(' ', f
) == EOF
)
634 if (qualifier
== 'l' || qualifier
== 'w')
636 if (putc((unsigned char)(wchar_t) va_arg(args
, int), f
) == EOF
)
642 if (putc((unsigned char) va_arg(args
, int), f
) == EOF
)
646 while (--field_width
> 0)
648 if (putc(' ', f
) == EOF
)
656 while (--field_width
> 0)
658 if (putc(' ', f
) == EOF
)
662 if (qualifier
== 'h')
664 if (putc((unsigned char) va_arg(args
, int), f
) == EOF
)
670 if (putc((unsigned char)(wchar_t) va_arg(args
, int), f
) == EOF
)
674 while (--field_width
> 0)
676 if (putc(' ', f
) == EOF
)
683 if (qualifier
== 'l' || qualifier
== 'w') {
684 /* print unicode string */
685 sw
= va_arg(args
, wchar_t *);
686 result
= stringw(f
, sw
, -1, field_width
, precision
, flags
);
688 /* print ascii string */
689 s
= va_arg(args
, char *);
690 result
= string(f
, s
, -1, field_width
, precision
, flags
);
698 if (qualifier
== 'h') {
699 /* print ascii string */
700 s
= va_arg(args
, char *);
701 result
= string(f
, s
, -1, field_width
, precision
, flags
);
703 /* print unicode string */
704 sw
= va_arg(args
, wchar_t *);
705 result
= stringw(f
, sw
, -1, field_width
, precision
, flags
);
713 if (qualifier
== 'w') {
714 /* print counted unicode string */
715 PUNICODE_STRING pus
= va_arg(args
, PUNICODE_STRING
);
716 if ((pus
== NULL
) || (pus
->Buffer
== NULL
)) {
721 len
= pus
->Length
/ sizeof(WCHAR
);
723 result
= stringw(f
, sw
, len
, field_width
, precision
, flags
);
725 /* print counted ascii string */
726 PANSI_STRING pas
= va_arg(args
, PANSI_STRING
);
727 if ((pas
== NULL
) || (pas
->Buffer
== NULL
)) {
734 result
= string(f
, s
, -1, field_width
, precision
, flags
);
746 _double
= (double)va_arg(args
, double);
748 if ( _isnan(_double
) ) {
752 if (putc(*s
++,f
) == EOF
)
757 } else if ( _isinf(_double
) < 0 ) {
761 if (putc(*s
++,f
) == EOF
)
766 } else if ( _isinf(_double
) > 0 ) {
770 if (putc(*s
++,f
) == EOF
)
776 if ( precision
== -1 )
778 result
= numberf(f
,_double
,*fmt
,field_width
,precision
,flags
);
786 if (field_width
== -1) {
787 field_width
= 2*sizeof(void *);
791 (unsigned long) va_arg(args
, void *), 16,
792 field_width
, precision
, flags
);
799 if (qualifier
== 'l') {
800 long * ip
= va_arg(args
, long *);
803 int * ip
= va_arg(args
, int *);
808 /* integer number formats - set up the flags and "break" */
832 if (putc('%', f
) == EOF
)
838 if (putc(*fmt
, f
) == EOF
)
847 if (qualifier
== 'I')
848 num
= va_arg(args
, ULONGLONG
);
849 else if (qualifier
== 'l') {
851 num
= va_arg(args
, long);
853 num
= va_arg(args
, unsigned long);
855 else if (qualifier
== 'h') {
857 num
= va_arg(args
, int);
859 num
= va_arg(args
, unsigned int);
861 else if (flags
& SIGN
)
862 num
= va_arg(args
, int);
864 num
= va_arg(args
, unsigned int);
865 result
= number(f
, num
, base
, field_width
, precision
, flags
);