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);
21 vfprintf(FILE *f, const char *fmt, va_list ap)
24 char localbuf[BUFSIZ];
26 if (f->_flag & _IONBF)
29 f->_ptr = f->_base = localbuf;
31 len = __vfprintf(f,fmt, ap);
39 len = __vfprintf(f,fmt, ap);
40 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 <msvcrt/ctype.h>
62 #include <msvcrt/string.h>
63 #include <msvcrt/stdio.h>
64 #include <msvcrt/string.h>
65 #include <msvcrt/math.h>
66 #include <msvcrt/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 */
80 skip_atoi(const char **s)
85 i = i*10 + *((*s)++) - '0';
91 do_div(long long *n,int base)
93 int __res = ((unsigned long long) *n) % (unsigned) base;
94 *n = ((unsigned long long) *n) / (unsigned) base;
100 number(FILE * f, long long num, int base, int size, int precision ,int type)
103 const char *digits="0123456789abcdefghijklmnopqrstuvwxyz";
107 digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
110 if (base < 2 || base > 36)
112 c = (type & ZEROPAD) ? '0' : ' ';
119 } else if (type & PLUS) {
122 } else if (type & SPACE) {
127 if (type & SPECIAL) {
136 else while (num != 0)
137 tmp[i++] = digits[do_div(&num,base)];
141 if (!(type&(ZEROPAD+LEFT)))
146 if (type & SPECIAL) {
158 while (i < precision--)
169 numberf(FILE * f, double __n, char exp_sign, int size, int precision, int type)
171 double exponent = 0.0;
187 double_t *n = (double_t *)&__n;
189 if ( exp_sign == 'g' || exp_sign == 'G' || exp_sign == 'e' || exp_sign == 'E' ) {
190 ie = ((unsigned int)n->exponent - (unsigned int)0x3ff);
191 exponent = ie/3.321928;
194 if ( exp_sign == 'g' || exp_sign == 'G' ) {
196 if ( exponent < -4 || fabs(exponent) >= precision )
197 exp_sign -= 2; // g -> e and G -> E
200 if ( exp_sign == 'e' || exp_sign == 'E' ) {
201 frac = modf(exponent,&e);
204 else if ( frac < -0.5 )
207 numberf(f,__n/pow(10.0L,e),'f',size-4, precision, type);
215 number(f,ie, 10,2, 2,type );
219 if ( exp_sign == 'f' ) {
225 c = (type & ZEROPAD) ? '0' : ' ';
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 + '0';
262 if ( precision >= 1 || type & SPECIAL) {
273 while ( intr > 0.0 ) {
275 p = modf(intr, &intr);
279 buf[i++] = (int)p + '0';
285 while ( j < i && ro == 1) {
286 if ( buf[j] >= '0' && buf[j] <= '8' ) {
290 else if ( buf[j] == '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 == '0' || *tmp == '.' )) {
326 // while (i < precision--)
337 numberfl(FILE * f, long double __n, char exp_sign, int size, int precision, int type)
339 long double exponent = 0.0;
349 long double frac, intr;
355 long_double_t *n = (long_double_t *)&__n;
357 if ( exp_sign == 'g' || exp_sign == 'G' || exp_sign == 'e' || exp_sign == 'E' ) {
358 ie = ((unsigned int)n->exponent - (unsigned int)0x3fff);
359 exponent = ie/3.321928;
362 if ( exp_sign == 'g' || exp_sign == 'G' ) {
364 if ( exponent < -4 || fabs(exponent) >= precision )
365 exp_sign -= 2; // g -> e and G -> E
368 if ( exp_sign == 'e' || exp_sign == 'E' ) {
369 frac = modfl(exponent,&e);
372 else if ( frac < -0.5 )
375 numberf(f,__n/powl(10.0L,e),'f',size-4, precision, type);
383 number(f,ie, 10,2, 2,type );
387 if ( exp_sign == 'f' ) {
394 c = (type & ZEROPAD) ? '0' : ' ';
401 } else if (type & PLUS) {
404 } else if (type & SPACE) {
410 frac = modfl(__n,&intr);
412 // # flags forces a . and prevents trucation of trailing zero's
413 if ( precision > 0 ) {
414 //frac = modfl(__n,&intr);
419 frac = modfl((long double)frac, &p);
420 buf[i] = (int)p + '0';
431 if ( precision >= 1 || type & SPECIAL) {
442 while ( intr > 0.0 ) {
444 p = modfl(intr, &intr);
448 buf[i++] = (int)p + '0';
454 while ( j < i && ro == 1) {
455 if ( buf[j] >= '0' && buf[j] <= '8' ) {
459 else if ( buf[j] == '9' ) {
470 if (!(type&(ZEROPAD+LEFT)))
476 if (!(type&(ZEROPAD+LEFT)))
479 if (type & SPECIAL) {
487 if ( type & ZEROTRUNC && ((type & SPECIAL) != SPECIAL) ) {
489 while ( j < i && ( *tmp == '0' || *tmp == '.' )) {
495 // while (i < precision--)
506 __vfprintf(FILE *f, const char *fmt, va_list args)
509 unsigned long long num;
511 long double _ldouble;
516 int flags; /* flags to number() */
518 int field_width; /* width of output field */
519 int precision; /* min. # of digits for integers; max
520 number of chars for from string */
521 int qualifier = 0; /* 'h', 'l', 'L' or 'I64' for integer fields */
523 for (; *fmt ; ++fmt) {
532 ++fmt; /* this also skips first '%' */
534 case '-': flags |= LEFT; goto repeat;
535 case '+': flags |= PLUS; goto repeat;
536 case ' ': flags |= SPACE; goto repeat;
537 case '#': flags |= SPECIAL; goto repeat;
538 case '0': flags |= ZEROPAD; goto repeat;
541 /* get field width */
544 field_width = skip_atoi(&fmt);
545 else if (*fmt == '*') {
547 /* it's the next argument */
548 field_width = va_arg(args, int);
549 if (field_width < 0) {
550 field_width = -field_width;
555 /* get the precision */
560 precision = skip_atoi(&fmt);
561 else if (*fmt == '*') {
563 /* it's the next argument */
564 precision = va_arg(args, int);
570 /* get the conversion qualifier */
571 // %Z can be just stand alone or as size_t qualifier
587 } else if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt == 'w') {
590 } else if (*fmt == 'I' && *(fmt+1) == '6' && *(fmt+2) == '4') {
595 // go fine with ll instead of L
607 while (--field_width > 0)
609 if (qualifier == 'l' || qualifier == 'w')
610 putc((unsigned char)(wchar_t) va_arg(args, int), f);
612 putc((unsigned char) va_arg(args, int), f);
613 while (--field_width > 0)
619 while (--field_width > 0)
621 if (qualifier == 'h')
622 putc((unsigned char) va_arg(args, int), f);
624 putc((unsigned char)(wchar_t) va_arg(args, int), f);
625 while (--field_width > 0)
630 if (qualifier == 'l' || qualifier == 'w') {
631 /* print unicode string */
632 sw = va_arg(args, wchar_t *);
637 if ((unsigned int)len > (unsigned int)precision)
641 while (len < field_width--)
643 for (i = 0; i < len; ++i)
644 putc((unsigned char)(*sw++), f);
645 while (len < field_width--)
648 /* print ascii string */
649 s = va_arg(args, char *);
654 if ((unsigned int)len > (unsigned int)precision)
658 while (len < field_width--)
660 for (i = 0; i < len; ++i)
662 while (len < field_width--)
668 if (qualifier == 'h') {
669 /* print ascii string */
670 s = va_arg(args, char *);
675 if ((unsigned int)len > (unsigned int)precision)
679 while (len < field_width--)
681 for (i = 0; i < len; ++i)
683 while (len < field_width--)
686 /* print unicode string */
687 sw = va_arg(args, wchar_t *);
692 if ((unsigned int)len > (unsigned int)precision)
696 while (len < field_width--)
698 for (i = 0; i < len; ++i)
699 putc((unsigned char)(*sw++), f);
700 while (len < field_width--)
706 if (qualifier == 'w') {
707 /* print counted unicode string */
708 PUNICODE_STRING pus = va_arg(args, PUNICODE_STRING);
709 if ((pus == NULL) || (pus->Buffer == NULL)) {
714 for (i = 0; pus->Buffer[i] && i < pus->Length / sizeof(WCHAR); i++)
715 putc((unsigned char)(pus->Buffer[i]), f);
718 /* print counted ascii string */
719 PANSI_STRING pus = va_arg(args, PANSI_STRING);
720 if ((pus == NULL) || (pus->Buffer == NULL)) {
725 for (i = 0; pus->Buffer[i] && i < pus->Length; i++)
726 putc(pus->Buffer[i], f);
736 if (qualifier == 'l' || qualifier == 'L' ) {
737 _ldouble = va_arg(args, long double);
739 if ( _isnanl(_ldouble) ) {
747 else if ( _isinfl(_ldouble) < 0 ) {
755 else if ( _isinfl(_ldouble) > 0 ) {
763 if ( precision == -1 )
765 numberfl(f,_ldouble,*fmt,field_width,precision,flags);
768 _double = (double)va_arg(args, double);
770 if ( _isnan(_double) ) {
777 } else if ( _isinf(_double) < 0 ) {
784 } else if ( _isinf(_double) > 0 ) {
792 if ( precision == -1 )
794 numberf(f,_double,*fmt,field_width,precision,flags);
800 if (field_width == -1) {
801 field_width = 2*sizeof(void *);
805 (unsigned long) va_arg(args, void *), 16,
806 field_width, precision, flags);
810 if (qualifier == 'l') {
811 long * ip = va_arg(args, long *);
814 int * ip = va_arg(args, int *);
819 /* integer number formats - set up the flags and "break" */
850 if (qualifier == 'I')
851 num = va_arg(args, unsigned long long);
852 else if (qualifier == 'l')
853 num = va_arg(args, unsigned long);
854 else if (qualifier == 'h') {
856 num = va_arg(args, int);
858 num = va_arg(args, unsigned int);
860 else if (flags & SIGN)
861 num = va_arg(args, int);
863 num = va_arg(args, unsigned int);
864 number(f, num, base, field_width, precision, flags);