1 /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
2 #include <crtdll/stdio.h>
4 #include <crtdll/malloc.h>
5 #include <crtdll/internal/file.h>
12 extern int putwc (wchar_t wc, FILE* fileWrite);
15 __vfwprintf(FILE *fp, const wchar_t *fmt0, va_list argp);
19 vfwprintf(FILE *f, const wchar_t *fmt, va_list ap)
22 wchar_t localbuf[BUFSIZ];
24 if (f->_flag & _IONBF) {
26 f->_ptr = f->_base = (char *)localbuf;
28 len = __vfwprintf(f,fmt,ap);
35 len = __vfwprintf(f,fmt,ap);
37 return (ferror(f) ? EOF : len);
45 * linux/lib/vsprintf.c
47 * Copyright (C) 1991, 1992 Linus Torvalds
50 /* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */
52 * Wirzenius wrote this portably, Torvalds fucked it up :-)
56 * Appropiated for the reactos kernel, March 1998 -- David Welch
61 #include <crtdll/ctype.h>
62 #include <crtdll/string.h>
63 #include <crtdll/stdio.h>
64 #include <crtdll/string.h>
65 #include <crtdll/math.h>
66 #include <crtdll/internal/ieee.h>
69 #define ZEROPAD 1 /* pad with zero */
70 #define SIGN 2 /* unsigned/signed long */
71 #define PLUS 4 /* show plus */
72 #define SPACE 8 /* space if plus */
73 #define LEFT 16 /* left justified */
74 #define SPECIAL 32 /* 0x */
75 #define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */
76 #define ZEROTRUNC 128 /* truncate zero 's */
79 static int skip_wtoi(const wchar_t **s)
84 i = i*10 + *((*s)++) - L'0';
89 static int do_div(long long *n,int base)
91 int __res = ((unsigned long long) *n) % (unsigned) base;
92 *n = ((unsigned long long) *n) / (unsigned) base;
97 static void number(FILE * f, long long num, int base, int size, int precision ,int type)
99 wchar_t c,sign,tmp[66];
100 const wchar_t *digits=L"0123456789abcdefghijklmnopqrstuvwxyz";
104 digits = L"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
107 if (base < 2 || base > 36)
109 c = (type & ZEROPAD) ? L'0' : L' ';
116 } else if (type & PLUS) {
119 } else if (type & SPACE) {
124 if (type & SPECIAL) {
133 else while (num != 0)
134 tmp[i++] = digits[do_div(&num,base)];
138 if (!(type&(ZEROPAD+LEFT)))
143 if (type & SPECIAL) {
155 while (i < precision--)
165 static void numberf(FILE * f, double __n, wchar_t exp_sign, int size, int precision, int type)
167 double exponent = 0.0;
183 double_t *n = (double_t *)&__n;
185 if ( exp_sign == L'g' || exp_sign == L'G' || exp_sign == L'e' || exp_sign == L'E' ) {
186 ie = ((unsigned int)n->exponent - (unsigned int)0x3ff);
187 exponent = ie/3.321928;
190 if ( exp_sign == L'g' || exp_sign == L'G' ) {
192 if ( exponent < -4 || fabs(exponent) >= precision )
193 exp_sign -= 2; // g -> e and G -> E
196 if ( exp_sign == L'e' || exp_sign == L'E' ) {
197 frac = modf(exponent,&e);
200 else if ( frac < -0.5 )
203 numberf(f,__n/pow(10.0L,e),L'f',size-4, precision, type);
211 number(f,ie, 10,2, 2,type );
215 if ( exp_sign == 'f' ) {
221 c = (type & ZEROPAD) ? L'0' : L' ';
228 } else if (type & PLUS) {
231 } else if (type & SPACE) {
237 frac = modf(__n,&intr);
239 // # flags forces a . and prevents trucation of trailing zero's
241 if ( precision > 0 ) {
242 //frac = modfl(__n,&intr);
246 frac = modf(frac, &p);
247 buf[i] = (int)p + L'0';
258 if ( precision >= 1 || type & SPECIAL) {
269 while ( intr > 0.0 ) {
271 p = modf(intr, &intr);
275 buf[i++] = (int)p + L'0';
281 while ( j < i && ro == 1 ) {
282 if ( buf[j] >= L'0' && buf[j] <= L'8' ) {
286 else if ( buf[j] == L'9' ) {
297 if (!(type&(ZEROPAD+LEFT)))
303 if (!(type&(ZEROPAD+LEFT)))
306 if (type & SPECIAL) {
314 if ( type & ZEROTRUNC && ((type & SPECIAL) != SPECIAL) ) {
316 while ( j < i && ( *tmp == L'0' || *tmp == L'.' )) {
322 // while (i < precision--)
332 static void numberfl(FILE * f, long double __n, wchar_t exp_sign, int size, int precision, int type)
334 long double exponent = 0.0;
344 long double frac, intr;
350 long_double_t *n = (long_double_t *)&__n;
352 if ( exp_sign == L'g' || exp_sign == L'G' || exp_sign == L'e' || exp_sign == L'E' ) {
353 ie = ((unsigned int)n->exponent - (unsigned int)0x3fff);
354 exponent = ie/3.321928;
357 if ( exp_sign == L'g' || exp_sign == L'G' ) {
359 if ( exponent < -4 || fabs(exponent) >= precision )
360 exp_sign -= 2; // g -> e and G -> E
363 if ( exp_sign == L'e' || exp_sign == L'E' ) {
364 frac = modfl(exponent,&e);
367 else if ( frac < -0.5 )
370 numberf(f,__n/powl(10.0L,e),L'f',size-4, precision, type);
378 number(f,ie, 10,2, 2,type );
382 if ( exp_sign == L'f' ) {
388 c = (type & ZEROPAD) ? L'0' : L' ';
395 } else if (type & PLUS) {
398 } else if (type & SPACE) {
404 frac = modfl(__n,&intr);
406 // # flags forces a . and prevents trucation of trailing zero's
407 if ( precision > 0 ) {
408 //frac = modfl(__n,&intr);
413 frac = modfl((long double)frac, &p);
414 buf[i] = (int)p + L'0';
425 if ( precision >= 1 || type & SPECIAL) {
436 while ( intr > 0.0 ) {
438 p = modfl(intr, &intr);
442 buf[i++] = (int)p + L'0';
448 while ( j < i && ro == 1) {
449 if ( buf[j] >= L'0' && buf[j] <= L'8' ) {
453 else if ( buf[j] == L'9' ) {
464 if (!(type&(ZEROPAD+LEFT)))
470 if (!(type&(ZEROPAD+LEFT)))
473 if (type & SPECIAL) {
481 if ( type & ZEROTRUNC && ((type & SPECIAL) != SPECIAL) ) {
483 while ( j < i && ( *tmp == L'0' || *tmp == L'.' )) {
489 // while (i < precision--)
499 int __vfwprintf(FILE *f, const wchar_t *fmt, va_list args)
502 unsigned long long num;
504 long double _ldouble;
509 int flags; /* flags to number() */
511 int field_width; /* width of output field */
512 int precision; /* min. # of digits for integers; max
513 number of chars for from string */
514 int qualifier = 0; /* 'h', 'l', 'L' or 'I64' for integer fields */
516 for (; *fmt ; ++fmt) {
525 ++fmt; /* this also skips first '%' */
527 case L'-': flags |= LEFT; goto repeat;
528 case L'+': flags |= PLUS; goto repeat;
529 case L' ': flags |= SPACE; goto repeat;
530 case L'#': flags |= SPECIAL; goto repeat;
531 case L'0': flags |= ZEROPAD; goto repeat;
534 /* get field width */
537 field_width = skip_wtoi(&fmt);
538 else if (*fmt == L'*') {
540 /* it's the next argument */
541 field_width = va_arg(args, int);
542 if (field_width < 0) {
543 field_width = -field_width;
548 /* get the precision */
553 precision = skip_wtoi(&fmt);
554 else if (*fmt == L'*') {
556 /* it's the next argument */
557 precision = va_arg(args, int);
563 /* get the conversion qualifier */
564 // %Z can be just stand alone or as size_t qualifier
580 } else if (*fmt == L'h' || *fmt == L'l' || *fmt == L'L' || *fmt == L'w') {
583 } else if (*fmt == L'I' && *(fmt+1) == L'6' && *(fmt+2) == L'4') {
588 // go fine with ll instead of L
589 if ( *fmt == L'l' ) {
598 case L'c': /* finished */
600 while (--field_width > 0)
602 if (qualifier == L'h')
603 putwc((wchar_t) va_arg(args, int), f);
605 putwc((wchar_t) va_arg(args, int), f);
606 while (--field_width > 0)
610 case L'C': /* finished */
612 while (--field_width > 0)
614 if (qualifier == L'l' || qualifier == L'w')
615 putwc((unsigned char)(wchar_t) va_arg(args, int), f);
617 putwc((unsigned char) va_arg(args, int), f);
618 while (--field_width > 0)
622 case L's': /* finished */
623 if (qualifier == L'h') {
624 /* print ascii string */
625 s = va_arg(args, char *);
630 if ((unsigned int)len > (unsigned int)precision)
634 while (len < field_width--)
636 for (i = 0; i < len; ++i)
637 putwc((wchar_t)(*s++), f);
638 while (len < field_width--)
641 /* print unicode string */
642 sw = va_arg(args, wchar_t *);
647 if ((unsigned int)len > (unsigned int)precision)
651 while (len < field_width--)
653 for (i = 0; i < len; ++i)
655 while (len < field_width--)
661 if (qualifier == L'l' || qualifier == L'w') {
662 /* print unicode string */
663 sw = va_arg(args, wchar_t *);
668 if ((unsigned int)len > (unsigned int)precision)
672 while (len < field_width--)
674 for (i = 0; i < len; ++i)
676 while (len < field_width--)
679 /* print ascii string */
680 s = va_arg(args, char *);
685 if ((unsigned int)len > (unsigned int)precision)
689 while (len < field_width--)
691 for (i = 0; i < len; ++i)
692 putwc((wchar_t)(*s++), f);
693 while (len < field_width--)
699 case L'Z': /* finished */
700 if (qualifier == L'w') {
701 /* print counted unicode string */
702 PUNICODE_STRING pus = va_arg(args, PUNICODE_STRING);
703 if ((pus == NULL) || (pus->Buffer)) {
708 for (i = 0; pus->Buffer[i] && i < pus->Length; i++)
709 putwc(pus->Buffer[i], f);
712 /* print counted ascii string */
713 PANSI_STRING pus = va_arg(args, PANSI_STRING);
714 if ((pus == NULL) || (pus->Buffer)) {
719 for (i = 0; pus->Buffer[i] && i < pus->Length; i++)
720 putwc((wchar_t)pus->Buffer[i], f);
726 case L'e': /* finished */
731 if (qualifier == L'l' || qualifier == L'L' ) {
732 _ldouble = va_arg(args, long double);
734 if ( _isnanl(_ldouble) ) {
742 else if ( _isinfl(_ldouble) < 0 ) {
750 else if ( _isinfl(_ldouble) > 0 ) {
758 if ( precision == -1 )
760 numberfl(f,_ldouble,*fmt,field_width,precision,flags);
763 _double = (double)va_arg(args, double);
765 if ( _isnan(_double) ) {
772 } else if ( _isinf(_double) < 0 ) {
779 } else if ( _isinf(_double) > 0 ) {
787 if ( precision == -1 )
789 numberf(f,_double,*fmt,field_width,precision,flags);
795 if (field_width == -1) {
796 field_width = 2*sizeof(void *);
800 (unsigned long) va_arg(args, void *), 16,
801 field_width, precision, flags);
805 if (qualifier == L'l') {
806 long * ip = va_arg(args, long *);
809 int * ip = va_arg(args, int *);
814 /* integer number formats - set up the flags and "break" */
845 if (qualifier == L'I')
846 num = va_arg(args, unsigned long long);
847 else if (qualifier == L'l')
848 num = va_arg(args, unsigned long);
849 else if (qualifier == L'h') {
851 num = va_arg(args, int);
853 num = va_arg(args, unsigned int);
855 else if (flags & SIGN)
856 num = va_arg(args, int);
858 num = va_arg(args, unsigned int);
859 number(f, num, base, field_width, precision, flags);