1 /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
2 #include <crtdll/stdio.h>
3 #include <crtdll/stdarg.h>
4 #include <crtdll/malloc.h>
5 #include <crtdll/internal/file.h>
15 __vfprintf (FILE *fp, const char *fmt0, va_list argp);
18 vfprintf(FILE *f, const char *fmt, va_list ap)
21 char localbuf[BUFSIZ];
23 if (f->_flag & _IONBF)
26 f->_ptr = f->_base = localbuf;
28 len = __vfprintf(f,fmt, ap);
36 len = __vfprintf(f,fmt, ap);
37 return (ferror(f) ? EOF : len);
42 * linux/lib/vsprintf.c
44 * Copyright (C) 1991, 1992 Linus Torvalds
47 /* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */
49 * Wirzenius wrote this portably, Torvalds fucked it up :-)
53 * Appropiated for the reactos kernel, March 1998 -- David Welch
58 #include <crtdll/ctype.h>
59 #include <crtdll/string.h>
60 #include <crtdll/stdio.h>
61 #include <crtdll/string.h>
62 #include <crtdll/math.h>
63 #include <crtdll/internal/ieee.h>
66 #define ZEROPAD 1 /* pad with zero */
67 #define SIGN 2 /* unsigned/signed long */
68 #define PLUS 4 /* show plus */
69 #define SPACE 8 /* space if plus */
70 #define LEFT 16 /* left justified */
71 #define SPECIAL 32 /* 0x */
72 #define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */
73 #define ZEROTRUNC 128 /* truncate zero 's */
76 static int skip_atoi(const char **s)
81 i = i*10 + *((*s)++) - '0';
86 static int do_div(long long *n,int base)
88 int __res = ((unsigned long long) *n) % (unsigned) base;
89 *n = ((unsigned long long) *n) / (unsigned) base;
94 static void number(FILE * f, long long num, int base, int size, int precision ,int type)
97 const char *digits="0123456789abcdefghijklmnopqrstuvwxyz";
101 digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
104 if (base < 2 || base > 36)
106 c = (type & ZEROPAD) ? '0' : ' ';
113 } else if (type & PLUS) {
116 } else if (type & SPACE) {
121 if (type & SPECIAL) {
130 else while (num != 0)
131 tmp[i++] = digits[do_div(&num,base)];
135 if (!(type&(ZEROPAD+LEFT)))
140 if (type & SPECIAL) {
152 while (i < precision--)
162 static void numberf(FILE * f, double __n, char exp_sign, int size, int precision, int type)
164 double exponent = 0.0;
180 double_t *n = (double_t *)&__n;
182 if ( exp_sign == 'g' || exp_sign == 'G' || exp_sign == 'e' || exp_sign == 'E' ) {
183 ie = ((unsigned int)n->exponent - (unsigned int)0x3ff);
184 exponent = ie/3.321928;
187 if ( exp_sign == 'g' || exp_sign == 'G' ) {
189 if ( exponent < -4 || fabs(exponent) >= precision )
190 exp_sign -= 2; // g -> e and G -> E
193 if ( exp_sign == 'e' || exp_sign == 'E' ) {
194 frac = modf(exponent,&e);
197 else if ( frac < -0.5 )
200 numberf(f,__n/pow(10.0L,e),'f',size-4, precision, type);
208 number(f,ie, 10,2, 2,type );
212 if ( exp_sign == 'f' ) {
218 c = (type & ZEROPAD) ? '0' : ' ';
225 } else if (type & PLUS) {
228 } else if (type & SPACE) {
234 frac = modf(__n,&intr);
236 // # flags forces a . and prevents trucation of trailing zero's
238 if ( precision > 0 ) {
239 //frac = modfl(__n,&intr);
243 frac = modf(frac, &p);
244 buf[i] = (int)p + '0';
255 if ( precision >= 1 || type & SPECIAL) {
266 while ( intr > 0.0 ) {
268 p = modf(intr, &intr);
272 buf[i++] = (int)p + '0';
278 while ( j < i && ro == 1) {
279 if ( buf[j] >= '0' && buf[j] <= '8' ) {
283 else if ( buf[j] == '9' ) {
294 if (!(type&(ZEROPAD+LEFT)))
300 if (!(type&(ZEROPAD+LEFT)))
303 if (type & SPECIAL) {
311 if ( type & ZEROTRUNC && ((type & SPECIAL) != SPECIAL) ) {
313 while ( j < i && ( *tmp == '0' || *tmp == '.' )) {
319 // while (i < precision--)
329 static void numberfl(FILE * f, long double __n, char exp_sign, int size, int precision, int type)
331 long double exponent = 0.0;
341 long double frac, intr;
347 long_double_t *n = (long_double_t *)&__n;
349 if ( exp_sign == 'g' || exp_sign == 'G' || exp_sign == 'e' || exp_sign == 'E' ) {
350 ie = ((unsigned int)n->exponent - (unsigned int)0x3fff);
351 exponent = ie/3.321928;
354 if ( exp_sign == 'g' || exp_sign == 'G' ) {
356 if ( exponent < -4 || fabs(exponent) >= precision )
357 exp_sign -= 2; // g -> e and G -> E
360 if ( exp_sign == 'e' || exp_sign == 'E' ) {
361 frac = modfl(exponent,&e);
364 else if ( frac < -0.5 )
367 numberf(f,__n/powl(10.0L,e),'f',size-4, precision, type);
375 number(f,ie, 10,2, 2,type );
379 if ( exp_sign == 'f' ) {
386 c = (type & ZEROPAD) ? '0' : ' ';
393 } else if (type & PLUS) {
396 } else if (type & SPACE) {
402 frac = modfl(__n,&intr);
404 // # flags forces a . and prevents trucation of trailing zero's
405 if ( precision > 0 ) {
406 //frac = modfl(__n,&intr);
411 frac = modfl((long double)frac, &p);
412 buf[i] = (int)p + '0';
423 if ( precision >= 1 || type & SPECIAL) {
434 while ( intr > 0.0 ) {
436 p = modfl(intr, &intr);
440 buf[i++] = (int)p + '0';
446 while ( j < i && ro == 1) {
447 if ( buf[j] >= '0' && buf[j] <= '8' ) {
451 else if ( buf[j] == '9' ) {
462 if (!(type&(ZEROPAD+LEFT)))
468 if (!(type&(ZEROPAD+LEFT)))
471 if (type & SPECIAL) {
479 if ( type & ZEROTRUNC && ((type & SPECIAL) != SPECIAL) ) {
481 while ( j < i && ( *tmp == '0' || *tmp == '.' )) {
487 // while (i < precision--)
497 int __vfprintf(FILE *f, const char *fmt, va_list args)
500 unsigned long long num;
502 long double _ldouble;
507 int flags; /* flags to number() */
509 int field_width; /* width of output field */
510 int precision; /* min. # of digits for integers; max
511 number of chars for from string */
512 int qualifier = 0; /* 'h', 'l', 'L' or 'I64' for integer fields */
514 for (; *fmt ; ++fmt) {
523 ++fmt; /* this also skips first '%' */
525 case '-': flags |= LEFT; goto repeat;
526 case '+': flags |= PLUS; goto repeat;
527 case ' ': flags |= SPACE; goto repeat;
528 case '#': flags |= SPECIAL; goto repeat;
529 case '0': flags |= ZEROPAD; goto repeat;
532 /* get field width */
535 field_width = skip_atoi(&fmt);
536 else if (*fmt == '*') {
538 /* it's the next argument */
539 field_width = va_arg(args, int);
540 if (field_width < 0) {
541 field_width = -field_width;
546 /* get the precision */
551 precision = skip_atoi(&fmt);
552 else if (*fmt == '*') {
554 /* it's the next argument */
555 precision = va_arg(args, int);
561 /* get the conversion qualifier */
562 // %Z can be just stand alone or as size_t qualifier
578 } else if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt == 'w') {
581 } else if (*fmt == 'I' && *(fmt+1) == '6' && *(fmt+2) == '4') {
586 // go fine with ll instead of L
598 while (--field_width > 0)
600 if (qualifier == 'l' || qualifier == 'w')
601 putc((unsigned char)(wchar_t) va_arg(args, int), f);
603 putc((unsigned char) va_arg(args, int), f);
604 while (--field_width > 0)
610 while (--field_width > 0)
612 if (qualifier == 'h')
613 putc((unsigned char) va_arg(args, int), f);
615 putc((unsigned char)(wchar_t) va_arg(args, int), f);
616 while (--field_width > 0)
621 if (qualifier == 'l' || qualifier == 'w') {
622 /* print unicode string */
623 sw = va_arg(args, wchar_t *);
628 if ((unsigned int)len > (unsigned int)precision)
632 while (len < field_width--)
634 for (i = 0; i < len; ++i)
635 putc((unsigned char)(*sw++), f);
636 while (len < field_width--)
639 /* print ascii string */
640 s = va_arg(args, char *);
645 if ((unsigned int)len > (unsigned int)precision)
649 while (len < field_width--)
651 for (i = 0; i < len; ++i)
653 while (len < field_width--)
659 if (qualifier == 'h') {
660 /* print ascii string */
661 s = va_arg(args, char *);
666 if ((unsigned int)len > (unsigned int)precision)
670 while (len < field_width--)
672 for (i = 0; i < len; ++i)
674 while (len < field_width--)
677 /* print unicode string */
678 sw = va_arg(args, wchar_t *);
683 if ((unsigned int)len > (unsigned int)precision)
687 while (len < field_width--)
689 for (i = 0; i < len; ++i)
690 putc((unsigned char)(*sw++), f);
691 while (len < field_width--)
697 if (qualifier == 'w') {
698 /* print counted unicode string */
699 PUNICODE_STRING pus = va_arg(args, PUNICODE_STRING);
700 if ((pus == NULL) || (pus->Buffer == NULL)) {
705 for (i = 0; pus->Buffer[i] && i < pus->Length / sizeof(WCHAR); i++)
706 putc((unsigned char)(pus->Buffer[i]), f);
709 /* print counted ascii string */
710 PANSI_STRING pus = va_arg(args, PANSI_STRING);
711 if ((pus == NULL) || (pus->Buffer == NULL)) {
716 for (i = 0; pus->Buffer[i] && i < pus->Length; i++)
717 putc(pus->Buffer[i], f);
727 if (qualifier == 'l' || qualifier == 'L' ) {
728 _ldouble = va_arg(args, long double);
730 if ( _isnanl(_ldouble) ) {
738 else if ( _isinfl(_ldouble) < 0 ) {
746 else if ( _isinfl(_ldouble) > 0 ) {
754 if ( precision == -1 )
756 numberfl(f,_ldouble,*fmt,field_width,precision,flags);
759 _double = (double)va_arg(args, double);
761 if ( _isnan(_double) ) {
768 } else if ( _isinf(_double) < 0 ) {
775 } else if ( _isinf(_double) > 0 ) {
783 if ( precision == -1 )
785 numberf(f,_double,*fmt,field_width,precision,flags);
791 if (field_width == -1) {
792 field_width = 2*sizeof(void *);
796 (unsigned long) va_arg(args, void *), 16,
797 field_width, precision, flags);
801 if (qualifier == 'l') {
802 long * ip = va_arg(args, long *);
805 int * ip = va_arg(args, int *);
810 /* integer number formats - set up the flags and "break" */
841 if (qualifier == 'I')
842 num = va_arg(args, unsigned long long);
843 else if (qualifier == 'l')
844 num = va_arg(args, unsigned long);
845 else if (qualifier == 'h') {
847 num = va_arg(args, int);
849 num = va_arg(args, unsigned int);
851 else if (flags & SIGN)
852 num = va_arg(args, int);
854 num = va_arg(args, unsigned int);
855 number(f, num, base, field_width, precision, flags);