1 /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
3 #include <msvcrt/stdio.h>
4 #include <msvcrt/malloc.h>
5 #include <msvcrt/internal/file.h>
14 int __vfprintf(FILE*, const char*, va_list);
17 int vfprintf(FILE* f
, const char* fmt
, va_list ap
)
20 char localbuf
[BUFSIZ
];
23 __fileno_lock(fileno(f
));
25 if (f
->_flag
& _IONBF
) {
27 f
->_ptr
= f
->_base
= localbuf
;
29 len
= __vfprintf(f
, fmt
, ap
);
36 len
= __vfprintf(f
,fmt
, ap
);
39 __fileno_unlock(fileno(f
));
41 return (ferror(f
) ? EOF
: len
);
46 * linux/lib/vsprintf.c
48 * Copyright (C) 1991, 1992 Linus Torvalds
51 /* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */
53 * Wirzenius wrote this portably, Torvalds fucked it up :-)
57 * Appropiated for the reactos kernel, March 1998 -- David Welch
60 #include <msvcrt/stdarg.h>
62 #include <msvcrt/ctype.h>
63 #include <msvcrt/string.h>
64 #include <msvcrt/stdio.h>
65 #include <msvcrt/string.h>
66 #include <msvcrt/math.h>
67 #include <msvcrt/internal/ieee.h>
70 #define ZEROPAD 1 /* pad with zero */
71 #define SIGN 2 /* unsigned/signed long */
72 #define PLUS 4 /* show plus */
73 #define SPACE 8 /* space if plus */
74 #define LEFT 16 /* left justified */
75 #define SPECIAL 32 /* 0x */
76 #define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */
77 #define ZEROTRUNC 128 /* truncate zero 's */
80 static int skip_atoi(const char **s
)
85 i
= i
*10 + *((*s
)++) - '0';
90 static int do_div(LONGLONG
*n
,int base
)
92 int __res
= ((ULONGLONG
) *n
) % (unsigned) base
;
93 *n
= ((ULONGLONG
) *n
) / (unsigned) base
;
98 static int number(FILE * f
, LONGLONG num
, int base
, int size
, int precision
,int type
)
101 const char *digits
="0123456789abcdefghijklmnopqrstuvwxyz";
105 digits
= "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
108 if (base
< 2 || base
> 36)
110 c
= (type
& ZEROPAD
) ? '0' : ' ';
117 } else if (type
& PLUS
) {
120 } else if (type
& SPACE
) {
125 if (type
& SPECIAL
) {
134 else while (num
!= 0)
135 tmp
[i
++] = digits
[do_div(&num
,base
)];
139 if (!(type
&(ZEROPAD
+LEFT
)))
142 if (putc(' ',f
) == EOF
)
148 if (putc(sign
,f
) == EOF
)
152 if (type
& SPECIAL
) {
154 if (putc('0',f
) == EOF
)
159 if (putc('0', f
) == EOF
)
162 if (putc(digits
[33],f
) == EOF
)
170 if (putc(c
,f
) == EOF
)
174 while (i
< precision
--)
176 if (putc('0', f
) == EOF
)
182 if (putc(tmp
[i
],f
) == EOF
)
188 if (putc(' ', f
) == EOF
)
196 static int numberf(FILE * f
, double __n
, char exp_sign
, int size
, int precision
, int type
)
198 double exponent
= 0.0;
213 int result
, done
= 0;
215 double_t
*n
= (double_t
*)&__n
;
217 if ( exp_sign
== 'g' || exp_sign
== 'G' || exp_sign
== 'e' || exp_sign
== 'E' ) {
218 ie
= ((unsigned int)n
->exponent
- (unsigned int)0x3ff);
219 exponent
= ie
/3.321928;
222 if ( exp_sign
== 'g' || exp_sign
== 'G' ) {
224 if ( exponent
< -4 || fabs(exponent
) >= precision
)
225 exp_sign
-= 2; // g -> e and G -> E
228 if ( exp_sign
== 'e' || exp_sign
== 'E' ) {
229 frac
= modf(exponent
,&e
);
232 else if ( frac
< -0.5 )
235 result
= numberf(f
,__n
/pow(10.0L,e
),'f',size
-4, precision
, type
);
239 if (putc( exp_sign
,f
) == EOF
)
248 result
= number(f
,ie
, 10,2, 2,type
);
255 if ( exp_sign
== 'f' ) {
261 c
= (type
& ZEROPAD
) ? '0' : ' ';
268 } else if (type
& PLUS
) {
271 } else if (type
& SPACE
) {
277 frac
= modf(__n
,&intr
);
279 // # flags forces a . and prevents trucation of trailing zero's
281 if ( precision
> 0 ) {
282 //frac = modfl(__n,&intr);
286 frac
= modf(frac
, &p
);
287 buf
[i
] = (int)p
+ '0';
298 if ( precision
>= 1 || type
& SPECIAL
) {
309 while ( intr
> 0.0 ) {
311 p
= modf(intr
, &intr
);
315 buf
[i
++] = (int)p
+ '0';
321 while ( j
< i
&& ro
== 1) {
322 if ( buf
[j
] >= '0' && buf
[j
] <= '8' ) {
326 else if ( buf
[j
] == '9' ) {
337 if (!(type
&(ZEROPAD
+LEFT
)))
340 if (putc(' ',f
) == EOF
)
346 if (putc( sign
,f
) == EOF
)
351 if (!(type
&(ZEROPAD
+LEFT
)))
354 if (putc(' ',f
) == EOF
)
358 if (type
& SPECIAL
) {
364 if (putc(c
,f
) == EOF
)
370 if ( type
& ZEROTRUNC
&& ((type
& SPECIAL
) != SPECIAL
) ) {
372 while ( j
< i
&& ( *tmp
== '0' || *tmp
== '.' )) {
378 // while (i < precision--)
382 if (putc(tmp
[i
],f
) == EOF
)
388 if (putc(' ', f
) == EOF
)
397 static int numberfl(FILE * f
, long double __n
, char exp_sign
, int size
, int precision
, int type
)
399 long double exponent
= 0.0;
409 long double frac
, intr
;
415 int result
, done
= 0;
417 long_double_t
*n
= (long_double_t
*)&__n
;
419 if ( exp_sign
== 'g' || exp_sign
== 'G' || exp_sign
== 'e' || exp_sign
== 'E' ) {
420 ie
= ((unsigned int)n
->exponent
- (unsigned int)0x3fff);
421 exponent
= ie
/3.321928;
424 if ( exp_sign
== 'g' || exp_sign
== 'G' ) {
426 if ( exponent
< -4 || fabs(exponent
) >= precision
)
427 exp_sign
-= 2; // g -> e and G -> E
430 if ( exp_sign
== 'e' || exp_sign
== 'E' ) {
431 frac
= modfl(exponent
,&e
);
434 else if ( frac
< -0.5 )
437 result
= numberf(f
,__n
/powl(10.0L,e
),'f',size
-4, precision
, type
);
441 if (putc( exp_sign
,f
) == EOF
)
450 result
= number(f
,ie
, 10,2, 2,type
);
457 if ( exp_sign
== 'f' ) {
464 c
= (type
& ZEROPAD
) ? '0' : ' ';
471 } else if (type
& PLUS
) {
474 } else if (type
& SPACE
) {
480 frac
= modfl(__n
,&intr
);
482 // # flags forces a . and prevents trucation of trailing zero's
483 if ( precision
> 0 ) {
484 //frac = modfl(__n,&intr);
489 frac
= modfl((long double)frac
, &p
);
490 buf
[i
] = (int)p
+ '0';
501 if ( precision
>= 1 || type
& SPECIAL
) {
512 while ( intr
> 0.0 ) {
514 p
= modfl(intr
, &intr
);
518 buf
[i
++] = (int)p
+ '0';
524 while ( j
< i
&& ro
== 1) {
525 if ( buf
[j
] >= '0' && buf
[j
] <= '8' ) {
529 else if ( buf
[j
] == '9' ) {
540 if (!(type
&(ZEROPAD
+LEFT
)))
543 if (putc(' ',f
) == EOF
)
549 if (putc(sign
,f
) == EOF
)
554 if (!(type
&(ZEROPAD
+LEFT
)))
557 if (putc(' ',f
) == EOF
)
561 if (type
& SPECIAL
) {
567 if (putc(c
,f
) == EOF
)
572 if ( type
& ZEROTRUNC
&& ((type
& SPECIAL
) != SPECIAL
) ) {
574 while ( j
< i
&& ( *tmp
== '0' || *tmp
== '.' )) {
580 // while (i < precision--)
584 if ( putc(tmp
[i
],f
) == EOF
)
590 if (putc(' ', f
) == EOF
)
598 static int string(FILE *f
, const char* s
, int len
, int field_width
, int precision
, int flags
)
611 while (s
[len
] && (unsigned int)len
< (unsigned int)precision
)
616 if ((unsigned int)len
> (unsigned int)precision
)
621 while (len
< field_width
--)
623 if (putc(' ', f
) == EOF
)
627 for (i
= 0; i
< len
; ++i
)
629 if (putc(*s
++, f
) == EOF
)
633 while (len
< field_width
--)
635 if (putc(' ', f
) == EOF
)
642 static int stringw(FILE *f
, const wchar_t* sw
, int len
, int field_width
, int precision
, int flags
)
655 while (sw
[len
] && (unsigned int)len
< (unsigned int)precision
)
660 if ((unsigned int)len
> (unsigned int)precision
)
665 while (len
< field_width
--)
667 if (putc(' ', f
) == EOF
)
671 for (i
= 0; i
< len
; ++i
)
673 if (putc((unsigned char)(*sw
++), f
) == EOF
)
677 while (len
< field_width
--)
679 if (putc(' ', f
) == EOF
)
686 int __vfprintf(FILE *f
, const char *fmt
, va_list args
)
691 long double _ldouble
;
695 int result
, done
= 0;
697 int flags
; /* flags to number() */
699 int field_width
; /* width of output field */
700 int precision
; /* min. # of digits for integers; max
701 number of chars for from string */
702 int qualifier
= 0; /* 'h', 'l', 'L' or 'I64' for integer fields */
704 for (; *fmt
; ++fmt
) {
706 if (putc(*fmt
,f
) == EOF
)
715 ++fmt
; /* this also skips first '%' */
717 case '-': flags
|= LEFT
; goto repeat
;
718 case '+': flags
|= PLUS
; goto repeat
;
719 case ' ': flags
|= SPACE
; goto repeat
;
720 case '#': flags
|= SPECIAL
; goto repeat
;
721 case '0': flags
|= ZEROPAD
; goto repeat
;
724 /* get field width */
727 field_width
= skip_atoi(&fmt
);
728 else if (*fmt
== '*') {
730 /* it's the next argument */
731 field_width
= va_arg(args
, int);
732 if (field_width
< 0) {
733 field_width
= -field_width
;
738 /* get the precision */
743 precision
= skip_atoi(&fmt
);
744 else if (*fmt
== '*') {
746 /* it's the next argument */
747 precision
= va_arg(args
, int);
753 /* get the conversion qualifier */
755 // %Z can be just stand alone or as size_t qualifier
771 } else if (*fmt
== 'h' || *fmt
== 'l' || *fmt
== 'L' || *fmt
== 'w') {
774 } else if (*fmt
== 'I' && *(fmt
+1) == '6' && *(fmt
+2) == '4') {
779 // go fine with ll instead of L
791 while (--field_width
> 0)
793 if (putc(' ', f
) == EOF
)
797 if (qualifier
== 'l' || qualifier
== 'w')
799 if (putc((unsigned char)(wchar_t) va_arg(args
, int), f
) == EOF
)
805 if (putc((unsigned char) va_arg(args
, int), f
) == EOF
)
809 while (--field_width
> 0)
811 if (putc(' ', f
) == EOF
)
819 while (--field_width
> 0)
821 if (putc(' ', f
) == EOF
)
825 if (qualifier
== 'h')
827 if (putc((unsigned char) va_arg(args
, int), f
) == EOF
)
833 if (putc((unsigned char)(wchar_t) va_arg(args
, int), f
) == EOF
)
837 while (--field_width
> 0)
839 if (putc(' ', f
) == EOF
)
846 if (qualifier
== 'l' || qualifier
== 'w') {
847 /* print unicode string */
848 sw
= va_arg(args
, wchar_t *);
849 result
= stringw(f
, sw
, -1, field_width
, precision
, flags
);
851 /* print ascii string */
852 s
= va_arg(args
, char *);
853 result
= string(f
, s
, -1, field_width
, precision
, flags
);
861 if (qualifier
== 'h') {
862 /* print ascii string */
863 s
= va_arg(args
, char *);
864 result
= string(f
, s
, -1, field_width
, precision
, flags
);
866 /* print unicode string */
867 sw
= va_arg(args
, wchar_t *);
868 result
= stringw(f
, sw
, -1, field_width
, precision
, flags
);
876 if (qualifier
== 'w') {
877 /* print counted unicode string */
878 PUNICODE_STRING pus
= va_arg(args
, PUNICODE_STRING
);
879 if ((pus
== NULL
) || (pus
->Buffer
== NULL
)) {
884 len
= pus
->Length
/ sizeof(WCHAR
);
886 result
= stringw(f
, sw
, len
, field_width
, precision
, flags
);
888 /* print counted ascii string */
889 PANSI_STRING pas
= va_arg(args
, PANSI_STRING
);
890 if ((pas
== NULL
) || (pas
->Buffer
== NULL
)) {
897 result
= string(f
, s
, -1, field_width
, precision
, flags
);
909 if (qualifier
== 'l' || qualifier
== 'L' ) {
910 _ldouble
= va_arg(args
, long double);
912 if ( _isnanl(_ldouble
) ) {
916 if (putc(*s
++,f
) == EOF
)
922 else if ( _isinfl(_ldouble
) < 0 ) {
926 if (putc(*s
++,f
) == EOF
)
932 else if ( _isinfl(_ldouble
) > 0 ) {
936 if (putc(*s
++,f
) == EOF
)
942 if ( precision
== -1 )
944 result
= numberfl(f
,_ldouble
,*fmt
,field_width
,precision
,flags
);
950 _double
= (double)va_arg(args
, double);
952 if ( _isnan(_double
) ) {
956 if (putc(*s
++,f
) == EOF
)
961 } else if ( _isinf(_double
) < 0 ) {
965 if (putc(*s
++,f
) == EOF
)
970 } else if ( _isinf(_double
) > 0 ) {
974 if (putc(*s
++,f
) == EOF
)
980 if ( precision
== -1 )
982 result
= numberf(f
,_double
,*fmt
,field_width
,precision
,flags
);
991 if (field_width
== -1) {
992 field_width
= 2*sizeof(void *);
996 (unsigned long) va_arg(args
, void *), 16,
997 field_width
, precision
, flags
);
1004 if (qualifier
== 'l') {
1005 long * ip
= va_arg(args
, long *);
1008 int * ip
= va_arg(args
, int *);
1013 /* integer number formats - set up the flags and "break" */
1037 if (putc('%', f
) == EOF
)
1043 if (putc(*fmt
, f
) == EOF
)
1052 if (qualifier
== 'I')
1053 num
= va_arg(args
, ULONGLONG
);
1054 else if (qualifier
== 'l')
1055 num
= va_arg(args
, unsigned long);
1056 else if (qualifier
== 'h') {
1058 num
= va_arg(args
, int);
1060 num
= va_arg(args
, unsigned int);
1062 else if (flags
& SIGN
)
1063 num
= va_arg(args
, int);
1065 num
= va_arg(args
, unsigned int);
1066 result
= number(f
, num
, base
, field_width
, precision
, flags
);