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 __vfwprintf(FILE *fp, const wchar_t *fmt0, va_list argp);
18 vfwprintf(FILE *f, const wchar_t *fmt, va_list ap)
21 wchar_t localbuf[BUFSIZ];
24 __fileno_lock(fileno(f));
26 if (f->_flag & _IONBF) {
28 f->_ptr = f->_base = (char *)localbuf;
30 len = __vfwprintf(f,fmt,ap);
37 len = __vfwprintf(f,fmt,ap);
39 __fileno_unlock(fileno(f));
41 return (ferror(f) ? EOF : len);
47 * linux/lib/vsprintf.c
49 * Copyright (C) 1991, 1992 Linus Torvalds
52 /* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */
54 * Wirzenius wrote this portably, Torvalds fucked it up :-)
58 * Appropiated for the reactos kernel, March 1998 -- David Welch
61 #include <msvcrt/stdarg.h>
63 #include <msvcrt/ctype.h>
64 #include <msvcrt/string.h>
65 #include <msvcrt/stdio.h>
66 #include <msvcrt/string.h>
67 #include <msvcrt/math.h>
68 #include <msvcrt/internal/ieee.h>
71 #define ZEROPAD 1 /* pad with zero */
72 #define SIGN 2 /* unsigned/signed long */
73 #define PLUS 4 /* show plus */
74 #define SPACE 8 /* space if plus */
75 #define LEFT 16 /* left justified */
76 #define SPECIAL 32 /* 0x */
77 #define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */
78 #define ZEROTRUNC 128 /* truncate zero 's */
81 static int skip_wtoi(const wchar_t **s)
86 i = i*10 + *((*s)++) - L'0';
91 static int do_div(long long *n,int base)
93 int __res = ((unsigned long long) *n) % (unsigned) base;
94 *n = ((unsigned long long) *n) / (unsigned) base;
99 static int number(FILE * f, long long num, int base, int size, int precision ,int type)
101 wchar_t c,sign,tmp[66];
102 const wchar_t *digits=L"0123456789abcdefghijklmnopqrstuvwxyz";
106 digits = L"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
109 if (base < 2 || base > 36)
111 c = (type & ZEROPAD) ? L'0' : L' ';
118 } else if (type & PLUS) {
121 } else if (type & SPACE) {
126 if (type & SPECIAL) {
135 else while (num != 0)
136 tmp[i++] = digits[do_div(&num,base)];
140 if (!(type&(ZEROPAD+LEFT)))
143 if (putwc(L' ',f) == WEOF)
150 if (putwc(sign,f) == WEOF)
154 if (type & SPECIAL) {
156 if (putwc(L'0',f) == WEOF)
161 if (putwc(L'0', f) == WEOF)
164 if (putwc(digits[33],f) == WEOF)
172 if (putwc(c,f) == WEOF)
176 while (i < precision--)
178 if (putwc(L'0', f) == WEOF)
184 if (putwc(tmp[i],f) == WEOF)
190 if (putwc(L' ', f) == WEOF)
198 static int numberf(FILE * f, double __n, wchar_t exp_sign, int size, int precision, int type)
200 double exponent = 0.0;
215 int result, done = 0;
217 double_t *n = (double_t *)&__n;
219 if ( exp_sign == L'g' || exp_sign == L'G' || exp_sign == L'e' || exp_sign == L'E' ) {
220 ie = ((unsigned int)n->exponent - (unsigned int)0x3ff);
221 exponent = ie/3.321928;
224 if ( exp_sign == L'g' || exp_sign == L'G' ) {
226 if ( exponent < -4 || fabs(exponent) >= precision )
227 exp_sign -= 2; // g -> e and G -> E
230 if ( exp_sign == L'e' || exp_sign == L'E' ) {
231 frac = modf(exponent,&e);
234 else if ( frac < -0.5 )
237 result = numberf(f,__n/pow(10.0L,e),L'f',size-4, precision, type);
241 if (putwc( exp_sign,f) == WEOF)
250 result = number(f,ie, 10,2, 2,type );
257 if ( exp_sign == 'f' ) {
263 c = (type & ZEROPAD) ? L'0' : L' ';
270 } else if (type & PLUS) {
273 } else if (type & SPACE) {
279 frac = modf(__n,&intr);
281 // # flags forces a . and prevents trucation of trailing zero's
283 if ( precision > 0 ) {
284 //frac = modfl(__n,&intr);
288 frac = modf(frac, &p);
289 buf[i] = (int)p + L'0';
300 if ( precision >= 1 || type & SPECIAL) {
311 while ( intr > 0.0 ) {
313 p = modf(intr, &intr);
317 buf[i++] = (int)p + L'0';
323 while ( j < i && ro == 1 ) {
324 if ( buf[j] >= L'0' && buf[j] <= L'8' ) {
328 else if ( buf[j] == L'9' ) {
339 if (!(type&(ZEROPAD+LEFT)))
342 if (putwc(L' ',f) == WEOF)
348 if (putwc( sign,f) == WEOF)
353 if (!(type&(ZEROPAD+LEFT)))
356 if (putwc(L' ',f) == WEOF)
360 if (type & SPECIAL) {
366 if (putwc(c,f) == WEOF)
372 if ( type & ZEROTRUNC && ((type & SPECIAL) != SPECIAL) ) {
374 while ( j < i && ( *tmp == L'0' || *tmp == L'.' )) {
380 // while (i < precision--)
384 if (putwc(tmp[i],f) == WEOF)
390 if (putwc(L' ', f) == WEOF)
399 static int numberfl(FILE * f, long double __n, wchar_t exp_sign, int size, int precision, int type)
401 long double exponent = 0.0;
411 long double frac, intr;
417 int result, done = 0;
419 long_double_t *n = (long_double_t *)&__n;
421 if ( exp_sign == L'g' || exp_sign == L'G' || exp_sign == L'e' || exp_sign == L'E' ) {
422 ie = ((unsigned int)n->exponent - (unsigned int)0x3fff);
423 exponent = ie/3.321928;
426 if ( exp_sign == L'g' || exp_sign == L'G' ) {
428 if ( exponent < -4 || fabs(exponent) >= precision )
429 exp_sign -= 2; // g -> e and G -> E
432 if ( exp_sign == L'e' || exp_sign == L'E' ) {
433 frac = modfl(exponent,&e);
436 else if ( frac < -0.5 )
439 result = numberf(f,__n/powl(10.0L,e),L'f',size-4, precision, type);
443 if (putwc( exp_sign,f) == WEOF)
452 result = number(f,ie, 10,2, 2,type );
459 if ( exp_sign == L'f' ) {
465 c = (type & ZEROPAD) ? L'0' : L' ';
472 } else if (type & PLUS) {
475 } else if (type & SPACE) {
481 frac = modfl(__n,&intr);
483 // # flags forces a . and prevents trucation of trailing zero's
484 if ( precision > 0 ) {
485 //frac = modfl(__n,&intr);
490 frac = modfl((long double)frac, &p);
491 buf[i] = (int)p + L'0';
502 if ( precision >= 1 || type & SPECIAL) {
513 while ( intr > 0.0 ) {
515 p = modfl(intr, &intr);
519 buf[i++] = (int)p + L'0';
525 while ( j < i && ro == 1) {
526 if ( buf[j] >= L'0' && buf[j] <= L'8' ) {
530 else if ( buf[j] == L'9' ) {
541 if (!(type&(ZEROPAD+LEFT)))
547 if (!(type&(ZEROPAD+LEFT)))
550 if (type & SPECIAL) {
558 if ( type & ZEROTRUNC && ((type & SPECIAL) != SPECIAL) ) {
560 while ( j < i && ( *tmp == L'0' || *tmp == L'.' )) {
566 // while (i < precision--)
570 if (putwc(tmp[i],f) == WEOF)
576 if (putwc(L' ', f) == WEOF)
584 static int string(FILE *f, const char* s, int len, int field_width, int precision, int flags)
597 while (s[len] && (unsigned int)len < (unsigned int)precision)
602 if ((unsigned int)len > (unsigned int)precision)
607 while (len < field_width--)
609 if (putwc(L' ', f) == WEOF)
613 for (i = 0; i < len; ++i)
615 if (putwc(*s++, f) == WEOF)
619 while (len < field_width--)
621 if (putwc(L' ', f) == WEOF)
628 static int stringw(FILE *f, const wchar_t* sw, int len, int field_width, int precision, int flags)
641 while (sw[len] && (unsigned int)len < (unsigned int)precision)
646 if ((unsigned int)len > (unsigned int)precision)
651 while (len < field_width--)
653 if (putwc(L' ', f) == WEOF)
657 for (i = 0; i < len; ++i)
659 if (putwc(*sw++, f) == WEOF)
663 while (len < field_width--)
665 if (putwc(L' ', f) == WEOF)
672 int __vfwprintf(FILE *f, const wchar_t *fmt, va_list args)
675 unsigned long long num;
677 long double _ldouble;
681 int result, done = 0;
683 int flags; /* flags to number() */
685 int field_width; /* width of output field */
686 int precision; /* min. # of digits for integers; max
687 number of chars for from string */
688 int qualifier = 0; /* 'h', 'l', 'L' or 'I64' for integer fields */
690 for (; *fmt ; ++fmt) {
692 if (putwc(*fmt,f) == WEOF)
701 ++fmt; /* this also skips first '%' */
703 case L'-': flags |= LEFT; goto repeat;
704 case L'+': flags |= PLUS; goto repeat;
705 case L' ': flags |= SPACE; goto repeat;
706 case L'#': flags |= SPECIAL; goto repeat;
707 case L'0': flags |= ZEROPAD; goto repeat;
710 /* get field width */
713 field_width = skip_wtoi(&fmt);
714 else if (*fmt == L'*') {
716 /* it's the next argument */
717 field_width = va_arg(args, int);
718 if (field_width < 0) {
719 field_width = -field_width;
724 /* get the precision */
729 precision = skip_wtoi(&fmt);
730 else if (*fmt == L'*') {
732 /* it's the next argument */
733 precision = va_arg(args, int);
739 /* get the conversion qualifier */
741 // %Z can be just stand alone or as size_t qualifier
757 } else if (*fmt == L'h' || *fmt == L'l' || *fmt == L'L' || *fmt == L'w') {
760 } else if (*fmt == L'I' && *(fmt+1) == L'6' && *(fmt+2) == L'4') {
765 // go fine with ll instead of L
766 if ( *fmt == L'l' ) {
775 case L'c': /* finished */
777 while (--field_width > 0)
779 if (putwc(L' ', f) == WEOF)
783 if (qualifier == L'h')
785 if (putwc((wchar_t) va_arg(args, int), f) == WEOF)
790 if (putwc((wchar_t) va_arg(args, int), f) == WEOF)
794 while (--field_width > 0)
796 if (putwc(L' ', f) == WEOF)
802 case L'C': /* finished */
804 while (--field_width > 0)
806 if (putwc(L' ', f) == WEOF)
810 if (qualifier == L'l' || qualifier == L'w')
812 if (putwc((unsigned char) va_arg(args, int), f) == WEOF)
817 if (putwc((unsigned char) va_arg(args, int), f) == WEOF)
821 while (--field_width > 0)
823 if (putwc(L' ', f) == WEOF)
829 case L's': /* finished */
830 if (qualifier == L'h') {
831 /* print ascii string */
832 s = va_arg(args, char *);
833 result = string(f, s, -1, field_width, precision, flags);
835 /* print unicode string */
836 sw = va_arg(args, wchar_t *);
837 result = stringw(f, sw, -1, field_width, precision, flags);
845 if (qualifier == L'l' || qualifier == L'w') {
846 /* print unicode string */
847 sw = va_arg(args, wchar_t *);
848 result = stringw(f, sw, -1, field_width, precision, flags);
850 /* print ascii string */
851 s = va_arg(args, char *);
858 case L'Z': /* finished */
859 if (qualifier == L'w') {
860 /* print counted unicode string */
861 PUNICODE_STRING pus = va_arg(args, PUNICODE_STRING);
862 if ((pus == NULL) || (pus->Buffer)) {
868 result = stringw(f, sw, len, field_width, precision, flags);
870 /* print counted ascii string */
871 PANSI_STRING pus = va_arg(args, PANSI_STRING);
872 if ((pus == NULL) || (pus->Buffer)) {
879 result = string(f, s, len, field_width, precision, flags);
886 case L'e': /* finished */
891 if (qualifier == L'l' || qualifier == L'L' ) {
892 _ldouble = va_arg(args, long double);
894 if ( _isnanl(_ldouble) ) {
898 if (putwc(*sw++,f) == WEOF)
904 else if ( _isinfl(_ldouble) < 0 ) {
908 if (putwc(*sw++,f) == WEOF)
914 else if ( _isinfl(_ldouble) > 0 ) {
918 if (putwc(*sw++,f) == WEOF)
924 if ( precision == -1 )
926 result = numberfl(f,_ldouble,*fmt,field_width,precision,flags);
932 _double = (double)va_arg(args, double);
934 if ( _isnan(_double) ) {
938 if (putwc(*sw++,f) == WEOF)
943 } else if ( _isinf(_double) < 0 ) {
947 if (putwc(*sw++,f) == WEOF)
952 } else if ( _isinf(_double) > 0 ) {
956 if (putwc(*sw++,f) == WEOF)
962 if ( precision == -1 )
964 result = numberf(f,_double,*fmt,field_width,precision,flags);
973 if (field_width == -1) {
974 field_width = 2*sizeof(void *);
978 (unsigned long) va_arg(args, void *), 16,
979 field_width, precision, flags);
986 if (qualifier == L'l') {
987 long * ip = va_arg(args, long *);
990 int * ip = va_arg(args, int *);
995 /* integer number formats - set up the flags and "break" */
1019 if (putwc(L'%', f) == WEOF)
1025 if (putwc(*fmt, f) == WEOF)
1034 if (qualifier == L'I')
1035 num = va_arg(args, unsigned long long);
1036 else if (qualifier == L'l')
1037 num = va_arg(args, unsigned long);
1038 else if (qualifier == L'h') {
1040 num = va_arg(args, int);
1042 num = va_arg(args, unsigned int);
1044 else if (flags & SIGN)
1045 num = va_arg(args, int);
1047 num = va_arg(args, unsigned int);
1048 result = number(f, num, base, field_width, precision, flags);