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);
20 int vfprintf(FILE* f, const char* fmt, va_list ap)
23 char localbuf[BUFSIZ];
26 __fileno_lock(fileno(f));
28 if (f->_flag & _IONBF) {
30 f->_ptr = f->_base = localbuf;
32 len = __vfprintf(f, fmt, ap);
39 len = __vfprintf(f,fmt, ap);
42 __fileno_unlock(fileno(f));
44 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
63 #include <msvcrt/stdarg.h>
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_atoi(const char **s)
88 i = i*10 + *((*s)++) - '0';
93 static int do_div(LONGLONG *n,int base)
95 int __res = ((ULONGLONG) *n) % (unsigned) base;
96 *n = ((ULONGLONG) *n) / (unsigned) base;
101 static int number(FILE * f, LONGLONG num, int base, int size, int precision ,int type)
104 const char *digits="0123456789abcdefghijklmnopqrstuvwxyz";
108 digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
111 if (base < 2 || base > 36)
113 c = (type & ZEROPAD) ? '0' : ' ';
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)))
145 if (putc(' ',f) == EOF)
151 if (putc(sign,f) == EOF)
155 if (type & SPECIAL) {
157 if (putc('0',f) == EOF)
162 if (putc('0', f) == EOF)
165 if (putc(digits[33],f) == EOF)
173 if (putc(c,f) == EOF)
177 while (i < precision--)
179 if (putc('0', f) == EOF)
185 if (putc(tmp[i],f) == EOF)
191 if (putc(' ', f) == EOF)
199 static int numberf(FILE * f, double __n, char exp_sign, int size, int precision, int type)
201 double exponent = 0.0;
216 int result, done = 0;
218 double_t *n = (double_t *)&__n;
220 if ( exp_sign == 'g' || exp_sign == 'G' || exp_sign == 'e' || exp_sign == 'E' ) {
221 ie = ((unsigned int)n->exponent - (unsigned int)0x3ff);
222 exponent = ie/3.321928;
225 if ( exp_sign == 'g' || exp_sign == 'G' ) {
227 if ( exponent < -4 || fabs(exponent) >= precision )
228 exp_sign -= 2; // g -> e and G -> E
231 if ( exp_sign == 'e' || exp_sign == 'E' ) {
232 frac = modf(exponent,&e);
235 else if ( frac < -0.5 )
238 result = numberf(f,__n/pow(10.0L,e),'f',size-4, precision, type);
242 if (putc( exp_sign,f) == EOF)
251 result = number(f,ie, 10,2, 2,type );
258 if ( exp_sign == 'f' ) {
264 c = (type & ZEROPAD) ? '0' : ' ';
271 } else if (type & PLUS) {
274 } else if (type & SPACE) {
280 frac = modf(__n,&intr);
282 // # flags forces a . and prevents trucation of trailing zero's
284 if ( precision > 0 ) {
285 //frac = modfl(__n,&intr);
289 frac = modf(frac, &p);
290 buf[i] = (int)p + '0';
301 if ( precision >= 1 || type & SPECIAL) {
312 while ( intr > 0.0 ) {
319 buf[i++] = (int)p + '0';
325 while ( j < i && ro == 1) {
326 if ( buf[j] >= '0' && buf[j] <= '8' ) {
330 else if ( buf[j] == '9' ) {
341 if (!(type&(ZEROPAD+LEFT)))
344 if (putc(' ',f) == EOF)
350 if (putc( sign,f) == EOF)
355 if (!(type&(ZEROPAD+LEFT)))
358 if (putc(' ',f) == EOF)
362 if (type & SPECIAL) {
368 if (putc(c,f) == EOF)
374 if ( type & ZEROTRUNC && ((type & SPECIAL) != SPECIAL) ) {
376 while ( j < i && ( *tmp == '0' || *tmp == '.' )) {
382 // while (i < precision--)
386 if (putc(tmp[i],f) == EOF)
392 if (putc(' ', f) == EOF)
401 static int numberfl(FILE * f, long double __n, char exp_sign, int size, int precision, int type)
403 long double exponent = 0.0;
413 long double frac, intr;
419 int result, done = 0;
421 long_double_t *n = (long_double_t *)&__n;
423 if ( exp_sign == 'g' || exp_sign == 'G' || exp_sign == 'e' || exp_sign == 'E' ) {
424 ie = ((unsigned int)n->exponent - (unsigned int)0x3fff);
425 exponent = ie/3.321928;
428 if ( exp_sign == 'g' || exp_sign == 'G' ) {
430 if ( exponent < -4 || fabs(exponent) >= precision )
431 exp_sign -= 2; // g -> e and G -> E
434 if ( exp_sign == 'e' || exp_sign == 'E' ) {
435 frac = modfl(exponent,&e);
438 else if ( frac < -0.5 )
441 result = numberf(f,__n/powl(10.0L,e),'f',size-4, precision, type);
445 if (putc( exp_sign,f) == EOF)
454 result = number(f,ie, 10,2, 2,type );
461 if ( exp_sign == 'f' ) {
468 c = (type & ZEROPAD) ? '0' : ' ';
475 } else if (type & PLUS) {
478 } else if (type & SPACE) {
484 frac = modfl(__n,&intr);
486 // # flags forces a . and prevents trucation of trailing zero's
487 if ( precision > 0 ) {
488 //frac = modfl(__n,&intr);
493 frac = modfl((long double)frac, &p);
494 buf[i] = (int)p + '0';
505 if ( precision >= 1 || type & SPECIAL) {
516 while ( intr > 0.0 ) {
523 buf[i++] = (int)p + '0';
529 while ( j < i && ro == 1) {
530 if ( buf[j] >= '0' && buf[j] <= '8' ) {
534 else if ( buf[j] == '9' ) {
545 if (!(type&(ZEROPAD+LEFT)))
548 if (putc(' ',f) == EOF)
554 if (putc(sign,f) == EOF)
559 if (!(type&(ZEROPAD+LEFT)))
562 if (putc(' ',f) == EOF)
566 if (type & SPECIAL) {
572 if (putc(c,f) == EOF)
577 if ( type & ZEROTRUNC && ((type & SPECIAL) != SPECIAL) ) {
579 while ( j < i && ( *tmp == '0' || *tmp == '.' )) {
585 // while (i < precision--)
589 if ( putc(tmp[i],f) == EOF)
595 if (putc(' ', f) == EOF)
603 static int string(FILE *f, const char* s, int len, int field_width, int precision, int flags)
616 while (s[len] && (unsigned int)len < (unsigned int)precision)
621 if ((unsigned int)len > (unsigned int)precision)
626 while (len < field_width--)
628 if (putc(' ', f) == EOF)
632 for (i = 0; i < len; ++i)
634 if (putc(*s++, f) == EOF)
638 while (len < field_width--)
640 if (putc(' ', f) == EOF)
647 static int stringw(FILE *f, const wchar_t* sw, int len, int field_width, int precision, int flags)
660 while (sw[len] && (unsigned int)len < (unsigned int)precision)
665 if ((unsigned int)len > (unsigned int)precision)
670 while (len < field_width--)
672 if (putc(' ', f) == EOF)
676 for (i = 0; i < len; ++i)
678 if (putc((unsigned char)(*sw++), f) == EOF)
682 while (len < field_width--)
684 if (putc(' ', f) == EOF)
691 int __vfprintf(FILE *f, const char *fmt, va_list args)
696 long double _ldouble;
700 int result, done = 0;
702 int flags; /* flags to number() */
704 int field_width; /* width of output field */
705 int precision; /* min. # of digits for integers; max
706 number of chars for from string */
707 int qualifier = 0; /* 'h', 'l', 'L' or 'I64' for integer fields */
709 for (; *fmt ; ++fmt) {
711 if (putc(*fmt,f) == EOF)
720 ++fmt; /* this also skips first '%' */
722 case '-': flags |= LEFT; goto repeat;
723 case '+': flags |= PLUS; goto repeat;
724 case ' ': flags |= SPACE; goto repeat;
725 case '#': flags |= SPECIAL; goto repeat;
726 case '0': flags |= ZEROPAD; goto repeat;
729 /* get field width */
732 field_width = skip_atoi(&fmt);
733 else if (*fmt == '*') {
735 /* it's the next argument */
736 field_width = va_arg(args, int);
737 if (field_width < 0) {
738 field_width = -field_width;
743 /* get the precision */
748 precision = skip_atoi(&fmt);
749 else if (*fmt == '*') {
751 /* it's the next argument */
752 precision = va_arg(args, int);
758 /* get the conversion qualifier */
760 // %Z can be just stand alone or as size_t qualifier
776 } else if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt == 'w') {
779 } else if (*fmt == 'I' && *(fmt+1) == '6' && *(fmt+2) == '4') {
784 // go fine with ll instead of L
796 while (--field_width > 0)
798 if (putc(' ', f) == EOF)
802 if (qualifier == 'l' || qualifier == 'w')
804 if (putc((unsigned char)(wchar_t) va_arg(args, int), f) == EOF)
810 if (putc((unsigned char) va_arg(args, int), f) == EOF)
814 while (--field_width > 0)
816 if (putc(' ', f) == EOF)
824 while (--field_width > 0)
826 if (putc(' ', f) == EOF)
830 if (qualifier == 'h')
832 if (putc((unsigned char) va_arg(args, int), f) == EOF)
838 if (putc((unsigned char)(wchar_t) va_arg(args, int), f) == EOF)
842 while (--field_width > 0)
844 if (putc(' ', f) == EOF)
851 if (qualifier == 'l' || qualifier == 'w') {
852 /* print unicode string */
853 sw = va_arg(args, wchar_t *);
854 result = stringw(f, sw, -1, field_width, precision, flags);
856 /* print ascii string */
857 s = va_arg(args, char *);
858 result = string(f, s, -1, field_width, precision, flags);
866 if (qualifier == 'h') {
867 /* print ascii string */
868 s = va_arg(args, char *);
869 result = string(f, s, -1, field_width, precision, flags);
871 /* print unicode string */
872 sw = va_arg(args, wchar_t *);
873 result = stringw(f, sw, -1, field_width, precision, flags);
881 if (qualifier == 'w') {
882 /* print counted unicode string */
883 PUNICODE_STRING pus = va_arg(args, PUNICODE_STRING);
884 if ((pus == NULL) || (pus->Buffer == NULL)) {
889 len = pus->Length / sizeof(WCHAR);
891 result = stringw(f, sw, len, field_width, precision, flags);
893 /* print counted ascii string */
894 PANSI_STRING pas = va_arg(args, PANSI_STRING);
895 if ((pas == NULL) || (pas->Buffer == NULL)) {
902 result = string(f, s, -1, field_width, precision, flags);
914 if (qualifier == 'l' || qualifier == 'L' ) {
915 _ldouble = va_arg(args, long double);
917 if ( _isnanl(_ldouble) ) {
921 if (putc(*s++,f) == EOF)
927 else if ( _isinfl(_ldouble) < 0 ) {
931 if (putc(*s++,f) == EOF)
937 else if ( _isinfl(_ldouble) > 0 ) {
941 if (putc(*s++,f) == EOF)
947 if ( precision == -1 )
949 result = numberfl(f,_ldouble,*fmt,field_width,precision,flags);
955 _double = (double)va_arg(args, double);
957 if ( _isnan(_double) ) {
961 if (putc(*s++,f) == EOF)
966 } else if ( _isinf(_double) < 0 ) {
970 if (putc(*s++,f) == EOF)
975 } else if ( _isinf(_double) > 0 ) {
979 if (putc(*s++,f) == EOF)
985 if ( precision == -1 )
987 result = numberf(f,_double,*fmt,field_width,precision,flags);
996 if (field_width == -1) {
997 field_width = 2*sizeof(void *);
1001 (unsigned long) va_arg(args, void *), 16,
1002 field_width, precision, flags);
1009 if (qualifier == 'l') {
1010 long * ip = va_arg(args, long *);
1013 int * ip = va_arg(args, int *);
1018 /* integer number formats - set up the flags and "break" */
1042 if (putc('%', f) == EOF)
1048 if (putc(*fmt, f) == EOF)
1057 if (qualifier == 'I')
1058 num = va_arg(args, ULONGLONG);
1059 else if (qualifier == 'l')
1060 num = va_arg(args, unsigned long);
1061 else if (qualifier == 'h') {
1063 num = va_arg(args, int);
1065 num = va_arg(args, unsigned int);
1067 else if (flags & SIGN)
1068 num = va_arg(args, int);
1070 num = va_arg(args, unsigned int);
1071 result = number(f, num, base, field_width, precision, flags);