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