1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 /* Copyright (c) 1988 AT&T */ 30 31 /* All Rights Reserved */ 32 33 34 /* 35 * _doprnt: common code for printf, fprintf, sprintf 36 */ 37 38 #include "synonyms.h" 39 #include "mtlib.h" 40 #include "print.h" /* parameters & macros for doprnt */ 41 #include <wchar.h> 42 #include "libc.h" 43 #include <stdlib.h> 44 #include <limits.h> 45 #include <ctype.h> 46 #include <stdarg.h> 47 #include <values.h> 48 #include <memory.h> 49 #include <string.h> 50 #include <locale.h> 51 #include <widec.h> 52 #include "../i18n/_locale.h" 53 #include <errno.h> 54 #include <sys/types.h> 55 #include <libw.h> 56 #include "mse.h" 57 #include "xpg6.h" 58 59 #if defined(__i386) || defined(__amd64) || defined(__sparcv9) 60 #define GETQVAL(arg) (va_arg(arg, long double)) 61 #else /* !defined(__i386) && !defined(__sparcv9) */ 62 #define GETQVAL(arg) *(va_arg(arg, long double *)) 63 #endif /* !defined(__i386) && !defined(__sparcv9) */ 64 65 #ifdef _WIDE 66 #define STRCHR wcschr 67 #define STRSPN wcsspn 68 #define ATOI(x) _watoi((wchar_t *)x) 69 #define _P_HYPHEN L"-" 70 #define _P_PLUS L"+" 71 #define _P_BLANK L" " 72 #define _P_ZEROx L"0x" 73 #define _P_ZEROX L"0X" 74 #define _M_ISDIGIT(c) (((c) >= 0) && ((c) < 256) && isdigit((c))) 75 #define _M_ISUPPER(c) (((c) >= 0) && ((c) < 256) && isupper((c))) 76 #else /* _WIDE */ 77 #define STRCHR strchr 78 #define STRSPN strspn 79 #define ATOI(x) atoi(x) 80 #define _P_HYPHEN "-" 81 #define _P_PLUS "+" 82 #define _P_BLANK " " 83 #define _P_ZEROx "0x" 84 #define _P_ZEROX "0X" 85 #define _M_ISDIGIT(c) isdigit((c)) 86 #define _M_ISUPPER(c) isupper((c)) 87 #endif /* _WIDE */ 88 89 #ifdef _WIDE 90 #define PUT(p, n) \ 91 { \ 92 int retp; \ 93 retp = put_wide(iop, &bufptr, bufferend, p, n, sflag, lc, fp); \ 94 if (retp == EOF) { \ 95 return ((ssize_t)EOF); \ 96 } \ 97 } 98 99 #define PAD(s, n) \ 100 { \ 101 int retp; \ 102 retp = pad_wide(iop, &bufptr, bufferend, s, n, sflag); \ 103 if (retp == EOF) { \ 104 return ((ssize_t)EOF); \ 105 } \ 106 } 107 108 #define FPCONV(func, val, prec, decpt, sign, cvtbuf) \ 109 { \ 110 char cb[DECIMAL_STRING_LENGTH]; \ 111 wchar_t *wp; \ 112 char *cp; \ 113 (void) func(val, prec, decpt, sign, cb); \ 114 wp = cvtbuf; \ 115 cp = cb; \ 116 while (*cp) { \ 117 *wp++ = (wchar_t)*cp++; \ 118 } \ 119 *wp = L'\0'; \ 120 } 121 122 #else /* _WIDE */ 123 #define PUT(p, n) \ 124 {\ 125 /*\ 126 * When _doprnt() is called by [v]snprintf, we need to \ 127 * always call _dowrite(). We also need to call _dowrite() \ 128 * if the bufptr lies beyond the end of the buffer. This \ 129 * is possible due to known off-by-one errors in __flsbuf() \ 130 * and _fwrite_unlocked(). See 1235867 and 1231720 for the \ 131 * sordid details. \ 132 */\ 133 if (snflag || bufptr > bufferend ||\ 134 (unsigned long)(bufferend - bufptr) < (n)) {\ 135 if (!_dowrite(p, n, iop, &bufptr)) {\ 136 return (EOF);\ 137 }\ 138 } else {\ 139 unsigned char *fbp = bufptr;\ 140 switch (n) {\ 141 case 4:\ 142 *fbp = *p;\ 143 *(fbp + 1) = *(p + 1);\ 144 *(fbp + 2) = *(p + 2);\ 145 *(fbp + 3) = *(p + 3);\ 146 bufptr += 4;\ 147 break;\ 148 case 3:\ 149 *fbp = *p;\ 150 *(fbp + 1) = *(p + 1);\ 151 *(fbp + 2) = *(p + 2);\ 152 bufptr += 3;\ 153 break;\ 154 case 2:\ 155 *fbp = *p;\ 156 *(fbp + 1) = *(p + 1);\ 157 bufptr += 2;\ 158 break;\ 159 case 1:\ 160 *bufptr++ = *p;\ 161 break;\ 162 default:\ 163 bufptr = (unsigned char *)memcpy(fbp, p, n)\ 164 + (n);\ 165 }\ 166 }\ 167 } 168 169 #define PAD(s, n) { ssize_t nn; \ 170 for (nn = n; nn > PAD_LEN; nn -= PAD_LEN) \ 171 if (!_dowrite(s, PAD_LEN, iop, &bufptr)) \ 172 return (EOF); \ 173 PUT(s, nn); \ 174 } 175 176 #define FPCONV(func, val, prec, decpt, sign, cvtbuf) \ 177 (void) func(val, prec, decpt, sign, cvtbuf); 178 179 #endif /* _WIDE */ 180 181 /* bit positions for flags used in doprnt */ 182 183 #define LENGTH 0x1 /* l */ 184 #define FPLUS 0x2 /* + */ 185 #define FMINUS 0x4 /* - */ 186 #define FBLANK 0x8 /* blank */ 187 #define FSHARP 0x10 /* # */ 188 #define PADZERO 0x20 /* padding zeroes requested via '0' */ 189 #define DOTSEEN 0x40 /* dot appeared in format specification */ 190 #define SUFFIX 0x80 /* a suffix is to appear in the output */ 191 #define RZERO 0x100 /* there will be trailing zeros in output */ 192 #define LZERO 0x200 /* there will be leading zeroes in output */ 193 #define SHORT 0x400 /* h */ 194 #define QUAD 0x800 /* Q for long double */ 195 #define XLONG 0x1000 /* ll for long long */ 196 #define CHAR 0x2000 /* hh for char */ 197 198 #ifdef _WIDE 199 static wchar_t * 200 insert_thousands_sep(wchar_t *bp, wchar_t *ep); 201 #else /* _WIDE */ 202 static char * 203 insert_thousands_sep(char *bp, char *ep); 204 #endif /* _WIDE */ 205 206 static int _rec_scrswidth(wchar_t *, ssize_t); 207 208 /* 209 * Positional Parameter information 210 */ 211 #define MAXARGS 30 /* max. number of args for fast positional paramters */ 212 213 static ssize_t 214 _dowrite(const char *p, ssize_t n, FILE *iop, unsigned char **ptrptr); 215 216 /* 217 * stva_list is used to subvert C's restriction that a variable with an 218 * array type can not appear on the left hand side of an assignment operator. 219 * By putting the array inside a structure, the functionality of assigning to 220 * the whole array through a simple assignment is achieved.. 221 */ 222 typedef struct stva_list { 223 va_list ap; 224 } stva_list; 225 226 #ifdef _WIDE 227 static void _wmkarglst(wchar_t *, stva_list, stva_list [], int); 228 static void _wgetarg(wchar_t *, stva_list *, long, int); 229 #else /* _WIDE */ 230 void _mkarglst(char *, stva_list, stva_list [], int); 231 void _getarg(char *, stva_list *, long, int); 232 #endif /* _WIDE */ 233 234 235 236 237 static int 238 _lowdigit(ssize_t *valptr) 239 { 240 /* This function computes the decimal low-order digit of the number */ 241 /* pointed to by valptr, and returns this digit after dividing */ 242 /* *valptr by ten. This function is called ONLY to compute the */ 243 /* low-order digit of a long whose high-order bit is set. */ 244 245 ssize_t lowbit = *valptr & 1; 246 long value = (*valptr >> 1) & ~HIBITL; 247 248 *valptr = value / 5; 249 value = value % 5 * 2 + lowbit + '0'; 250 return ((int)value); 251 } 252 253 static int 254 _lowlldigit(long long *valptr) 255 { 256 ssize_t lowbit = *valptr & 1; 257 long long value = (*valptr >> 1) & ~HIBITLL; 258 *valptr = value / 5; 259 value = value % 5 * 2 + lowbit + '0'; 260 return ((int)value); 261 } 262 263 /* The function _dowrite carries out buffer pointer bookkeeping surrounding */ 264 /* a call to fwrite. It is called only when the end of the file output */ 265 /* buffer is approached or in other unusual situations. */ 266 267 static ssize_t 268 _dowrite(const char *p, ssize_t n, FILE *iop, unsigned char **ptrptr) 269 { 270 if (!(iop->_flag & _IOREAD)) { 271 iop->_cnt -= (*ptrptr - iop->_ptr); 272 iop->_ptr = *ptrptr; 273 _bufsync(iop, _bufend(iop)); 274 if (_FWRITE(p, 1, n, iop) != n) { 275 return (0); 276 } 277 *ptrptr = iop->_ptr; 278 } else { 279 if (n > iop->_cnt) 280 n = iop->_cnt; 281 iop->_cnt -= n; 282 *ptrptr = (unsigned char *)memcpy((char *)*ptrptr, p, n) + n; 283 iop->_ptr = *ptrptr; 284 } 285 return (1); 286 } 287 288 #define PAD_LEN 20 289 static const char _blanks[] = " "; 290 static const char _zeroes[] = "00000000000000000000"; 291 #ifdef _WIDE 292 static const wchar_t uc_digs[] = L"0123456789ABCDEF"; 293 static const wchar_t lc_digs[] = L"0123456789abcdef"; 294 #else /* _WIDE */ 295 static const char uc_digs[] = "0123456789ABCDEF"; 296 static const char lc_digs[] = "0123456789abcdef"; 297 #endif /* _WIDE */ 298 299 #ifdef _WIDE 300 static int 301 put_wide(FILE *iop, unsigned char **bufptr, 302 unsigned char *bufferend, wchar_t *p, size_t n, 303 int sflag, void *lc, int (*fp_wctomb)(void *, char *, wchar_t)) 304 { 305 unsigned char *newbufptr; 306 wchar_t *q; 307 int r; 308 size_t len, i; 309 310 if (sflag) { 311 len = (wchar_t *)bufferend - (wchar_t *)*bufptr; 312 if (n > len) { 313 (void) wmemcpy((wchar_t *)*bufptr, p, len); 314 iop->_ptr = bufferend; 315 return (EOF); 316 } else { 317 (void) wmemcpy((wchar_t *)*bufptr, p, n); 318 *bufptr = (unsigned char *) 319 ((wchar_t *)*bufptr + n); 320 return (0); 321 } 322 } else { 323 char *tmpp, *tmpq; 324 size_t tsize; 325 326 tsize = (n + 1) * MB_LEN_MAX; 327 tmpp = lmalloc(tsize); 328 if (tmpp == NULL) { 329 errno = ENOMEM; 330 return (EOF); 331 } 332 q = p; 333 tmpq = tmpp; 334 for (len = 0, i = 0; i < n; i++) { 335 r = fp_wctomb(lc, tmpq, *q++); 336 if (r == -1) { 337 lfree(tmpp, tsize); 338 errno = EILSEQ; 339 return (EOF); 340 } 341 len += r; 342 tmpq += r; 343 } 344 tmpq = tmpp; 345 newbufptr = *bufptr + len; 346 if (newbufptr > bufferend) { 347 if (!_dowrite(tmpp, len, iop, bufptr)) { 348 lfree(tmpp, tsize); 349 return (EOF); 350 } 351 } else { 352 (void) memcpy(*bufptr, tmpp, len); 353 *bufptr = newbufptr; 354 } 355 lfree(tmpp, tsize); 356 return (0); 357 } 358 } 359 360 static int 361 pad_wide(FILE *iop, unsigned char **bufptr, 362 unsigned char *bufferend, const char *s, size_t n, 363 int sflag) 364 { 365 unsigned char *newbufptr; 366 ssize_t nn; 367 size_t len; 368 wchar_t ps; 369 370 if (sflag) { 371 /* for swprintf */ 372 ps = (wchar_t)s[0]; 373 len = (wchar_t *)bufferend - (wchar_t *)*bufptr; 374 if (n > len) { 375 (void) wmemset((wchar_t *)*bufptr, ps, len); 376 iop->_ptr = bufferend; 377 return (EOF); 378 } else { 379 (void) wmemset((wchar_t *)*bufptr, ps, n); 380 *bufptr = (unsigned char *) 381 ((wchar_t *)*bufptr + n); 382 return (0); 383 } 384 } else { 385 for (nn = n; nn > PAD_LEN; nn -= PAD_LEN) { 386 if (!_dowrite(s, PAD_LEN, iop, bufptr)) 387 return (EOF); 388 } 389 newbufptr = *bufptr + nn; 390 if (newbufptr > bufferend) { 391 if (!_dowrite(s, nn, iop, bufptr)) 392 return (EOF); 393 } else { 394 (void) memcpy(*bufptr, s, nn); 395 *bufptr = newbufptr; 396 } 397 return (0); 398 } 399 } 400 #endif /* _WIDE */ 401 402 #ifdef _WIDE 403 ssize_t 404 _wdoprnt(const wchar_t *format, va_list in_args, FILE *iop) 405 { 406 return (_wndoprnt(format, in_args, iop, 0)); 407 } 408 #else /* _WIDE */ 409 ssize_t 410 _doprnt(const char *format, va_list in_args, FILE *iop) 411 { 412 return (_ndoprnt(format, in_args, iop, 0)); 413 } 414 #endif /* _WIDE */ 415 416 417 #ifdef _WIDE 418 ssize_t 419 _wndoprnt(const wchar_t *format, va_list in_args, FILE *iop, int prflag) 420 #else /* _WIDE */ 421 ssize_t 422 _ndoprnt(const char *format, va_list in_args, FILE *iop, int prflag) 423 #endif /* _WIDE */ 424 { 425 426 #ifdef _WIDE 427 int sflag = 0; 428 size_t maxcount; 429 mbstate_t *mbst; 430 void *lc; 431 int (*fp)(void *, char *, wchar_t); 432 #else 433 int snflag = 0; 434 #endif /* _WIDE */ 435 /* bufptr is used inside of doprnt instead of iop->_ptr; */ 436 /* bufferend is a copy of _bufend(iop), if it exists. For */ 437 /* dummy file descriptors (iop->_flag & _IOREAD), bufferend */ 438 /* may be meaningless. Dummy file descriptors are used so that */ 439 /* sprintf and vsprintf may share the _doprnt routine with the */ 440 /* rest of the printf family. */ 441 442 unsigned char *bufptr; 443 unsigned char *bufferend; 444 445 #ifdef _WIDE 446 /* This variable counts output characters. */ 447 size_t count = 0; 448 #else /* _WIDE */ 449 /* This variable counts output characters. */ 450 int count = 0; 451 #endif /* _WIDE */ 452 453 #ifdef _WIDE 454 wchar_t *bp; 455 size_t bpsize; 456 wchar_t *p; 457 char *cbp; 458 char *cp; 459 460 #else /* _WIDE */ 461 /* Starting and ending points for value to be printed */ 462 char *bp; 463 char *p; 464 #endif /* _WIDE */ 465 /* Field width and precision */ 466 int prec = 0; 467 ssize_t width; 468 ssize_t num; 469 ssize_t sec_display; 470 wchar_t *wp; 471 ssize_t preco; 472 ssize_t wcount = 0; 473 char tmpbuf[10]; 474 char wflag; 475 char lflag; 476 int quote; /* ' */ 477 int retcode; 478 479 480 #ifdef _WIDE 481 /* Format code */ 482 wchar_t fcode; 483 #else /* _WIDE */ 484 /* Format code */ 485 char fcode; 486 #endif /* _WIDE */ 487 488 /* Number of padding zeroes required on the left and right */ 489 ssize_t lzero, rzero, rz, leadzeroes; 490 491 492 /* Flags - bit positions defined by LENGTH, FPLUS, FMINUS, FBLANK, */ 493 /* and FSHARP are set if corresponding character is in format */ 494 /* Bit position defined by PADZERO means extra space in the field */ 495 /* should be padded with leading zeroes rather than with blanks */ 496 497 ssize_t flagword; 498 499 #ifdef _WIDE 500 /* Values are developed in this buffer */ 501 wchar_t buf[max(MAXLLDIGS, 1034)]; 502 wchar_t cvtbuf[512 + DECIMAL_STRING_LENGTH]; 503 504 /* Pointer to sign, "0x", "0X", or empty */ 505 wchar_t *prefix; 506 wchar_t prefixbuf[4]; 507 508 /* Exponent or empty */ 509 wchar_t *suffix; 510 511 /* Buffer to create exponent */ 512 wchar_t expbuf[MAXESIZ + 1]; 513 #else /* _WIDE */ 514 /* Values are developed in this buffer */ 515 char buf[max(MAXLLDIGS, 1034)]; 516 char cvtbuf[512 + DECIMAL_STRING_LENGTH]; 517 518 /* Pointer to sign, "0x", "0X", or empty */ 519 char *prefix; 520 char prefixbuf[4]; 521 522 /* Exponent or empty */ 523 char *suffix; 524 525 /* Buffer to create exponent */ 526 char expbuf[MAXESIZ + 1]; 527 #endif /* _WIDE */ 528 529 /* Length of prefix and of suffix */ 530 ssize_t prefixlength, suffixlength; 531 532 /* Combined length of leading zeroes, trailing zeroes, and suffix */ 533 ssize_t otherlength; 534 535 /* The value being converted, if integer */ 536 ssize_t val; 537 538 /* The value being converted, if long long */ 539 long long ll = 0LL; 540 541 /* Output value from aconvert */ 542 int exp; 543 544 /* Output values from fcvt and ecvt */ 545 int decpt, sign; 546 547 #ifdef _WIDE 548 /* Pointer to a translate table for digits of whatever radix */ 549 const wchar_t *tab; 550 #else /* _WIDE */ 551 /* Pointer to a translate table for digits of whatever radix */ 552 const char *tab; 553 #endif /* _WIDE */ 554 555 /* Work variables */ 556 ssize_t k, lradix, mradix; 557 558 int inf_nan = 0; 559 int inf_nan_mixed_case = 0; 560 561 #ifdef _WIDE 562 /* variables for positional parameters */ 563 /* save the beginning of the format */ 564 wchar_t *sformat = (wchar_t *)format; 565 #else /* _WIDE */ 566 /* variables for positional parameters */ 567 char *sformat = (char *)format; /* save the beginning of the format */ 568 #endif 569 570 int fpos = 1; /* 1 if first positional parameter */ 571 stva_list args, /* used to step through the argument list */ 572 sargs; /* used to save the start of the arg list */ 573 stva_list bargs; /* used to restore args if positional width */ 574 /* or precision */ 575 stva_list arglst[MAXARGS]; /* array giving appropriate values */ 576 /* for va_arg() to retrieve the */ 577 /* corresponding argument: */ 578 /* arglst[0] is the first arg */ 579 /* arglst[1] is the second arg, etc */ 580 581 int starflg = 0; /* set to 1 if * format specifier seen */ 582 /* 583 * Initialize args and sargs to the start of the argument list. 584 * We don't know any portable way to copy an arbitrary C object 585 * so we use a system-specific routine (probably a macro) from 586 * stdarg.h. (Remember that if va_list is an array, in_args will 587 * be a pointer and &in_args won't be what we would want for 588 * memcpy.) 589 */ 590 va_copy(args.ap, in_args); 591 sargs = args; 592 593 #ifdef _WIDE 594 if (iop->_flag == _IOREAD) 595 sflag = 1; 596 597 if (!sflag) { 598 mbst = _getmbstate(iop); 599 if (mbst == NULL) { 600 errno = EBADF; 601 return (EOF); 602 } 603 lc = __mbst_get_lc_and_fp((const mbstate_t *)mbst, 604 (void (*(*))(void))&fp, FP_WCTOMB); 605 #endif /* _WIDE */ 606 /* if first I/O to the stream get a buffer */ 607 /* Note that iop->_base should not equal 0 for sprintf and vsprintf */ 608 if (iop->_base == 0) { 609 if (_findbuf(iop) == 0) 610 return (EOF); 611 /* _findbuf leaves _cnt set to 0 which is the wrong thing to do */ 612 /* for fully buffered files */ 613 if (!(iop->_flag & (_IOLBF|_IONBF))) 614 iop->_cnt = _bufend(iop) - iop->_base; 615 } 616 #ifdef _WIDE 617 } 618 #endif /* _WIDE */ 619 620 #ifdef _WIDE 621 bufptr = iop->_ptr; 622 if (sflag) { 623 maxcount = (size_t)iop->_cnt; 624 bufferend = (unsigned char *)(((wchar_t *)iop->_ptr) + 625 maxcount); 626 } else { 627 bufferend = _bufend(iop); 628 } 629 #else /* _WIDE */ 630 /* initialize buffer pointer and buffer end pointer */ 631 bufptr = iop->_ptr; 632 if (iop->_flag & _IOREAD) { 633 /* 634 * [v]sprintf or [v]snprintf 635 */ 636 if (iop->_cnt == MAXINT) { 637 /* 638 * [v]sprintf (no boundschecking) 639 */ 640 bufferend = 641 (unsigned char *)((long)bufptr | (-1L & ~HIBITL)); 642 } else { 643 /* 644 * [v]snprintf (with boundschecking) or 645 * iop with _IORW has been read. 646 */ 647 bufferend = _bufend(iop); 648 if (bufferend == NULL) { 649 /* 650 * [v]snprintf 651 * 652 * [v]snprint() needs to be always handled by 653 * _dowrite(). 654 */ 655 snflag = 1; 656 } 657 } 658 } else { 659 /* 660 * [v]printf or [v]fprintf 661 */ 662 bufferend = _bufend(iop); 663 } 664 #endif /* _WIDE */ 665 666 /* 667 * The main loop -- this loop goes through one iteration 668 * for each string of ordinary characters or format specification. 669 */ 670 for (; ; ) { 671 ssize_t n; 672 673 if ((fcode = *format) != '\0' && fcode != '%') { 674 #ifdef _WIDE 675 bp = (wchar_t *)format; 676 #else /* _WIDE */ 677 bp = (char *)format; 678 #endif /* _WIDE */ 679 do { 680 format++; 681 } while ((fcode = *format) != '\0' && fcode != '%'); 682 683 count += (n = format - bp); /* n = no. of non-% chars */ 684 PUT(bp, n); 685 } 686 if (fcode == '\0') { /* end of format; return */ 687 ssize_t nn = bufptr - iop->_ptr; 688 689 #ifdef _WIDE 690 if (sflag) { 691 iop->_ptr = bufptr; 692 return ((ssize_t)count); 693 } 694 #endif /* _WIDE */ 695 696 iop->_cnt -= nn; 697 iop->_ptr = bufptr; 698 /* in case of interrupt during last several lines */ 699 if ((bufptr + iop->_cnt) > bufferend && !(iop->_flag \ 700 & _IOREAD)) 701 _bufsync(iop, bufferend); 702 if (iop->_flag & (_IONBF | _IOLBF) && \ 703 (iop->_flag & _IONBF || \ 704 memchr((char *)(bufptr+iop->_cnt), \ 705 '\n', -iop->_cnt) != NULL)) 706 (void) _xflsbuf(iop); 707 #ifdef _WIDE 708 return (FERROR(iop) ? EOF : (ssize_t)count); 709 #else /* _WIDE */ 710 return (FERROR(iop) ? EOF : (int)count); 711 #endif /* _WIDE */ 712 } 713 714 /* 715 * % has been found. 716 * The following switch is used to parse the format 717 * specification and to perform the operation specified 718 * by the format letter. The program repeatedly goes 719 * back to this switch until the format letter is 720 * encountered. 721 */ 722 width = prefixlength = otherlength = 0; 723 flagword = suffixlength = 0; 724 format++; 725 wflag = 0; 726 lflag = 0; 727 sec_display = 0; 728 quote = 0; 729 730 charswitch: 731 732 switch (fcode = *format++) { 733 734 case '+': 735 flagword |= FPLUS; 736 goto charswitch; 737 case '-': 738 flagword |= FMINUS; 739 flagword &= ~PADZERO; /* ignore 0 flag */ 740 goto charswitch; 741 case ' ': 742 flagword |= FBLANK; 743 goto charswitch; 744 case '\'': /* XSH4 */ 745 quote++; 746 goto charswitch; 747 case '#': 748 flagword |= FSHARP; 749 goto charswitch; 750 751 /* Scan the field width and precision */ 752 case '.': 753 flagword |= DOTSEEN; 754 prec = 0; 755 goto charswitch; 756 757 case '*': 758 if (_M_ISDIGIT(*format)) { 759 starflg = 1; 760 bargs = args; 761 goto charswitch; 762 } 763 if (!(flagword & DOTSEEN)) { 764 width = va_arg(args.ap, int); 765 if (width < 0) { 766 width = -width; 767 flagword |= FMINUS; 768 } 769 } else { 770 prec = va_arg(args.ap, int); 771 if (prec < 0) { 772 prec = 0; 773 flagword ^= DOTSEEN; /* ANSI sez so */ 774 } 775 } 776 goto charswitch; 777 778 case '$': 779 { 780 ssize_t position; 781 stva_list targs; 782 if (fpos) { 783 #ifdef _WIDE 784 _wmkarglst(sformat, sargs, arglst, prflag); 785 #else /* _WIDE */ 786 _mkarglst(sformat, sargs, arglst, prflag); 787 #endif /* _WIDE */ 788 fpos = 0; 789 } 790 if (flagword & DOTSEEN) { 791 position = prec; 792 prec = 0; 793 } else { 794 position = width; 795 width = 0; 796 } 797 if (position <= 0) { 798 /* illegal position */ 799 format--; 800 continue; 801 } 802 if (position <= MAXARGS) { 803 targs = arglst[position - 1]; 804 } else { 805 targs = arglst[MAXARGS - 1]; 806 #ifdef _WIDE 807 _wgetarg(sformat, &targs, position, prflag); 808 #else /* _WIDE */ 809 _getarg(sformat, &targs, position, prflag); 810 #endif /* _WIDE */ 811 } 812 if (!starflg) 813 args = targs; 814 else { 815 starflg = 0; 816 args = bargs; 817 if (flagword & DOTSEEN) { 818 prec = va_arg(targs.ap, int); 819 if (prec < 0) { 820 prec = 0; 821 flagword ^= DOTSEEN; /* XSH */ 822 } 823 } else { 824 width = va_arg(targs.ap, int); 825 if (width < 0) { 826 width = -width; 827 flagword |= FMINUS; 828 } 829 } 830 } 831 goto charswitch; 832 } 833 834 case '0': /* obsolescent spec: leading zero in width */ 835 /* means pad with leading zeros */ 836 if (!(flagword & (DOTSEEN | FMINUS))) 837 flagword |= PADZERO; 838 /* FALLTHROUGH */ 839 case '1': 840 case '2': 841 case '3': 842 case '4': 843 case '5': 844 case '6': 845 case '7': 846 case '8': 847 case '9': 848 { num = fcode - '0'; 849 while (_M_ISDIGIT(fcode = *format)) { 850 num = num * 10 + fcode - '0'; 851 format++; 852 } 853 if (flagword & DOTSEEN) 854 prec = num; 855 else 856 width = num; 857 goto charswitch; 858 } 859 860 /* Scan the length modifier */ 861 case 'l': 862 if (!(flagword & XLONG)) { 863 if (lflag) { 864 /* long long */ 865 flagword &= ~LENGTH; 866 flagword |= XLONG; 867 } else { 868 /* long */ 869 flagword |= LENGTH; 870 } 871 } 872 lflag++; 873 goto charswitch; 874 875 case 'L': /* long double */ 876 flagword |= QUAD; 877 goto charswitch; 878 879 case 'h': 880 if (!(flagword & CHAR)) { 881 if (flagword & SHORT) { 882 /* char - hh */ 883 flagword &= ~SHORT; 884 flagword |= CHAR; 885 } else { 886 /* short */ 887 flagword |= SHORT; 888 } 889 } 890 goto charswitch; 891 case 'j': 892 #ifndef _LP64 893 /* 894 * *printf_c89() in 32-bit libc uses 895 * 32-bit intmax_t; otherwise intmax_t 896 * is 64-bits. 897 */ 898 if (!(prflag & _F_INTMAX32)) { 899 #endif 900 flagword |= XLONG; /* [u]intmax_t (64) */ 901 #ifndef _LP64 902 } 903 #endif 904 goto charswitch; 905 906 case 't': 907 /* 908 * LENGTH is shared by l, t, z specifiers; protect 909 * against (destructive) undefined behavior (eg: 910 * avoid %llt setting XLONG and LENGTH) with invalid 911 * combinations of specifiers 912 */ 913 if (!(flagword & XLONG)) { 914 flagword |= LENGTH; /* ptrdiff_t */ 915 } 916 goto charswitch; 917 918 case 'z': 919 if (!(flagword & XLONG)) { 920 flagword |= LENGTH; /* [s]size_t */ 921 } 922 goto charswitch; 923 924 /* 925 * The character addressed by format must be 926 * the format letter -- there is nothing 927 * left for it to be. 928 * 929 * The status of the +, -, #, and blank 930 * flags are reflected in the variable 931 * "flagword". "width" and "prec" contain 932 * numbers corresponding to the digit 933 * strings before and after the decimal 934 * point, respectively. If there was no 935 * decimal point, then flagword & DOTSEEN 936 * is false and the value of prec is meaningless. 937 * 938 * The following switch cases set things up 939 * for printing. What ultimately gets 940 * printed will be padding blanks, a 941 * prefix, left padding zeroes, a value, 942 * right padding zeroes, a suffix, and 943 * more padding blanks. Padding blanks 944 * will not appear simultaneously on both 945 * the left and the right. Each case in 946 * this switch will compute the value, and 947 * leave in several variables the informa- 948 * tion necessary to construct what is to 949 * be printed. 950 * 951 * The prefix is a sign, a blank, "0x", 952 * "0X", a sign or a blank followed by "0x" 953 * or "0X", or nothing, and is addressed by 954 * "prefix". 955 * 956 * The suffix is either null or an 957 * exponent, and is addressed by "suffix". 958 * If there is a suffix, the flagword bit 959 * SUFFIX will be set. 960 * 961 * The value to be printed starts at "bp" 962 * and continues up to and not including 963 * "p". 964 * 965 * "lzero" and "rzero" will contain the 966 * number of padding zeroes required on 967 * the left and right, respectively. 968 * The flagword bits LZERO and RZERO tell 969 * whether padding zeros are required. 970 * 971 * The number of padding blanks, and 972 * whether they go on the left or the 973 * right, will be computed on exit from 974 * the switch. 975 */ 976 977 978 979 /* 980 * decimal fixed point representations 981 * 982 * HIBITL is 100...000 983 * binary, and is equal to the maximum 984 * negative number. 985 * We assume a 2's complement machine 986 */ 987 case 'i': 988 case 'd': 989 if ((flagword & PADZERO) && (flagword & DOTSEEN)) 990 flagword &= ~PADZERO; /* ignore 0 flag */ 991 /* Set buffer pointer to last digit */ 992 p = bp = buf + MAXLLDIGS; 993 994 /* Fetch the argument to be printed */ 995 if (flagword & XLONG) { /* long long */ 996 ll = va_arg(args.ap, long long); 997 998 /* If signed conversion, make sign */ 999 if (ll < 0) { 1000 prefix = _P_HYPHEN; 1001 prefixlength = 1; 1002 /* 1003 * Negate, checking in advance for 1004 * possible overflow. 1005 */ 1006 if (ll != HIBITLL) 1007 ll = -ll; 1008 else 1009 /* number is -HIBITLL; convert last */ 1010 /* digit now and get positive number */ 1011 *--bp = _lowlldigit(&ll); 1012 } else if (flagword & FPLUS) { 1013 prefix = _P_PLUS; 1014 prefixlength = 1; 1015 } else if (flagword & FBLANK) { 1016 prefix = _P_BLANK; 1017 prefixlength = 1; 1018 } 1019 } else { /* not long long */ 1020 if (flagword & LENGTH) 1021 val = va_arg(args.ap, long); 1022 else 1023 val = va_arg(args.ap, int); 1024 1025 if (flagword & SHORT) 1026 val = (short)val; 1027 else if (flagword & CHAR) 1028 val = (char)val; 1029 1030 /* If signed conversion, make sign */ 1031 if (val < 0) { 1032 prefix = _P_HYPHEN; 1033 prefixlength = 1; 1034 /* 1035 * Negate, checking in advance 1036 * for possible overflow. 1037 */ 1038 if (val != HIBITL) 1039 val = -val; 1040 /* 1041 * number is -HIBITL; convert 1042 * last digit now and get 1043 * positive number 1044 */ 1045 else 1046 *--bp = _lowdigit(&val); 1047 } else if (flagword & FPLUS) { 1048 prefix = _P_PLUS; 1049 prefixlength = 1; 1050 } else if (flagword & FBLANK) { 1051 prefix = _P_BLANK; 1052 prefixlength = 1; 1053 } 1054 } 1055 1056 decimal: 1057 { 1058 long qval = val; 1059 long long lll = ll; 1060 long long tll; 1061 if (flagword & XLONG) { 1062 if (lll < 10LL) { 1063 #ifdef _WIDE 1064 if (lll != 0LL || !(flagword & DOTSEEN)) 1065 *--bp = (wchar_t)lll + L'0'; 1066 #else /* _WIDE */ 1067 if (lll != 0LL || !(flagword & DOTSEEN)) 1068 *--bp = (char)lll + '0'; 1069 #endif /* _WIDE */ 1070 } else { 1071 do { 1072 tll = lll; 1073 lll /= 10; 1074 #ifdef _WIDE 1075 *--bp = (wchar_t) 1076 (tll - lll * 10 + '0'); 1077 #else /* _WIDE */ 1078 *--bp = (char) \ 1079 (tll - lll * 10 + '0'); 1080 #endif /* _WIDE */ 1081 } while (lll >= 10); 1082 #ifdef _WIDE 1083 *--bp = (wchar_t)lll + '0'; 1084 #else /* _WIDE */ 1085 *--bp = (char)lll + '0'; 1086 #endif /* _WIDE */ 1087 } 1088 } else { 1089 if (qval <= 9) { 1090 #ifdef _WIDE 1091 if (qval != 0 || !(flagword & DOTSEEN)) 1092 *--bp = (wchar_t)qval + '0'; 1093 #else /* _WIDE */ 1094 if (qval != 0 || !(flagword & DOTSEEN)) 1095 *--bp = (char)qval + '0'; 1096 #endif /* _WIDE */ 1097 } else { 1098 do { 1099 n = qval; 1100 qval /= 10; 1101 #ifdef _WIDE 1102 *--bp = (wchar_t) \ 1103 (n - qval * 10 + '0'); 1104 #else /* _WIDE */ 1105 *--bp = (char) \ 1106 (n - qval * 10 + '0'); 1107 #endif /* _WIDE */ 1108 } while (qval > 9); 1109 #ifdef _WIDE 1110 *--bp = (wchar_t)qval + '0'; 1111 #else /* _WIDE */ 1112 *--bp = (char)qval + '0'; 1113 #endif /* _WIDE */ 1114 } 1115 } 1116 } 1117 /* Handle the ' flag */ 1118 if (quote) { 1119 p = insert_thousands_sep(bp, p); 1120 } 1121 1122 /* Calculate minimum padding zero requirement */ 1123 if (flagword & DOTSEEN) { 1124 leadzeroes = prec - (p - bp); 1125 if (leadzeroes > 0) { 1126 otherlength = lzero = leadzeroes; 1127 flagword |= LZERO; 1128 } 1129 } 1130 break; 1131 1132 case 'u': 1133 if ((flagword & PADZERO) && (flagword & DOTSEEN)) 1134 flagword &= ~PADZERO; /* ignore 0 flag */ 1135 p = bp = buf + MAXLLDIGS; 1136 1137 /* Fetch the argument to be printed */ 1138 if (flagword & XLONG) { 1139 ll = va_arg(args.ap, long long); 1140 1141 if (ll & HIBITLL) 1142 *--bp = _lowlldigit(&ll); 1143 } else { 1144 if (flagword & LENGTH) 1145 val = va_arg(args.ap, long); 1146 else 1147 val = va_arg(args.ap, unsigned); 1148 1149 if (flagword & SHORT) 1150 val = (unsigned short)val; 1151 else if (flagword & CHAR) 1152 val = (unsigned char)val; 1153 1154 if (val & HIBITL) 1155 *--bp = _lowdigit(&val); 1156 } 1157 1158 goto decimal; 1159 1160 /* 1161 * non-decimal fixed point representations 1162 * for radix equal to a power of two 1163 * 1164 * "mradix" is one less than the radix for the conversion. 1165 * "lradix" is one less than the base 2 log 1166 * of the radix for the conversion. Conversion is unsigned. 1167 * HIBITL is 100...000 1168 * binary, and is equal to the maximum 1169 * negative number. 1170 * We assume a 2's complement machine 1171 */ 1172 1173 case 'o': 1174 mradix = 7; 1175 lradix = 2; 1176 /* 1177 * DR151 and clarification in C90 1178 * presence of '#' increases precision to first 1179 * digit of the result to be zero 1180 */ 1181 if ((flagword & DOTSEEN) && (flagword & FSHARP) && 1182 prec == 0) 1183 prec = 1; 1184 1185 goto fixed; 1186 1187 case 'p': 1188 flagword &= ~(XLONG | SHORT); 1189 flagword |= LENGTH; 1190 1191 /* FALLTHRU */ 1192 case 'X': 1193 case 'x': 1194 mradix = 15; 1195 lradix = 3; 1196 1197 fixed: 1198 if ((flagword & PADZERO) && (flagword & DOTSEEN)) 1199 flagword &= ~PADZERO; /* ignore 0 flag */ 1200 1201 #ifdef _WIDE 1202 /* Set translate table for digits */ 1203 tab = (wchar_t *)((fcode == 'X') ? uc_digs : lc_digs); 1204 #else /* _WIDE */ 1205 /* Set translate table for digits */ 1206 tab = (fcode == 'X') ? uc_digs : lc_digs; 1207 #endif /* _WIDE */ 1208 1209 /* Fetch the argument to be printed */ 1210 if (flagword & XLONG) { 1211 ll = va_arg(args.ap, long long); 1212 } else { 1213 if (flagword & LENGTH) 1214 val = va_arg(args.ap, long); 1215 else 1216 val = va_arg(args.ap, unsigned); 1217 1218 if (flagword & SHORT) 1219 val = (unsigned short) val; 1220 else if (flagword & CHAR) 1221 val = (unsigned char) val; 1222 } 1223 p = bp = buf + MAXLLDIGS; 1224 1225 /* Develop the digits of the value */ 1226 if (flagword & XLONG) { 1227 long long lll = ll; 1228 1229 if (lll == 0LL) { 1230 if (!(flagword & DOTSEEN)) { 1231 otherlength = lzero = 1; 1232 flagword |= LZERO; 1233 } 1234 } else do { 1235 *--bp = tab[(ssize_t)(lll & mradix)]; 1236 lll = ((lll >> 1) & ~HIBITLL) \ 1237 >> lradix; 1238 } while (lll != 0LL); 1239 } else { 1240 long qval = val; 1241 1242 if (qval == 0) { 1243 if (!(flagword & DOTSEEN)) { 1244 otherlength = lzero = 1; 1245 flagword |= LZERO; 1246 } 1247 } else do { 1248 *--bp = tab[qval & mradix]; 1249 qval = ((qval >> 1) & ~HIBITL) \ 1250 >> lradix; 1251 } while (qval != 0); 1252 } 1253 1254 /* Calculate minimum padding zero requirement */ 1255 if (flagword & DOTSEEN) { 1256 leadzeroes = prec - (p - bp); 1257 if (leadzeroes > 0) { 1258 otherlength = lzero = leadzeroes; 1259 flagword |= LZERO; 1260 } 1261 } 1262 1263 /* Handle the # flag, (val != 0) for int and long */ 1264 /* (ll!= 0) handles long long case */ 1265 if ((flagword & FSHARP) && 1266 (((flagword & XLONG) == 0 && val != 0) || 1267 ((flagword & XLONG) == XLONG && ll != 0))) 1268 switch (fcode) { 1269 case 'o': 1270 if (!(flagword & LZERO)) { 1271 otherlength = lzero = 1; 1272 flagword |= LZERO; 1273 } 1274 break; 1275 case 'x': 1276 prefix = _P_ZEROx; 1277 prefixlength = 2; 1278 break; 1279 case 'X': 1280 prefix = _P_ZEROX; 1281 prefixlength = 2; 1282 break; 1283 } 1284 1285 break; 1286 1287 case 'A': 1288 case 'a': 1289 /* A format */ 1290 if (flagword & QUAD) { 1291 long double qval = GETQVAL(args.ap); 1292 1293 /* establish default precision */ 1294 if (!(flagword & DOTSEEN)) 1295 #if defined(__sparc) 1296 prec = HEXFP_QUAD_DIG - 1; 1297 #elif defined(__i386) || defined(__amd64) 1298 prec = HEXFP_EXTENDED_DIG - 1; 1299 #else 1300 #error Unknown architecture 1301 #endif 1302 1303 FPCONV(__qaconvert, &qval, 1304 min(prec + 1, MAXECVT), &exp, &sign, 1305 cvtbuf); 1306 } else { 1307 double dval = va_arg(args.ap, double); 1308 1309 /* establish default precision */ 1310 if (!(flagword & DOTSEEN)) 1311 prec = HEXFP_DOUBLE_DIG - 1; 1312 1313 FPCONV(__aconvert, dval, 1314 min(prec + 1, MAXECVT), &exp, &sign, 1315 cvtbuf); 1316 } 1317 bp = cvtbuf; 1318 1319 /* 1320 * The following is wide-character safe because 1321 * __aconvert and __qaconvert only produce ASCII 1322 * characters. 1323 */ 1324 if (!isxdigit((unsigned char)*bp)) { 1325 inf_nan = 1; 1326 break; 1327 } 1328 1329 /* 1330 * Create the prefix. We ought to use the strings 1331 * defined above (_P_HYPHEN, etc.), but that would 1332 * be awkward: we'd either have to define six more 1333 * of them or we'd have to use strcpy/strcat to 1334 * assemble the ones already defined. So instead, 1335 * we just build the prefix character by character. 1336 */ 1337 p = prefix = prefixbuf; 1338 if (sign) { 1339 *p++ = '-'; 1340 prefixlength = 1; 1341 } else if (flagword & FPLUS) { 1342 *p++ = '+'; 1343 prefixlength = 1; 1344 } else if (flagword & FBLANK) { 1345 *p++ = ' '; 1346 prefixlength = 1; 1347 } 1348 *p++ = '0'; 1349 *p++ = (fcode == 'A') ? 'X' : 'x'; 1350 *p = '\0'; 1351 prefixlength += 2; 1352 1353 /* put the first digit in the buffer */ 1354 p = &buf[0]; 1355 *p++ = (*bp != '\0') ? *bp++ : '0'; 1356 1357 /* put in a decimal point if needed */ 1358 if (prec != 0 || (flagword & FSHARP)) 1359 *p++ = _numeric[0]; 1360 1361 /* create the rest of the mantissa */ 1362 rz = prec; 1363 if (fcode == 'A') { 1364 for (; rz > 0 && *bp != '\0'; --rz) { 1365 *p++ = ('a' <= *bp && *bp <= 'f')? 1366 *bp - 32 : *bp; 1367 bp++; 1368 } 1369 } else { 1370 for (; rz > 0 && *bp != '\0'; --rz) 1371 *p++ = *bp++; 1372 } 1373 if (rz > 0) { 1374 otherlength = rzero = rz; 1375 flagword |= RZERO; 1376 } 1377 1378 bp = &buf[0]; 1379 1380 /* 1381 * Create the exponent in right-to-left order. 1382 * buf[0] == '0' if and only if the value being 1383 * converted is exactly zero, in which case the 1384 * exponent should be +0 regardless of exp. 1385 */ 1386 suffix = &expbuf[MAXESIZ]; 1387 *suffix = '\0'; 1388 if (buf[0] != '0') { 1389 int nn; 1390 1391 nn = exp; 1392 if (nn < 0) 1393 nn = -nn; 1394 for (; nn > 9; nn /= 10) 1395 *--suffix = todigit(nn % 10); 1396 *--suffix = todigit(nn); 1397 *--suffix = (exp >= 0) ? '+' : '-'; 1398 } else { 1399 *--suffix = '0'; 1400 *--suffix = '+'; 1401 } 1402 1403 /* put in the p */ 1404 *--suffix = (fcode == 'A') ? 'P' : 'p'; 1405 1406 /* compute size of suffix */ 1407 suffixlength = &expbuf[MAXESIZ] - suffix; 1408 otherlength += suffixlength; 1409 flagword |= SUFFIX; 1410 break; 1411 1412 case 'E': 1413 case 'e': 1414 /* 1415 * E-format. The general strategy 1416 * here is fairly easy: we take what 1417 * econvert gives us and re-format it. 1418 * (qeconvert for long double) 1419 */ 1420 1421 /* Establish default precision */ 1422 if (!(flagword & DOTSEEN)) 1423 prec = 6; 1424 1425 if (flagword & QUAD) { /* long double */ 1426 long double qval = GETQVAL(args.ap); 1427 1428 FPCONV(qeconvert, &qval, 1429 min(prec + 1, MAXECVT), &decpt, &sign, 1430 cvtbuf); 1431 } else { /* double */ 1432 double dval = va_arg(args.ap, double); 1433 1434 FPCONV(econvert, dval, 1435 min(prec + 1, MAXECVT), &decpt, &sign, 1436 cvtbuf); 1437 } 1438 bp = cvtbuf; 1439 if (*bp > '9') { 1440 inf_nan = 1; 1441 inf_nan_mixed_case = (__xpg6 & 1442 _C99SUSv3_mixed_case_Inf_and_NaN); 1443 break; 1444 } 1445 1446 /* Determine the prefix */ 1447 e_merge: 1448 if (sign) { 1449 prefix = _P_HYPHEN; 1450 prefixlength = 1; 1451 } else if (flagword & FPLUS) { 1452 prefix = _P_PLUS; 1453 prefixlength = 1; 1454 } else if (flagword & FBLANK) { 1455 prefix = _P_BLANK; 1456 prefixlength = 1; 1457 } 1458 1459 /* Place the first digit in the buffer */ 1460 p = &buf[0]; 1461 *p++ = (*bp != '\0') ? *bp++ : '0'; 1462 1463 /* Put in a decimal point if needed */ 1464 if (prec != 0 || (flagword & FSHARP)) 1465 *p++ = _numeric[0]; 1466 1467 /* Create the rest of the mantissa */ 1468 rz = prec; 1469 for (; rz > 0 && *bp != '\0'; --rz) 1470 *p++ = *bp++; 1471 if (rz > 0) { 1472 otherlength = rzero = rz; 1473 flagword |= RZERO; 1474 } 1475 1476 bp = &buf[0]; 1477 1478 /* 1479 * Create the exponent. buf[0] == '0' if and 1480 * only if the value being converted is exactly 1481 * zero, in which case the exponent should be 1482 * +0 regardless of decpt. 1483 */ 1484 *(suffix = &expbuf[MAXESIZ]) = '\0'; 1485 if (buf[0] != '0') { 1486 int nn = decpt - 1; 1487 if (nn < 0) 1488 nn = -nn; 1489 for (; nn > 9; nn /= 10) 1490 *--suffix = todigit(nn % 10); 1491 *--suffix = todigit(nn); 1492 } 1493 1494 /* Prepend leading zeroes to the exponent */ 1495 while (suffix > &expbuf[MAXESIZ - 2]) 1496 *--suffix = '0'; 1497 1498 /* Put in the exponent sign */ 1499 *--suffix = (decpt > 0 || buf[0] == '0') ? '+' : '-'; 1500 1501 /* Put in the e */ 1502 *--suffix = _M_ISUPPER(fcode) ? 'E' : 'e'; 1503 1504 /* compute size of suffix */ 1505 otherlength += (suffixlength = &expbuf[MAXESIZ] \ 1506 - suffix); 1507 flagword |= SUFFIX; 1508 break; 1509 1510 case 'F': 1511 case 'f': 1512 /* 1513 * F-format floating point. This is a 1514 * good deal less simple than E-format. 1515 * The overall strategy will be to call 1516 * fconvert, reformat its result into buf, 1517 * and calculate how many trailing 1518 * zeroes will be required. There will 1519 * never be any leading zeroes needed. 1520 * (qfconvert for long double) 1521 */ 1522 1523 /* Establish default precision */ 1524 if (!(flagword & DOTSEEN)) 1525 prec = 6; 1526 1527 if (flagword & QUAD) { /* long double */ 1528 long double qval = GETQVAL(args.ap); 1529 1530 FPCONV(qfconvert, &qval, min(prec, MAXFCVT), 1531 &decpt, &sign, cvtbuf); 1532 bp = cvtbuf; 1533 if (*bp == 0) { 1534 /* 1535 * qfconvert would have required 1536 * too many characters; use qeconvert 1537 * instead 1538 */ 1539 FPCONV(qeconvert, &qval, 1540 min(prec + 1, MAXECVT), &decpt, 1541 &sign, cvtbuf); 1542 goto e_merge; 1543 } 1544 } else { /* double */ 1545 double dval = va_arg(args.ap, double); 1546 1547 FPCONV(fconvert, dval, min(prec, MAXFCVT), 1548 &decpt, &sign, cvtbuf); 1549 } 1550 bp = cvtbuf; 1551 if (*bp > '9') { 1552 inf_nan = 1; 1553 if (fcode == 'f') 1554 inf_nan_mixed_case = (__xpg6 & 1555 _C99SUSv3_mixed_case_Inf_and_NaN); 1556 break; 1557 } 1558 1559 /* Determine the prefix */ 1560 f_merge: 1561 if (sign) { 1562 prefix = _P_HYPHEN; 1563 prefixlength = 1; 1564 } else if (flagword & FPLUS) { 1565 prefix = _P_PLUS; 1566 prefixlength = 1; 1567 } else if (flagword & FBLANK) { 1568 prefix = _P_BLANK; 1569 prefixlength = 1; 1570 } 1571 1572 /* Initialize buffer pointer */ 1573 p = &buf[0]; 1574 1575 { 1576 ssize_t nn = decpt; 1577 1578 /* Emit the digits before the decimal point */ 1579 k = 0; 1580 do { 1581 *p++ = (nn <= 0 || *bp == '\0' || \ 1582 k >= MAXFSIG) ? '0' : (k++, *bp++); 1583 } while (--nn > 0); 1584 1585 if (quote) 1586 p = insert_thousands_sep(buf, p); 1587 1588 /* Decide whether we need a decimal point */ 1589 if ((flagword & FSHARP) || prec > 0) 1590 *p++ = _numeric[0]; 1591 1592 /* Digits (if any) after the decimal point */ 1593 nn = min(prec, MAXFCVT); 1594 if (prec > nn) { 1595 flagword |= RZERO; 1596 otherlength = rzero = prec - nn; 1597 } 1598 while (--nn >= 0) 1599 *p++ = (++decpt <= 0 || *bp == '\0' || \ 1600 k >= MAXFSIG) ? '0' : (k++, *bp++); 1601 } 1602 1603 bp = &buf[0]; 1604 1605 break; 1606 1607 case 'G': 1608 case 'g': 1609 /* 1610 * g-format. We play around a bit 1611 * and then jump into e or f, as needed. 1612 */ 1613 1614 /* Establish default precision */ 1615 if (!(flagword & DOTSEEN)) 1616 prec = 6; 1617 else if (prec == 0) 1618 prec = 1; 1619 1620 if (flagword & QUAD) { /* long double */ 1621 long double qval = GETQVAL(args.ap); 1622 1623 FPCONV(qeconvert, &qval, min(prec, MAXECVT), 1624 &decpt, &sign, cvtbuf); 1625 } else { /* double */ 1626 double dval = va_arg(args.ap, double); 1627 1628 FPCONV(econvert, dval, min(prec, MAXECVT), 1629 &decpt, &sign, cvtbuf); 1630 } 1631 bp = cvtbuf; 1632 if (*bp > '9') { 1633 inf_nan = 1; 1634 inf_nan_mixed_case = (__xpg6 & 1635 _C99SUSv3_mixed_case_Inf_and_NaN); 1636 break; 1637 } 1638 if (*bp == '0') /* the value converted is zero */ 1639 decpt = 1; 1640 1641 { 1642 int kk = prec; 1643 if (!(flagword & FSHARP)) { 1644 #ifdef _WIDE 1645 n = wcslen(bp); 1646 #else /* _WIDE */ 1647 n = strlen(bp); 1648 #endif /* _WIDE */ 1649 if (n < kk) 1650 kk = (int)n; 1651 while (kk >= 1 && bp[kk-1] == '0') 1652 --kk; 1653 } 1654 if (decpt < -3 || decpt > prec) { 1655 prec = kk - 1; 1656 goto e_merge; 1657 } 1658 prec = kk - decpt; 1659 goto f_merge; 1660 } 1661 1662 case '%': 1663 buf[0] = fcode; 1664 goto c_merge; 1665 1666 #ifndef _WIDE 1667 case 'w': 1668 wflag = 1; 1669 goto charswitch; 1670 #endif /* _WIDE */ 1671 1672 1673 case 'C': /* XPG XSH4 extention */ 1674 wide_C: 1675 { 1676 wchar_t temp; 1677 1678 temp = va_arg(args.ap, wchar_t); 1679 #ifdef _WIDE 1680 if (temp) { 1681 buf[0] = temp; 1682 p = (bp = buf) + 1; 1683 } else { 1684 buf[0] = 0; 1685 p = (bp = buf) + 1; 1686 } 1687 wcount = 1; 1688 wflag = 1; 1689 #else /* _WIDE */ 1690 if (temp) { 1691 if ((retcode = wctomb(buf, temp)) 1692 == -1) { 1693 errno = EILSEQ; 1694 return (EOF); 1695 } else { 1696 p = (bp = buf) + retcode; 1697 } 1698 } else { /* NULL character */ 1699 buf[0] = 0; 1700 p = (bp = buf) + 1; 1701 } 1702 wcount = p - bp; 1703 #endif /* _WIDE */ 1704 } 1705 break; 1706 case 'c': 1707 if (lflag) { 1708 goto wide_C; 1709 } 1710 #ifndef _WIDE 1711 if (wflag) { 1712 wchar_t temp; 1713 1714 temp = va_arg(args.ap, wchar_t); 1715 if (temp) { 1716 if ((retcode = wctomb(buf, temp)) 1717 == -1) { 1718 p = (bp = buf) + 1; 1719 } else { 1720 p = (bp = buf) + retcode; 1721 } 1722 } else { /* NULL character */ 1723 buf[0] = 0; 1724 p = (bp = buf) + 1; 1725 } 1726 wcount = p - bp; 1727 } else { 1728 #endif /* _WIDE */ 1729 if (flagword & XLONG) { 1730 long long temp; 1731 temp = va_arg(args.ap, long long); 1732 #ifdef _WIDE 1733 buf[0] = (wchar_t)temp; 1734 #else /* _WIDE */ 1735 buf[0] = (char)temp; 1736 #endif /* _WIDE */ 1737 } else 1738 buf[0] = va_arg(args.ap, int); 1739 c_merge: 1740 p = (bp = &buf[0]) + 1; 1741 #ifdef _WIDE 1742 wcount = 1; 1743 wflag = 1; 1744 #endif /* _WIDE */ 1745 #ifndef _WIDE 1746 } 1747 #endif /* _WIDE */ 1748 break; 1749 1750 case 'S': /* XPG XSH4 extention */ 1751 wide_S: 1752 #ifdef _WIDE 1753 if (!lflag) { 1754 lflag++; 1755 } 1756 bp = va_arg(args.ap, wchar_t *); 1757 if (!(flagword & DOTSEEN)) { 1758 /* wide character handling */ 1759 prec = MAXINT; 1760 } 1761 1762 wp = bp; 1763 wcount = 0; 1764 while (*wp) { 1765 if ((prec - wcount - 1) >= 0) { 1766 wcount++; 1767 wp++; 1768 } else { 1769 break; 1770 } 1771 } 1772 p = wp; 1773 wflag = 1; 1774 break; 1775 #else /* _WIDE */ 1776 if (!wflag) 1777 wflag++; 1778 bp = va_arg(args.ap, char *); 1779 if (!(flagword & DOTSEEN)) { 1780 /* wide character handling */ 1781 prec = MAXINT; 1782 } 1783 1784 wp = (wchar_t *)(uintptr_t)bp; 1785 wcount = 0; 1786 while (*wp) { 1787 int nbytes; 1788 1789 nbytes = wctomb(tmpbuf, *wp); 1790 if (nbytes < 0) { 1791 errno = EILSEQ; 1792 return (EOF); 1793 } 1794 if ((prec - (wcount + nbytes)) >= 0) { 1795 wcount += nbytes; 1796 wp++; 1797 } else { 1798 break; 1799 } 1800 } 1801 sec_display = wcount; 1802 p = (char *)wp; 1803 break; 1804 #endif /* _WIDE */ 1805 case 's': 1806 if (lflag) { 1807 goto wide_S; 1808 } 1809 #ifdef _WIDE 1810 cbp = va_arg(args.ap, char *); 1811 if (!(flagword & DOTSEEN)) { 1812 size_t nwc; 1813 wchar_t *wstr; 1814 1815 nwc = mbstowcs(NULL, cbp, 0); 1816 if (nwc == (size_t)-1) { 1817 errno = EILSEQ; 1818 return (EOF); 1819 } 1820 bpsize = sizeof (wchar_t) * (nwc + 1); 1821 wstr = (wchar_t *)lmalloc(bpsize); 1822 if (wstr == NULL) { 1823 errno = EILSEQ; 1824 return (EOF); 1825 } 1826 nwc = mbstowcs(wstr, cbp, MAXINT); 1827 wcount = nwc; 1828 bp = wstr; 1829 p = wstr + nwc; 1830 } else { 1831 size_t nwc; 1832 wchar_t *wstr; 1833 1834 nwc = mbstowcs(NULL, cbp, 0); 1835 if (nwc == (size_t)-1) { 1836 errno = EILSEQ; 1837 return (EOF); 1838 } 1839 if (prec > nwc) { 1840 bpsize = sizeof (wchar_t) * nwc; 1841 wstr = (wchar_t *)lmalloc(bpsize); 1842 if (wstr == NULL) { 1843 errno = ENOMEM; 1844 return (EOF); 1845 } 1846 nwc = mbstowcs(wstr, cbp, nwc); 1847 cp = cbp + strlen(cbp); 1848 wcount = nwc; 1849 bp = wstr; 1850 p = wstr + nwc; 1851 } else { 1852 size_t nnwc; 1853 int len; 1854 char *s; 1855 wchar_t *wstr; 1856 1857 bpsize = sizeof (wchar_t) * prec; 1858 wstr = (wchar_t *)lmalloc(bpsize); 1859 if (wstr == NULL) { 1860 errno = ENOMEM; 1861 return (EOF); 1862 } 1863 nwc = mbstowcs(wstr, cbp, prec); 1864 wcount = prec; 1865 bp = wstr; 1866 p = wstr + nwc; 1867 } 1868 } 1869 wflag = 1; 1870 #else /* _WIDE */ 1871 bp = va_arg(args.ap, char *); 1872 if (!(flagword & DOTSEEN)) { 1873 if (wflag) { 1874 /* wide character handling */ 1875 prec = MAXINT; 1876 goto wide_hand; 1877 } 1878 1879 1880 p = bp + strlen(bp); 1881 1882 /* 1883 * sec_display only needed if width 1884 * is specified (ie, "%<width>s") 1885 * Solaris behavior counts <width> in 1886 * screen column width. (If XPG4 behavior, 1887 * <width> is counted in bytes.) 1888 */ 1889 if (width > 0 && __xpg4 == 0 && 1890 MB_CUR_MAX > 1) { 1891 #define NW 256 1892 wchar_t wbuff[NW]; 1893 wchar_t *wp, *wptr; 1894 size_t wpsize; 1895 size_t nwc; 1896 1897 wp = NULL; 1898 if ((nwc = mbstowcs(wbuff, bp, 1899 NW)) == (size_t)-1) { 1900 /* Estimate width */ 1901 sec_display = strlen(bp); 1902 goto mbs_err; 1903 } 1904 if (nwc < NW) { 1905 wptr = wbuff; 1906 } else { 1907 /* 1908 * If widechar does not fit into 1909 * wbuff, allocate larger buffer 1910 */ 1911 if ((nwc = 1912 mbstowcs(NULL, bp, NULL)) == 1913 (size_t)-1) { 1914 sec_display = 1915 strlen(bp); 1916 goto mbs_err; 1917 } 1918 wpsize = (nwc + 1) * 1919 sizeof (wchar_t); 1920 if ((wp = lmalloc(wpsize)) 1921 == NULL) { 1922 errno = ENOMEM; 1923 return (EOF); 1924 } 1925 if ((nwc = mbstowcs(wp, 1926 bp, nwc)) == (size_t)-1) { 1927 sec_display = \ 1928 strlen(bp); 1929 goto mbs_err; 1930 } 1931 wptr = wp; 1932 } 1933 if ((sec_display = wcswidth(wptr, nwc)) 1934 == -1) { 1935 sec_display = 1936 _rec_scrswidth 1937 (wptr, nwc); 1938 } 1939 mbs_err: 1940 if (wp) 1941 lfree(wp, wpsize); 1942 } 1943 } else { /* a strnlen function would be useful here! */ 1944 /* 1945 * If we've seen a dot, and count has been set 1946 * to 0, then we don't output in any cases 1947 * below. prec should be always >= 0. So we only 1948 * check to see if it's zero. 1949 */ 1950 if (prec == 0) { 1951 p = bp; 1952 break; 1953 } 1954 1955 if (wflag) { 1956 /* wide character handling */ 1957 1958 wide_hand: 1959 wp = (wchar_t *)(uintptr_t)bp; 1960 preco = prec; 1961 wcount = 0; 1962 while (*wp && 1963 (prec -= _scrwidth(*wp)) >= 0) { 1964 if ((retcode = 1965 wctomb(tmpbuf, *wp)) < 0) 1966 wcount++; 1967 else 1968 wcount += retcode; 1969 wp++; 1970 } 1971 if (*wp) 1972 prec += _scrwidth(*wp); 1973 p = (char *)wp; 1974 sec_display = preco - prec; 1975 } else if (__xpg4 == 0 && MB_CUR_MAX > 1) { 1976 /* 1977 * Solaris behavior - count 1978 * precision as screen column width 1979 */ 1980 char *qp = bp; 1981 int ncol, nbytes; 1982 wchar_t wc; 1983 1984 ncol = 0; 1985 preco = prec; 1986 while (*qp) { 1987 if (isascii(*qp)) { 1988 qp++; 1989 if (--prec == 0) 1990 break; 1991 continue; 1992 } 1993 if ((nbytes = mbtowc(&wc, qp, 1994 MB_LEN_MAX)) == -1) { 1995 /* print illegal char */ 1996 nbytes = 1; 1997 ncol = 1; 1998 } else { 1999 if ((ncol = 2000 _scrwidth(wc)) 2001 == 0) { 2002 ncol = 1; 2003 } 2004 } 2005 2006 if ((prec -= ncol) >= 0) { 2007 qp += nbytes; 2008 if (prec == 0) 2009 break; 2010 } else { 2011 break; 2012 } 2013 } 2014 if (prec < 0) 2015 prec += ncol; 2016 p = qp; 2017 sec_display = preco - prec; 2018 } else { 2019 /* 2020 * XPG4 behavior - count 2021 * precision as bytes. 2022 * We don't use strlen() because 2023 * the given char string may not 2024 * be null-terminated. 2025 */ 2026 char *qp; 2027 2028 qp = memchr(bp, '\0', prec); 2029 if (qp == NULL) { 2030 p = bp + prec; 2031 } else { 2032 p = qp; 2033 } 2034 } 2035 } 2036 #endif /* _WIDE */ 2037 break; 2038 2039 case 'n': 2040 { 2041 if (flagword & XLONG) { 2042 long long *svcount; 2043 svcount = va_arg(args.ap, long long *); 2044 *svcount = (long long)count; 2045 } else if (flagword & LENGTH) { 2046 long *svcount; 2047 svcount = va_arg(args.ap, long *); 2048 *svcount = (long)count; 2049 } else if (flagword & SHORT) { 2050 short *svcount; 2051 svcount = va_arg(args.ap, short *); 2052 *svcount = (short)count; 2053 } else if (flagword & CHAR) { 2054 char *svcount; 2055 svcount = va_arg(args.ap, char *); 2056 *svcount = (char)count; 2057 } else { 2058 int *svcount; 2059 svcount = va_arg(args.ap, int *); 2060 *svcount = count; 2061 } 2062 continue; 2063 } 2064 default: /* this is technically an error; what we do is to */ 2065 /* back up the format pointer to the offending char */ 2066 /* and continue with the format scan */ 2067 format--; 2068 continue; 2069 } 2070 2071 if (inf_nan) { 2072 if (inf_nan_mixed_case) { 2073 /* advance p */ 2074 for (p = bp + 1; *p != '\0'; p++) 2075 ; 2076 } else { 2077 int upper; 2078 2079 /* advance p and make output all one case */ 2080 upper = _M_ISUPPER(fcode); 2081 for (p = bp; *p != '\0'; p++) 2082 *p = upper? toupper(*p) : tolower(*p); 2083 } 2084 if (sign) { 2085 prefix = _P_HYPHEN; 2086 prefixlength = 1; 2087 } else if (flagword & FPLUS) { 2088 prefix = _P_PLUS; 2089 prefixlength = 1; 2090 } else if (flagword & FBLANK) { 2091 prefix = _P_BLANK; 2092 prefixlength = 1; 2093 } 2094 inf_nan = 0; 2095 inf_nan_mixed_case = 0; 2096 } 2097 2098 /* Calculate number of padding blanks */ 2099 n = p - bp; /* n == size of the converted value (in bytes) */ 2100 2101 #ifdef _WIDE 2102 k = n; 2103 #else /* _WIDE */ 2104 if (sec_display) /* when format is %s or %ws or %S */ 2105 k = sec_display; 2106 else 2107 k = n; 2108 #endif /* _WIDE */ 2109 /* 2110 * k is the (screen) width or # of bytes of the converted value 2111 */ 2112 k += prefixlength + otherlength; 2113 2114 #ifdef _WIDE 2115 if (wflag) { 2116 count += wcount; 2117 } else { 2118 count += n; 2119 } 2120 #else /* _WIDE */ 2121 /* 2122 * update count which is the overall size of the output data 2123 * and passed to memchr() 2124 */ 2125 if (wflag) 2126 /* 2127 * when wflag != 0 (i.e. %ws or %wc), the size of the 2128 * converted value is wcount bytes 2129 */ 2130 count += wcount; 2131 else 2132 /* 2133 * when wflag == 0, the size of the converted 2134 * value is n (= p-bp) bytes 2135 */ 2136 count += n; 2137 #endif /* _WIDE */ 2138 count += prefixlength + otherlength; 2139 2140 if (width > k) { 2141 count += (width - k); 2142 /* 2143 * Set up for padding zeroes if requested 2144 * Otherwise emit padding blanks unless output is 2145 * to be left-justified. 2146 */ 2147 2148 if (flagword & PADZERO) { 2149 if (!(flagword & LZERO)) { 2150 flagword |= LZERO; 2151 lzero = width - k; 2152 } else 2153 lzero += width - k; 2154 k = width; /* cancel padding blanks */ 2155 } else 2156 /* Blanks on left if required */ 2157 if (!(flagword & FMINUS)) 2158 PAD(_blanks, width - k); 2159 } 2160 2161 /* Prefix, if any */ 2162 if (prefixlength != 0) 2163 PUT(prefix, prefixlength); 2164 2165 /* Zeroes on the left */ 2166 if ((flagword & LZERO)) /* && */ 2167 /* (!(flagword & SHORT) || !(flagword & FMINUS)) */ 2168 PAD(_zeroes, lzero); 2169 2170 #ifdef _WIDE 2171 if (n > 0) 2172 PUT(bp, n); 2173 if ((fcode == 's') && !lflag) { 2174 if (bp) 2175 lfree(bp, bpsize); 2176 } 2177 #else /* _WIDE */ 2178 /* The value itself */ 2179 if ((fcode == 's' || fcode == 'S') && wflag) { 2180 /* wide character handling */ 2181 wchar_t *wp = (wchar_t *)(uintptr_t)bp; 2182 int cnt; 2183 char *bufp; 2184 long printn; 2185 printn = (wchar_t *)(uintptr_t)p - 2186 (wchar_t *)(uintptr_t)bp; 2187 bufp = buf; 2188 while (printn > 0) { 2189 if ((cnt = wctomb(buf, *wp)) < 0) 2190 cnt = 1; 2191 PUT(bufp, cnt); 2192 wp++; 2193 printn--; 2194 } 2195 } else { /* non wide character value */ 2196 if (n > 0) 2197 PUT(bp, n); 2198 } 2199 #endif /* _WIDE */ 2200 2201 if (flagword & (RZERO | SUFFIX | FMINUS)) { 2202 /* Zeroes on the right */ 2203 if (flagword & RZERO) 2204 PAD(_zeroes, rzero); 2205 2206 /* The suffix */ 2207 if (flagword & SUFFIX) 2208 PUT(suffix, suffixlength); 2209 2210 /* Blanks on the right if required */ 2211 if (flagword & FMINUS && width > k) 2212 PAD(_blanks, width - k); 2213 } 2214 } 2215 } 2216 2217 #ifdef _WIDE 2218 static int 2219 _watoi(wchar_t *fmt) 2220 { 2221 int n = 0; 2222 wchar_t ch; 2223 2224 ch = *fmt; 2225 if (_M_ISDIGIT(ch)) { 2226 n = ch - '0'; 2227 ch = *++fmt; 2228 while (_M_ISDIGIT(ch)) { 2229 n *= 10; 2230 n += ch - '0'; 2231 ch = *++fmt; 2232 } 2233 } 2234 return (n); 2235 } 2236 #endif /* _WIDE */ 2237 2238 /* 2239 * This function initializes arglst, to contain the appropriate va_list values 2240 * for the first MAXARGS arguments. 2241 */ 2242 2243 /* 2244 * Type modifier flags: 2245 * 0x01 for long 2246 * 0x02 for int 2247 * 0x04 for long long 2248 * 0x08 for long double 2249 */ 2250 2251 #define FLAG_LONG 0x01 2252 #define FLAG_INT 0x02 2253 #define FLAG_LONG_LONG 0x04 2254 #define FLAG_LONG_DBL 0x08 2255 2256 /* ARGSUSED3 */ 2257 #ifdef _WIDE 2258 static void 2259 _wmkarglst(wchar_t *fmt, stva_list args, stva_list arglst[], int prflag) 2260 #else /* _WIDE */ 2261 void 2262 _mkarglst(char *fmt, stva_list args, stva_list arglst[], int prflag) 2263 #endif /* _WIDE */ 2264 { 2265 #ifdef _WIDE 2266 static const wchar_t digits[] = L"01234567890"; 2267 static const wchar_t skips[] = L"# +-.'0123456789h$"; 2268 #else /* _WIDE */ 2269 static const char digits[] = "01234567890"; 2270 static const char skips[] = "# +-.'0123456789h$"; 2271 #endif /* _WIDE */ 2272 enum types {INT = 1, LONG, CHAR_PTR, DOUBLE, LONG_DOUBLE, VOID_PTR, 2273 LONG_PTR, INT_PTR, LONG_LONG, LONG_LONG_PTR}; 2274 enum types typelst[MAXARGS], curtype; 2275 ssize_t n; 2276 int maxnum, curargno, flags; 2277 2278 /* 2279 * Algorithm 1. set all argument types to zero. 2280 * 2. walk through fmt putting arg types in typelst[]. 2281 * 3. walk through args using va_arg(args.ap, typelst[n]) 2282 * and set arglst[] to the appropriate values. 2283 * Assumptions: Cannot use %*$... to specify variable position. 2284 */ 2285 2286 (void) memset((void *) typelst, 0, sizeof (typelst)); 2287 maxnum = -1; 2288 curargno = 0; 2289 while ((fmt = STRCHR(fmt, '%')) != 0) { 2290 fmt++; /* skip % */ 2291 if (fmt[n = STRSPN(fmt, digits)] == '$') { 2292 /* convert to zero base */ 2293 curargno = ATOI(fmt) - 1; 2294 if (curargno < 0) 2295 continue; 2296 fmt += n + 1; 2297 } 2298 flags = 0; 2299 again:; 2300 fmt += STRSPN(fmt, skips); 2301 switch (*fmt++) { 2302 case '%': /* there is no argument! */ 2303 continue; 2304 case 'l': 2305 if (flags & (FLAG_LONG | FLAG_LONG_LONG)) { 2306 flags |= FLAG_LONG_LONG; 2307 flags &= ~FLAG_LONG; 2308 } else { 2309 flags |= FLAG_LONG; 2310 } 2311 goto again; 2312 case 'j': 2313 #ifndef _LP64 2314 /* 2315 * *printf_c89() in 32-bit libc uses 2316 * 32-bit intmax_t; otherwise intmax_t 2317 * is 64-bits. 2318 */ 2319 if (!(prflag & _F_INTMAX32)) { 2320 #endif 2321 flags |= FLAG_LONG_LONG; /* 64-bit */ 2322 #ifndef _LP64 2323 } 2324 #endif 2325 goto again; 2326 case 't': 2327 flags |= FLAG_LONG; 2328 goto again; 2329 case 'z': 2330 flags |= FLAG_LONG; 2331 goto again; 2332 case 'L': 2333 flags |= FLAG_LONG_DBL; 2334 goto again; 2335 case '*': /* int argument used for value */ 2336 /* check if there is a positional parameter */ 2337 #ifdef _WIDE 2338 if ((*fmt >= 0) && (*fmt < 256) && 2339 isdigit(*fmt)) 2340 #else /* _WIDE */ 2341 if (isdigit(*fmt)) 2342 #endif /* _WIDE */ 2343 { 2344 int targno; 2345 targno = ATOI(fmt) - 1; 2346 fmt += STRSPN(fmt, digits); 2347 if (*fmt == '$') 2348 fmt++; /* skip '$' */ 2349 if (targno >= 0 && targno < MAXARGS) { 2350 typelst[targno] = INT; 2351 if (maxnum < targno) 2352 maxnum = targno; 2353 } 2354 goto again; 2355 } 2356 flags |= FLAG_INT; 2357 curtype = INT; 2358 break; 2359 case 'a': 2360 case 'A': 2361 case 'e': 2362 case 'E': 2363 case 'f': 2364 case 'F': 2365 case 'g': 2366 case 'G': 2367 if (flags & FLAG_LONG_DBL) 2368 curtype = LONG_DOUBLE; 2369 else 2370 curtype = DOUBLE; 2371 break; 2372 case 's': 2373 curtype = CHAR_PTR; 2374 break; 2375 case 'p': 2376 curtype = VOID_PTR; 2377 break; 2378 case 'n': 2379 if (flags & FLAG_LONG_LONG) 2380 curtype = LONG_LONG_PTR; 2381 else if (flags & FLAG_LONG) 2382 curtype = LONG_PTR; 2383 else 2384 curtype = INT_PTR; 2385 break; 2386 default: 2387 if (flags & FLAG_LONG_LONG) 2388 curtype = LONG_LONG; 2389 else if (flags & FLAG_LONG) 2390 curtype = LONG; 2391 else 2392 curtype = INT; 2393 break; 2394 } 2395 if (curargno >= 0 && curargno < MAXARGS) { 2396 typelst[curargno] = curtype; 2397 if (maxnum < curargno) 2398 maxnum = curargno; 2399 } 2400 curargno++; /* default to next in list */ 2401 if (flags & FLAG_INT) /* took care of *, keep going */ 2402 { 2403 flags ^= FLAG_INT; 2404 goto again; 2405 } 2406 } 2407 for (n = 0; n <= maxnum; n++) { 2408 arglst[n] = args; 2409 if (typelst[n] == 0) 2410 typelst[n] = INT; 2411 2412 switch (typelst[n]) { 2413 case INT: 2414 (void) va_arg(args.ap, int); 2415 break; 2416 case LONG: 2417 (void) va_arg(args.ap, long); 2418 break; 2419 case CHAR_PTR: 2420 (void) va_arg(args.ap, char *); 2421 break; 2422 case DOUBLE: 2423 (void) va_arg(args.ap, double); 2424 break; 2425 case LONG_DOUBLE: 2426 (void) GETQVAL(args.ap); 2427 break; 2428 case VOID_PTR: 2429 (void) va_arg(args.ap, void *); 2430 break; 2431 case LONG_PTR: 2432 (void) va_arg(args.ap, long *); 2433 break; 2434 case INT_PTR: 2435 (void) va_arg(args.ap, int *); 2436 break; 2437 case LONG_LONG: 2438 (void) va_arg(args.ap, long long); 2439 break; 2440 case LONG_LONG_PTR: 2441 (void) va_arg(args.ap, long long *); 2442 break; 2443 } 2444 } 2445 } 2446 2447 /* 2448 * This function is used to find the va_list value for arguments whose 2449 * position is greater than MAXARGS. This function is slow, so hopefully 2450 * MAXARGS will be big enough so that this function need only be called in 2451 * unusual circumstances. 2452 * pargs is assumed to contain the value of arglst[MAXARGS - 1]. 2453 */ 2454 /* ARGSUSED3 */ 2455 #ifdef _WIDE 2456 static void 2457 _wgetarg(wchar_t *fmt, stva_list *pargs, long argno, int prflag) 2458 #else /* _WIDE */ 2459 void 2460 _getarg(char *fmt, stva_list *pargs, long argno, int prflag) 2461 #endif /* _WIDE */ 2462 { 2463 2464 #ifdef _WIDE 2465 static const wchar_t digits[] = L"01234567890"; 2466 static const wchar_t skips[] = L"# +-.'0123456789h$"; 2467 wchar_t *sfmt = fmt; 2468 #else /* _WIDE */ 2469 static const char digits[] = "01234567890"; 2470 static const char skips[] = "# +-.'0123456789h$"; 2471 char *sfmt = fmt; 2472 #endif /* _WIDE */ 2473 ssize_t n; 2474 int i, curargno, flags; 2475 int found = 1; 2476 2477 i = MAXARGS; 2478 curargno = 1; 2479 while (found) { 2480 fmt = sfmt; 2481 found = 0; 2482 while ((i != argno) && (fmt = STRCHR(fmt, '%')) != 0) { 2483 fmt++; /* skip % */ 2484 if (fmt[n = STRSPN(fmt, digits)] == '$') { 2485 curargno = ATOI(fmt); 2486 if (curargno <= 0) 2487 continue; 2488 fmt += n + 1; 2489 } 2490 2491 /* find conversion specifier for next argument */ 2492 if (i != curargno) { 2493 curargno++; 2494 continue; 2495 } else 2496 found = 1; 2497 flags = 0; 2498 again:; 2499 fmt += STRSPN(fmt, skips); 2500 switch (*fmt++) { 2501 case '%': /* there is no argument! */ 2502 continue; 2503 case 'l': 2504 if (flags & (FLAG_LONG | FLAG_LONG_LONG)) { 2505 flags |= FLAG_LONG_LONG; 2506 flags &= ~FLAG_LONG; 2507 } else { 2508 flags |= FLAG_LONG; 2509 } 2510 goto again; 2511 case 'j': 2512 #ifndef _LP64 2513 /* 2514 * *printf_c89() in 32-bit libc uses 2515 * 32-bit intmax_t; otherwise intmax_t 2516 * is 64-bits. 2517 */ 2518 if (!(prflag & _F_INTMAX32)) { 2519 #endif 2520 flags |= FLAG_LONG_LONG; /* 64-bit */ 2521 #ifndef _LP64 2522 } 2523 #endif 2524 goto again; 2525 case 't': 2526 flags |= FLAG_LONG; 2527 goto again; 2528 case 'z': 2529 flags |= FLAG_LONG; 2530 goto again; 2531 case 'L': 2532 flags |= FLAG_LONG_DBL; 2533 goto again; 2534 case '*': /* int argument used for value */ 2535 /* 2536 * check if there is a positional parameter; 2537 * if so, just skip it; its size will be 2538 * correctly determined by default 2539 */ 2540 if (_M_ISDIGIT(*fmt)) { 2541 fmt += STRSPN(fmt, digits); 2542 if (*fmt == '$') 2543 fmt++; /* skip '$' */ 2544 goto again; 2545 } 2546 flags |= FLAG_INT; 2547 (void) va_arg((*pargs).ap, int); 2548 break; 2549 case 'a': 2550 case 'A': 2551 case 'e': 2552 case 'E': 2553 case 'f': 2554 case 'F': 2555 case 'g': 2556 case 'G': 2557 if (flags & FLAG_LONG_DBL) 2558 (void) GETQVAL((*pargs).ap); 2559 else 2560 (void) va_arg((*pargs).ap, double); 2561 break; 2562 case 's': 2563 (void) va_arg((*pargs).ap, char *); 2564 break; 2565 case 'p': 2566 (void) va_arg((*pargs).ap, void *); 2567 break; 2568 case 'n': 2569 if (flags & FLAG_LONG_LONG) 2570 (void) va_arg((*pargs).ap, long long *); 2571 else if (flags & FLAG_LONG) 2572 (void) va_arg((*pargs).ap, long *); 2573 else 2574 (void) va_arg((*pargs).ap, int *); 2575 break; 2576 default: 2577 if (flags & FLAG_LONG_LONG) 2578 (void) va_arg((*pargs).ap, long long); 2579 else if (flags & FLAG_LONG) 2580 (void) va_arg((*pargs).ap, long int); 2581 else 2582 (void) va_arg((*pargs).ap, int); 2583 break; 2584 } 2585 i++; 2586 curargno++; /* default to next in list */ 2587 if (flags & FLAG_INT) /* took care of *, keep going */ 2588 { 2589 flags ^= FLAG_INT; 2590 goto again; 2591 } 2592 } 2593 2594 /* missing specifier for parameter, assume param is an int */ 2595 if (!found && i != argno) { 2596 (void) va_arg((*pargs).ap, int); 2597 i++; 2598 curargno = i; 2599 found = 1; 2600 } 2601 } 2602 } 2603 2604 #ifdef _WIDE 2605 static wchar_t * 2606 insert_thousands_sep(wchar_t *bp, wchar_t *ep) 2607 #else /* _WIDE */ 2608 static char * 2609 insert_thousands_sep(char *bp, char *ep) 2610 #endif /* _WIDE */ 2611 { 2612 char thousep; 2613 struct lconv *locptr; 2614 ssize_t buf_index; 2615 int i; 2616 #ifdef _WIDE 2617 wchar_t *obp = bp; 2618 wchar_t buf[371]; 2619 wchar_t *bufptr = buf; 2620 #else /* _WIDE */ 2621 char *obp = bp; 2622 char buf[371]; 2623 char *bufptr = buf; 2624 #endif /* _WIDE */ 2625 char *grp_ptr; 2626 2627 /* get the thousands sep. from the current locale */ 2628 locptr = localeconv(); 2629 thousep = *locptr->thousands_sep; 2630 grp_ptr = locptr->grouping; 2631 2632 /* thousands sep. not use in this locale or no grouping required */ 2633 if (!thousep || (*grp_ptr == '\0')) 2634 return (ep); 2635 2636 buf_index = ep - bp; 2637 for (;;) { 2638 if (*grp_ptr == CHAR_MAX) { 2639 for (i = 0; i < buf_index--; i++) 2640 *bufptr++ = *(bp + buf_index); 2641 break; 2642 } 2643 for (i = 0; i < *grp_ptr && buf_index-- > 0; i++) 2644 *bufptr++ = *(bp + buf_index); 2645 2646 if (buf_index > 0) { 2647 #ifdef _WIDE 2648 *bufptr++ = (wchar_t)thousep; 2649 #else /* _WIDE */ 2650 *bufptr++ = thousep; 2651 #endif /* _WIDE */ 2652 ep++; 2653 } 2654 else 2655 break; 2656 if (*(grp_ptr + 1) != '\0') 2657 ++grp_ptr; 2658 } 2659 2660 /* put the string in the caller's buffer in reverse order */ 2661 --bufptr; 2662 while (buf <= bufptr) 2663 *obp++ = *bufptr--; 2664 return (ep); 2665 } 2666 2667 2668 /* 2669 * Recovery scrswidth function - 2670 * this variant of wcswidth() accepts non-printable or illegal 2671 * widechar characters. 2672 */ 2673 static int 2674 _rec_scrswidth(wchar_t *wp, ssize_t n) 2675 { 2676 int col; 2677 int i; 2678 2679 col = 0; 2680 while (*wp && (n-- > 0)) { 2681 if ((i = _scrwidth(*wp++)) == 0) 2682 i = 1; 2683 col += i; 2684 } 2685 return (col); 2686 } 2687