00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150 #if defined(LIBC_SCCS) && !defined(lint)
00151 static char *sccsid = "from: @(#)vfprintf.c 5.50 (Berkeley) 12/16/92";
00152 #endif
00153
00154
00155
00156
00157
00158
00159
00160
00161 #ifdef _SMALL_PRINTF
00162 #define _NO_LONGDBL
00163 #endif
00164
00165
00166 #ifdef INTEGER_ONLY
00167 #define VFPRINTF vfiprintf
00168 #define _VFPRINTF_R _vfiprintf_r
00169 #else
00170 #define VFPRINTF vfprintf
00171 #define _VFPRINTF_R _vfprintf_r
00172 #ifndef NO_FLOATING_POINT
00173 #define FLOATING_POINT
00174 #endif
00175 #endif
00176
00177 #define _NO_LONGLONG
00178 #if defined WANT_PRINTF_LONG_LONG && defined __GNUC__
00179 # undef _NO_LONGLONG
00180 #endif
00181
00182 #define _NO_POS_ARGS
00183 #if defined WANT_IO_POS_ARGS
00184 # undef _NO_POS_ARGS
00185 #endif
00186
00187 #include <_ansi.h>
00188 #include <stdio.h>
00189 #include <stdlib.h>
00190 #include <string.h>
00191 #include <limits.h>
00192 #include <reent.h>
00193 #include <wchar.h>
00194 #include <string.h>
00195 #include <sys/lock.h>
00196
00197 #ifdef _HAVE_STDC
00198 #include <stdarg.h>
00199 #else
00200 #include <varargs.h>
00201 #endif
00202
00203 #ifndef _SMALL_PRINTF
00204 #include "local.h"
00205 #include "fvwrite.h"
00206 #else
00207 #define MAXBUFLOC 80
00208 #endif
00209
00210 #include "vfieeefp.h"
00211
00212
00213
00214
00215 #define _NO_LONGDBL
00216 #if defined WANT_IO_LONG_DBL && (LDBL_MANT_DIG > DBL_MANT_DIG)
00217 # undef _NO_LONGDBL
00218 #endif
00219
00220
00221 #ifndef _SMALL_PRINTF
00222
00223
00224
00225
00226 static int
00227 __sprint(fp, uio)
00228 FILE *fp;
00229 register struct __suio *uio;
00230 {
00231 register int err;
00232
00233 if (uio->uio_resid == 0) {
00234 uio->uio_iovcnt = 0;
00235 return (0);
00236 }
00237 err = __sfvwrite(fp, uio);
00238 uio->uio_resid = 0;
00239 uio->uio_iovcnt = 0;
00240 return (err);
00241 }
00242
00243
00244
00245
00246
00247
00248 static int
00249 __sbprintf(fp, fmt, ap)
00250 register FILE *fp;
00251 const char *fmt;
00252 va_list ap;
00253 {
00254 int ret;
00255 FILE fake;
00256 unsigned char buf[BUFSIZ];
00257
00258
00259 fake._flags = fp->_flags & ~__SNBF;
00260 fake._file = fp->_file;
00261 fake._cookie = fp->_cookie;
00262 fake._write = fp->_write;
00263
00264
00265 fake._bf._base = fake._p = buf;
00266 fake._bf._size = fake._w = sizeof(buf);
00267 fake._lbfsize = 0;
00268 #ifndef __SINGLE_THREAD__
00269 __lock_init_recursive (*(_LOCK_RECURSIVE_T *)&fake._lock);
00270 #endif
00271
00272
00273 ret = VFPRINTF(&fake, fmt, ap);
00274 if (ret >= 0 && fflush(&fake))
00275 ret = EOF;
00276 if (fake._flags & __SERR)
00277 fp->_flags |= __SERR;
00278
00279 #ifndef __SINGLE_THREAD__
00280 __lock_close_recursive (*(_LOCK_RECURSIVE_T *)&fake._lock);
00281 #endif
00282 return (ret);
00283 }
00284 #endif
00285
00286
00287
00288 #ifdef FLOATING_POINT
00289 #include <locale.h>
00290 #include <math.h>
00291 #include "floatio.h"
00292
00293 #if ((MAXEXP+MAXFRACT+1) > MB_LEN_MAX)
00294 # define BUF (MAXEXP+MAXFRACT+1)
00295 #else
00296 # define BUF MB_LEN_MAX
00297 #endif
00298
00299 #define DEFPREC 6
00300
00301 #ifdef _NO_LONGDBL
00302 static char *cvt _PARAMS((struct _reent *, double, int, int, char *, int *, int, int *));
00303 #else
00304 static char *cvt _PARAMS((struct _reent *, _LONG_DOUBLE, int, int, char *, int *, int, int *));
00305 extern int _ldcheck _PARAMS((_LONG_DOUBLE *));
00306 #endif
00307
00308 static int exponent _PARAMS((char *, int, int));
00309
00310 #else
00311
00312 #define BUF 40
00313
00314 #endif
00315
00316 #ifndef _NO_LONGLONG
00317 #define quad_t long long
00318 #define u_quad_t unsigned long long
00319 #else
00320 #define quad_t long
00321 #define u_quad_t unsigned long
00322 #endif
00323
00324 typedef quad_t * quad_ptr_t;
00325 typedef void * void_ptr_t;
00326 typedef char * char_ptr_t;
00327 typedef long * long_ptr_t;
00328 typedef int * int_ptr_t;
00329 typedef short * short_ptr_t;
00330
00331 #ifndef _NO_POS_ARGS
00332 #define MAX_POS_ARGS 32
00333
00334 union arg_val
00335 {
00336 int val_int;
00337 u_int val_u_int;
00338 long val_long;
00339 u_long val_u_long;
00340 float val_float;
00341 double val_double;
00342 _LONG_DOUBLE val__LONG_DOUBLE;
00343 int_ptr_t val_int_ptr_t;
00344 short_ptr_t val_short_ptr_t;
00345 long_ptr_t val_long_ptr_t;
00346 char_ptr_t val_char_ptr_t;
00347 quad_ptr_t val_quad_ptr_t;
00348 void_ptr_t val_void_ptr_t;
00349 quad_t val_quad_t;
00350 u_quad_t val_u_quad_t;
00351 wint_t val_wint_t;
00352 };
00353
00354 static union arg_val *get_arg (struct _reent *data, int n, char *fmt,
00355 va_list *ap, int *numargs, union arg_val *args,
00356 int *arg_type, char **last_fmt);
00357 #endif
00358
00359
00360
00361
00362 #define to_digit(c) ((c) - '0')
00363 #define is_digit(c) ((unsigned)to_digit(c) <= 9)
00364 #define to_char(n) ((n) + '0')
00365
00366
00367
00368
00369 #define ALT 0x001
00370 #define HEXPREFIX 0x002
00371 #define LADJUST 0x004
00372 #define LONGDBL 0x008
00373 #define LONGINT 0x010
00374 #ifndef _NO_LONGLONG
00375 #define QUADINT 0x020
00376 #else
00377
00378
00379 #define QUADINT LONGINT
00380 #endif
00381 #define SHORTINT 0x040
00382 #define ZEROPAD 0x080
00383 #define FPT 0x100
00384
00385
00386 int _EXFUN (_VFPRINTF_R, (struct _reent *, FILE *, _CONST char *, va_list));
00387
00388 int
00389 _DEFUN (VFPRINTF, (fp, fmt0, ap),
00390 FILE * fp _AND
00391 _CONST char *fmt0 _AND
00392 va_list ap)
00393 {
00394 int result;
00395 _flockfile(fp);
00396 #ifndef _SMALL_PRINTF
00397 CHECK_INIT (fp);
00398 #endif
00399 result = _VFPRINTF_R (_REENT, fp, fmt0, ap);
00400 _funlockfile(fp);
00401 return result;
00402 }
00403
00404
00405
00406 int
00407 _DEFUN (_VFPRINTF_R, (data, fp, fmt0, ap),
00408 struct _reent *data _AND
00409 FILE * fp _AND
00410 _CONST char *fmt0 _AND
00411 va_list ap)
00412 {
00413 register char *fmt;
00414 register int ch;
00415 register int n, m;
00416 register char *cp;
00417 register struct __siov *iovp;
00418 register int flags;
00419 char *fmt_anchor;
00420 int N;
00421 int arg_index;
00422 #ifndef _NO_POS_ARGS
00423 int numargs;
00424 char *saved_fmt;
00425 union arg_val args[MAX_POS_ARGS];
00426 int arg_type[MAX_POS_ARGS];
00427 int is_pos_arg;
00428 int old_is_pos_arg;
00429 #endif
00430 int ret;
00431 int width;
00432 int prec;
00433 char sign;
00434 #ifdef FLOATING_POINT
00435 #ifdef _SMALL_PRINTF
00436 char *decimal_point = ".";
00437 #else
00438 char *decimal_point = localeconv()->decimal_point;
00439 #endif
00440 char softsign;
00441 #ifdef _NO_LONGDBL
00442 union { int i; double d; } _double_ = {0};
00443 #define _fpvalue (_double_.d)
00444 #else
00445 union { int i; _LONG_DOUBLE ld; } _long_double_ = {0};
00446 #define _fpvalue (_long_double_.ld)
00447 int tmp;
00448 #endif
00449 int expt;
00450 int expsize = 0;
00451 int ndig;
00452 char expstr[7];
00453 #endif
00454 u_quad_t _uquad;
00455 enum { OCT, DEC, HEX } base;
00456 int dprec;
00457 int realsz;
00458 int size;
00459 char *xdigs = NULL;
00460 #ifndef _SMALL_PRINTF
00461 #define NIOV 8
00462 struct __suio uio;
00463 struct __siov iov[NIOV];
00464 char *malloc_buf = NULL;
00465 #else
00466 char malloc_buf [MAXBUFLOC];
00467 #endif
00468
00469 char buf[BUF];
00470 char ox[2];
00471 #ifdef MB_CAPABLE
00472 wchar_t wc;
00473 mbstate_t state;
00474 #endif
00475
00476
00477
00478
00479
00480
00481
00482 #define PADSIZE 16
00483 static _CONST char blanks[PADSIZE] =
00484 {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};
00485 static _CONST char zeroes[PADSIZE] =
00486 {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
00487
00488 #ifdef MB_CAPABLE
00489 memset (&state, '\0', sizeof (state));
00490 #endif
00491
00492 #ifndef _SMALL_PRINTF
00493
00494
00495
00496 #define PRINT(ptr, len,f) { \
00497 iovp->iov_base = (ptr); \
00498 iovp->iov_len = (len); \
00499 uio.uio_resid += (len); \
00500 iovp++; \
00501 if (++uio.uio_iovcnt >= NIOV) { \
00502 if (__sprint(fp, &uio)) \
00503 goto error; \
00504 iovp = iov; \
00505 } \
00506 }
00507 #define PAD(howmany, with,f) { \
00508 if ((n = (howmany)) > 0) { \
00509 while (n > PADSIZE) { \
00510 PRINT(with, PADSIZE,f); \
00511 n -= PADSIZE; \
00512 } \
00513 PRINT(with, n,f); \
00514 } \
00515 }
00516 #define FLUSH() { \
00517 if (uio.uio_resid && __sprint(fp, &uio)) \
00518 goto error; \
00519 uio.uio_iovcnt = 0; \
00520 iovp = iov; \
00521 }
00522 #else
00523
00524 void _SMALL_PRINTF_puts(const char *ptr, int len, FILE *f);
00525 #define PRINT(ptr, len, f) {_SMALL_PRINTF_puts(ptr,len,f);}
00526 #define PAD(howmany, with, f) { \
00527 if ((n = (howmany)) > 0) { \
00528 while (n > PADSIZE) { \
00529 PRINT(with, PADSIZE,f); \
00530 n -= PADSIZE; \
00531 } \
00532 PRINT(with, n, f); \
00533 } \
00534 }
00535 #define FLUSH() { ; }
00536 #endif
00537
00538
00539
00540 #ifndef _NO_POS_ARGS
00541 #define GET_ARG(n, ap, type) \
00542 ( is_pos_arg \
00543 ? n < numargs \
00544 ? args[n].val_##type \
00545 : get_arg (data, n, fmt_anchor, &ap, &numargs, args, arg_type, &saved_fmt)->val_##type \
00546 : arg_index++ < numargs \
00547 ? args[n].val_##type \
00548 : numargs < MAX_POS_ARGS \
00549 ? args[numargs++].val_##type = va_arg(ap, type) \
00550 : va_arg(ap, type) \
00551 )
00552 #else
00553 #define GET_ARG(n, ap, type) (va_arg(ap, type))
00554 #endif
00555
00556
00557
00558
00559
00560 #ifndef _NO_LONGLONG
00561 #define SARG() \
00562 (flags&QUADINT ? GET_ARG(N, ap, quad_t) : \
00563 flags&LONGINT ? GET_ARG(N, ap, long) : \
00564 flags&SHORTINT ? (long)(short)GET_ARG(N, ap, int) : \
00565 (long)GET_ARG(N, ap, int))
00566 #define UARG() \
00567 (flags&QUADINT ? GET_ARG(N, ap, u_quad_t) : \
00568 flags&LONGINT ? GET_ARG(N, ap, u_long) : \
00569 flags&SHORTINT ? (u_long)(u_short)GET_ARG(N, ap, int) : \
00570 (u_long)GET_ARG(N, ap, u_int))
00571 #else
00572 #define SARG() \
00573 (flags&LONGINT ? GET_ARG(N, ap, long) : \
00574 flags&SHORTINT ? (long)(short)GET_ARG(N, ap, int) : \
00575 (long)GET_ARG(N, ap, int))
00576 #define UARG() \
00577 (flags&LONGINT ? GET_ARG(N, ap, u_long) : \
00578 flags&SHORTINT ? (u_long)(u_short)GET_ARG(N, ap, int) : \
00579 (u_long)GET_ARG(N, ap, u_int))
00580 #endif
00581
00582 #ifndef _SMALL_PRINTF
00583
00584 if (cantwrite(fp))
00585 return (EOF);
00586
00587
00588 if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) &&
00589 fp->_file >= 0)
00590 return (__sbprintf(fp, fmt0, ap));
00591
00592 uio.uio_iov = iovp = iov;
00593 uio.uio_resid = 0;
00594 uio.uio_iovcnt = 0;
00595 #endif
00596 fmt = (char *)fmt0;
00597
00598 ret = 0;
00599 arg_index = 0;
00600
00601 #ifndef _NO_POS_ARGS
00602 saved_fmt = NULL;
00603 arg_type[0] = -1;
00604 numargs = 0;
00605 is_pos_arg = 0;
00606 #endif
00607
00608
00609
00610
00611 for (;;) {
00612 cp = fmt;
00613 #ifdef MB_CAPABLE
00614 while ((n = _mbtowc_r(data, &wc, fmt, MB_CUR_MAX, &state)) > 0) {
00615 if (wc == '%')
00616 break;
00617 fmt += n;
00618 }
00619 #else
00620 while (*fmt != '\0' && *fmt != '%')
00621 fmt += 1;
00622 #endif
00623 if ((m = fmt - cp) != 0) {
00624 PRINT(cp, m, fp);
00625 ret += m;
00626 }
00627 #ifdef MB_CAPABLE
00628 if (n <= 0)
00629 goto done;
00630 #else
00631 if (*fmt == '\0')
00632 goto done;
00633 #endif
00634 fmt_anchor = fmt;
00635 fmt++;
00636
00637 flags = 0;
00638 dprec = 0;
00639 width = 0;
00640 prec = -1;
00641 sign = '\0';
00642 N = arg_index;
00643 #ifndef _NO_POS_ARGS
00644 is_pos_arg = 0;
00645 #endif
00646
00647 rflag: ch = *fmt++;
00648 reswitch: switch (ch) {
00649 case ' ':
00650
00651
00652
00653
00654
00655 if (!sign)
00656 sign = ' ';
00657 goto rflag;
00658 case '#':
00659 flags |= ALT;
00660 goto rflag;
00661 case '*':
00662 n = N;
00663 #ifndef _NO_POS_ARGS
00664
00665 old_is_pos_arg = is_pos_arg;
00666 is_pos_arg = 0;
00667 if (is_digit(*fmt)) {
00668 char *old_fmt = fmt;
00669
00670 n = 0;
00671 ch = *fmt++;
00672 do {
00673 n = 10 * n + to_digit(ch);
00674 ch = *fmt++;
00675 } while (is_digit(ch));
00676
00677 if (ch == '$') {
00678 if (n <= MAX_POS_ARGS) {
00679 n -= 1;
00680 is_pos_arg = 1;
00681 }
00682 else
00683 goto error;
00684 }
00685 else {
00686 fmt = old_fmt;
00687 goto rflag;
00688 }
00689 }
00690 #endif
00691
00692
00693
00694
00695
00696
00697
00698 width = GET_ARG(n, ap, int);
00699 #ifndef _NO_POS_ARGS
00700 is_pos_arg = old_is_pos_arg;
00701 #endif
00702 if (width >= 0)
00703 goto rflag;
00704 width = -width;
00705
00706 case '-':
00707 flags |= LADJUST;
00708 goto rflag;
00709 case '+':
00710 sign = '+';
00711 goto rflag;
00712 case '.':
00713 if ((ch = *fmt++) == '*') {
00714 n = N;
00715 #ifndef _NO_POS_ARGS
00716
00717 old_is_pos_arg = is_pos_arg;
00718 is_pos_arg = 0;
00719 if (is_digit(*fmt)) {
00720 char *old_fmt = fmt;
00721
00722 n = 0;
00723 ch = *fmt++;
00724 do {
00725 n = 10 * n + to_digit(ch);
00726 ch = *fmt++;
00727 } while (is_digit(ch));
00728
00729 if (ch == '$') {
00730 if (n <= MAX_POS_ARGS) {
00731 n -= 1;
00732 is_pos_arg = 1;
00733 }
00734 else
00735 goto error;
00736 }
00737 else {
00738 fmt = old_fmt;
00739 goto rflag;
00740 }
00741 }
00742 #endif
00743 prec = GET_ARG(n, ap, int);
00744 #ifndef _NO_POS_ARGS
00745 is_pos_arg = old_is_pos_arg;
00746 #endif
00747 if (prec < 0)
00748 prec = -1;
00749 goto rflag;
00750 }
00751 n = 0;
00752 while (is_digit(ch)) {
00753 n = 10 * n + to_digit(ch);
00754 ch = *fmt++;
00755 }
00756 prec = n < 0 ? -1 : n;
00757 goto reswitch;
00758 case '0':
00759
00760
00761
00762
00763
00764 flags |= ZEROPAD;
00765 goto rflag;
00766 case '1': case '2': case '3': case '4':
00767 case '5': case '6': case '7': case '8': case '9':
00768 n = 0;
00769 do {
00770 n = 10 * n + to_digit(ch);
00771 ch = *fmt++;
00772 } while (is_digit(ch));
00773 #ifndef _NO_POS_ARGS
00774 if (ch == '$') {
00775 if (n <= MAX_POS_ARGS) {
00776 N = n - 1;
00777 is_pos_arg = 1;
00778 goto rflag;
00779 }
00780 else
00781 goto error;
00782 }
00783 #endif
00784 width = n;
00785 goto reswitch;
00786 #ifdef FLOATING_POINT
00787 case 'L':
00788 flags |= LONGDBL;
00789 goto rflag;
00790 #endif
00791 case 'h':
00792 flags |= SHORTINT;
00793 goto rflag;
00794 case 'l':
00795 if (*fmt == 'l') {
00796 fmt++;
00797 flags |= QUADINT;
00798 } else {
00799 flags |= LONGINT;
00800 }
00801 goto rflag;
00802 case 'q':
00803 flags |= QUADINT;
00804 goto rflag;
00805 case 'c':
00806 case 'C':
00807 cp = buf;
00808 if (ch == 'C' || (flags & LONGINT)) {
00809 mbstate_t ps;
00810
00811 memset((void *)&ps, '\0', sizeof(mbstate_t));
00812 if ((size = (int)_wcrtomb_r(data, cp,
00813 (wchar_t)GET_ARG(N, ap, wint_t),
00814 &ps)) == -1)
00815 goto error;
00816 }
00817 else {
00818 *cp = GET_ARG(N, ap, int);
00819 size = 1;
00820 }
00821 sign = '\0';
00822 break;
00823 case 'D':
00824 flags |= LONGINT;
00825
00826 case 'd':
00827 case 'i':
00828 _uquad = SARG();
00829 #ifndef _NO_LONGLONG
00830 if ((quad_t)_uquad < 0)
00831 #else
00832 if ((long) _uquad < 0)
00833 #endif
00834 {
00835
00836 _uquad = -_uquad;
00837 sign = '-';
00838 }
00839 base = DEC;
00840 goto number;
00841 #ifdef FLOATING_POINT
00842 case 'e':
00843 case 'E':
00844 case 'f':
00845 case 'g':
00846 case 'G':
00847 if (prec == -1) {
00848 prec = DEFPREC;
00849 } else if ((ch == 'g' || ch == 'G') && prec == 0) {
00850 prec = 1;
00851 }
00852
00853 #ifdef _NO_LONGDBL
00854 if (flags & LONGDBL) {
00855 _fpvalue = (double) GET_ARG(N, ap, _LONG_DOUBLE);
00856 } else {
00857 _fpvalue = GET_ARG(N, ap, double);
00858 }
00859
00860
00861 if (isinf(_fpvalue)) {
00862 if (_fpvalue < 0)
00863 sign = '-';
00864 cp = "Inf";
00865 size = 3;
00866 break;
00867 }
00868 if (isnan(_fpvalue)) {
00869 cp = "NaN";
00870 size = 3;
00871 break;
00872 }
00873
00874 #else
00875
00876 if (flags & LONGDBL) {
00877 _fpvalue = GET_ARG(N, ap, _LONG_DOUBLE);
00878 } else {
00879 _fpvalue = (_LONG_DOUBLE)GET_ARG(N, ap, double);
00880 }
00881
00882
00883 tmp = _ldcheck (&_fpvalue);
00884 if (tmp == 2) {
00885 if (_fpvalue < 0)
00886 sign = '-';
00887 cp = "Inf";
00888 size = 3;
00889 break;
00890 }
00891 if (tmp == 1) {
00892 cp = "NaN";
00893 size = 3;
00894 break;
00895 }
00896 #endif
00897
00898 flags |= FPT;
00899
00900 cp = cvt(data, _fpvalue, prec, flags, &softsign,
00901 &expt, ch, &ndig);
00902
00903 if (ch == 'g' || ch == 'G') {
00904 if (expt <= -4 || expt > prec)
00905 ch = (ch == 'g') ? 'e' : 'E';
00906 else
00907 ch = 'g';
00908 }
00909 if (ch <= 'e') {
00910 --expt;
00911 expsize = exponent(expstr, expt, ch);
00912 size = expsize + ndig;
00913 if (ndig > 1 || flags & ALT)
00914 ++size;
00915 } else if (ch == 'f') {
00916 if (expt > 0) {
00917 size = expt;
00918 if (prec || flags & ALT)
00919 size += prec + 1;
00920 } else
00921 size = (prec || flags & ALT)
00922 ? prec + 2
00923 : 1;
00924 } else if (expt >= ndig) {
00925 size = expt;
00926 if (flags & ALT)
00927 ++size;
00928 } else
00929 size = ndig + (expt > 0 ?
00930 1 : 2 - expt);
00931
00932 if (softsign)
00933 sign = '-';
00934 break;
00935 #endif
00936 case 'n':
00937 #ifndef _NO_LONGLONG
00938 if (flags & QUADINT)
00939 *GET_ARG(N, ap, quad_ptr_t) = ret;
00940 else
00941 #endif
00942 if (flags & LONGINT)
00943 *GET_ARG(N, ap, long_ptr_t) = ret;
00944 else if (flags & SHORTINT)
00945 *GET_ARG(N, ap, short_ptr_t) = ret;
00946 else
00947 *GET_ARG(N, ap, int_ptr_t) = ret;
00948 continue;
00949 case 'O':
00950 flags |= LONGINT;
00951
00952 case 'o':
00953 _uquad = UARG();
00954 base = OCT;
00955 goto nosign;
00956 case 'p':
00957
00958
00959
00960
00961
00962
00963
00964
00965 _uquad = (u_long)(unsigned _POINTER_INT)GET_ARG(N, ap, void_ptr_t);
00966 base = HEX;
00967 xdigs = "0123456789abcdef";
00968 flags |= HEXPREFIX;
00969 ch = 'x';
00970 goto nosign;
00971 case 's':
00972 case 'S':
00973 sign = '\0';
00974 if ((cp = GET_ARG(N, ap, char_ptr_t)) == NULL) {
00975 cp = "(null)";
00976 size = 6;
00977 }
00978 else if (ch == 'S' || (flags & LONGINT)) {
00979 mbstate_t ps;
00980 _CONST wchar_t *wcp;
00981
00982 wcp = (_CONST wchar_t *)cp;
00983 size = m = 0;
00984 memset((void *)&ps, '\0', sizeof(mbstate_t));
00985
00986
00987
00988
00989 if (prec >= 0) {
00990 while (1) {
00991 if (wcp[m] == L'\0')
00992 break;
00993 if ((n = (int)_wcrtomb_r(data,
00994 buf, wcp[m], &ps)) == -1)
00995 goto error;
00996 if (n + size > prec)
00997 break;
00998 m += 1;
00999 size += n;
01000 if (size == prec)
01001 break;
01002 }
01003 }
01004 else {
01005 if ((size = (int)_wcsrtombs_r(data,
01006 NULL, &wcp, 0, &ps)) == -1)
01007 goto error;
01008 wcp = (_CONST wchar_t *)cp;
01009 }
01010
01011 if (size == 0)
01012 break;
01013
01014 #ifndef _SMALL_PRINTF
01015 if ((malloc_buf =
01016 (char *)_malloc_r(data, size + 1)) == NULL)
01017 goto error;
01018 #endif
01019
01020
01021 memset((void *)&ps, '\0', sizeof(mbstate_t));
01022 if (_wcsrtombs_r(data, malloc_buf, &wcp, size, &ps) != size)
01023 goto error;
01024 cp = malloc_buf;
01025 cp[size] = '\0';
01026 }
01027 else if (prec >= 0) {
01028
01029
01030
01031
01032
01033 char *p = memchr(cp, 0, prec);
01034
01035 if (p != NULL) {
01036 size = p - cp;
01037 if (size > prec)
01038 size = prec;
01039 } else
01040 size = prec;
01041 } else
01042 size = strlen(cp);
01043
01044 break;
01045 case 'U':
01046 flags |= LONGINT;
01047
01048 case 'u':
01049 _uquad = UARG();
01050 base = DEC;
01051 goto nosign;
01052 case 'X':
01053 xdigs = "0123456789ABCDEF";
01054 goto hex;
01055 case 'x':
01056 xdigs = "0123456789abcdef";
01057 hex: _uquad = UARG();
01058 base = HEX;
01059
01060 if (flags & ALT && _uquad != 0)
01061 flags |= HEXPREFIX;
01062
01063
01064 nosign: sign = '\0';
01065
01066
01067
01068
01069
01070 number: if ((dprec = prec) >= 0)
01071 flags &= ~ZEROPAD;
01072
01073
01074
01075
01076
01077
01078 cp = buf + BUF;
01079 if (_uquad != 0 || prec != 0) {
01080
01081
01082
01083
01084
01085 switch (base) {
01086 case OCT:
01087 do {
01088 *--cp = to_char(_uquad & 7);
01089 _uquad >>= 3;
01090 } while (_uquad);
01091
01092 if (flags & ALT && *cp != '0')
01093 *--cp = '0';
01094 break;
01095
01096 case DEC:
01097
01098 while (_uquad >= 10) {
01099 *--cp = to_char(_uquad % 10);
01100 _uquad /= 10;
01101 }
01102 *--cp = to_char(_uquad);
01103 break;
01104
01105 case HEX:
01106 do {
01107 *--cp = xdigs[_uquad & 15];
01108 _uquad >>= 4;
01109 } while (_uquad);
01110 break;
01111
01112 default:
01113 cp = "bug in vfprintf: bad base";
01114 size = strlen(cp);
01115 goto skipsize;
01116 }
01117 }
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127 else if (base == OCT && (flags & ALT))
01128 *--cp = '0';
01129
01130 size = buf + BUF - cp;
01131 skipsize:
01132 break;
01133 default:
01134 if (ch == '\0')
01135 goto done;
01136
01137 cp = buf;
01138 *cp = ch;
01139 size = 1;
01140 sign = '\0';
01141 break;
01142 }
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158 realsz = dprec > size ? dprec : size;
01159 if (sign)
01160 realsz++;
01161 else if (flags & HEXPREFIX)
01162 realsz+= 2;
01163
01164
01165 if ((flags & (LADJUST|ZEROPAD)) == 0)
01166 PAD(width - realsz, blanks, fp);
01167
01168
01169 if (sign) {
01170 PRINT(&sign, 1, fp);
01171 } else if (flags & HEXPREFIX) {
01172 ox[0] = '0';
01173 ox[1] = ch;
01174 PRINT(ox, 2 ,fp);
01175 }
01176
01177
01178 if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD)
01179 PAD(width - realsz, zeroes, fp);
01180
01181
01182 PAD(dprec - size, zeroes, fp);
01183
01184
01185 #ifdef FLOATING_POINT
01186 if ((flags & FPT) == 0) {
01187 PRINT(cp, size, fp);
01188 } else {
01189 if (ch >= 'f') {
01190 if (_fpvalue == 0) {
01191
01192 PRINT("0", 1, fp);
01193 if (expt < ndig || (flags & ALT) != 0) {
01194 PRINT(decimal_point, 1, fp);
01195 PAD(ndig - 1, zeroes, fp);
01196 }
01197 } else if (expt <= 0) {
01198 PRINT("0", 1, fp);
01199 if(expt || ndig) {
01200 PRINT(decimal_point, 1, fp);
01201 PAD(-expt, zeroes, fp);
01202 PRINT(cp, ndig, fp);
01203 }
01204 } else if (expt >= ndig) {
01205 PRINT(cp, ndig, fp);
01206 PAD(expt - ndig, zeroes, fp);
01207 if (flags & ALT)
01208 PRINT(".", 1, fp);
01209 } else {
01210 PRINT(cp, expt, fp);
01211 cp += expt;
01212 PRINT(".", 1, fp);
01213 PRINT(cp, ndig-expt, fp);
01214 }
01215 } else {
01216 if (ndig > 1 || flags & ALT) {
01217 ox[0] = *cp++;
01218 ox[1] = '.';
01219 PRINT(ox, 2, fp);
01220 if (_fpvalue) {
01221 PRINT(cp, ndig-1, fp);
01222 } else
01223
01224 PAD(ndig - 1, zeroes, fp);
01225 } else
01226 PRINT(cp, 1, fp);
01227 PRINT(expstr, expsize, fp);
01228 }
01229 }
01230 #else
01231 PRINT(cp, size, fp);
01232 #endif
01233
01234 if (flags & LADJUST)
01235 PAD(width - realsz, blanks, fp);
01236
01237
01238 ret += width > realsz ? width : realsz;
01239
01240 FLUSH();
01241
01242 #ifndef _SMALL_PRINTF
01243 if (malloc_buf != NULL) {
01244 free(malloc_buf);
01245 malloc_buf = NULL;
01246 }
01247 #endif
01248 }
01249 done:
01250 FLUSH();
01251 error:
01252
01253 #ifndef _SMALL_PRINTF
01254 if (malloc_buf != NULL)
01255 free(malloc_buf);
01256 return (__sferror(fp) ? EOF : ret);
01257 #else
01258 return ret;
01259 #endif
01260
01261 }
01262
01263 #ifdef FLOATING_POINT
01264
01265 #ifdef _NO_LONGDBL
01266 extern char *_dtoa_r _PARAMS((struct _reent *, double, int,
01267 int, int *, int *, char **));
01268 #else
01269 extern char *_ldtoa_r _PARAMS((struct _reent *, _LONG_DOUBLE, int,
01270 int, int *, int *, char **));
01271 #undef word0
01272 #define word0(x) ldword0(x)
01273 #endif
01274
01275 static char *
01276 cvt(data, value, ndigits, flags, sign, decpt, ch, length)
01277 struct _reent *data;
01278 #ifdef _NO_LONGDBL
01279 double value;
01280 #else
01281 _LONG_DOUBLE value;
01282 #endif
01283 int ndigits, flags, *decpt, ch, *length;
01284 char *sign;
01285 {
01286 int mode, dsgn;
01287 char *digits, *bp, *rve;
01288 #ifdef _NO_LONGDBL
01289 union double_union tmp;
01290 #else
01291 struct ldieee *ldptr;
01292 #endif
01293
01294 if (ch == 'f') {
01295 mode = 3;
01296 } else {
01297
01298
01299
01300
01301 if (ch == 'e' || ch == 'E') {
01302 ndigits++;
01303 }
01304 mode = 2;
01305 }
01306
01307 #ifdef _NO_LONGDBL
01308 tmp.d = value;
01309
01310 if (word0(tmp) & Sign_bit) {
01311 value = -value;
01312 *sign = '-';
01313 } else
01314 *sign = '\000';
01315
01316 digits = _dtoa_r(data, value, mode, ndigits, decpt, &dsgn, &rve);
01317 #else
01318 ldptr = (struct ldieee *)&value;
01319 if (ldptr->sign) {
01320 value = -value;
01321 *sign = '-';
01322 } else
01323 *sign = '\000';
01324
01325 digits = _ldtoa_r(data, value, mode, ndigits, decpt, &dsgn, &rve);
01326 #endif
01327
01328 if ((ch != 'g' && ch != 'G') || flags & ALT) {
01329 bp = digits + ndigits;
01330 if (ch == 'f') {
01331 if (*digits == '0' && value)
01332 *decpt = -ndigits + 1;
01333 bp += *decpt;
01334 }
01335 if (value == 0)
01336 rve = bp;
01337 while (rve < bp)
01338 *rve++ = '0';
01339 }
01340 *length = rve - digits;
01341 return (digits);
01342 }
01343
01344 static int
01345 exponent(p0, exp, fmtch)
01346 char *p0;
01347 int exp, fmtch;
01348 {
01349 register char *p, *t;
01350 char expbuf[40];
01351
01352 p = p0;
01353 *p++ = fmtch;
01354 if (exp < 0) {
01355 exp = -exp;
01356 *p++ = '-';
01357 }
01358 else
01359 *p++ = '+';
01360 t = expbuf + 40;
01361 if (exp > 9) {
01362 do {
01363 *--t = to_char(exp % 10);
01364 } while ((exp /= 10) > 9);
01365 *--t = to_char(exp);
01366 for (; t < expbuf + 40; *p++ = *t++);
01367 }
01368 else {
01369 *p++ = '0';
01370 *p++ = to_char(exp);
01371 }
01372 return (p - p0);
01373 }
01374 #endif
01375
01376
01377 #ifndef _NO_POS_ARGS
01378
01379
01380
01381
01382
01383
01384
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409
01410 typedef enum {
01411 ZERO,
01412 DIGIT,
01413 DOLLAR,
01414 MODFR,
01415 SPEC,
01416 DOT,
01417 STAR,
01418 FLAG,
01419 OTHER,
01420 MAX_CH_CLASS
01421 } CH_CLASS;
01422
01423 typedef enum {
01424 START,
01425 SFLAG,
01426 WDIG,
01427 WIDTH,
01428 SMOD,
01429 SDOT,
01430 VARW,
01431 VARP,
01432 PREC,
01433 VWDIG,
01434 VPDIG,
01435 DONE,
01436 MAX_STATE,
01437 } STATE;
01438
01439 typedef enum {
01440 NOOP,
01441 NUMBER,
01442 SKIPNUM,
01443 GETMOD,
01444 GETARG,
01445 GETPW,
01446 GETPWB,
01447 GETPOS,
01448 PWPOS,
01449 } ACTION;
01450
01451 const static CH_CLASS chclass[256] = {
01452 OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER,
01453 OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER,
01454 OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER,
01455 OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER,
01456 FLAG, OTHER, OTHER, FLAG, DOLLAR, OTHER, OTHER, OTHER,
01457 OTHER, OTHER, STAR, FLAG, OTHER, FLAG, DOT, OTHER,
01458 ZERO, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT,
01459 DIGIT, DIGIT, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER,
01460 OTHER, OTHER, OTHER, SPEC, SPEC, SPEC, OTHER, SPEC,
01461 OTHER, OTHER, OTHER, OTHER, MODFR, OTHER, OTHER, SPEC,
01462 OTHER, OTHER, OTHER, SPEC, OTHER, SPEC, OTHER, SPEC,
01463 OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER,
01464 OTHER, OTHER, OTHER, SPEC, SPEC, SPEC, SPEC, SPEC,
01465 MODFR, SPEC, OTHER, OTHER, MODFR, OTHER, OTHER, SPEC,
01466 SPEC, MODFR, OTHER, SPEC, OTHER, SPEC, OTHER, OTHER,
01467 SPEC, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER,
01468 OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER,
01469 OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER,
01470 OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER,
01471 OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER,
01472 OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER,
01473 OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER,
01474 OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER,
01475 OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER,
01476 OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER,
01477 OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER,
01478 OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER,
01479 OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER,
01480 OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER,
01481 OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER,
01482 OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER,
01483 OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER,
01484 };
01485
01486 const static STATE state_table[MAX_STATE][MAX_CH_CLASS] = {
01487
01488 { SFLAG, WDIG, DONE, SMOD, DONE, SDOT, VARW, SFLAG, DONE },
01489 { SFLAG, WDIG, DONE, SMOD, DONE, SDOT, VARW, SFLAG, DONE },
01490 { DONE, DONE, WIDTH, SMOD, DONE, SDOT, DONE, DONE, DONE },
01491 { DONE, DONE, DONE, SMOD, DONE, SDOT, DONE, DONE, DONE },
01492 { DONE, DONE, DONE, DONE, DONE, DONE, DONE, DONE, DONE },
01493 { SDOT, PREC, DONE, SMOD, DONE, DONE, VARP, DONE, DONE },
01494 { DONE, VWDIG, DONE, SMOD, DONE, SDOT, DONE, DONE, DONE },
01495 { DONE, VPDIG, DONE, SMOD, DONE, DONE, DONE, DONE, DONE },
01496 { DONE, DONE, DONE, SMOD, DONE, DONE, DONE, DONE, DONE },
01497 { DONE, DONE, WIDTH, DONE, DONE, DONE, DONE, DONE, DONE },
01498 { DONE, DONE, PREC, DONE, DONE, DONE, DONE, DONE, DONE },
01499 };
01500
01501 const static ACTION action_table[MAX_STATE][MAX_CH_CLASS] = {
01502
01503 { NOOP, NUMBER, NOOP, GETMOD, GETARG, NOOP, NOOP, NOOP, NOOP },
01504 { NOOP, NUMBER, NOOP, GETMOD, GETARG, NOOP, NOOP, NOOP, NOOP },
01505 { NOOP, NOOP, GETPOS, GETMOD, GETARG, NOOP, NOOP, NOOP, NOOP },
01506 { NOOP, NOOP, NOOP, GETMOD, GETARG, NOOP, NOOP, NOOP, NOOP },
01507 { NOOP, NOOP, NOOP, NOOP, GETARG, NOOP, NOOP, NOOP, NOOP },
01508 { NOOP, SKIPNUM, NOOP, GETMOD, GETARG, NOOP, NOOP, NOOP, NOOP },
01509 { NOOP, NUMBER, NOOP, GETPW, GETPWB, GETPW, NOOP, NOOP, NOOP },
01510 { NOOP, NUMBER, NOOP, GETPW, GETPWB, NOOP, NOOP, NOOP, NOOP },
01511 { NOOP, NOOP, NOOP, GETMOD, GETARG, NOOP, NOOP, NOOP, NOOP },
01512 { NOOP, NOOP, PWPOS, NOOP, NOOP, NOOP, NOOP, NOOP, NOOP },
01513 { NOOP, NOOP, PWPOS, NOOP, NOOP, NOOP, NOOP, NOOP, NOOP },
01514 };
01515
01516
01517 static union arg_val *
01518 get_arg (struct _reent *data, int n, char *fmt, va_list *ap,
01519 int *numargs_p, union arg_val *args,
01520 int *arg_type, char **last_fmt)
01521 {
01522 int ch;
01523 int number, flags;
01524 int spec_type;
01525 int numargs = *numargs_p;
01526 CH_CLASS chtype;
01527 STATE state, next_state;
01528 ACTION action;
01529 int pos, last_arg;
01530 int max_pos_arg = n;
01531 enum types { INT, LONG_INT, SHORT_INT, QUAD_INT, CHAR, CHAR_PTR, DOUBLE, LONG_DOUBLE, WIDE_CHAR };
01532 #ifdef MB_CAPABLE
01533 wchar_t wc;
01534 mbstate_t wc_state;
01535 int nbytes;
01536 #endif
01537
01538
01539 if (*last_fmt != NULL)
01540 fmt = *last_fmt;
01541
01542 #ifdef MB_CAPABLE
01543 memset (&wc_state, '\0', sizeof (wc_state));
01544 #endif
01545
01546
01547
01548 while (*fmt && n >= numargs)
01549 {
01550 #ifdef MB_CAPABLE
01551 while ((nbytes = _mbtowc_r(data, &wc, fmt, MB_CUR_MAX, &wc_state)) > 0)
01552 {
01553 fmt += nbytes;
01554 if (wc == '%')
01555 break;
01556 }
01557
01558 if (nbytes <= 0)
01559 break;
01560 #else
01561 while (*fmt != '\0' && *fmt != '%')
01562 fmt += 1;
01563
01564 if (*fmt == '\0')
01565 break;
01566 #endif
01567 state = START;
01568 flags = 0;
01569 pos = -1;
01570 number = 0;
01571 spec_type = INT;
01572
01573
01574
01575
01576 while (state != DONE)
01577 {
01578 ch = *fmt++;
01579 chtype = chclass[ch];
01580 next_state = state_table[state][chtype];
01581 action = action_table[state][chtype];
01582 state = next_state;
01583
01584 switch (action)
01585 {
01586 case GETMOD:
01587 switch (ch)
01588 {
01589 case 'h':
01590 flags |= SHORTINT;
01591 break;
01592 case 'L':
01593 flags |= LONGDBL;
01594 break;
01595 case 'q':
01596 flags |= QUADINT;
01597 break;
01598 case 'l':
01599 default:
01600 if (*fmt == 'l')
01601 {
01602 flags |= QUADINT;
01603 ++fmt;
01604 }
01605 else
01606 flags |= LONGINT;
01607 break;
01608 }
01609 break;
01610 case GETARG:
01611 {
01612 numargs &= (MAX_POS_ARGS - 1);
01613
01614 switch (ch)
01615 {
01616 case 'd':
01617 case 'i':
01618 case 'o':
01619 case 'x':
01620 case 'X':
01621 case 'u':
01622 if (flags & LONGINT)
01623 spec_type = LONG_INT;
01624 else if (flags & SHORTINT)
01625 spec_type = SHORT_INT;
01626 #ifndef _NO_LONGLONG
01627 else if (flags & QUADINT)
01628 spec_type = QUAD_INT;
01629 #endif
01630 else
01631 spec_type = INT;
01632 break;
01633 case 'D':
01634 case 'U':
01635 case 'O':
01636 spec_type = LONG_INT;
01637 break;
01638 case 'f':
01639 case 'g':
01640 case 'G':
01641 case 'E':
01642 case 'e':
01643 #ifndef _NO_LONGDBL
01644 if (flags & LONGDBL)
01645 spec_type = LONG_DOUBLE;
01646 else
01647 #endif
01648 spec_type = DOUBLE;
01649 break;
01650 case 's':
01651 case 'S':
01652 case 'p':
01653 spec_type = CHAR_PTR;
01654 break;
01655 case 'c':
01656 spec_type = CHAR;
01657 break;
01658 case 'C':
01659 spec_type = WIDE_CHAR;
01660 break;
01661 }
01662
01663
01664
01665 if (pos != -1)
01666 arg_type[pos] = spec_type;
01667 else
01668 {
01669 switch (spec_type)
01670 {
01671 case LONG_INT:
01672 args[numargs++].val_long = va_arg(*ap, long);
01673 break;
01674 case QUAD_INT:
01675 args[numargs++].val_quad_t = va_arg(*ap, quad_t);
01676 break;
01677 case WIDE_CHAR:
01678 args[numargs++].val_wint_t = va_arg(*ap, wint_t);
01679 break;
01680 case CHAR:
01681 case SHORT_INT:
01682 case INT:
01683 args[numargs++].val_int = va_arg(*ap, int);
01684 break;
01685 case CHAR_PTR:
01686 args[numargs++].val_char_ptr_t = va_arg(*ap, char *);
01687 break;
01688 case DOUBLE:
01689 args[numargs++].val_double = va_arg(*ap, double);
01690 break;
01691 case LONG_DOUBLE:
01692 args[numargs++].val__LONG_DOUBLE = va_arg(*ap, _LONG_DOUBLE);
01693 break;
01694 }
01695 }
01696 }
01697 break;
01698 case GETPOS:
01699 if (arg_type[0] == -1)
01700 memset (arg_type, 0, sizeof(int) * MAX_POS_ARGS);
01701 pos = number - 1;
01702 max_pos_arg = (max_pos_arg > pos ? max_pos_arg : pos);
01703 break;
01704 case PWPOS:
01705 if (arg_type[0] == -1)
01706 memset (arg_type, 0, sizeof(int) * MAX_POS_ARGS);
01707 number -= 1;
01708 arg_type[number] = INT;
01709 max_pos_arg = (max_pos_arg > number ? max_pos_arg : number);
01710 break;
01711 case GETPWB:
01712 --fmt;
01713
01714 case GETPW:
01715 args[numargs++].val_int = va_arg(*ap, int);
01716 break;
01717 case NUMBER:
01718 number = (ch - '0');
01719 while ((ch = *fmt) != '\0' && is_digit(ch))
01720 {
01721 number = number * 10 + (ch - '0');
01722 ++fmt;
01723 }
01724 break;
01725 case SKIPNUM:
01726 while ((ch = *fmt) != '\0' && is_digit(ch))
01727 ++fmt;
01728 break;
01729 case NOOP:
01730 default:
01731 break;
01732 }
01733 }
01734 }
01735
01736
01737
01738 if (*fmt == '\0')
01739 last_arg = max_pos_arg;
01740 else
01741 last_arg = n;
01742
01743 while (numargs <= last_arg)
01744 {
01745 switch (arg_type[numargs])
01746 {
01747 case LONG_INT:
01748 args[numargs++].val_long = va_arg(*ap, long);
01749 break;
01750 case QUAD_INT:
01751 args[numargs++].val_quad_t = va_arg(*ap, quad_t);
01752 break;
01753 case CHAR_PTR:
01754 args[numargs++].val_char_ptr_t = va_arg(*ap, char *);
01755 break;
01756 case DOUBLE:
01757 args[numargs++].val_double = va_arg(*ap, double);
01758 break;
01759 case LONG_DOUBLE:
01760 args[numargs++].val__LONG_DOUBLE = va_arg(*ap, _LONG_DOUBLE);
01761 break;
01762 case WIDE_CHAR:
01763 args[numargs++].val_wint_t = va_arg(*ap, wint_t);
01764 break;
01765 case INT:
01766 case SHORT_INT:
01767 case CHAR:
01768 default:
01769 args[numargs++].val_int = va_arg(*ap, int);
01770 break;
01771 }
01772 }
01773
01774
01775
01776 *numargs_p = numargs;
01777 *last_fmt = fmt;
01778 return &args[n];
01779 }
01780 #endif