1 /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
2 #include <msvcrt/stdio.h>
4 #include <msvcrt/malloc.h>
5 #include <msvcrt/internal/file.h>
12 int putwc(wint_t wc, FILE* fileWrite);
13 //wint_t putwc (wint_t wc, FILE* fileWrite);
16 __vfwprintf(FILE *fp, const wchar_t *fmt0, va_list argp);
20 vfwprintf(FILE *f, const wchar_t *fmt, va_list ap)
23 wchar_t localbuf[BUFSIZ];
25 if (f->_flag & _IONBF) {
27 f->_ptr = f->_base = (char *)localbuf;
29 len = __vfwprintf(f,fmt,ap);
36 len = __vfwprintf(f,fmt,ap);
38 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
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_wtoi(const wchar_t **s)
85 i = i*10 + *((*s)++) - L'0';
90 static int do_div(long long *n,int base)
92 int __res = ((unsigned long long) *n) % (unsigned) base;
93 *n = ((unsigned long long) *n) / (unsigned) base;
98 static void number(FILE * f, long long num, int base, int size, int precision ,int type)
100 wchar_t c,sign,tmp[66];
101 const wchar_t *digits=L"0123456789abcdefghijklmnopqrstuvwxyz";
105 digits = L"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
108 if (base < 2 || base > 36)
110 c = (type & ZEROPAD) ? L'0' : L' ';
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)))
144 if (type & SPECIAL) {
156 while (i < precision--)
166 static void numberf(FILE * f, double __n, wchar_t exp_sign, int size, int precision, int type)
168 double exponent = 0.0;
184 double_t *n = (double_t *)&__n;
186 if ( exp_sign == L'g' || exp_sign == L'G' || exp_sign == L'e' || exp_sign == L'E' ) {
187 ie = ((unsigned int)n->exponent - (unsigned int)0x3ff);
188 exponent = ie/3.321928;
191 if ( exp_sign == L'g' || exp_sign == L'G' ) {
193 if ( exponent < -4 || fabs(exponent) >= precision )
194 exp_sign -= 2; // g -> e and G -> E
197 if ( exp_sign == L'e' || exp_sign == L'E' ) {
198 frac = modf(exponent,&e);
201 else if ( frac < -0.5 )
204 numberf(f,__n/pow(10.0L,e),L'f',size-4, precision, type);
212 number(f,ie, 10,2, 2,type );
216 if ( exp_sign == 'f' ) {
222 c = (type & ZEROPAD) ? L'0' : L' ';
229 } else if (type & PLUS) {
232 } else if (type & SPACE) {
238 frac = modf(__n,&intr);
240 // # flags forces a . and prevents trucation of trailing zero's
242 if ( precision > 0 ) {
243 //frac = modfl(__n,&intr);
247 frac = modf(frac, &p);
248 buf[i] = (int)p + L'0';
259 if ( precision >= 1 || type & SPECIAL) {
270 while ( intr > 0.0 ) {
272 p = modf(intr, &intr);
276 buf[i++] = (int)p + L'0';
282 while ( j < i && ro == 1 ) {
283 if ( buf[j] >= L'0' && buf[j] <= L'8' ) {
287 else if ( buf[j] == L'9' ) {
298 if (!(type&(ZEROPAD+LEFT)))
304 if (!(type&(ZEROPAD+LEFT)))
307 if (type & SPECIAL) {
315 if ( type & ZEROTRUNC && ((type & SPECIAL) != SPECIAL) ) {
317 while ( j < i && ( *tmp == L'0' || *tmp == L'.' )) {
323 // while (i < precision--)
333 static void numberfl(FILE * f, long double __n, wchar_t exp_sign, int size, int precision, int type)
335 long double exponent = 0.0;
345 long double frac, intr;
351 long_double_t *n = (long_double_t *)&__n;
353 if ( exp_sign == L'g' || exp_sign == L'G' || exp_sign == L'e' || exp_sign == L'E' ) {
354 ie = ((unsigned int)n->exponent - (unsigned int)0x3fff);
355 exponent = ie/3.321928;
358 if ( exp_sign == L'g' || exp_sign == L'G' ) {
360 if ( exponent < -4 || fabs(exponent) >= precision )
361 exp_sign -= 2; // g -> e and G -> E
364 if ( exp_sign == L'e' || exp_sign == L'E' ) {
365 frac = modfl(exponent,&e);
368 else if ( frac < -0.5 )
371 numberf(f,__n/powl(10.0L,e),L'f',size-4, precision, type);
379 number(f,ie, 10,2, 2,type );
383 if ( exp_sign == L'f' ) {
389 c = (type & ZEROPAD) ? L'0' : L' ';
396 } else if (type & PLUS) {
399 } else if (type & SPACE) {
405 frac = modfl(__n,&intr);
407 // # flags forces a . and prevents trucation of trailing zero's
408 if ( precision > 0 ) {
409 //frac = modfl(__n,&intr);
414 frac = modfl((long double)frac, &p);
415 buf[i] = (int)p + L'0';
426 if ( precision >= 1 || type & SPECIAL) {
437 while ( intr > 0.0 ) {
439 p = modfl(intr, &intr);
443 buf[i++] = (int)p + L'0';
449 while ( j < i && ro == 1) {
450 if ( buf[j] >= L'0' && buf[j] <= L'8' ) {
454 else if ( buf[j] == L'9' ) {
465 if (!(type&(ZEROPAD+LEFT)))
471 if (!(type&(ZEROPAD+LEFT)))
474 if (type & SPECIAL) {
482 if ( type & ZEROTRUNC && ((type & SPECIAL) != SPECIAL) ) {
484 while ( j < i && ( *tmp == L'0' || *tmp == L'.' )) {
490 // while (i < precision--)
500 int __vfwprintf(FILE *f, const wchar_t *fmt, va_list args)
503 unsigned long long num;
505 long double _ldouble;
510 int flags; /* flags to number() */
512 int field_width; /* width of output field */
513 int precision; /* min. # of digits for integers; max
514 number of chars for from string */
515 int qualifier = 0; /* 'h', 'l', 'L' or 'I64' for integer fields */
517 for (; *fmt ; ++fmt) {
526 ++fmt; /* this also skips first '%' */
528 case L'-': flags |= LEFT; goto repeat;
529 case L'+': flags |= PLUS; goto repeat;
530 case L' ': flags |= SPACE; goto repeat;
531 case L'#': flags |= SPECIAL; goto repeat;
532 case L'0': flags |= ZEROPAD; goto repeat;
535 /* get field width */
538 field_width = skip_wtoi(&fmt);
539 else if (*fmt == L'*') {
541 /* it's the next argument */
542 field_width = va_arg(args, int);
543 if (field_width < 0) {
544 field_width = -field_width;
549 /* get the precision */
554 precision = skip_wtoi(&fmt);
555 else if (*fmt == L'*') {
557 /* it's the next argument */
558 precision = va_arg(args, int);
564 /* get the conversion qualifier */
565 // %Z can be just stand alone or as size_t qualifier
581 } else if (*fmt == L'h' || *fmt == L'l' || *fmt == L'L' || *fmt == L'w') {
584 } else if (*fmt == L'I' && *(fmt+1) == L'6' && *(fmt+2) == L'4') {
589 // go fine with ll instead of L
590 if ( *fmt == L'l' ) {
599 case L'c': /* finished */
601 while (--field_width > 0)
603 if (qualifier == L'h')
604 putwc((wchar_t) va_arg(args, int), f);
606 putwc((wchar_t) va_arg(args, int), f);
607 while (--field_width > 0)
611 case L'C': /* finished */
613 while (--field_width > 0)
615 if (qualifier == L'l' || qualifier == L'w')
616 putwc((unsigned char)(wchar_t) va_arg(args, int), f);
618 putwc((unsigned char) va_arg(args, int), f);
619 while (--field_width > 0)
623 case L's': /* finished */
624 if (qualifier == L'h') {
625 /* print ascii string */
626 s = va_arg(args, char *);
631 if ((unsigned int)len > (unsigned int)precision)
635 while (len < field_width--)
637 for (i = 0; i < len; ++i)
638 putwc((wchar_t)(*s++), f);
639 while (len < field_width--)
642 /* print unicode string */
643 sw = va_arg(args, wchar_t *);
648 if ((unsigned int)len > (unsigned int)precision)
652 while (len < field_width--)
654 for (i = 0; i < len; ++i)
656 while (len < field_width--)
662 if (qualifier == L'l' || qualifier == L'w') {
663 /* print unicode string */
664 sw = va_arg(args, wchar_t *);
669 if ((unsigned int)len > (unsigned int)precision)
673 while (len < field_width--)
675 for (i = 0; i < len; ++i)
677 while (len < field_width--)
680 /* print ascii string */
681 s = va_arg(args, char *);
686 if ((unsigned int)len > (unsigned int)precision)
690 while (len < field_width--)
692 for (i = 0; i < len; ++i)
693 putwc((wchar_t)(*s++), f);
694 while (len < field_width--)
700 case L'Z': /* finished */
701 if (qualifier == L'w') {
702 /* print counted unicode string */
703 PUNICODE_STRING pus = va_arg(args, PUNICODE_STRING);
704 if ((pus == NULL) || (pus->Buffer)) {
709 for (i = 0; pus->Buffer[i] && i < pus->Length; i++)
710 putwc(pus->Buffer[i], f);
713 /* print counted ascii string */
714 PANSI_STRING pus = va_arg(args, PANSI_STRING);
715 if ((pus == NULL) || (pus->Buffer)) {
720 for (i = 0; pus->Buffer[i] && i < pus->Length; i++)
721 putwc((wchar_t)pus->Buffer[i], f);
727 case L'e': /* finished */
732 if (qualifier == L'l' || qualifier == L'L' ) {
733 _ldouble = va_arg(args, long double);
735 if ( _isnanl(_ldouble) ) {
743 else if ( _isinfl(_ldouble) < 0 ) {
751 else if ( _isinfl(_ldouble) > 0 ) {
759 if ( precision == -1 )
761 numberfl(f,_ldouble,*fmt,field_width,precision,flags);
764 _double = (double)va_arg(args, double);
766 if ( _isnan(_double) ) {
773 } else if ( _isinf(_double) < 0 ) {
780 } else if ( _isinf(_double) > 0 ) {
788 if ( precision == -1 )
790 numberf(f,_double,*fmt,field_width,precision,flags);
796 if (field_width == -1) {
797 field_width = 2*sizeof(void *);
801 (unsigned long) va_arg(args, void *), 16,
802 field_width, precision, flags);
806 if (qualifier == L'l') {
807 long * ip = va_arg(args, long *);
810 int * ip = va_arg(args, int *);
815 /* integer number formats - set up the flags and "break" */
846 if (qualifier == L'I')
847 num = va_arg(args, unsigned long long);
848 else if (qualifier == L'l')
849 num = va_arg(args, unsigned long);
850 else if (qualifier == L'h') {
852 num = va_arg(args, int);
854 num = va_arg(args, unsigned int);
856 else if (flags & SIGN)
857 num = va_arg(args, int);
859 num = va_arg(args, unsigned int);
860 number(f, num, base, field_width, precision, flags);