1 /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
2 #include <msvcrt/stdio.h>
3 #include <msvcrt/stdarg.h>
4 #include <msvcrt/malloc.h>
5 #include <msvcrt/internal/file.h>
15 __vfprintf (FILE *fp
, const char *fmt0
, va_list argp
);
18 vfprintf(FILE *f
, const char *fmt
, va_list ap
)
21 char localbuf
[BUFSIZ
];
23 if (f
->_flag
& _IONBF
)
26 f
->_ptr
= f
->_base
= localbuf
;
28 len
= __vfprintf(f
,fmt
, ap
);
36 len
= __vfprintf(f
,fmt
, ap
);
37 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
58 #include <msvcrt/ctype.h>
59 #include <msvcrt/string.h>
60 #include <msvcrt/stdio.h>
61 #include <msvcrt/string.h>
62 #include <msvcrt/math.h>
63 #include <msvcrt/internal/ieee.h>
66 #define ZEROPAD 1 /* pad with zero */
67 #define SIGN 2 /* unsigned/signed long */
68 #define PLUS 4 /* show plus */
69 #define SPACE 8 /* space if plus */
70 #define LEFT 16 /* left justified */
71 #define SPECIAL 32 /* 0x */
72 #define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */
73 #define ZEROTRUNC 128 /* truncate zero 's */
76 static int skip_atoi(const char **s
)
81 i
= i
*10 + *((*s
)++) - '0';
86 static int do_div(long long *n
,int base
)
88 int __res
= ((unsigned long long) *n
) % (unsigned) base
;
89 *n
= ((unsigned long long) *n
) / (unsigned) base
;
94 static void number(FILE * f
, long long num
, int base
, int size
, int precision
,int type
)
97 const char *digits
="0123456789abcdefghijklmnopqrstuvwxyz";
101 digits
= "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
104 if (base
< 2 || base
> 36)
106 c
= (type
& ZEROPAD
) ? '0' : ' ';
113 } else if (type
& PLUS
) {
116 } else if (type
& SPACE
) {
121 if (type
& SPECIAL
) {
130 else while (num
!= 0)
131 tmp
[i
++] = digits
[do_div(&num
,base
)];
135 if (!(type
&(ZEROPAD
+LEFT
)))
140 if (type
& SPECIAL
) {
152 while (i
< precision
--)
162 static void numberf(FILE * f
, double __n
, char exp_sign
, int size
, int precision
, int type
)
164 double exponent
= 0.0;
180 double_t
*n
= (double_t
*)&__n
;
182 if ( exp_sign
== 'g' || exp_sign
== 'G' || exp_sign
== 'e' || exp_sign
== 'E' ) {
183 ie
= ((unsigned int)n
->exponent
- (unsigned int)0x3ff);
184 exponent
= ie
/3.321928;
187 if ( exp_sign
== 'g' || exp_sign
== 'G' ) {
189 if ( exponent
< -4 || fabs(exponent
) >= precision
)
190 exp_sign
-= 2; // g -> e and G -> E
193 if ( exp_sign
== 'e' || exp_sign
== 'E' ) {
194 frac
= modf(exponent
,&e
);
197 else if ( frac
< -0.5 )
200 numberf(f
,__n
/pow(10.0L,e
),'f',size
-4, precision
, type
);
208 number(f
,ie
, 10,2, 2,type
);
212 if ( exp_sign
== 'f' ) {
218 c
= (type
& ZEROPAD
) ? '0' : ' ';
225 } else if (type
& PLUS
) {
228 } else if (type
& SPACE
) {
234 frac
= modf(__n
,&intr
);
236 // # flags forces a . and prevents trucation of trailing zero's
238 if ( precision
> 0 ) {
239 //frac = modfl(__n,&intr);
243 frac
= modf(frac
, &p
);
244 buf
[i
] = (int)p
+ '0';
255 if ( precision
>= 1 || type
& SPECIAL
) {
266 while ( intr
> 0.0 ) {
268 p
= modf(intr
, &intr
);
272 buf
[i
++] = (int)p
+ '0';
278 while ( j
< i
&& ro
== 1) {
279 if ( buf
[j
] >= '0' && buf
[j
] <= '8' ) {
283 else if ( buf
[j
] == '9' ) {
294 if (!(type
&(ZEROPAD
+LEFT
)))
300 if (!(type
&(ZEROPAD
+LEFT
)))
303 if (type
& SPECIAL
) {
311 if ( type
& ZEROTRUNC
&& ((type
& SPECIAL
) != SPECIAL
) ) {
313 while ( j
< i
&& ( *tmp
== '0' || *tmp
== '.' )) {
319 // while (i < precision--)
329 static void numberfl(FILE * f
, long double __n
, char exp_sign
, int size
, int precision
, int type
)
331 long double exponent
= 0.0;
341 long double frac
, intr
;
347 long_double_t
*n
= (long_double_t
*)&__n
;
349 if ( exp_sign
== 'g' || exp_sign
== 'G' || exp_sign
== 'e' || exp_sign
== 'E' ) {
350 ie
= ((unsigned int)n
->exponent
- (unsigned int)0x3fff);
351 exponent
= ie
/3.321928;
354 if ( exp_sign
== 'g' || exp_sign
== 'G' ) {
356 if ( exponent
< -4 || fabs(exponent
) >= precision
)
357 exp_sign
-= 2; // g -> e and G -> E
360 if ( exp_sign
== 'e' || exp_sign
== 'E' ) {
361 frac
= modfl(exponent
,&e
);
364 else if ( frac
< -0.5 )
367 numberf(f
,__n
/powl(10.0L,e
),'f',size
-4, precision
, type
);
375 number(f
,ie
, 10,2, 2,type
);
379 if ( exp_sign
== 'f' ) {
386 c
= (type
& ZEROPAD
) ? '0' : ' ';
393 } else if (type
& PLUS
) {
396 } else if (type
& SPACE
) {
402 frac
= modfl(__n
,&intr
);
404 // # flags forces a . and prevents trucation of trailing zero's
405 if ( precision
> 0 ) {
406 //frac = modfl(__n,&intr);
411 frac
= modfl((long double)frac
, &p
);
412 buf
[i
] = (int)p
+ '0';
423 if ( precision
>= 1 || type
& SPECIAL
) {
434 while ( intr
> 0.0 ) {
436 p
= modfl(intr
, &intr
);
440 buf
[i
++] = (int)p
+ '0';
446 while ( j
< i
&& ro
== 1) {
447 if ( buf
[j
] >= '0' && buf
[j
] <= '8' ) {
451 else if ( buf
[j
] == '9' ) {
462 if (!(type
&(ZEROPAD
+LEFT
)))
468 if (!(type
&(ZEROPAD
+LEFT
)))
471 if (type
& SPECIAL
) {
479 if ( type
& ZEROTRUNC
&& ((type
& SPECIAL
) != SPECIAL
) ) {
481 while ( j
< i
&& ( *tmp
== '0' || *tmp
== '.' )) {
487 // while (i < precision--)
497 int __vfprintf(FILE *f
, const char *fmt
, va_list args
)
500 unsigned long long num
;
502 long double _ldouble
;
507 int flags
; /* flags to number() */
509 int field_width
; /* width of output field */
510 int precision
; /* min. # of digits for integers; max
511 number of chars for from string */
512 int qualifier
= 0; /* 'h', 'l', 'L' or 'I64' for integer fields */
514 for (; *fmt
; ++fmt
) {
523 ++fmt
; /* this also skips first '%' */
525 case '-': flags
|= LEFT
; goto repeat
;
526 case '+': flags
|= PLUS
; goto repeat
;
527 case ' ': flags
|= SPACE
; goto repeat
;
528 case '#': flags
|= SPECIAL
; goto repeat
;
529 case '0': flags
|= ZEROPAD
; goto repeat
;
532 /* get field width */
535 field_width
= skip_atoi(&fmt
);
536 else if (*fmt
== '*') {
538 /* it's the next argument */
539 field_width
= va_arg(args
, int);
540 if (field_width
< 0) {
541 field_width
= -field_width
;
546 /* get the precision */
551 precision
= skip_atoi(&fmt
);
552 else if (*fmt
== '*') {
554 /* it's the next argument */
555 precision
= va_arg(args
, int);
561 /* get the conversion qualifier */
562 // %Z can be just stand alone or as size_t qualifier
578 } else if (*fmt
== 'h' || *fmt
== 'l' || *fmt
== 'L' || *fmt
== 'w') {
581 } else if (*fmt
== 'I' && *(fmt
+1) == '6' && *(fmt
+2) == '4') {
586 // go fine with ll instead of L
598 while (--field_width
> 0)
600 if (qualifier
== 'l' || qualifier
== 'w')
601 putc((unsigned char)(wchar_t) va_arg(args
, int), f
);
603 putc((unsigned char) va_arg(args
, int), f
);
604 while (--field_width
> 0)
610 while (--field_width
> 0)
612 if (qualifier
== 'h')
613 putc((unsigned char) va_arg(args
, int), f
);
615 putc((unsigned char)(wchar_t) va_arg(args
, int), f
);
616 while (--field_width
> 0)
621 if (qualifier
== 'l' || qualifier
== 'w') {
622 /* print unicode string */
623 sw
= va_arg(args
, wchar_t *);
628 if ((unsigned int)len
> (unsigned int)precision
)
632 while (len
< field_width
--)
634 for (i
= 0; i
< len
; ++i
)
635 putc((unsigned char)(*sw
++), f
);
636 while (len
< field_width
--)
639 /* print ascii string */
640 s
= va_arg(args
, char *);
645 if ((unsigned int)len
> (unsigned int)precision
)
649 while (len
< field_width
--)
651 for (i
= 0; i
< len
; ++i
)
653 while (len
< field_width
--)
659 if (qualifier
== 'h') {
660 /* print ascii string */
661 s
= va_arg(args
, char *);
666 if ((unsigned int)len
> (unsigned int)precision
)
670 while (len
< field_width
--)
672 for (i
= 0; i
< len
; ++i
)
674 while (len
< field_width
--)
677 /* print unicode string */
678 sw
= va_arg(args
, wchar_t *);
683 if ((unsigned int)len
> (unsigned int)precision
)
687 while (len
< field_width
--)
689 for (i
= 0; i
< len
; ++i
)
690 putc((unsigned char)(*sw
++), f
);
691 while (len
< field_width
--)
697 if (qualifier
== 'w') {
698 /* print counted unicode string */
699 PUNICODE_STRING pus
= va_arg(args
, PUNICODE_STRING
);
700 if ((pus
== NULL
) || (pus
->Buffer
== NULL
)) {
705 for (i
= 0; pus
->Buffer
[i
] && i
< pus
->Length
/ sizeof(WCHAR
); i
++)
706 putc((unsigned char)(pus
->Buffer
[i
]), f
);
709 /* print counted ascii string */
710 PANSI_STRING pus
= va_arg(args
, PANSI_STRING
);
711 if ((pus
== NULL
) || (pus
->Buffer
== NULL
)) {
716 for (i
= 0; pus
->Buffer
[i
] && i
< pus
->Length
; i
++)
717 putc(pus
->Buffer
[i
], f
);
727 if (qualifier
== 'l' || qualifier
== 'L' ) {
728 _ldouble
= va_arg(args
, long double);
730 if ( _isnanl(_ldouble
) ) {
738 else if ( _isinfl(_ldouble
) < 0 ) {
746 else if ( _isinfl(_ldouble
) > 0 ) {
754 if ( precision
== -1 )
756 numberfl(f
,_ldouble
,*fmt
,field_width
,precision
,flags
);
759 _double
= (double)va_arg(args
, double);
761 if ( _isnan(_double
) ) {
768 } else if ( _isinf(_double
) < 0 ) {
775 } else if ( _isinf(_double
) > 0 ) {
783 if ( precision
== -1 )
785 numberf(f
,_double
,*fmt
,field_width
,precision
,flags
);
791 if (field_width
== -1) {
792 field_width
= 2*sizeof(void *);
796 (unsigned long) va_arg(args
, void *), 16,
797 field_width
, precision
, flags
);
801 if (qualifier
== 'l') {
802 long * ip
= va_arg(args
, long *);
805 int * ip
= va_arg(args
, int *);
810 /* integer number formats - set up the flags and "break" */
841 if (qualifier
== 'I')
842 num
= va_arg(args
, unsigned long long);
843 else if (qualifier
== 'l')
844 num
= va_arg(args
, unsigned long);
845 else if (qualifier
== 'h') {
847 num
= va_arg(args
, int);
849 num
= va_arg(args
, unsigned int);
851 else if (flags
& SIGN
)
852 num
= va_arg(args
, int);
854 num
= va_arg(args
, unsigned int);
855 number(f
, num
, base
, field_width
, precision
, flags
);