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