4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 /* Copyright (c) 1988 AT&T */
28 /* All Rights Reserved */
31 * _doprnt: common code for printf, fprintf, sprintf
36 #include "print.h" /* parameters & macros for doprnt */
48 #include "../i18n/_locale.h"
50 #include <sys/types.h>
55 static const char nullstr
[] = "(null)";
56 static const wchar_t widenullstr
[] = L
"(null)";
58 #if defined(__i386) || defined(__amd64) || defined(__sparcv9)
59 #define GETQVAL(arg) (va_arg(arg, long double))
60 #else /* !defined(__i386) && !defined(__sparcv9) */
61 #define GETQVAL(arg) *(va_arg(arg, long double *))
62 #endif /* !defined(__i386) && !defined(__sparcv9) */
67 #define ATOI(x) _watoi((wchar_t *)x)
68 #define _P_HYPHEN L"-"
71 #define _P_ZEROx L"0x"
72 #define _P_ZEROX L"0X"
73 #define _M_ISDIGIT(c) (((c) >= 0) && ((c) < 256) && isdigit((c)))
74 #define _M_ISUPPER(c) (((c) >= 0) && ((c) < 256) && isupper((c)))
78 #define ATOI(x) atoi(x)
84 #define _M_ISDIGIT(c) isdigit((c))
85 #define _M_ISUPPER(c) isupper((c))
92 retp = put_wide(iop, &bufptr, bufferend, p, n, sflag); \
94 return ((ssize_t)EOF); \
101 retp = pad_wide(iop, &bufptr, bufferend, s, n, sflag); \
103 return ((ssize_t)EOF); \
107 #define FPCONV(func, val, prec, decpt, sign, cvtbuf) \
109 char cb[DECIMAL_STRING_LENGTH]; \
112 (void) func(val, prec, decpt, sign, cb); \
116 *wp++ = (wchar_t)*cp++; \
125 * When _doprnt() is called by [v]snprintf, we need to \
126 * always call _dowrite(). We also need to call _dowrite() \
127 * if the bufptr lies beyond the end of the buffer. This \
128 * is possible due to known off-by-one errors in __flsbuf() \
129 * and _fwrite_unlocked(). See 1235867 and 1231720 for the \
132 if (snflag || bufptr > bufferend ||\
133 (unsigned long)(bufferend - bufptr) < (n)) {\
134 if (!_dowrite(p, n, iop, &bufptr)) {\
138 unsigned char *fbp = bufptr;\
142 *(fbp + 1) = *(p + 1);\
143 *(fbp + 2) = *(p + 2);\
144 *(fbp + 3) = *(p + 3);\
149 *(fbp + 1) = *(p + 1);\
150 *(fbp + 2) = *(p + 2);\
155 *(fbp + 1) = *(p + 1);\
162 bufptr = (unsigned char *)memcpy(fbp, p, n)\
168 #define PAD(s, n) { ssize_t nn; \
169 for (nn = n; nn > PAD_LEN; nn -= PAD_LEN) \
170 if (!_dowrite(s, PAD_LEN, iop, &bufptr)) \
175 #define FPCONV(func, val, prec, decpt, sign, cvtbuf) \
176 (void) func(val, prec, decpt, sign, cvtbuf);
180 /* bit positions for flags used in doprnt */
182 #define LENGTH 0x1 /* l */
183 #define FPLUS 0x2 /* + */
184 #define FMINUS 0x4 /* - */
185 #define FBLANK 0x8 /* blank */
186 #define FSHARP 0x10 /* # */
187 #define PADZERO 0x20 /* padding zeroes requested via '0' */
188 #define DOTSEEN 0x40 /* dot appeared in format specification */
189 #define SUFFIX 0x80 /* a suffix is to appear in the output */
190 #define RZERO 0x100 /* there will be trailing zeros in output */
191 #define LZERO 0x200 /* there will be leading zeroes in output */
192 #define SHORT 0x400 /* h */
193 #define QUAD 0x800 /* Q for long double */
194 #define XLONG 0x1000 /* ll for long long */
195 #define CHAR 0x2000 /* hh for char */
199 insert_thousands_sep(wchar_t *bp
, wchar_t *ep
);
202 insert_thousands_sep(char *bp
, char *ep
);
205 static int _rec_scrswidth(wchar_t *, ssize_t
);
208 * Positional Parameter information
210 #define MAXARGS 30 /* max. number of args for fast positional paramters */
213 _dowrite(const char *p
, ssize_t n
, FILE *iop
, unsigned char **ptrptr
);
216 * stva_list is used to subvert C's restriction that a variable with an
217 * array type can not appear on the left hand side of an assignment operator.
218 * By putting the array inside a structure, the functionality of assigning to
219 * the whole array through a simple assignment is achieved..
221 typedef struct stva_list
{
226 static void _wmkarglst(wchar_t *, stva_list
, stva_list
[], int);
227 static void _wgetarg(wchar_t *, stva_list
*, long, int);
229 static void _mkarglst(char *, stva_list
, stva_list
[], int);
230 void _getarg(char *, stva_list
*, long, int);
237 _lowdigit(ssize_t
*valptr
)
239 /* This function computes the decimal low-order digit of the number */
240 /* pointed to by valptr, and returns this digit after dividing */
241 /* *valptr by ten. This function is called ONLY to compute the */
242 /* low-order digit of a long whose high-order bit is set. */
244 ssize_t lowbit
= *valptr
& 1;
245 long value
= (*valptr
>> 1) & ~HIBITL
;
248 value
= value
% 5 * 2 + lowbit
+ '0';
253 _lowlldigit(long long *valptr
)
255 ssize_t lowbit
= *valptr
& 1;
256 long long value
= (*valptr
>> 1) & ~HIBITLL
;
258 value
= value
% 5 * 2 + lowbit
+ '0';
262 /* The function _dowrite carries out buffer pointer bookkeeping surrounding */
263 /* a call to fwrite. It is called only when the end of the file output */
264 /* buffer is approached or in other unusual situations. */
267 _dowrite(const char *p
, ssize_t n
, FILE *iop
, unsigned char **ptrptr
)
269 if (!(iop
->_flag
& _IOREAD
)) {
270 iop
->_cnt
-= (*ptrptr
- iop
->_ptr
);
272 _bufsync(iop
, _bufend(iop
));
273 if (_FWRITE(p
, 1, n
, iop
) != n
) {
281 *ptrptr
= (unsigned char *)memcpy((char *)*ptrptr
, p
, n
) + n
;
288 static const char _blanks
[] = " ";
289 static const char _zeroes
[] = "00000000000000000000";
291 static const wchar_t uc_digs
[] = L
"0123456789ABCDEF";
292 static const wchar_t lc_digs
[] = L
"0123456789abcdef";
294 static const char uc_digs
[] = "0123456789ABCDEF";
295 static const char lc_digs
[] = "0123456789abcdef";
300 put_wide(FILE *iop
, unsigned char **bufptr
,
301 unsigned char *bufferend
, wchar_t *p
, size_t n
,
304 unsigned char *newbufptr
;
310 len
= (wchar_t *)bufferend
- (wchar_t *)*bufptr
;
312 (void) wmemcpy((wchar_t *)*bufptr
, p
, len
);
313 iop
->_ptr
= bufferend
;
316 (void) wmemcpy((wchar_t *)*bufptr
, p
, n
);
317 *bufptr
= (unsigned char *)((wchar_t *)*bufptr
+ n
);
324 tsize
= (n
+ 1) * MB_LEN_MAX
;
325 tmpp
= lmalloc(tsize
);
332 for (len
= 0, i
= 0; i
< n
; i
++) {
333 r
= wctomb(tmpq
, *q
++);
343 newbufptr
= *bufptr
+ len
;
344 if (newbufptr
> bufferend
) {
345 if (!_dowrite(tmpp
, len
, iop
, bufptr
)) {
350 (void) memcpy(*bufptr
, tmpp
, len
);
359 pad_wide(FILE *iop
, unsigned char **bufptr
,
360 unsigned char *bufferend
, const char *s
, size_t n
,
363 unsigned char *newbufptr
;
371 len
= (wchar_t *)bufferend
- (wchar_t *)*bufptr
;
373 (void) wmemset((wchar_t *)*bufptr
, ps
, len
);
374 iop
->_ptr
= bufferend
;
377 (void) wmemset((wchar_t *)*bufptr
, ps
, n
);
378 *bufptr
= (unsigned char *)((wchar_t *)*bufptr
+ n
);
382 for (nn
= n
; nn
> PAD_LEN
; nn
-= PAD_LEN
) {
383 if (!_dowrite(s
, PAD_LEN
, iop
, bufptr
))
386 newbufptr
= *bufptr
+ nn
;
387 if (newbufptr
> bufferend
) {
388 if (!_dowrite(s
, nn
, iop
, bufptr
))
391 (void) memcpy(*bufptr
, s
, nn
);
401 _wdoprnt(const wchar_t *format
, va_list in_args
, FILE *iop
)
403 return (_wndoprnt(format
, in_args
, iop
, 0));
407 _doprnt(const char *format
, va_list in_args
, FILE *iop
)
409 return (_ndoprnt(format
, in_args
, iop
, 0));
416 _wndoprnt(const wchar_t *format
, va_list in_args
, FILE *iop
, int prflag
)
419 _ndoprnt(const char *format
, va_list in_args
, FILE *iop
, int prflag
)
429 /* bufptr is used inside of doprnt instead of iop->_ptr; */
430 /* bufferend is a copy of _bufend(iop), if it exists. For */
431 /* dummy file descriptors (iop->_flag & _IOREAD), bufferend */
432 /* may be meaningless. Dummy file descriptors are used so that */
433 /* sprintf and vsprintf may share the _doprnt routine with the */
434 /* rest of the printf family. */
436 unsigned char *bufptr
;
437 unsigned char *bufferend
;
440 /* This variable counts output characters. */
443 /* This variable counts output characters. */
455 /* Starting and ending points for value to be printed */
459 /* Field width and precision */
482 /* Number of padding zeroes required on the left and right */
483 ssize_t lzero
, rzero
, rz
, leadzeroes
;
486 /* Flags - bit positions defined by LENGTH, FPLUS, FMINUS, FBLANK, */
487 /* and FSHARP are set if corresponding character is in format */
488 /* Bit position defined by PADZERO means extra space in the field */
489 /* should be padded with leading zeroes rather than with blanks */
494 /* Values are developed in this buffer */
495 wchar_t buf
[max(MAXLLDIGS
, 1034)];
496 wchar_t cvtbuf
[512 + DECIMAL_STRING_LENGTH
];
498 /* Pointer to sign, "0x", "0X", or empty */
500 wchar_t prefixbuf
[4];
502 /* Exponent or empty */
505 /* Buffer to create exponent */
506 wchar_t expbuf
[MAXESIZ
+ 1];
508 /* Values are developed in this buffer */
509 char buf
[max(MAXLLDIGS
, 1034)];
510 char cvtbuf
[512 + DECIMAL_STRING_LENGTH
];
512 /* Pointer to sign, "0x", "0X", or empty */
516 /* Exponent or empty */
519 /* Buffer to create exponent */
520 char expbuf
[MAXESIZ
+ 1];
523 /* Length of prefix and of suffix */
524 ssize_t prefixlength
, suffixlength
;
526 /* Combined length of leading zeroes, trailing zeroes, and suffix */
529 /* The value being converted, if integer */
532 /* The value being converted, if long long */
535 /* Output value from aconvert */
538 /* Output values from fcvt and ecvt */
542 /* Pointer to a translate table for digits of whatever radix */
545 /* Pointer to a translate table for digits of whatever radix */
550 ssize_t k
, lradix
, mradix
;
553 int inf_nan_mixed_case
= 0;
556 /* variables for positional parameters */
557 /* save the beginning of the format */
558 wchar_t *sformat
= (wchar_t *)format
;
560 /* variables for positional parameters */
561 char *sformat
= (char *)format
; /* save the beginning of the format */
564 int fpos
= 1; /* 1 if first positional parameter */
565 stva_list args
, /* used to step through the argument list */
566 sargs
; /* used to save the start of the arg list */
567 stva_list bargs
; /* used to restore args if positional width */
569 stva_list arglst
[MAXARGS
]; /* array giving appropriate values */
570 /* for va_arg() to retrieve the */
571 /* corresponding argument: */
572 /* arglst[0] is the first arg */
573 /* arglst[1] is the second arg, etc */
575 int starflg
= 0; /* set to 1 if * format specifier seen */
576 struct lconv
*locptr
= localeconv();
577 char decimal_point
= *locptr
->decimal_point
;
580 * Initialize args and sargs to the start of the argument list.
581 * We don't know any portable way to copy an arbitrary C object
582 * so we use a system-specific routine (probably a macro) from
583 * stdarg.h. (Remember that if va_list is an array, in_args will
584 * be a pointer and &in_args won't be what we would want for
587 va_copy(args
.ap
, in_args
);
591 if (iop
->_flag
== _IOREAD
)
596 /* if first I/O to the stream get a buffer */
597 /* Note that iop->_base should not equal 0 for sprintf and vsprintf */
598 if (iop
->_base
== 0) {
599 if (_findbuf(iop
) == 0)
601 /* _findbuf leaves _cnt set to 0 which is the wrong thing to do */
602 /* for fully buffered files */
603 if (!(iop
->_flag
& (_IOLBF
|_IONBF
)))
604 iop
->_cnt
= _bufend(iop
) - iop
->_base
;
613 maxcount
= (size_t)iop
->_cnt
;
614 bufferend
= (unsigned char *)(((wchar_t *)iop
->_ptr
) +
617 bufferend
= _bufend(iop
);
620 /* initialize buffer pointer and buffer end pointer */
622 if (iop
->_flag
& _IOREAD
) {
624 * [v]sprintf or [v]snprintf
626 if (iop
->_cnt
== MAXINT
) {
628 * [v]sprintf (no boundschecking)
631 (unsigned char *)((long)bufptr
| (-1L & ~HIBITL
));
634 * [v]snprintf (with boundschecking) or
635 * iop with _IORW has been read.
637 bufferend
= _bufend(iop
);
638 if (bufferend
== NULL
) {
642 * [v]snprint() needs to be always handled by
650 * [v]printf or [v]fprintf
652 bufferend
= _bufend(iop
);
657 * The main loop -- this loop goes through one iteration
658 * for each string of ordinary characters or format specification.
663 if ((fcode
= *format
) != '\0' && fcode
!= '%') {
665 bp
= (wchar_t *)format
;
671 } while ((fcode
= *format
) != '\0' && fcode
!= '%');
673 count
+= (n
= format
- bp
); /* n = no. of non-% chars */
676 if (fcode
== '\0') { /* end of format; return */
677 ssize_t nn
= bufptr
- iop
->_ptr
;
682 return ((ssize_t
)count
);
688 /* in case of interrupt during last several lines */
689 if ((bufptr
+ iop
->_cnt
) > bufferend
&& !(iop
->_flag \
691 _bufsync(iop
, bufferend
);
692 if (iop
->_flag
& (_IONBF
| _IOLBF
) && \
693 (iop
->_flag
& _IONBF
|| \
694 memchr((char *)(bufptr
+iop
->_cnt
), \
695 '\n', -iop
->_cnt
) != NULL
))
696 (void) _xflsbuf(iop
);
698 return (FERROR(iop
) ? EOF
: (ssize_t
)count
);
700 return (FERROR(iop
) ? EOF
: (int)count
);
706 * The following switch is used to parse the format
707 * specification and to perform the operation specified
708 * by the format letter. The program repeatedly goes
709 * back to this switch until the format letter is
712 width
= prefixlength
= otherlength
= 0;
713 flagword
= suffixlength
= 0;
722 switch (fcode
= *format
++) {
729 flagword
&= ~PADZERO
; /* ignore 0 flag */
734 case '\'': /* XSH4 */
741 /* Scan the field width and precision */
748 if (_M_ISDIGIT(*format
)) {
753 if (!(flagword
& DOTSEEN
)) {
754 width
= va_arg(args
.ap
, int);
760 prec
= va_arg(args
.ap
, int);
763 flagword
^= DOTSEEN
; /* ANSI sez so */
774 _wmkarglst(sformat
, sargs
, arglst
, prflag
);
776 _mkarglst(sformat
, sargs
, arglst
, prflag
);
780 if (flagword
& DOTSEEN
) {
788 /* illegal position */
792 if (position
<= MAXARGS
) {
793 targs
= arglst
[position
- 1];
795 targs
= arglst
[MAXARGS
- 1];
797 _wgetarg(sformat
, &targs
, position
, prflag
);
799 _getarg(sformat
, &targs
, position
, prflag
);
807 if (flagword
& DOTSEEN
) {
808 prec
= va_arg(targs
.ap
, int);
811 flagword
^= DOTSEEN
; /* XSH */
814 width
= va_arg(targs
.ap
, int);
824 case '0': /* obsolescent spec: leading zero in width */
825 /* means pad with leading zeros */
826 if (!(flagword
& (DOTSEEN
| FMINUS
)))
839 while (_M_ISDIGIT(fcode
= *format
)) {
840 num
= num
* 10 + fcode
- '0';
843 if (flagword
& DOTSEEN
)
850 /* Scan the length modifier */
852 if (!(flagword
& XLONG
)) {
865 case 'L': /* long double */
870 if (!(flagword
& CHAR
)) {
871 if (flagword
& SHORT
) {
884 * *printf_c89() in 32-bit libc uses
885 * 32-bit intmax_t; otherwise intmax_t
888 if (!(prflag
& _F_INTMAX32
)) {
890 flagword
|= XLONG
; /* [u]intmax_t (64) */
898 * LENGTH is shared by l, t, z specifiers; protect
899 * against (destructive) undefined behavior (eg:
900 * avoid %llt setting XLONG and LENGTH) with invalid
901 * combinations of specifiers
903 if (!(flagword
& XLONG
)) {
904 flagword
|= LENGTH
; /* ptrdiff_t */
909 if (!(flagword
& XLONG
)) {
910 flagword
|= LENGTH
; /* [s]size_t */
915 * The character addressed by format must be
916 * the format letter -- there is nothing
919 * The status of the +, -, #, and blank
920 * flags are reflected in the variable
921 * "flagword". "width" and "prec" contain
922 * numbers corresponding to the digit
923 * strings before and after the decimal
924 * point, respectively. If there was no
925 * decimal point, then flagword & DOTSEEN
926 * is false and the value of prec is meaningless.
928 * The following switch cases set things up
929 * for printing. What ultimately gets
930 * printed will be padding blanks, a
931 * prefix, left padding zeroes, a value,
932 * right padding zeroes, a suffix, and
933 * more padding blanks. Padding blanks
934 * will not appear simultaneously on both
935 * the left and the right. Each case in
936 * this switch will compute the value, and
937 * leave in several variables the informa-
938 * tion necessary to construct what is to
941 * The prefix is a sign, a blank, "0x",
942 * "0X", a sign or a blank followed by "0x"
943 * or "0X", or nothing, and is addressed by
946 * The suffix is either null or an
947 * exponent, and is addressed by "suffix".
948 * If there is a suffix, the flagword bit
949 * SUFFIX will be set.
951 * The value to be printed starts at "bp"
952 * and continues up to and not including
955 * "lzero" and "rzero" will contain the
956 * number of padding zeroes required on
957 * the left and right, respectively.
958 * The flagword bits LZERO and RZERO tell
959 * whether padding zeros are required.
961 * The number of padding blanks, and
962 * whether they go on the left or the
963 * right, will be computed on exit from
970 * decimal fixed point representations
972 * HIBITL is 100...000
973 * binary, and is equal to the maximum
975 * We assume a 2's complement machine
979 if ((flagword
& PADZERO
) && (flagword
& DOTSEEN
))
980 flagword
&= ~PADZERO
; /* ignore 0 flag */
981 /* Set buffer pointer to last digit */
982 p
= bp
= buf
+ MAXLLDIGS
;
984 /* Fetch the argument to be printed */
985 if (flagword
& XLONG
) { /* long long */
986 ll
= va_arg(args
.ap
, long long);
988 /* If signed conversion, make sign */
993 * Negate, checking in advance for
999 /* number is -HIBITLL; convert last */
1000 /* digit now and get positive number */
1001 *--bp
= _lowlldigit(&ll
);
1002 } else if (flagword
& FPLUS
) {
1005 } else if (flagword
& FBLANK
) {
1009 } else { /* not long long */
1010 if (flagword
& LENGTH
)
1011 val
= va_arg(args
.ap
, long);
1013 val
= va_arg(args
.ap
, int);
1015 if (flagword
& SHORT
)
1017 else if (flagword
& CHAR
)
1020 /* If signed conversion, make sign */
1025 * Negate, checking in advance
1026 * for possible overflow.
1031 * number is -HIBITL; convert
1032 * last digit now and get
1036 *--bp
= _lowdigit(&val
);
1037 } else if (flagword
& FPLUS
) {
1040 } else if (flagword
& FBLANK
) {
1051 if (flagword
& XLONG
) {
1054 if (lll
!= 0LL || !(flagword
& DOTSEEN
))
1055 *--bp
= (wchar_t)lll
+ L
'0';
1057 if (lll
!= 0LL || !(flagword
& DOTSEEN
))
1058 *--bp
= (char)lll
+ '0';
1066 (tll
- lll
* 10 + '0');
1069 (tll
- lll
* 10 + '0');
1071 } while (lll
>= 10);
1073 *--bp
= (wchar_t)lll
+ '0';
1075 *--bp
= (char)lll
+ '0';
1081 if (qval
!= 0 || !(flagword
& DOTSEEN
))
1082 *--bp
= (wchar_t)qval
+ '0';
1084 if (qval
!= 0 || !(flagword
& DOTSEEN
))
1085 *--bp
= (char)qval
+ '0';
1093 (n
- qval
* 10 + '0');
1096 (n
- qval
* 10 + '0');
1100 *--bp
= (wchar_t)qval
+ '0';
1102 *--bp
= (char)qval
+ '0';
1107 /* Handle the ' flag */
1109 p
= insert_thousands_sep(bp
, p
);
1112 /* Calculate minimum padding zero requirement */
1113 if (flagword
& DOTSEEN
) {
1114 leadzeroes
= prec
- (p
- bp
);
1115 if (leadzeroes
> 0) {
1116 otherlength
= lzero
= leadzeroes
;
1123 if ((flagword
& PADZERO
) && (flagword
& DOTSEEN
))
1124 flagword
&= ~PADZERO
; /* ignore 0 flag */
1125 p
= bp
= buf
+ MAXLLDIGS
;
1127 /* Fetch the argument to be printed */
1128 if (flagword
& XLONG
) {
1129 ll
= va_arg(args
.ap
, long long);
1132 *--bp
= _lowlldigit(&ll
);
1134 if (flagword
& LENGTH
)
1135 val
= va_arg(args
.ap
, long);
1137 val
= va_arg(args
.ap
, unsigned);
1139 if (flagword
& SHORT
)
1140 val
= (unsigned short)val
;
1141 else if (flagword
& CHAR
)
1142 val
= (unsigned char)val
;
1145 *--bp
= _lowdigit(&val
);
1151 * non-decimal fixed point representations
1152 * for radix equal to a power of two
1154 * "mradix" is one less than the radix for the conversion.
1155 * "lradix" is one less than the base 2 log
1156 * of the radix for the conversion. Conversion is unsigned.
1157 * HIBITL is 100...000
1158 * binary, and is equal to the maximum
1160 * We assume a 2's complement machine
1167 * DR151 and clarification in C90
1168 * presence of '#' increases precision to first
1169 * digit of the result to be zero
1171 if ((flagword
& DOTSEEN
) && (flagword
& FSHARP
) &&
1178 flagword
&= ~(XLONG
| SHORT
);
1188 if ((flagword
& PADZERO
) && (flagword
& DOTSEEN
))
1189 flagword
&= ~PADZERO
; /* ignore 0 flag */
1192 /* Set translate table for digits */
1193 tab
= (wchar_t *)((fcode
== 'X') ? uc_digs
: lc_digs
);
1195 /* Set translate table for digits */
1196 tab
= (fcode
== 'X') ? uc_digs
: lc_digs
;
1199 /* Fetch the argument to be printed */
1200 if (flagword
& XLONG
) {
1201 ll
= va_arg(args
.ap
, long long);
1203 if (flagword
& LENGTH
)
1204 val
= va_arg(args
.ap
, long);
1206 val
= va_arg(args
.ap
, unsigned);
1208 if (flagword
& SHORT
)
1209 val
= (unsigned short) val
;
1210 else if (flagword
& CHAR
)
1211 val
= (unsigned char) val
;
1213 p
= bp
= buf
+ MAXLLDIGS
;
1215 /* Develop the digits of the value */
1216 if (flagword
& XLONG
) {
1220 if (!(flagword
& DOTSEEN
)) {
1221 otherlength
= lzero
= 1;
1225 *--bp
= tab
[(ssize_t
)(lll
& mradix
)];
1226 lll
= ((lll
>> 1) & ~HIBITLL
) \
1228 } while (lll
!= 0LL);
1233 if (!(flagword
& DOTSEEN
)) {
1234 otherlength
= lzero
= 1;
1238 *--bp
= tab
[qval
& mradix
];
1239 qval
= ((qval
>> 1) & ~HIBITL
) \
1241 } while (qval
!= 0);
1244 /* Calculate minimum padding zero requirement */
1245 if (flagword
& DOTSEEN
) {
1246 leadzeroes
= prec
- (p
- bp
);
1247 if (leadzeroes
> 0) {
1248 otherlength
= lzero
= leadzeroes
;
1253 /* Handle the # flag, (val != 0) for int and long */
1254 /* (ll!= 0) handles long long case */
1255 if ((flagword
& FSHARP
) &&
1256 (((flagword
& XLONG
) == 0 && val
!= 0) ||
1257 ((flagword
& XLONG
) == XLONG
&& ll
!= 0)))
1260 if (!(flagword
& LZERO
)) {
1261 otherlength
= lzero
= 1;
1280 if (flagword
& QUAD
) {
1281 long double qval
= GETQVAL(args
.ap
);
1283 /* establish default precision */
1284 if (!(flagword
& DOTSEEN
))
1285 #if defined(__sparc)
1286 prec
= HEXFP_QUAD_DIG
- 1;
1287 #elif defined(__i386) || defined(__amd64)
1288 prec
= HEXFP_EXTENDED_DIG
- 1;
1290 #error Unknown architecture
1293 FPCONV(__qaconvert
, &qval
,
1294 min(prec
+ 1, MAXECVT
), &exp
, &sign
,
1297 double dval
= va_arg(args
.ap
, double);
1299 /* establish default precision */
1300 if (!(flagword
& DOTSEEN
))
1301 prec
= HEXFP_DOUBLE_DIG
- 1;
1303 FPCONV(__aconvert
, dval
,
1304 min(prec
+ 1, MAXECVT
), &exp
, &sign
,
1310 * The following is wide-character safe because
1311 * __aconvert and __qaconvert only produce ASCII
1314 if (!isxdigit((unsigned char)*bp
)) {
1320 * Create the prefix. We ought to use the strings
1321 * defined above (_P_HYPHEN, etc.), but that would
1322 * be awkward: we'd either have to define six more
1323 * of them or we'd have to use strcpy/strcat to
1324 * assemble the ones already defined. So instead,
1325 * we just build the prefix character by character.
1327 p
= prefix
= prefixbuf
;
1331 } else if (flagword
& FPLUS
) {
1334 } else if (flagword
& FBLANK
) {
1339 *p
++ = (fcode
== 'A') ? 'X' : 'x';
1343 /* put the first digit in the buffer */
1345 *p
++ = (*bp
!= '\0') ? *bp
++ : '0';
1347 /* put in a decimal point if needed */
1348 if (prec
!= 0 || (flagword
& FSHARP
))
1349 *p
++ = decimal_point
;
1351 /* create the rest of the mantissa */
1354 for (; rz
> 0 && *bp
!= '\0'; --rz
) {
1355 *p
++ = ('a' <= *bp
&& *bp
<= 'f')?
1360 for (; rz
> 0 && *bp
!= '\0'; --rz
)
1364 otherlength
= rzero
= rz
;
1371 * Create the exponent in right-to-left order.
1372 * buf[0] == '0' if and only if the value being
1373 * converted is exactly zero, in which case the
1374 * exponent should be +0 regardless of exp.
1376 suffix
= &expbuf
[MAXESIZ
];
1378 if (buf
[0] != '0') {
1384 for (; nn
> 9; nn
/= 10)
1385 *--suffix
= todigit(nn
% 10);
1386 *--suffix
= todigit(nn
);
1387 *--suffix
= (exp
>= 0) ? '+' : '-';
1394 *--suffix
= (fcode
== 'A') ? 'P' : 'p';
1396 /* compute size of suffix */
1397 suffixlength
= &expbuf
[MAXESIZ
] - suffix
;
1398 otherlength
+= suffixlength
;
1405 * E-format. The general strategy
1406 * here is fairly easy: we take what
1407 * econvert gives us and re-format it.
1408 * (qeconvert for long double)
1411 /* Establish default precision */
1412 if (!(flagword
& DOTSEEN
))
1415 if (flagword
& QUAD
) { /* long double */
1416 long double qval
= GETQVAL(args
.ap
);
1418 FPCONV(qeconvert
, &qval
,
1419 min(prec
+ 1, MAXECVT
), &decpt
, &sign
,
1421 } else { /* double */
1422 double dval
= va_arg(args
.ap
, double);
1424 FPCONV(econvert
, dval
,
1425 min(prec
+ 1, MAXECVT
), &decpt
, &sign
,
1431 inf_nan_mixed_case
= (__xpg6
&
1432 _C99SUSv3_mixed_case_Inf_and_NaN
);
1436 /* Determine the prefix */
1441 } else if (flagword
& FPLUS
) {
1444 } else if (flagword
& FBLANK
) {
1449 /* Place the first digit in the buffer */
1451 *p
++ = (*bp
!= '\0') ? *bp
++ : '0';
1453 /* Put in a decimal point if needed */
1454 if (prec
!= 0 || (flagword
& FSHARP
))
1455 *p
++ = decimal_point
;
1457 /* Create the rest of the mantissa */
1459 for (; rz
> 0 && *bp
!= '\0'; --rz
)
1462 otherlength
= rzero
= rz
;
1469 * Create the exponent. buf[0] == '0' if and
1470 * only if the value being converted is exactly
1471 * zero, in which case the exponent should be
1472 * +0 regardless of decpt.
1474 *(suffix
= &expbuf
[MAXESIZ
]) = '\0';
1475 if (buf
[0] != '0') {
1479 for (; nn
> 9; nn
/= 10)
1480 *--suffix
= todigit(nn
% 10);
1481 *--suffix
= todigit(nn
);
1484 /* Prepend leading zeroes to the exponent */
1485 while (suffix
> &expbuf
[MAXESIZ
- 2])
1488 /* Put in the exponent sign */
1489 *--suffix
= (decpt
> 0 || buf
[0] == '0') ? '+' : '-';
1492 *--suffix
= _M_ISUPPER(fcode
) ? 'E' : 'e';
1494 /* compute size of suffix */
1495 otherlength
+= (suffixlength
= &expbuf
[MAXESIZ
] \
1503 * F-format floating point. This is a
1504 * good deal less simple than E-format.
1505 * The overall strategy will be to call
1506 * fconvert, reformat its result into buf,
1507 * and calculate how many trailing
1508 * zeroes will be required. There will
1509 * never be any leading zeroes needed.
1510 * (qfconvert for long double)
1513 /* Establish default precision */
1514 if (!(flagword
& DOTSEEN
))
1517 if (flagword
& QUAD
) { /* long double */
1518 long double qval
= GETQVAL(args
.ap
);
1520 FPCONV(qfconvert
, &qval
, min(prec
, MAXFCVT
),
1521 &decpt
, &sign
, cvtbuf
);
1525 * qfconvert would have required
1526 * too many characters; use qeconvert
1529 FPCONV(qeconvert
, &qval
,
1530 min(prec
+ 1, MAXECVT
), &decpt
,
1534 } else { /* double */
1535 double dval
= va_arg(args
.ap
, double);
1537 FPCONV(fconvert
, dval
, min(prec
, MAXFCVT
),
1538 &decpt
, &sign
, cvtbuf
);
1544 inf_nan_mixed_case
= (__xpg6
&
1545 _C99SUSv3_mixed_case_Inf_and_NaN
);
1549 /* Determine the prefix */
1554 } else if (flagword
& FPLUS
) {
1557 } else if (flagword
& FBLANK
) {
1562 /* Initialize buffer pointer */
1568 /* Emit the digits before the decimal point */
1571 *p
++ = (nn
<= 0 || *bp
== '\0' || \
1572 k
>= MAXFSIG
) ? '0' : (k
++, *bp
++);
1576 p
= insert_thousands_sep(buf
, p
);
1578 /* Decide whether we need a decimal point */
1579 if ((flagword
& FSHARP
) || prec
> 0)
1580 *p
++ = decimal_point
;
1582 /* Digits (if any) after the decimal point */
1583 nn
= min(prec
, MAXFCVT
);
1586 otherlength
= rzero
= prec
- nn
;
1589 *p
++ = (++decpt
<= 0 || *bp
== '\0' || \
1590 k
>= MAXFSIG
) ? '0' : (k
++, *bp
++);
1600 * g-format. We play around a bit
1601 * and then jump into e or f, as needed.
1604 /* Establish default precision */
1605 if (!(flagword
& DOTSEEN
))
1610 if (flagword
& QUAD
) { /* long double */
1611 long double qval
= GETQVAL(args
.ap
);
1613 FPCONV(qeconvert
, &qval
, min(prec
, MAXECVT
),
1614 &decpt
, &sign
, cvtbuf
);
1615 } else { /* double */
1616 double dval
= va_arg(args
.ap
, double);
1618 FPCONV(econvert
, dval
, min(prec
, MAXECVT
),
1619 &decpt
, &sign
, cvtbuf
);
1624 inf_nan_mixed_case
= (__xpg6
&
1625 _C99SUSv3_mixed_case_Inf_and_NaN
);
1628 if (*bp
== '0') /* the value converted is zero */
1633 if (!(flagword
& FSHARP
)) {
1641 while (kk
>= 1 && bp
[kk
-1] == '0')
1644 if (decpt
< -3 || decpt
> prec
) {
1663 case 'C': /* XPG XSH4 extention */
1668 temp
= va_arg(args
.ap
, wchar_t);
1681 if ((retcode
= wctomb(buf
, temp
))
1686 p
= (bp
= buf
) + retcode
;
1688 } else { /* NULL character */
1704 temp
= va_arg(args
.ap
, wchar_t);
1706 if ((retcode
= wctomb(buf
, temp
))
1710 p
= (bp
= buf
) + retcode
;
1712 } else { /* NULL character */
1719 if (flagword
& XLONG
) {
1721 temp
= va_arg(args
.ap
, long long);
1723 buf
[0] = (wchar_t)temp
;
1725 buf
[0] = (char)temp
;
1728 buf
[0] = va_arg(args
.ap
, int);
1730 p
= (bp
= &buf
[0]) + 1;
1740 case 'S': /* XPG XSH4 extention */
1746 bp
= va_arg(args
.ap
, wchar_t *);
1748 bp
= (wchar_t *)widenullstr
;
1749 if (!(flagword
& DOTSEEN
)) {
1750 /* wide character handling */
1757 if ((prec
- wcount
- 1) >= 0) {
1770 bp
= va_arg(args
.ap
, char *);
1772 bp
= (char *)widenullstr
;
1773 if (!(flagword
& DOTSEEN
)) {
1774 /* wide character handling */
1778 wp
= (wchar_t *)(uintptr_t)bp
;
1783 nbytes
= wctomb(tmpbuf
, *wp
);
1788 if ((prec
- (wcount
+ nbytes
)) >= 0) {
1795 sec_display
= wcount
;
1804 cbp
= va_arg(args
.ap
, char *);
1806 cbp
= (char *)nullstr
;
1807 if (!(flagword
& DOTSEEN
)) {
1811 nwc
= mbstowcs(NULL
, cbp
, 0);
1812 if (nwc
== (size_t)-1) {
1816 bpsize
= sizeof (wchar_t) * (nwc
+ 1);
1817 wstr
= (wchar_t *)lmalloc(bpsize
);
1822 nwc
= mbstowcs(wstr
, cbp
, MAXINT
);
1830 nwc
= mbstowcs(NULL
, cbp
, 0);
1831 if (nwc
== (size_t)-1) {
1836 bpsize
= sizeof (wchar_t) * nwc
;
1837 wstr
= (wchar_t *)lmalloc(bpsize
);
1842 nwc
= mbstowcs(wstr
, cbp
, nwc
);
1843 cp
= cbp
+ strlen(cbp
);
1853 bpsize
= sizeof (wchar_t) * prec
;
1854 wstr
= (wchar_t *)lmalloc(bpsize
);
1859 nwc
= mbstowcs(wstr
, cbp
, prec
);
1867 bp
= va_arg(args
.ap
, char *);
1869 bp
= (char *)nullstr
;
1870 if (!(flagword
& DOTSEEN
)) {
1872 /* wide character handling */
1878 p
= bp
+ strlen(bp
);
1881 * sec_display only needed if width
1882 * is specified (ie, "%<width>s")
1883 * Solaris behavior counts <width> in
1884 * screen column width. (If XPG4 behavior,
1885 * <width> is counted in bytes.)
1887 if (width
> 0 && __xpg4
== 0 &&
1896 if ((nwc
= mbstowcs(wbuff
, bp
,
1897 NW
)) == (size_t)-1) {
1898 /* Estimate width */
1899 sec_display
= strlen(bp
);
1906 * If widechar does not fit into
1907 * wbuff, allocate larger buffer
1910 mbstowcs(NULL
, bp
, 0)) ==
1916 wpsize
= (nwc
+ 1) *
1918 if ((wp
= lmalloc(wpsize
))
1923 if ((nwc
= mbstowcs(wp
,
1924 bp
, nwc
)) == (size_t)-1) {
1931 if ((sec_display
= wcswidth(wptr
, nwc
))
1941 } else { /* a strnlen function would be useful here! */
1943 * If we've seen a dot, and count has been set
1944 * to 0, then we don't output in any cases
1945 * below. prec should be always >= 0. So we only
1946 * check to see if it's zero.
1954 /* wide character handling */
1957 wp
= (wchar_t *)(uintptr_t)bp
;
1961 (prec
-= _scrwidth(*wp
)) >= 0) {
1963 wctomb(tmpbuf
, *wp
)) < 0)
1970 prec
+= _scrwidth(*wp
);
1972 sec_display
= preco
- prec
;
1973 } else if (__xpg4
== 0 && MB_CUR_MAX
> 1) {
1975 * Solaris behavior - count
1976 * precision as screen column width
1991 if ((nbytes
= mbtowc(&wc
, qp
,
1992 MB_LEN_MAX
)) == -1) {
1993 /* print illegal char */
2004 if ((prec
-= ncol
) >= 0) {
2015 sec_display
= preco
- prec
;
2018 * XPG4 behavior - count
2019 * precision as bytes.
2020 * We don't use strlen() because
2021 * the given char string may not
2022 * be null-terminated.
2026 qp
= memchr(bp
, '\0', prec
);
2039 if (flagword
& XLONG
) {
2041 svcount
= va_arg(args
.ap
, long long *);
2042 *svcount
= (long long)count
;
2043 } else if (flagword
& LENGTH
) {
2045 svcount
= va_arg(args
.ap
, long *);
2046 *svcount
= (long)count
;
2047 } else if (flagword
& SHORT
) {
2049 svcount
= va_arg(args
.ap
, short *);
2050 *svcount
= (short)count
;
2051 } else if (flagword
& CHAR
) {
2053 svcount
= va_arg(args
.ap
, char *);
2054 *svcount
= (char)count
;
2057 svcount
= va_arg(args
.ap
, int *);
2062 default: /* this is technically an error; what we do is to */
2063 /* back up the format pointer to the offending char */
2064 /* and continue with the format scan */
2070 if (inf_nan_mixed_case
) {
2072 for (p
= bp
+ 1; *p
!= '\0'; p
++)
2077 /* advance p and make output all one case */
2078 upper
= _M_ISUPPER(fcode
);
2079 for (p
= bp
; *p
!= '\0'; p
++)
2080 *p
= upper
? toupper(*p
) : tolower(*p
);
2085 } else if (flagword
& FPLUS
) {
2088 } else if (flagword
& FBLANK
) {
2093 inf_nan_mixed_case
= 0;
2094 flagword
&= ~PADZERO
; /* ignore 0 flag */
2097 /* Calculate number of padding blanks */
2098 n
= p
- bp
; /* n == size of the converted value (in bytes) */
2103 if (sec_display
) /* when format is %s or %ws or %S */
2109 * k is the (screen) width or # of bytes of the converted value
2111 k
+= prefixlength
+ otherlength
;
2121 * update count which is the overall size of the output data
2122 * and passed to memchr()
2126 * when wflag != 0 (i.e. %ws or %wc), the size of the
2127 * converted value is wcount bytes
2132 * when wflag == 0, the size of the converted
2133 * value is n (= p-bp) bytes
2137 count
+= prefixlength
+ otherlength
;
2140 count
+= (width
- k
);
2142 * Set up for padding zeroes if requested
2143 * Otherwise emit padding blanks unless output is
2144 * to be left-justified.
2147 if (flagword
& PADZERO
) {
2148 if (!(flagword
& LZERO
)) {
2153 k
= width
; /* cancel padding blanks */
2155 /* Blanks on left if required */
2156 if (!(flagword
& FMINUS
))
2157 PAD(_blanks
, width
- k
);
2160 /* Prefix, if any */
2161 if (prefixlength
!= 0)
2162 PUT(prefix
, prefixlength
);
2164 /* Zeroes on the left */
2165 if ((flagword
& LZERO
)) /* && */
2166 /* (!(flagword & SHORT) || !(flagword & FMINUS)) */
2167 PAD(_zeroes
, lzero
);
2172 if ((fcode
== 's') && !lflag
) {
2177 /* The value itself */
2178 if ((fcode
== 's' || fcode
== 'S') && wflag
) {
2179 /* wide character handling */
2180 wchar_t *wp
= (wchar_t *)(uintptr_t)bp
;
2184 printn
= (wchar_t *)(uintptr_t)p
-
2185 (wchar_t *)(uintptr_t)bp
;
2187 while (printn
> 0) {
2188 if ((cnt
= wctomb(buf
, *wp
)) < 0)
2194 } else { /* non wide character value */
2200 if (flagword
& (RZERO
| SUFFIX
| FMINUS
)) {
2201 /* Zeroes on the right */
2202 if (flagword
& RZERO
)
2203 PAD(_zeroes
, rzero
);
2206 if (flagword
& SUFFIX
)
2207 PUT(suffix
, suffixlength
);
2209 /* Blanks on the right if required */
2210 if (flagword
& FMINUS
&& width
> k
)
2211 PAD(_blanks
, width
- k
);
2218 _watoi(wchar_t *fmt
)
2224 if (_M_ISDIGIT(ch
)) {
2227 while (_M_ISDIGIT(ch
)) {
2238 * This function initializes arglst, to contain the appropriate va_list values
2239 * for the first MAXARGS arguments.
2243 * Type modifier flags:
2246 * 0x04 for long long
2247 * 0x08 for long double
2250 #define FLAG_LONG 0x01
2251 #define FLAG_INT 0x02
2252 #define FLAG_LONG_LONG 0x04
2253 #define FLAG_LONG_DBL 0x08
2258 _wmkarglst(wchar_t *fmt
, stva_list args
, stva_list arglst
[], int prflag
)
2261 _mkarglst(char *fmt
, stva_list args
, stva_list arglst
[], int prflag
)
2265 static const wchar_t digits
[] = L
"01234567890";
2266 static const wchar_t skips
[] = L
"# +-.'0123456789h$";
2268 static const char digits
[] = "01234567890";
2269 static const char skips
[] = "# +-.'0123456789h$";
2271 enum types
{INT
= 1, LONG
, CHAR_PTR
, DOUBLE
, LONG_DOUBLE
, VOID_PTR
,
2272 LONG_PTR
, INT_PTR
, LONG_LONG
, LONG_LONG_PTR
};
2273 enum types typelst
[MAXARGS
], curtype
;
2275 int maxnum
, curargno
, flags
;
2278 * Algorithm 1. set all argument types to zero.
2279 * 2. walk through fmt putting arg types in typelst[].
2280 * 3. walk through args using va_arg(args.ap, typelst[n])
2281 * and set arglst[] to the appropriate values.
2282 * Assumptions: Cannot use %*$... to specify variable position.
2285 (void) memset(typelst
, 0, sizeof (typelst
));
2288 while ((fmt
= STRCHR(fmt
, '%')) != 0) {
2290 if (fmt
[n
= STRSPN(fmt
, digits
)] == '$') {
2291 /* convert to zero base */
2292 curargno
= ATOI(fmt
) - 1;
2299 fmt
+= STRSPN(fmt
, skips
);
2301 case '%': /* there is no argument! */
2304 if (flags
& (FLAG_LONG
| FLAG_LONG_LONG
)) {
2305 flags
|= FLAG_LONG_LONG
;
2306 flags
&= ~FLAG_LONG
;
2314 * *printf_c89() in 32-bit libc uses
2315 * 32-bit intmax_t; otherwise intmax_t
2318 if (!(prflag
& _F_INTMAX32
)) {
2320 flags
|= FLAG_LONG_LONG
; /* 64-bit */
2332 flags
|= FLAG_LONG_DBL
;
2334 case '*': /* int argument used for value */
2335 /* check if there is a positional parameter */
2337 if ((*fmt
>= 0) && (*fmt
< 256) &&
2344 targno
= ATOI(fmt
) - 1;
2345 fmt
+= STRSPN(fmt
, digits
);
2347 fmt
++; /* skip '$' */
2348 if (targno
>= 0 && targno
< MAXARGS
) {
2349 typelst
[targno
] = INT
;
2350 if (maxnum
< targno
)
2366 if (flags
& FLAG_LONG_DBL
)
2367 curtype
= LONG_DOUBLE
;
2378 if (flags
& FLAG_LONG_LONG
)
2379 curtype
= LONG_LONG_PTR
;
2380 else if (flags
& FLAG_LONG
)
2386 if (flags
& FLAG_LONG_LONG
)
2387 curtype
= LONG_LONG
;
2388 else if (flags
& FLAG_LONG
)
2394 if (curargno
>= 0 && curargno
< MAXARGS
) {
2395 typelst
[curargno
] = curtype
;
2396 if (maxnum
< curargno
)
2399 curargno
++; /* default to next in list */
2400 if (flags
& FLAG_INT
) /* took care of *, keep going */
2406 for (n
= 0; n
<= maxnum
; n
++) {
2408 if (typelst
[n
] == 0)
2411 switch (typelst
[n
]) {
2413 (void) va_arg(args
.ap
, int);
2416 (void) va_arg(args
.ap
, long);
2419 (void) va_arg(args
.ap
, char *);
2422 (void) va_arg(args
.ap
, double);
2425 (void) GETQVAL(args
.ap
);
2428 (void) va_arg(args
.ap
, void *);
2431 (void) va_arg(args
.ap
, long *);
2434 (void) va_arg(args
.ap
, int *);
2437 (void) va_arg(args
.ap
, long long);
2440 (void) va_arg(args
.ap
, long long *);
2447 * This function is used to find the va_list value for arguments whose
2448 * position is greater than MAXARGS. This function is slow, so hopefully
2449 * MAXARGS will be big enough so that this function need only be called in
2450 * unusual circumstances.
2451 * pargs is assumed to contain the value of arglst[MAXARGS - 1].
2456 _wgetarg(wchar_t *fmt
, stva_list
*pargs
, long argno
, int prflag
)
2459 _getarg(char *fmt
, stva_list
*pargs
, long argno
, int prflag
)
2464 static const wchar_t digits
[] = L
"01234567890";
2465 static const wchar_t skips
[] = L
"# +-.'0123456789h$";
2466 wchar_t *sfmt
= fmt
;
2468 static const char digits
[] = "01234567890";
2469 static const char skips
[] = "# +-.'0123456789h$";
2473 int i
, curargno
, flags
;
2481 while ((i
!= argno
) && (fmt
= STRCHR(fmt
, '%')) != 0) {
2483 if (fmt
[n
= STRSPN(fmt
, digits
)] == '$') {
2484 curargno
= ATOI(fmt
);
2490 /* find conversion specifier for next argument */
2491 if (i
!= curargno
) {
2498 fmt
+= STRSPN(fmt
, skips
);
2500 case '%': /* there is no argument! */
2503 if (flags
& (FLAG_LONG
| FLAG_LONG_LONG
)) {
2504 flags
|= FLAG_LONG_LONG
;
2505 flags
&= ~FLAG_LONG
;
2513 * *printf_c89() in 32-bit libc uses
2514 * 32-bit intmax_t; otherwise intmax_t
2517 if (!(prflag
& _F_INTMAX32
)) {
2519 flags
|= FLAG_LONG_LONG
; /* 64-bit */
2531 flags
|= FLAG_LONG_DBL
;
2533 case '*': /* int argument used for value */
2535 * check if there is a positional parameter;
2536 * if so, just skip it; its size will be
2537 * correctly determined by default
2539 if (_M_ISDIGIT(*fmt
)) {
2540 fmt
+= STRSPN(fmt
, digits
);
2542 fmt
++; /* skip '$' */
2546 (void) va_arg((*pargs
).ap
, int);
2556 if (flags
& FLAG_LONG_DBL
)
2557 (void) GETQVAL((*pargs
).ap
);
2559 (void) va_arg((*pargs
).ap
, double);
2562 (void) va_arg((*pargs
).ap
, char *);
2565 (void) va_arg((*pargs
).ap
, void *);
2568 if (flags
& FLAG_LONG_LONG
)
2569 (void) va_arg((*pargs
).ap
, long long *);
2570 else if (flags
& FLAG_LONG
)
2571 (void) va_arg((*pargs
).ap
, long *);
2573 (void) va_arg((*pargs
).ap
, int *);
2576 if (flags
& FLAG_LONG_LONG
)
2577 (void) va_arg((*pargs
).ap
, long long);
2578 else if (flags
& FLAG_LONG
)
2579 (void) va_arg((*pargs
).ap
, long int);
2581 (void) va_arg((*pargs
).ap
, int);
2585 curargno
++; /* default to next in list */
2586 if (flags
& FLAG_INT
) /* took care of *, keep going */
2593 /* missing specifier for parameter, assume param is an int */
2594 if (!found
&& i
!= argno
) {
2595 (void) va_arg((*pargs
).ap
, int);
2605 insert_thousands_sep(wchar_t *bp
, wchar_t *ep
)
2608 insert_thousands_sep(char *bp
, char *ep
)
2612 struct lconv
*locptr
;
2618 wchar_t *bufptr
= buf
;
2626 /* get the thousands sep. from the current locale */
2627 locptr
= localeconv();
2628 thousep
= *locptr
->thousands_sep
;
2629 grp_ptr
= locptr
->grouping
;
2631 /* thousands sep. not use in this locale or no grouping required */
2632 if (!thousep
|| (*grp_ptr
== '\0'))
2635 buf_index
= ep
- bp
;
2637 if (*grp_ptr
== CHAR_MAX
) {
2638 for (i
= 0; i
< buf_index
--; i
++)
2639 *bufptr
++ = *(bp
+ buf_index
);
2642 for (i
= 0; i
< *grp_ptr
&& buf_index
-- > 0; i
++)
2643 *bufptr
++ = *(bp
+ buf_index
);
2645 if (buf_index
> 0) {
2647 *bufptr
++ = (wchar_t)thousep
;
2649 *bufptr
++ = thousep
;
2655 if (*(grp_ptr
+ 1) != '\0')
2659 /* put the string in the caller's buffer in reverse order */
2661 while (buf
<= bufptr
)
2668 * Recovery scrswidth function -
2669 * this variant of wcswidth() accepts non-printable or illegal
2670 * widechar characters.
2673 _rec_scrswidth(wchar_t *wp
, ssize_t n
)
2679 while (*wp
&& (n
-- > 0)) {
2680 if ((i
= _scrwidth(*wp
++)) == 0)