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);
23 vfwprintf(FILE *f, const wchar_t *fmt, va_list ap)
26 wchar_t localbuf[BUFSIZ];
28 if (f->_flag & _IONBF) {
30 f->_ptr = f->_base = (char *)localbuf;
32 len = __vfwprintf(f,fmt,ap);
39 len = __vfwprintf(f,fmt,ap);
41 return (ferror(f) ? EOF : len);
49 * linux/lib/vsprintf.c
51 * Copyright (C) 1991, 1992 Linus Torvalds
54 /* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */
56 * Wirzenius wrote this portably, Torvalds fucked it up :-)
60 * Appropiated for the reactos kernel, March 1998 -- David Welch
65 #include <msvcrt/ctype.h>
66 #include <msvcrt/string.h>
67 #include <msvcrt/stdio.h>
68 #include <msvcrt/string.h>
69 #include <msvcrt/math.h>
70 #include <msvcrt/internal/ieee.h>
73 #define ZEROPAD 1 /* pad with zero */
74 #define SIGN 2 /* unsigned/signed long */
75 #define PLUS 4 /* show plus */
76 #define SPACE 8 /* space if plus */
77 #define LEFT 16 /* left justified */
78 #define SPECIAL 32 /* 0x */
79 #define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */
80 #define ZEROTRUNC 128 /* truncate zero 's */
83 static int skip_wtoi(const wchar_t **s)
88 i = i*10 + *((*s)++) - L'0';
93 static int do_div(long long *n,int base)
95 int __res = ((unsigned long long) *n) % (unsigned) base;
96 *n = ((unsigned long long) *n) / (unsigned) base;
101 static void number(FILE * f, long long num, int base, int size, int precision ,int type)
103 wchar_t c,sign,tmp[66];
104 const wchar_t *digits=L"0123456789abcdefghijklmnopqrstuvwxyz";
108 digits = L"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
111 if (base < 2 || base > 36)
113 c = (type & ZEROPAD) ? L'0' : L' ';
120 } else if (type & PLUS) {
123 } else if (type & SPACE) {
128 if (type & SPECIAL) {
137 else while (num != 0)
138 tmp[i++] = digits[do_div(&num,base)];
142 if (!(type&(ZEROPAD+LEFT)))
147 if (type & SPECIAL) {
159 while (i < precision--)
169 static void numberf(FILE * f, double __n, wchar_t exp_sign, int size, int precision, int type)
171 double exponent = 0.0;
187 double_t *n = (double_t *)&__n;
189 if ( exp_sign == L'g' || exp_sign == L'G' || exp_sign == L'e' || exp_sign == L'E' ) {
190 ie = ((unsigned int)n->exponent - (unsigned int)0x3ff);
191 exponent = ie/3.321928;
194 if ( exp_sign == L'g' || exp_sign == L'G' ) {
196 if ( exponent < -4 || fabs(exponent) >= precision )
197 exp_sign -= 2; // g -> e and G -> E
200 if ( exp_sign == L'e' || exp_sign == L'E' ) {
201 frac = modf(exponent,&e);
204 else if ( frac < -0.5 )
207 numberf(f,__n/pow(10.0L,e),L'f',size-4, precision, type);
215 number(f,ie, 10,2, 2,type );
219 if ( exp_sign == 'f' ) {
225 c = (type & ZEROPAD) ? L'0' : L' ';
232 } else if (type & PLUS) {
235 } else if (type & SPACE) {
241 frac = modf(__n,&intr);
243 // # flags forces a . and prevents trucation of trailing zero's
245 if ( precision > 0 ) {
246 //frac = modfl(__n,&intr);
250 frac = modf(frac, &p);
251 buf[i] = (int)p + L'0';
262 if ( precision >= 1 || type & SPECIAL) {
273 while ( intr > 0.0 ) {
275 p = modf(intr, &intr);
279 buf[i++] = (int)p + L'0';
285 while ( j < i && ro == 1 ) {
286 if ( buf[j] >= L'0' && buf[j] <= L'8' ) {
290 else if ( buf[j] == L'9' ) {
301 if (!(type&(ZEROPAD+LEFT)))
307 if (!(type&(ZEROPAD+LEFT)))
310 if (type & SPECIAL) {
318 if ( type & ZEROTRUNC && ((type & SPECIAL) != SPECIAL) ) {
320 while ( j < i && ( *tmp == L'0' || *tmp == L'.' )) {
326 // while (i < precision--)
336 static void numberfl(FILE * f, long double __n, wchar_t exp_sign, int size, int precision, int type)
338 long double exponent = 0.0;
348 long double frac, intr;
354 long_double_t *n = (long_double_t *)&__n;
356 if ( exp_sign == L'g' || exp_sign == L'G' || exp_sign == L'e' || exp_sign == L'E' ) {
357 ie = ((unsigned int)n->exponent - (unsigned int)0x3fff);
358 exponent = ie/3.321928;
361 if ( exp_sign == L'g' || exp_sign == L'G' ) {
363 if ( exponent < -4 || fabs(exponent) >= precision )
364 exp_sign -= 2; // g -> e and G -> E
367 if ( exp_sign == L'e' || exp_sign == L'E' ) {
368 frac = modfl(exponent,&e);
371 else if ( frac < -0.5 )
374 numberf(f,__n/powl(10.0L,e),L'f',size-4, precision, type);
382 number(f,ie, 10,2, 2,type );
386 if ( exp_sign == L'f' ) {
392 c = (type & ZEROPAD) ? L'0' : L' ';
399 } else if (type & PLUS) {
402 } else if (type & SPACE) {
408 frac = modfl(__n,&intr);
410 // # flags forces a . and prevents trucation of trailing zero's
411 if ( precision > 0 ) {
412 //frac = modfl(__n,&intr);
417 frac = modfl((long double)frac, &p);
418 buf[i] = (int)p + L'0';
429 if ( precision >= 1 || type & SPECIAL) {
440 while ( intr > 0.0 ) {
442 p = modfl(intr, &intr);
446 buf[i++] = (int)p + L'0';
452 while ( j < i && ro == 1) {
453 if ( buf[j] >= L'0' && buf[j] <= L'8' ) {
457 else if ( buf[j] == L'9' ) {
468 if (!(type&(ZEROPAD+LEFT)))
474 if (!(type&(ZEROPAD+LEFT)))
477 if (type & SPECIAL) {
485 if ( type & ZEROTRUNC && ((type & SPECIAL) != SPECIAL) ) {
487 while ( j < i && ( *tmp == L'0' || *tmp == L'.' )) {
493 // while (i < precision--)
503 int __vfwprintf(FILE *f, const wchar_t *fmt, va_list args)
506 unsigned long long num;
508 long double _ldouble;
513 int flags; /* flags to number() */
515 int field_width; /* width of output field */
516 int precision; /* min. # of digits for integers; max
517 number of chars for from string */
518 int qualifier = 0; /* 'h', 'l', 'L' or 'I64' for integer fields */
520 for (; *fmt ; ++fmt) {
529 ++fmt; /* this also skips first '%' */
531 case L'-': flags |= LEFT; goto repeat;
532 case L'+': flags |= PLUS; goto repeat;
533 case L' ': flags |= SPACE; goto repeat;
534 case L'#': flags |= SPECIAL; goto repeat;
535 case L'0': flags |= ZEROPAD; goto repeat;
538 /* get field width */
541 field_width = skip_wtoi(&fmt);
542 else if (*fmt == L'*') {
544 /* it's the next argument */
545 field_width = va_arg(args, int);
546 if (field_width < 0) {
547 field_width = -field_width;
552 /* get the precision */
557 precision = skip_wtoi(&fmt);
558 else if (*fmt == L'*') {
560 /* it's the next argument */
561 precision = va_arg(args, int);
567 /* get the conversion qualifier */
568 // %Z can be just stand alone or as size_t qualifier
584 } else if (*fmt == L'h' || *fmt == L'l' || *fmt == L'L' || *fmt == L'w') {
587 } else if (*fmt == L'I' && *(fmt+1) == L'6' && *(fmt+2) == L'4') {
592 // go fine with ll instead of L
593 if ( *fmt == L'l' ) {
602 case L'c': /* finished */
604 while (--field_width > 0)
606 if (qualifier == L'h')
607 putwc((wchar_t) va_arg(args, int), f);
609 putwc((wchar_t) va_arg(args, int), f);
610 while (--field_width > 0)
614 case L'C': /* finished */
616 while (--field_width > 0)
618 if (qualifier == L'l' || qualifier == L'w')
619 putwc((unsigned char)(wchar_t) va_arg(args, int), f);
621 putwc((unsigned char) va_arg(args, int), f);
622 while (--field_width > 0)
626 case L's': /* finished */
627 if (qualifier == L'h') {
628 /* print ascii string */
629 s = va_arg(args, char *);
634 if ((unsigned int)len > (unsigned int)precision)
638 while (len < field_width--)
640 for (i = 0; i < len; ++i)
641 putwc((wchar_t)(*s++), f);
642 while (len < field_width--)
645 /* print unicode string */
646 sw = va_arg(args, wchar_t *);
651 if ((unsigned int)len > (unsigned int)precision)
655 while (len < field_width--)
657 for (i = 0; i < len; ++i)
659 while (len < field_width--)
665 if (qualifier == L'l' || qualifier == L'w') {
666 /* print unicode string */
667 sw = va_arg(args, wchar_t *);
672 if ((unsigned int)len > (unsigned int)precision)
676 while (len < field_width--)
678 for (i = 0; i < len; ++i)
680 while (len < field_width--)
683 /* print ascii string */
684 s = va_arg(args, char *);
689 if ((unsigned int)len > (unsigned int)precision)
693 while (len < field_width--)
695 for (i = 0; i < len; ++i)
696 putwc((wchar_t)(*s++), f);
697 while (len < field_width--)
703 case L'Z': /* finished */
704 if (qualifier == L'w') {
705 /* print counted unicode string */
706 PUNICODE_STRING pus = va_arg(args, PUNICODE_STRING);
707 if ((pus == NULL) || (pus->Buffer)) {
712 for (i = 0; pus->Buffer[i] && i < pus->Length; i++)
713 putwc(pus->Buffer[i], f);
716 /* print counted ascii string */
717 PANSI_STRING pus = va_arg(args, PANSI_STRING);
718 if ((pus == NULL) || (pus->Buffer)) {
723 for (i = 0; pus->Buffer[i] && i < pus->Length; i++)
724 putwc((wchar_t)pus->Buffer[i], f);
730 case L'e': /* finished */
735 if (qualifier == L'l' || qualifier == L'L' ) {
736 _ldouble = va_arg(args, long double);
738 if ( _isnanl(_ldouble) ) {
746 else if ( _isinfl(_ldouble) < 0 ) {
754 else if ( _isinfl(_ldouble) > 0 ) {
762 if ( precision == -1 )
764 numberfl(f,_ldouble,*fmt,field_width,precision,flags);
767 _double = (double)va_arg(args, double);
769 if ( _isnan(_double) ) {
776 } else if ( _isinf(_double) < 0 ) {
783 } else if ( _isinf(_double) > 0 ) {
791 if ( precision == -1 )
793 numberf(f,_double,*fmt,field_width,precision,flags);
799 if (field_width == -1) {
800 field_width = 2*sizeof(void *);
804 (unsigned long) va_arg(args, void *), 16,
805 field_width, precision, flags);
809 if (qualifier == L'l') {
810 long * ip = va_arg(args, long *);
813 int * ip = va_arg(args, int *);
818 /* integer number formats - set up the flags and "break" */
849 if (qualifier == L'I')
850 num = va_arg(args, unsigned long long);
851 else if (qualifier == L'l')
852 num = va_arg(args, unsigned long);
853 else if (qualifier == L'h') {
855 num = va_arg(args, int);
857 num = va_arg(args, unsigned int);
859 else if (flags & SIGN)
860 num = va_arg(args, int);
862 num = va_arg(args, unsigned int);
863 number(f, num, base, field_width, precision, flags);