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