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