Improved unicode fileio support.
[reactos.git] / reactos / lib / msvcrt / stdio / vfprintf.c
1 /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
2 #include <stdarg.h>
3 #include <msvcrt/stdio.h>
4 #include <msvcrt/malloc.h>
5 #include <msvcrt/internal/file.h>
6
7 int _isnanl(double x);
8 int _isinfl(double x);
9 int _isnan(double x);
10 int _isinf(double x);
11
12
13
14 int __vfprintf(FILE*, const char*, va_list);
15
16
17 int vfprintf(FILE* f, const char* fmt, va_list ap)
18 {
19 int len;
20 char localbuf[BUFSIZ];
21
22 #if 0
23 __fileno_lock(fileno(f));
24 #endif
25 if (f->_flag & _IONBF) {
26 f->_flag &= ~_IONBF;
27 f->_ptr = f->_base = localbuf;
28 f->_bufsiz = BUFSIZ;
29 len = __vfprintf(f, fmt, ap);
30 (void)fflush(f);
31 f->_flag |= _IONBF;
32 f->_base = NULL;
33 f->_bufsiz = 0;
34 f->_cnt = 0;
35 } else {
36 len = __vfprintf(f,fmt, ap);
37 }
38 #if 0
39 __fileno_unlock(fileno(f));
40 #endif
41 return (ferror(f) ? EOF : len);
42 }
43
44
45 /*
46 * linux/lib/vsprintf.c
47 *
48 * Copyright (C) 1991, 1992 Linus Torvalds
49 */
50
51 /* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */
52 /*
53 * Wirzenius wrote this portably, Torvalds fucked it up :-)
54 */
55
56 /*
57 * Appropiated for the reactos kernel, March 1998 -- David Welch
58 */
59
60 #include <msvcrt/stdarg.h>
61
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>
68
69
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 */
78
79
80 static int skip_atoi(const char **s)
81 {
82 int i=0;
83
84 while (isdigit(**s))
85 i = i*10 + *((*s)++) - '0';
86 return i;
87 }
88
89
90 static int do_div(LONGLONG *n,int base)
91 {
92 int __res = ((ULONGLONG) *n) % (unsigned) base;
93 *n = ((ULONGLONG) *n) / (unsigned) base;
94 return __res;
95 }
96
97
98 static int number(FILE * f, LONGLONG num, int base, int size, int precision ,int type)
99 {
100 char c,sign,tmp[66];
101 const char *digits="0123456789abcdefghijklmnopqrstuvwxyz";
102 int i, done = 0;
103
104 if (type & LARGE)
105 digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
106 if (type & LEFT)
107 type &= ~ZEROPAD;
108 if (base < 2 || base > 36)
109 return done;
110 c = (type & ZEROPAD) ? '0' : ' ';
111 sign = 0;
112 if (type & SIGN) {
113 if (num < 0) {
114 sign = '-';
115 num = -num;
116 size--;
117 } else if (type & PLUS) {
118 sign = '+';
119 size--;
120 } else if (type & SPACE) {
121 sign = ' ';
122 size--;
123 }
124 }
125 if (type & SPECIAL) {
126 if (base == 16)
127 size -= 2;
128 else if (base == 8)
129 size--;
130 }
131 i = 0;
132 if (num == 0)
133 tmp[i++]='0';
134 else while (num != 0)
135 tmp[i++] = digits[do_div(&num,base)];
136 if (i > precision)
137 precision = i;
138 size -= precision;
139 if (!(type&(ZEROPAD+LEFT)))
140 while(size-->0)
141 {
142 if (putc(' ',f) == EOF)
143 return -1;
144 done++;
145 }
146 if (sign)
147 {
148 if (putc(sign,f) == EOF)
149 return -1;
150 done++;
151 }
152 if (type & SPECIAL) {
153 if (base==8) {
154 if (putc('0',f) == EOF)
155 return -1;
156 done++;
157 }
158 else if (base==16) {
159 if (putc('0', f) == EOF)
160 return -1;
161 done++;
162 if (putc(digits[33],f) == EOF)
163 return -1;
164 done++;
165 }
166 }
167 if (!(type & LEFT))
168 while (size-- > 0)
169 {
170 if (putc(c,f) == EOF)
171 return -1;
172 done++;
173 }
174 while (i < precision--)
175 {
176 if (putc('0', f) == EOF)
177 return -1;
178 done++;
179 }
180 while (i-- > 0)
181 {
182 if (putc(tmp[i],f) == EOF)
183 return -1;
184 done++;
185 }
186 while (size-- > 0)
187 {
188 if (putc(' ', f) == EOF)
189 return -1;
190 done++;
191 }
192 return done;
193 }
194
195
196 static int numberf(FILE * f, double __n, char exp_sign, int size, int precision, int type)
197 {
198 double exponent = 0.0;
199 double e;
200 long ie;
201
202 //int x;
203 char *buf, *tmp;
204 int i = 0;
205 int j = 0;
206 //int k = 0;
207
208 double frac, intr;
209 double p;
210 char sign;
211 char c;
212 char ro = 0;
213 int result, done = 0;
214
215 double_t *n = (double_t *)&__n;
216
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;
220 }
221
222 if ( exp_sign == 'g' || exp_sign == 'G' ) {
223 type |= ZEROTRUNC;
224 if ( exponent < -4 || fabs(exponent) >= precision )
225 exp_sign -= 2; // g -> e and G -> E
226 }
227
228 if ( exp_sign == 'e' || exp_sign == 'E' ) {
229 frac = modf(exponent,&e);
230 if ( frac > 0.5 )
231 e++;
232 else if ( frac < -0.5 )
233 e--;
234
235 result = numberf(f,__n/pow(10.0L,e),'f',size-4, precision, type);
236 if (result < 0)
237 return -1;
238 done += result;
239 if (putc( exp_sign,f) == EOF)
240 return -1;
241 done++;
242 size--;
243 ie = (long)e;
244 type = LEFT | PLUS;
245 if ( ie < 0 )
246 type |= SIGN;
247
248 result = number(f,ie, 10,2, 2,type );
249 if (result < 0)
250 return -1;
251 done += result;
252 return done;
253 }
254
255 if ( exp_sign == 'f' ) {
256 buf = alloca(4096);
257 if (type & LEFT) {
258 type &= ~ZEROPAD;
259 }
260
261 c = (type & ZEROPAD) ? '0' : ' ';
262 sign = 0;
263 if (type & SIGN) {
264 if (__n < 0) {
265 sign = '-';
266 __n = fabs(__n);
267 size--;
268 } else if (type & PLUS) {
269 sign = '+';
270 size--;
271 } else if (type & SPACE) {
272 sign = ' ';
273 size--;
274 }
275 }
276
277 frac = modf(__n,&intr);
278
279 // # flags forces a . and prevents trucation of trailing zero's
280
281 if ( precision > 0 ) {
282 //frac = modfl(__n,&intr);
283 i = precision-1;
284 while ( i >= 0 ) {
285 frac*=10.0L;
286 frac = modf(frac, &p);
287 buf[i] = (int)p + '0';
288 i--;
289 }
290 i = precision;
291 size -= precision;
292
293 ro = 0;
294 if ( frac > 0.5 ) {
295 ro = 1;
296 }
297
298 if ( precision >= 1 || type & SPECIAL) {
299 buf[i++] = '.';
300 size--;
301 }
302 }
303
304 if ( intr == 0.0 ) {
305 buf[i++] = '0';
306 size--;
307 }
308 else {
309 while ( intr > 0.0 ) {
310 intr/=10.0L;
311 p = modf(intr, &intr);
312
313 p *=10;
314
315 buf[i++] = (int)p + '0';
316 size--;
317 }
318 }
319
320 j = 0;
321 while ( j < i && ro == 1) {
322 if ( buf[j] >= '0' && buf[j] <= '8' ) {
323 buf[j]++;
324 ro = 0;
325 }
326 else if ( buf[j] == '9' ) {
327 buf[j] = '0';
328 }
329 j++;
330 }
331 if ( ro == 1 )
332 buf[i++] = '1';
333
334 buf[i] = 0;
335
336 size -= precision;
337 if (!(type&(ZEROPAD+LEFT)))
338 while(size-->0)
339 {
340 if (putc(' ',f) == EOF)
341 return -1;
342 done++;
343 }
344 if (sign)
345 {
346 if (putc( sign,f) == EOF)
347 return -1;
348 done++;
349 }
350
351 if (!(type&(ZEROPAD+LEFT)))
352 while(size-->0)
353 {
354 if (putc(' ',f) == EOF)
355 return -1;
356 done++;
357 }
358 if (type & SPECIAL) {
359 }
360
361 if (!(type & LEFT))
362 while (size-- > 0)
363 {
364 if (putc(c,f) == EOF)
365 return -1;
366 done++;
367 }
368
369 tmp = buf;
370 if ( type & ZEROTRUNC && ((type & SPECIAL) != SPECIAL) ) {
371 j = 0;
372 while ( j < i && ( *tmp == '0' || *tmp == '.' )) {
373 tmp++;
374 i--;
375 }
376 }
377 // else
378 // while (i < precision--)
379 // putc('0', f);
380 while (i-- > 0)
381 {
382 if (putc(tmp[i],f) == EOF)
383 return -1;
384 done++;
385 }
386 while (size-- > 0)
387 {
388 if (putc(' ', f) == EOF)
389 return -1;
390 done++;
391 }
392 }
393 return done;
394 }
395
396
397 static int numberfl(FILE * f, long double __n, char exp_sign, int size, int precision, int type)
398 {
399 long double exponent = 0.0;
400 long double e;
401 long ie;
402
403 //int x;
404 char *buf, *tmp;
405 int i = 0;
406 int j = 0;
407 //int k = 0;
408
409 long double frac, intr;
410 long double p;
411 char sign;
412 char c;
413 char ro = 0;
414
415 int result, done = 0;
416
417 long_double_t *n = (long_double_t *)&__n;
418
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;
422 }
423
424 if ( exp_sign == 'g' || exp_sign == 'G' ) {
425 type |= ZEROTRUNC;
426 if ( exponent < -4 || fabs(exponent) >= precision )
427 exp_sign -= 2; // g -> e and G -> E
428 }
429
430 if ( exp_sign == 'e' || exp_sign == 'E' ) {
431 frac = modfl(exponent,&e);
432 if ( frac > 0.5 )
433 e++;
434 else if ( frac < -0.5 )
435 e--;
436
437 result = numberf(f,__n/powl(10.0L,e),'f',size-4, precision, type);
438 if (result < 0)
439 return -1;
440 done += result;
441 if (putc( exp_sign,f) == EOF)
442 return -1;
443 done++;
444 size--;
445 ie = (long)e;
446 type = LEFT | PLUS;
447 if ( ie < 0 )
448 type |= SIGN;
449
450 result = number(f,ie, 10,2, 2,type );
451 if (result < 0)
452 return -1;
453 done += result;
454 return done;
455 }
456
457 if ( exp_sign == 'f' ) {
458
459 buf = alloca(4096);
460 if (type & LEFT) {
461 type &= ~ZEROPAD;
462 }
463
464 c = (type & ZEROPAD) ? '0' : ' ';
465 sign = 0;
466 if (type & SIGN) {
467 if (__n < 0) {
468 sign = '-';
469 __n = fabs(__n);
470 size--;
471 } else if (type & PLUS) {
472 sign = '+';
473 size--;
474 } else if (type & SPACE) {
475 sign = ' ';
476 size--;
477 }
478 }
479
480 frac = modfl(__n,&intr);
481
482 // # flags forces a . and prevents trucation of trailing zero's
483 if ( precision > 0 ) {
484 //frac = modfl(__n,&intr);
485
486 i = precision-1;
487 while ( i >= 0 ) {
488 frac*=10.0L;
489 frac = modfl((long double)frac, &p);
490 buf[i] = (int)p + '0';
491 i--;
492 }
493 i = precision;
494 size -= precision;
495
496 ro = 0;
497 if ( frac > 0.5 ) {
498 ro = 1;
499 }
500
501 if ( precision >= 1 || type & SPECIAL) {
502 buf[i++] = '.';
503 size--;
504 }
505 }
506
507 if ( intr == 0.0 ) {
508 buf[i++] = '0';
509 size--;
510 }
511 else {
512 while ( intr > 0.0 ) {
513 intr/=10.0L;
514 p = modfl(intr, &intr);
515
516 p *=10;
517
518 buf[i++] = (int)p + '0';
519 size--;
520 }
521 }
522
523 j = 0;
524 while ( j < i && ro == 1) {
525 if ( buf[j] >= '0' && buf[j] <= '8' ) {
526 buf[j]++;
527 ro = 0;
528 }
529 else if ( buf[j] == '9' ) {
530 buf[j] = '0';
531 }
532 j++;
533 }
534 if ( ro == 1 )
535 buf[i++] = '1';
536
537 buf[i] = 0;
538
539 size -= precision;
540 if (!(type&(ZEROPAD+LEFT)))
541 while(size-->0)
542 {
543 if (putc(' ',f) == EOF)
544 return -1;
545 done++;
546 }
547 if (sign)
548 {
549 if (putc(sign,f) == EOF)
550 return -1;
551 done++;
552 }
553
554 if (!(type&(ZEROPAD+LEFT)))
555 while(size-->0)
556 {
557 if (putc(' ',f) == EOF)
558 return -1;
559 done++;
560 }
561 if (type & SPECIAL) {
562 }
563
564 if (!(type & LEFT))
565 while (size-- > 0)
566 {
567 if (putc(c,f) == EOF)
568 return -1;
569 done++;
570 }
571 tmp = buf;
572 if ( type & ZEROTRUNC && ((type & SPECIAL) != SPECIAL) ) {
573 j = 0;
574 while ( j < i && ( *tmp == '0' || *tmp == '.' )) {
575 tmp++;
576 i--;
577 }
578 }
579 // else
580 // while (i < precision--)
581 // putc( '0', f);
582 while (i-- > 0)
583 {
584 if ( putc(tmp[i],f) == EOF)
585 return -1;
586 done++;
587 }
588 while (size-- > 0)
589 {
590 if (putc(' ', f) == EOF)
591 return -1;
592 done++;
593 }
594 }
595 return done;
596 }
597
598 static int string(FILE *f, const char* s, int len, int field_width, int precision, int flags)
599 {
600 int i, done = 0;
601 if (s == NULL)
602 {
603 s = "<NULL>";
604 len = 6;
605 }
606 else
607 {
608 if (len == -1)
609 {
610 len = 0;
611 while (s[len] && (unsigned int)len < (unsigned int)precision)
612 len++;
613 }
614 else
615 {
616 if ((unsigned int)len > (unsigned int)precision)
617 len = precision;
618 }
619 }
620 if (!(flags & LEFT))
621 while (len < field_width--)
622 {
623 if (putc(' ', f) == EOF)
624 return -1;
625 done++;
626 }
627 for (i = 0; i < len; ++i)
628 {
629 if (putc(*s++, f) == EOF)
630 return -1;
631 done++;
632 }
633 while (len < field_width--)
634 {
635 if (putc(' ', f) == EOF)
636 return -1;
637 done++;
638 }
639 return done;
640 }
641
642 static int stringw(FILE *f, const wchar_t* sw, int len, int field_width, int precision, int flags)
643 {
644 int i, done = 0;
645 if (sw == NULL)
646 {
647 sw = L"<NULL>";
648 len = 6;
649 }
650 else
651 {
652 if (len == -1)
653 {
654 len = 0;
655 while (sw[len] && (unsigned int)len < (unsigned int)precision)
656 len++;
657 }
658 else
659 {
660 if ((unsigned int)len > (unsigned int)precision)
661 len = precision;
662 }
663 }
664 if (!(flags & LEFT))
665 while (len < field_width--)
666 {
667 if (putc(' ', f) == EOF)
668 return -1;
669 done++;
670 }
671 for (i = 0; i < len; ++i)
672 {
673 if (putc((unsigned char)(*sw++), f) == EOF)
674 return -1;
675 done++;
676 }
677 while (len < field_width--)
678 {
679 if (putc(' ', f) == EOF)
680 return -1;
681 done++;
682 }
683 return done;
684 }
685
686 int __vfprintf(FILE *f, const char *fmt, va_list args)
687 {
688 int len;
689 ULONGLONG num;
690 int i, base;
691 long double _ldouble;
692 double _double;
693 const char *s;
694 const short int* sw;
695 int result, done = 0;
696
697 int flags; /* flags to number() */
698
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 */
703
704 for (; *fmt ; ++fmt) {
705 if (*fmt != '%') {
706 if (putc(*fmt,f) == EOF)
707 return -1;
708 done++;
709 continue;
710 }
711
712 /* process flags */
713 flags = 0;
714 repeat:
715 ++fmt; /* this also skips first '%' */
716 switch (*fmt) {
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;
722 }
723
724 /* get field width */
725 field_width = -1;
726 if (isdigit(*fmt))
727 field_width = skip_atoi(&fmt);
728 else if (*fmt == '*') {
729 ++fmt;
730 /* it's the next argument */
731 field_width = va_arg(args, int);
732 if (field_width < 0) {
733 field_width = -field_width;
734 flags |= LEFT;
735 }
736 }
737
738 /* get the precision */
739 precision = -1;
740 if (*fmt == '.') {
741 ++fmt;
742 if (isdigit(*fmt))
743 precision = skip_atoi(&fmt);
744 else if (*fmt == '*') {
745 ++fmt;
746 /* it's the next argument */
747 precision = va_arg(args, int);
748 }
749 if (precision < 0)
750 precision = 0;
751 }
752
753 /* get the conversion qualifier */
754 qualifier = 0;
755 // %Z can be just stand alone or as size_t qualifier
756 if ( *fmt == 'Z' ) {
757 qualifier = *fmt;
758 switch ( *(fmt+1)) {
759 case 'o':
760 case 'b':
761 case 'X':
762 case 'x':
763 case 'd':
764 case 'i':
765 case 'u':
766 ++fmt;
767 break;
768 default:
769 break;
770 }
771 } else if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt == 'w') {
772 qualifier = *fmt;
773 ++fmt;
774 } else if (*fmt == 'I' && *(fmt+1) == '6' && *(fmt+2) == '4') {
775 qualifier = *fmt;
776 fmt += 3;
777 }
778
779 // go fine with ll instead of L
780 if ( *fmt == 'l' ) {
781 ++fmt;
782 qualifier = 'L';
783 }
784
785 /* default base */
786 base = 10;
787
788 switch (*fmt) {
789 case 'c':
790 if (!(flags & LEFT))
791 while (--field_width > 0)
792 {
793 if (putc(' ', f) == EOF)
794 return -1;
795 done++;
796 }
797 if (qualifier == 'l' || qualifier == 'w')
798 {
799 if (putc((unsigned char)(wchar_t) va_arg(args, int), f) == EOF)
800 return -1;
801 done++;
802 }
803 else
804 {
805 if (putc((unsigned char) va_arg(args, int), f) == EOF)
806 return -1;
807 done++;
808 }
809 while (--field_width > 0)
810 {
811 if (putc(' ', f) == EOF)
812 return -1;
813 done++;
814 }
815 continue;
816
817 case 'C':
818 if (!(flags & LEFT))
819 while (--field_width > 0)
820 {
821 if (putc(' ', f) == EOF)
822 return -1;
823 done++;
824 }
825 if (qualifier == 'h')
826 {
827 if (putc((unsigned char) va_arg(args, int), f) == EOF)
828 return -1;
829 done++;
830 }
831 else
832 {
833 if (putc((unsigned char)(wchar_t) va_arg(args, int), f) == EOF)
834 return -1;
835 done++;
836 }
837 while (--field_width > 0)
838 {
839 if (putc(' ', f) == EOF)
840 return -1;
841 done++;
842 }
843 continue;
844
845 case 's':
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);
850 } else {
851 /* print ascii string */
852 s = va_arg(args, char *);
853 result = string(f, s, -1, field_width, precision, flags);
854 }
855 if (result < 0)
856 return -1;
857 done += result;
858 continue;
859
860 case 'S':
861 if (qualifier == 'h') {
862 /* print ascii string */
863 s = va_arg(args, char *);
864 result = string(f, s, -1, field_width, precision, flags);
865 } else {
866 /* print unicode string */
867 sw = va_arg(args, wchar_t *);
868 result = stringw(f, sw, -1, field_width, precision, flags);
869 }
870 if (result < 0)
871 return -1;
872 done += result;
873 continue;
874
875 case 'Z':
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)) {
880 sw = NULL;
881 len = -1;
882 } else {
883 sw = pus->Buffer;
884 len = pus->Length / sizeof(WCHAR);
885 }
886 result = stringw(f, sw, len, field_width, precision, flags);
887 } else {
888 /* print counted ascii string */
889 PANSI_STRING pas = va_arg(args, PANSI_STRING);
890 if ((pas == NULL) || (pas->Buffer == NULL)) {
891 s = NULL;
892 len = -1;
893 } else {
894 s = pas->Buffer;
895 len = pas->Length;
896 }
897 result = string(f, s, -1, field_width, precision, flags);
898 }
899 if (result < 0)
900 return -1;
901 done += result;
902 continue;
903
904 case 'e':
905 case 'E':
906 case 'f':
907 case 'g':
908 case 'G':
909 if (qualifier == 'l' || qualifier == 'L' ) {
910 _ldouble = va_arg(args, long double);
911
912 if ( _isnanl(_ldouble) ) {
913 s = "Nan";
914 len = 3;
915 while ( len > 0 ) {
916 if (putc(*s++,f) == EOF)
917 return -1;
918 done++;
919 len --;
920 }
921 }
922 else if ( _isinfl(_ldouble) < 0 ) {
923 s = "-Inf";
924 len = 4;
925 while ( len > 0 ) {
926 if (putc(*s++,f) == EOF)
927 return -1;
928 done++;
929 len --;
930 }
931 }
932 else if ( _isinfl(_ldouble) > 0 ) {
933 s = "+Inf";
934 len = 4;
935 while ( len > 0 ) {
936 if (putc(*s++,f) == EOF)
937 return -1;
938 done++;
939 len --;
940 }
941 } else {
942 if ( precision == -1 )
943 precision = 6;
944 result = numberfl(f,_ldouble,*fmt,field_width,precision,flags);
945 if (result < 0)
946 return -1;
947 done += result;
948 }
949 } else {
950 _double = (double)va_arg(args, double);
951
952 if ( _isnan(_double) ) {
953 s = "Nan";
954 len = 3;
955 while ( len > 0 ) {
956 if (putc(*s++,f) == EOF)
957 return -1;
958 done++;
959 len --;
960 }
961 } else if ( _isinf(_double) < 0 ) {
962 s = "-Inf";
963 len = 4;
964 while ( len > 0 ) {
965 if (putc(*s++,f) == EOF)
966 return -1;
967 done++;
968 len --;
969 }
970 } else if ( _isinf(_double) > 0 ) {
971 s = "+Inf";
972 len = 4;
973 while ( len > 0 ) {
974 if (putc(*s++,f) == EOF)
975 return -1;
976 done++;
977 len --;
978 }
979 } else {
980 if ( precision == -1 )
981 precision = 6;
982 result = numberf(f,_double,*fmt,field_width,precision,flags);
983 if (result < 0)
984 return -1;
985 done += result;
986 }
987 }
988 continue;
989
990 case 'p':
991 if (field_width == -1) {
992 field_width = 2*sizeof(void *);
993 flags |= ZEROPAD;
994 }
995 result = number(f,
996 (unsigned long) va_arg(args, void *), 16,
997 field_width, precision, flags);
998 if (result < 0)
999 return -1;
1000 done += result;
1001 continue;
1002
1003 case 'n':
1004 if (qualifier == 'l') {
1005 long * ip = va_arg(args, long *);
1006 *ip = 0;
1007 } else {
1008 int * ip = va_arg(args, int *);
1009 *ip = 0;
1010 }
1011 continue;
1012
1013 /* integer number formats - set up the flags and "break" */
1014 case 'o':
1015 base = 8;
1016 break;
1017
1018 case 'b':
1019 base = 2;
1020 break;
1021
1022 case 'X':
1023 flags |= LARGE;
1024 case 'x':
1025 base = 16;
1026 break;
1027
1028 case 'd':
1029 case 'i':
1030 flags |= SIGN;
1031 case 'u':
1032 break;
1033
1034 default:
1035 if (*fmt != '%')
1036 {
1037 if (putc('%', f) == EOF)
1038 return -1;
1039 done++;
1040 }
1041 if (*fmt)
1042 {
1043 if (putc(*fmt, f) == EOF)
1044 return -1;
1045 done++;
1046 }
1047 else
1048 --fmt;
1049 continue;
1050 }
1051
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') {
1057 if (flags & SIGN)
1058 num = va_arg(args, int);
1059 else
1060 num = va_arg(args, unsigned int);
1061 }
1062 else if (flags & SIGN)
1063 num = va_arg(args, int);
1064 else
1065 num = va_arg(args, unsigned int);
1066 result = number(f, num, base, field_width, precision, flags);
1067 if (result < 0)
1068 return -1;
1069 done += result;
1070 }
1071 //putc('\0',f);
1072 return done;
1073 }
1074
1075 /* EOF */