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