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 int __vfprintf(FILE*, const char*, va_list);
17 int vfprintf(FILE* f, const char* fmt, va_list ap)
20 char localbuf[BUFSIZ];
23 __fileno_lock(fileno(f));
25 if (f->_flag & _IONBF) {
27 f->_ptr = f->_base = localbuf;
29 len = __vfprintf(f, fmt, ap);
36 len = __vfprintf(f,fmt, ap);
39 __fileno_unlock(fileno(f));
41 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
60 #include <msvcrt/stdarg.h>
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_atoi(const char **s)
85 i = i*10 + *((*s)++) - '0';
90 static int do_div(LONGLONG *n,int base)
92 int __res = ((ULONGLONG) *n) % (unsigned) base;
93 *n = ((ULONGLONG) *n) / (unsigned) base;
98 static int number(FILE * f, LONGLONG num, int base, int size, int precision ,int type)
101 const char *digits="0123456789abcdefghijklmnopqrstuvwxyz";
105 digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
108 if (base < 2 || base > 36)
110 c = (type & ZEROPAD) ? '0' : ' ';
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)))
142 if (putc(' ',f) == EOF)
148 if (putc(sign,f) == EOF)
152 if (type & SPECIAL) {
154 if (putc('0',f) == EOF)
159 if (putc('0', f) == EOF)
162 if (putc(digits[33],f) == EOF)
170 if (putc(c,f) == EOF)
174 while (i < precision--)
176 if (putc('0', f) == EOF)
182 if (putc(tmp[i],f) == EOF)
188 if (putc(' ', f) == EOF)
196 static int numberf(FILE * f, double __n, char exp_sign, int size, int precision, int type)
198 double exponent = 0.0;
213 int result, done = 0;
215 double_t *n = (double_t *)&__n;
217 if ( exp_sign == 'g' || exp_sign == 'G' || exp_sign == 'e' || exp_sign == 'E' ) {
218 ie = ((unsigned int)n->exponent - (unsigned int)0x3ff);
219 exponent = ie/3.321928;
222 if ( exp_sign == 'g' || exp_sign == 'G' ) {
224 if ( exponent < -4 || fabs(exponent) >= precision )
225 exp_sign -= 2; // g -> e and G -> E
228 if ( exp_sign == 'e' || exp_sign == 'E' ) {
229 frac = modf(exponent,&e);
232 else if ( frac < -0.5 )
235 result = numberf(f,__n/pow(10.0L,e),'f',size-4, precision, type);
239 if (putc( exp_sign,f) == EOF)
248 result = number(f,ie, 10,2, 2,type );
255 if ( exp_sign == 'f' ) {
261 c = (type & ZEROPAD) ? '0' : ' ';
268 } else if (type & PLUS) {
271 } else if (type & SPACE) {
277 frac = modf(__n,&intr);
279 // # flags forces a . and prevents trucation of trailing zero's
281 if ( precision > 0 ) {
282 //frac = modfl(__n,&intr);
286 frac = modf(frac, &p);
287 buf[i] = (int)p + '0';
298 if ( precision >= 1 || type & SPECIAL) {
309 while ( intr > 0.0 ) {
311 p = modf(intr, &intr);
315 buf[i++] = (int)p + '0';
321 while ( j < i && ro == 1) {
322 if ( buf[j] >= '0' && buf[j] <= '8' ) {
326 else if ( buf[j] == '9' ) {
337 if (!(type&(ZEROPAD+LEFT)))
340 if (putc(' ',f) == EOF)
346 if (putc( sign,f) == EOF)
351 if (!(type&(ZEROPAD+LEFT)))
354 if (putc(' ',f) == EOF)
358 if (type & SPECIAL) {
364 if (putc(c,f) == EOF)
370 if ( type & ZEROTRUNC && ((type & SPECIAL) != SPECIAL) ) {
372 while ( j < i && ( *tmp == '0' || *tmp == '.' )) {
378 // while (i < precision--)
382 if (putc(tmp[i],f) == EOF)
388 if (putc(' ', f) == EOF)
397 static int numberfl(FILE * f, long double __n, char exp_sign, int size, int precision, int type)
399 long double exponent = 0.0;
409 long double frac, intr;
415 int result, done = 0;
417 long_double_t *n = (long_double_t *)&__n;
419 if ( exp_sign == 'g' || exp_sign == 'G' || exp_sign == 'e' || exp_sign == 'E' ) {
420 ie = ((unsigned int)n->exponent - (unsigned int)0x3fff);
421 exponent = ie/3.321928;
424 if ( exp_sign == 'g' || exp_sign == 'G' ) {
426 if ( exponent < -4 || fabs(exponent) >= precision )
427 exp_sign -= 2; // g -> e and G -> E
430 if ( exp_sign == 'e' || exp_sign == 'E' ) {
431 frac = modfl(exponent,&e);
434 else if ( frac < -0.5 )
437 result = numberf(f,__n/powl(10.0L,e),'f',size-4, precision, type);
441 if (putc( exp_sign,f) == EOF)
450 result = number(f,ie, 10,2, 2,type );
457 if ( exp_sign == 'f' ) {
464 c = (type & ZEROPAD) ? '0' : ' ';
471 } else if (type & PLUS) {
474 } else if (type & SPACE) {
480 frac = modfl(__n,&intr);
482 // # flags forces a . and prevents trucation of trailing zero's
483 if ( precision > 0 ) {
484 //frac = modfl(__n,&intr);
489 frac = modfl((long double)frac, &p);
490 buf[i] = (int)p + '0';
501 if ( precision >= 1 || type & SPECIAL) {
512 while ( intr > 0.0 ) {
514 p = modfl(intr, &intr);
518 buf[i++] = (int)p + '0';
524 while ( j < i && ro == 1) {
525 if ( buf[j] >= '0' && buf[j] <= '8' ) {
529 else if ( buf[j] == '9' ) {
540 if (!(type&(ZEROPAD+LEFT)))
543 if (putc(' ',f) == EOF)
549 if (putc(sign,f) == EOF)
554 if (!(type&(ZEROPAD+LEFT)))
557 if (putc(' ',f) == EOF)
561 if (type & SPECIAL) {
567 if (putc(c,f) == EOF)
572 if ( type & ZEROTRUNC && ((type & SPECIAL) != SPECIAL) ) {
574 while ( j < i && ( *tmp == '0' || *tmp == '.' )) {
580 // while (i < precision--)
584 if ( putc(tmp[i],f) == EOF)
590 if (putc(' ', f) == EOF)
598 static int string(FILE *f, const char* s, int len, int field_width, int precision, int flags)
611 while (s[len] && (unsigned int)len < (unsigned int)precision)
616 if ((unsigned int)len > (unsigned int)precision)
621 while (len < field_width--)
623 if (putc(' ', f) == EOF)
627 for (i = 0; i < len; ++i)
629 if (putc(*s++, f) == EOF)
633 while (len < field_width--)
635 if (putc(' ', f) == EOF)
642 static int stringw(FILE *f, const wchar_t* sw, int len, int field_width, int precision, int flags)
655 while (sw[len] && (unsigned int)len < (unsigned int)precision)
660 if ((unsigned int)len > (unsigned int)precision)
665 while (len < field_width--)
667 if (putc(' ', f) == EOF)
671 for (i = 0; i < len; ++i)
673 if (putc((unsigned char)(*sw++), f) == EOF)
677 while (len < field_width--)
679 if (putc(' ', f) == EOF)
686 int __vfprintf(FILE *f, const char *fmt, va_list args)
691 long double _ldouble;
695 int result, done = 0;
697 int flags; /* flags to number() */
699 int field_width; /* width of output field */
700 int precision; /* min. # of digits for integers; max
701 number of chars for from string */
702 int qualifier = 0; /* 'h', 'l', 'L' or 'I64' for integer fields */
704 for (; *fmt ; ++fmt) {
706 if (putc(*fmt,f) == EOF)
715 ++fmt; /* this also skips first '%' */
717 case '-': flags |= LEFT; goto repeat;
718 case '+': flags |= PLUS; goto repeat;
719 case ' ': flags |= SPACE; goto repeat;
720 case '#': flags |= SPECIAL; goto repeat;
721 case '0': flags |= ZEROPAD; goto repeat;
724 /* get field width */
727 field_width = skip_atoi(&fmt);
728 else if (*fmt == '*') {
730 /* it's the next argument */
731 field_width = va_arg(args, int);
732 if (field_width < 0) {
733 field_width = -field_width;
738 /* get the precision */
743 precision = skip_atoi(&fmt);
744 else if (*fmt == '*') {
746 /* it's the next argument */
747 precision = va_arg(args, int);
753 /* get the conversion qualifier */
755 // %Z can be just stand alone or as size_t qualifier
771 } else if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt == 'w') {
774 } else if (*fmt == 'I' && *(fmt+1) == '6' && *(fmt+2) == '4') {
779 // go fine with ll instead of L
791 while (--field_width > 0)
793 if (putc(' ', f) == EOF)
797 if (qualifier == 'l' || qualifier == 'w')
799 if (putc((unsigned char)(wchar_t) va_arg(args, int), f) == EOF)
805 if (putc((unsigned char) va_arg(args, int), f) == EOF)
809 while (--field_width > 0)
811 if (putc(' ', f) == EOF)
819 while (--field_width > 0)
821 if (putc(' ', f) == EOF)
825 if (qualifier == 'h')
827 if (putc((unsigned char) va_arg(args, int), f) == EOF)
833 if (putc((unsigned char)(wchar_t) va_arg(args, int), f) == EOF)
837 while (--field_width > 0)
839 if (putc(' ', f) == EOF)
846 if (qualifier == 'l' || qualifier == 'w') {
847 /* print unicode string */
848 sw = va_arg(args, wchar_t *);
849 result = stringw(f, sw, -1, field_width, precision, flags);
851 /* print ascii string */
852 s = va_arg(args, char *);
853 result = string(f, s, -1, field_width, precision, flags);
861 if (qualifier == 'h') {
862 /* print ascii string */
863 s = va_arg(args, char *);
864 result = string(f, s, -1, field_width, precision, flags);
866 /* print unicode string */
867 sw = va_arg(args, wchar_t *);
868 result = stringw(f, sw, -1, field_width, precision, flags);
876 if (qualifier == 'w') {
877 /* print counted unicode string */
878 PUNICODE_STRING pus = va_arg(args, PUNICODE_STRING);
879 if ((pus == NULL) || (pus->Buffer == NULL)) {
884 len = pus->Length / sizeof(WCHAR);
886 result = stringw(f, sw, len, field_width, precision, flags);
888 /* print counted ascii string */
889 PANSI_STRING pas = va_arg(args, PANSI_STRING);
890 if ((pas == NULL) || (pas->Buffer == NULL)) {
897 result = string(f, s, -1, field_width, precision, flags);
909 if (qualifier == 'l' || qualifier == 'L' ) {
910 _ldouble = va_arg(args, long double);
912 if ( _isnanl(_ldouble) ) {
916 if (putc(*s++,f) == EOF)
922 else if ( _isinfl(_ldouble) < 0 ) {
926 if (putc(*s++,f) == EOF)
932 else if ( _isinfl(_ldouble) > 0 ) {
936 if (putc(*s++,f) == EOF)
942 if ( precision == -1 )
944 result = numberfl(f,_ldouble,*fmt,field_width,precision,flags);
950 _double = (double)va_arg(args, double);
952 if ( _isnan(_double) ) {
956 if (putc(*s++,f) == EOF)
961 } else if ( _isinf(_double) < 0 ) {
965 if (putc(*s++,f) == EOF)
970 } else if ( _isinf(_double) > 0 ) {
974 if (putc(*s++,f) == EOF)
980 if ( precision == -1 )
982 result = numberf(f,_double,*fmt,field_width,precision,flags);
991 if (field_width == -1) {
992 field_width = 2*sizeof(void *);
996 (unsigned long) va_arg(args, void *), 16,
997 field_width, precision, flags);
1004 if (qualifier == 'l') {
1005 long * ip = va_arg(args, long *);
1008 int * ip = va_arg(args, int *);
1013 /* integer number formats - set up the flags and "break" */
1037 if (putc('%', f) == EOF)
1043 if (putc(*fmt, f) == EOF)
1052 if (qualifier == 'I')
1053 num = va_arg(args, ULONGLONG);
1054 else if (qualifier == 'l')
1055 num = va_arg(args, unsigned long);
1056 else if (qualifier == 'h') {
1058 num = va_arg(args, int);
1060 num = va_arg(args, unsigned int);
1062 else if (flags & SIGN)
1063 num = va_arg(args, int);
1065 num = va_arg(args, unsigned int);
1066 result = number(f, num, base, field_width, precision, flags);