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