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