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>
15 __vfprintf (FILE *fp, const char *fmt0, va_list args);
18 vfprintf(FILE *f, const char *fmt, va_list ap)
21 char localbuf[BUFSIZ];
24 __fileno_lock(fileno(f));
26 if (f->_flag & _IONBF)
29 f->_ptr = f->_base = localbuf;
31 len = __vfprintf(f,fmt, ap);
39 len = __vfprintf(f,fmt, ap);
41 __fileno_unlock(fileno(f));
43 return (ferror(f) ? EOF : len);
48 * linux/lib/vsprintf.c
50 * Copyright (C) 1991, 1992 Linus Torvalds
53 /* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */
55 * Wirzenius wrote this portably, Torvalds fucked it up :-)
59 * Appropiated for the reactos kernel, March 1998 -- David Welch
62 #include <msvcrt/stdarg.h>
64 #include <msvcrt/ctype.h>
65 #include <msvcrt/string.h>
66 #include <msvcrt/stdio.h>
67 #include <msvcrt/string.h>
68 #include <msvcrt/math.h>
69 #include <msvcrt/internal/ieee.h>
72 #define ZEROPAD 1 /* pad with zero */
73 #define SIGN 2 /* unsigned/signed long */
74 #define PLUS 4 /* show plus */
75 #define SPACE 8 /* space if plus */
76 #define LEFT 16 /* left justified */
77 #define SPECIAL 32 /* 0x */
78 #define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */
79 #define ZEROTRUNC 128 /* truncate zero 's */
82 static int skip_atoi(const char **s)
87 i = i*10 + *((*s)++) - '0';
92 static int do_div(long long *n,int base)
94 int __res = ((unsigned long long) *n) % (unsigned) base;
95 *n = ((unsigned long long) *n) / (unsigned) base;
100 static int 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)))
144 if (putc(' ',f) == EOF)
150 if (putc(sign,f) == EOF)
154 if (type & SPECIAL) {
156 if (putc('0',f) == EOF)
161 if (putc('0', f) == EOF)
164 if (putc(digits[33],f) == EOF)
172 if (putc(c,f) == EOF)
176 while (i < precision--)
178 if (putc('0', f) == EOF)
184 if (putc(tmp[i],f) == EOF)
190 if (putc(' ', f) == EOF)
198 static int numberf(FILE * f, double __n, char exp_sign, int size, int precision, int type)
200 double exponent = 0.0;
215 int result, done = 0;
217 double_t *n = (double_t *)&__n;
219 if ( exp_sign == 'g' || exp_sign == 'G' || exp_sign == 'e' || exp_sign == 'E' ) {
220 ie = ((unsigned int)n->exponent - (unsigned int)0x3ff);
221 exponent = ie/3.321928;
224 if ( exp_sign == 'g' || exp_sign == 'G' ) {
226 if ( exponent < -4 || fabs(exponent) >= precision )
227 exp_sign -= 2; // g -> e and G -> E
230 if ( exp_sign == 'e' || exp_sign == 'E' ) {
231 frac = modf(exponent,&e);
234 else if ( frac < -0.5 )
237 result = numberf(f,__n/pow(10.0L,e),'f',size-4, precision, type);
241 if (putc( exp_sign,f) == EOF)
250 result = number(f,ie, 10,2, 2,type );
257 if ( exp_sign == 'f' ) {
263 c = (type & ZEROPAD) ? '0' : ' ';
270 } else if (type & PLUS) {
273 } else if (type & SPACE) {
279 frac = modf(__n,&intr);
281 // # flags forces a . and prevents trucation of trailing zero's
283 if ( precision > 0 ) {
284 //frac = modfl(__n,&intr);
288 frac = modf(frac, &p);
289 buf[i] = (int)p + '0';
300 if ( precision >= 1 || type & SPECIAL) {
311 while ( intr > 0.0 ) {
313 p = modf(intr, &intr);
317 buf[i++] = (int)p + '0';
323 while ( j < i && ro == 1) {
324 if ( buf[j] >= '0' && buf[j] <= '8' ) {
328 else if ( buf[j] == '9' ) {
339 if (!(type&(ZEROPAD+LEFT)))
342 if (putc(' ',f) == EOF)
348 if (putc( sign,f) == EOF)
353 if (!(type&(ZEROPAD+LEFT)))
356 if (putc(' ',f) == EOF)
360 if (type & SPECIAL) {
366 if (putc(c,f) == EOF)
372 if ( type & ZEROTRUNC && ((type & SPECIAL) != SPECIAL) ) {
374 while ( j < i && ( *tmp == '0' || *tmp == '.' )) {
380 // while (i < precision--)
384 if (putc(tmp[i],f) == EOF)
390 if (putc(' ', f) == EOF)
399 static int numberfl(FILE * f, long double __n, char exp_sign, int size, int precision, int type)
401 long double exponent = 0.0;
411 long double frac, intr;
417 int result, done = 0;
419 long_double_t *n = (long_double_t *)&__n;
421 if ( exp_sign == 'g' || exp_sign == 'G' || exp_sign == 'e' || exp_sign == 'E' ) {
422 ie = ((unsigned int)n->exponent - (unsigned int)0x3fff);
423 exponent = ie/3.321928;
426 if ( exp_sign == 'g' || exp_sign == 'G' ) {
428 if ( exponent < -4 || fabs(exponent) >= precision )
429 exp_sign -= 2; // g -> e and G -> E
432 if ( exp_sign == 'e' || exp_sign == 'E' ) {
433 frac = modfl(exponent,&e);
436 else if ( frac < -0.5 )
439 result = numberf(f,__n/powl(10.0L,e),'f',size-4, precision, type);
443 if (putc( exp_sign,f) == EOF)
452 result = number(f,ie, 10,2, 2,type );
459 if ( exp_sign == 'f' ) {
466 c = (type & ZEROPAD) ? '0' : ' ';
473 } else if (type & PLUS) {
476 } else if (type & SPACE) {
482 frac = modfl(__n,&intr);
484 // # flags forces a . and prevents trucation of trailing zero's
485 if ( precision > 0 ) {
486 //frac = modfl(__n,&intr);
491 frac = modfl((long double)frac, &p);
492 buf[i] = (int)p + '0';
503 if ( precision >= 1 || type & SPECIAL) {
514 while ( intr > 0.0 ) {
516 p = modfl(intr, &intr);
520 buf[i++] = (int)p + '0';
526 while ( j < i && ro == 1) {
527 if ( buf[j] >= '0' && buf[j] <= '8' ) {
531 else if ( buf[j] == '9' ) {
542 if (!(type&(ZEROPAD+LEFT)))
545 if (putc(' ',f) == EOF)
551 if (putc(sign,f) == EOF)
556 if (!(type&(ZEROPAD+LEFT)))
559 if (putc(' ',f) == EOF)
563 if (type & SPECIAL) {
569 if (putc(c,f) == EOF)
574 if ( type & ZEROTRUNC && ((type & SPECIAL) != SPECIAL) ) {
576 while ( j < i && ( *tmp == '0' || *tmp == '.' )) {
582 // while (i < precision--)
586 if ( putc(tmp[i],f) == EOF)
592 if (putc(' ', f) == EOF)
600 static int string(FILE *f, const char* s, int len, int field_width, int precision, int flags)
613 while (s[len] && (unsigned int)len < (unsigned int)precision)
618 if ((unsigned int)len > (unsigned int)precision)
623 while (len < field_width--)
625 if (putc(' ', f) == EOF)
629 for (i = 0; i < len; ++i)
631 if (putc(*s++, f) == EOF)
635 while (len < field_width--)
637 if (putc(' ', f) == EOF)
644 static int stringw(FILE *f, const wchar_t* sw, int len, int field_width, int precision, int flags)
657 while (sw[len] && (unsigned int)len < (unsigned int)precision)
662 if ((unsigned int)len > (unsigned int)precision)
667 while (len < field_width--)
669 if (putc(' ', f) == EOF)
673 for (i = 0; i < len; ++i)
675 if (putc((unsigned char)(*sw++), f) == EOF)
679 while (len < field_width--)
681 if (putc(' ', f) == EOF)
688 int __vfprintf(FILE *f, const char *fmt, va_list args)
691 unsigned long long num;
693 long double _ldouble;
697 int result, done = 0;
699 int flags; /* flags to number() */
701 int field_width; /* width of output field */
702 int precision; /* min. # of digits for integers; max
703 number of chars for from string */
704 int qualifier = 0; /* 'h', 'l', 'L' or 'I64' for integer fields */
706 for (; *fmt ; ++fmt) {
708 if (putc(*fmt,f) == EOF)
717 ++fmt; /* this also skips first '%' */
719 case '-': flags |= LEFT; goto repeat;
720 case '+': flags |= PLUS; goto repeat;
721 case ' ': flags |= SPACE; goto repeat;
722 case '#': flags |= SPECIAL; goto repeat;
723 case '0': flags |= ZEROPAD; goto repeat;
726 /* get field width */
729 field_width = skip_atoi(&fmt);
730 else if (*fmt == '*') {
732 /* it's the next argument */
733 field_width = va_arg(args, int);
734 if (field_width < 0) {
735 field_width = -field_width;
740 /* get the precision */
745 precision = skip_atoi(&fmt);
746 else if (*fmt == '*') {
748 /* it's the next argument */
749 precision = va_arg(args, int);
755 /* get the conversion qualifier */
757 // %Z can be just stand alone or as size_t qualifier
773 } else if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt == 'w') {
776 } else if (*fmt == 'I' && *(fmt+1) == '6' && *(fmt+2) == '4') {
781 // go fine with ll instead of L
793 while (--field_width > 0)
795 if (putc(' ', f) == EOF)
799 if (qualifier == 'l' || qualifier == 'w')
801 if (putc((unsigned char)(wchar_t) va_arg(args, int), f) == EOF)
807 if (putc((unsigned char) va_arg(args, int), f) == EOF)
811 while (--field_width > 0)
813 if (putc(' ', f) == EOF)
821 while (--field_width > 0)
823 if (putc(' ', f) == EOF)
827 if (qualifier == 'h')
829 if (putc((unsigned char) va_arg(args, int), f) == EOF)
835 if (putc((unsigned char)(wchar_t) va_arg(args, int), f) == EOF)
839 while (--field_width > 0)
841 if (putc(' ', f) == EOF)
848 if (qualifier == 'l' || qualifier == 'w') {
849 /* print unicode string */
850 sw = va_arg(args, wchar_t *);
851 result = stringw(f, sw, -1, field_width, precision, flags);
853 /* print ascii string */
854 s = va_arg(args, char *);
855 result = string(f, s, -1, field_width, precision, flags);
863 if (qualifier == 'h') {
864 /* print ascii string */
865 s = va_arg(args, char *);
866 result = string(f, s, -1, field_width, precision, flags);
868 /* print unicode string */
869 sw = va_arg(args, wchar_t *);
870 result = stringw(f, sw, -1, field_width, precision, flags);
878 if (qualifier == 'w') {
879 /* print counted unicode string */
880 PUNICODE_STRING pus = va_arg(args, PUNICODE_STRING);
881 if ((pus == NULL) || (pus->Buffer == NULL)) {
886 len = pus->Length / sizeof(WCHAR);
888 result = stringw(f, sw, len, field_width, precision, flags);
890 /* print counted ascii string */
891 PANSI_STRING pas = va_arg(args, PANSI_STRING);
892 if ((pas == NULL) || (pas->Buffer == NULL)) {
899 result = string(f, s, -1, field_width, precision, flags);
911 if (qualifier == 'l' || qualifier == 'L' ) {
912 _ldouble = va_arg(args, long double);
914 if ( _isnanl(_ldouble) ) {
918 if (putc(*s++,f) == EOF)
924 else if ( _isinfl(_ldouble) < 0 ) {
928 if (putc(*s++,f) == EOF)
934 else if ( _isinfl(_ldouble) > 0 ) {
938 if (putc(*s++,f) == EOF)
944 if ( precision == -1 )
946 result = numberfl(f,_ldouble,*fmt,field_width,precision,flags);
952 _double = (double)va_arg(args, double);
954 if ( _isnan(_double) ) {
958 if (putc(*s++,f) == EOF)
963 } else if ( _isinf(_double) < 0 ) {
967 if (putc(*s++,f) == EOF)
972 } else if ( _isinf(_double) > 0 ) {
976 if (putc(*s++,f) == EOF)
982 if ( precision == -1 )
984 result = numberf(f,_double,*fmt,field_width,precision,flags);
993 if (field_width == -1) {
994 field_width = 2*sizeof(void *);
998 (unsigned long) va_arg(args, void *), 16,
999 field_width, precision, flags);
1006 if (qualifier == 'l') {
1007 long * ip = va_arg(args, long *);
1010 int * ip = va_arg(args, int *);
1015 /* integer number formats - set up the flags and "break" */
1039 if (putc('%', f) == EOF)
1045 if (putc(*fmt, f) == EOF)
1054 if (qualifier == 'I')
1055 num = va_arg(args, unsigned long long);
1056 else if (qualifier == 'l')
1057 num = va_arg(args, unsigned long);
1058 else if (qualifier == 'h') {
1060 num = va_arg(args, int);
1062 num = va_arg(args, unsigned int);
1064 else if (flags & SIGN)
1065 num = va_arg(args, int);
1067 num = va_arg(args, unsigned int);
1068 result = number(f, num, base, field_width, precision, flags);