1This file is printf.def, from which is created printf.c. 2It implements the builtin "printf" in Bash. 3 4Copyright (C) 1997-2020 Free Software Foundation, Inc. 5 6This file is part of GNU Bash, the Bourne Again SHell. 7 8Bash is free software: you can redistribute it and/or modify 9it under the terms of the GNU General Public License as published by 10the Free Software Foundation, either version 3 of the License, or 11(at your option) any later version. 12 13Bash is distributed in the hope that it will be useful, 14but WITHOUT ANY WARRANTY; without even the implied warranty of 15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16GNU General Public License for more details. 17 18You should have received a copy of the GNU General Public License 19along with Bash. If not, see <http://www.gnu.org/licenses/>. 20 21$PRODUCES printf.c 22 23$BUILTIN printf 24$FUNCTION printf_builtin 25$SHORT_DOC printf [-v var] format [arguments] 26Formats and prints ARGUMENTS under control of the FORMAT. 27 28Options: 29 -v var assign the output to shell variable VAR rather than 30 display it on the standard output 31 32FORMAT is a character string which contains three types of objects: plain 33characters, which are simply copied to standard output; character escape 34sequences, which are converted and copied to the standard output; and 35format specifications, each of which causes printing of the next successive 36argument. 37 38In addition to the standard format specifications described in printf(1), 39printf interprets: 40 41 %b expand backslash escape sequences in the corresponding argument 42 %q quote the argument in a way that can be reused as shell input 43 %(fmt)T output the date-time string resulting from using FMT as a format 44 string for strftime(3) 45 46The format is re-used as necessary to consume all of the arguments. If 47there are fewer arguments than the format requires, extra format 48specifications behave as if a zero value or null string, as appropriate, 49had been supplied. 50 51Exit Status: 52Returns success unless an invalid option is given or a write or assignment 53error occurs. 54$END 55 56#include <config.h> 57 58#include "../bashtypes.h" 59 60#include <errno.h> 61#if defined (HAVE_LIMITS_H) 62# include <limits.h> 63#else 64 /* Assume 32-bit ints. */ 65# define INT_MAX 2147483647 66# define INT_MIN (-2147483647-1) 67#endif 68 69#if defined (PREFER_STDARG) 70# include <stdarg.h> 71#else 72# include <varargs.h> 73#endif 74 75#include <stdio.h> 76#include <chartypes.h> 77 78#ifdef HAVE_INTTYPES_H 79# include <inttypes.h> 80#endif 81 82#include "posixtime.h" 83#include "../bashansi.h" 84#include "../bashintl.h" 85 86#define NEED_STRFTIME_DECL 87 88#include "../shell.h" 89#include "shmbutil.h" 90#include "stdc.h" 91#include "bashgetopt.h" 92#include "common.h" 93 94#if defined (PRI_MACROS_BROKEN) 95# undef PRIdMAX 96#endif 97 98#if !defined (PRIdMAX) 99# if HAVE_LONG_LONG 100# define PRIdMAX "lld" 101# else 102# define PRIdMAX "ld" 103# endif 104#endif 105 106#if !defined (errno) 107extern int errno; 108#endif 109 110#define PC(c) \ 111 do { \ 112 char b[2]; \ 113 tw++; \ 114 b[0] = c; b[1] = '\0'; \ 115 if (vflag) \ 116 vbadd (b, 1); \ 117 else \ 118 putchar (c); \ 119 QUIT; \ 120 } while (0) 121 122#define PF(f, func) \ 123 do { \ 124 int nw; \ 125 clearerr (stdout); \ 126 if (have_fieldwidth && have_precision) \ 127 nw = vflag ? vbprintf (f, fieldwidth, precision, func) : printf (f, fieldwidth, precision, func); \ 128 else if (have_fieldwidth) \ 129 nw = vflag ? vbprintf (f, fieldwidth, func) : printf (f, fieldwidth, func); \ 130 else if (have_precision) \ 131 nw = vflag ? vbprintf (f, precision, func) : printf (f, precision, func); \ 132 else \ 133 nw = vflag ? vbprintf (f, func) : printf (f, func); \ 134 tw += nw; \ 135 QUIT; \ 136 if (ferror (stdout)) \ 137 { \ 138 sh_wrerror (); \ 139 clearerr (stdout); \ 140 return (EXECUTION_FAILURE); \ 141 } \ 142 } while (0) 143 144/* We free the buffer used by mklong() if it's `too big'. */ 145#define PRETURN(value) \ 146 do \ 147 { \ 148 QUIT; \ 149 if (vflag) \ 150 { \ 151 SHELL_VAR *v; \ 152 v = builtin_bind_variable (vname, vbuf, 0); \ 153 stupidly_hack_special_variables (vname); \ 154 if (v == 0 || readonly_p (v) || noassign_p (v)) \ 155 return (EXECUTION_FAILURE); \ 156 } \ 157 if (conv_bufsize > 4096 ) \ 158 { \ 159 free (conv_buf); \ 160 conv_bufsize = 0; \ 161 conv_buf = 0; \ 162 } \ 163 if (vbsize > 4096) \ 164 { \ 165 free (vbuf); \ 166 vbsize = 0; \ 167 vbuf = 0; \ 168 } \ 169 else if (vbuf) \ 170 vbuf[0] = 0; \ 171 if (ferror (stdout) == 0) \ 172 fflush (stdout); \ 173 QUIT; \ 174 if (ferror (stdout)) \ 175 { \ 176 sh_wrerror (); \ 177 clearerr (stdout); \ 178 return (EXECUTION_FAILURE); \ 179 } \ 180 return (value); \ 181 } \ 182 while (0) 183 184#define SKIP1 "#'-+ 0" 185#define LENMODS "hjlLtz" 186 187extern time_t shell_start_time; 188 189#if !HAVE_ASPRINTF 190extern int asprintf PARAMS((char **, const char *, ...)) __attribute__((__format__ (printf, 2, 3))); 191#endif 192 193#if !HAVE_VSNPRINTF 194extern int vsnprintf PARAMS((char *, size_t, const char *, va_list)) __attribute__((__format__ (printf, 3, 0))); 195#endif 196 197static void printf_erange PARAMS((char *)); 198static int printstr PARAMS((char *, char *, int, int, int)); 199static int tescape PARAMS((char *, char *, int *, int *)); 200static char *bexpand PARAMS((char *, int, int *, int *)); 201static char *vbadd PARAMS((char *, int)); 202static int vbprintf PARAMS((const char *, ...)) __attribute__((__format__ (printf, 1, 2))); 203static char *mklong PARAMS((char *, char *, size_t)); 204static int getchr PARAMS((void)); 205static char *getstr PARAMS((void)); 206static int getint PARAMS((void)); 207static intmax_t getintmax PARAMS((void)); 208static uintmax_t getuintmax PARAMS((void)); 209 210#if defined (HAVE_LONG_DOUBLE) && HAVE_DECL_STRTOLD && !defined(STRTOLD_BROKEN) 211typedef long double floatmax_t; 212# define FLOATMAX_CONV "L" 213# define strtofltmax strtold 214#else 215typedef double floatmax_t; 216# define FLOATMAX_CONV "" 217# define strtofltmax strtod 218#endif 219static floatmax_t getfloatmax PARAMS((void)); 220 221static intmax_t asciicode PARAMS((void)); 222 223static WORD_LIST *garglist, *orig_arglist; 224static int retval; 225static int conversion_error; 226 227/* printf -v var support */ 228static int vflag = 0; 229static char *vbuf, *vname; 230static size_t vbsize; 231static int vblen; 232 233static intmax_t tw; 234 235static char *conv_buf; 236static size_t conv_bufsize; 237 238int 239printf_builtin (list) 240 WORD_LIST *list; 241{ 242 int ch, fieldwidth, precision; 243 int have_fieldwidth, have_precision; 244 char convch, thisch, nextch, *format, *modstart, *fmt, *start; 245#if defined (HANDLE_MULTIBYTE) 246 char mbch[25]; /* 25 > MB_LEN_MAX, plus can handle 4-byte UTF-8 and large Unicode characters*/ 247 int mbind, mblen; 248#endif 249#if defined (ARRAY_VARS) 250 int arrayflags; 251#endif 252 253 conversion_error = 0; 254 retval = EXECUTION_SUCCESS; 255 256 vflag = 0; 257 258 reset_internal_getopt (); 259 while ((ch = internal_getopt (list, "v:")) != -1) 260 { 261 switch (ch) 262 { 263 case 'v': 264 vname = list_optarg; 265#if defined (ARRAY_VARS) 266 arrayflags = assoc_expand_once ? (VA_NOEXPAND|VA_ONEWORD) : 0; 267 if (legal_identifier (vname) || valid_array_reference (vname, arrayflags)) 268#else 269 if (legal_identifier (vname)) 270#endif 271 { 272 vflag = 1; 273 if (vbsize == 0) 274 vbuf = xmalloc (vbsize = 16); 275 vblen = 0; 276 if (vbuf) 277 vbuf[0] = 0; 278 } 279 else 280 { 281 sh_invalidid (vname); 282 return (EX_USAGE); 283 } 284 break; 285 CASE_HELPOPT; 286 default: 287 builtin_usage (); 288 return (EX_USAGE); 289 } 290 } 291 list = loptend; /* skip over possible `--' */ 292 293 if (list == 0) 294 { 295 builtin_usage (); 296 return (EX_USAGE); 297 } 298 299 /* Allow printf -v var "" to act like var="" */ 300 if (vflag && list->word->word && list->word->word[0] == '\0') 301 { 302 SHELL_VAR *v; 303 v = builtin_bind_variable (vname, "", 0); 304 stupidly_hack_special_variables (vname); 305 return ((v == 0 || readonly_p (v) || noassign_p (v)) ? EXECUTION_FAILURE : EXECUTION_SUCCESS); 306 } 307 308 if (list->word->word == 0 || list->word->word[0] == '\0') 309 return (EXECUTION_SUCCESS); 310 311 format = list->word->word; 312 tw = 0; 313 314 garglist = orig_arglist = list->next; 315 316 /* If the format string is empty after preprocessing, return immediately. */ 317 if (format == 0 || *format == 0) 318 return (EXECUTION_SUCCESS); 319 320 /* Basic algorithm is to scan the format string for conversion 321 specifications -- once one is found, find out if the field 322 width or precision is a '*'; if it is, gather up value. Note, 323 format strings are reused as necessary to use up the provided 324 arguments, arguments of zero/null string are provided to use 325 up the format string. */ 326 do 327 { 328 tw = 0; 329 /* find next format specification */ 330 for (fmt = format; *fmt; fmt++) 331 { 332 precision = fieldwidth = 0; 333 have_fieldwidth = have_precision = 0; 334 335 if (*fmt == '\\') 336 { 337 fmt++; 338 /* A NULL third argument to tescape means to bypass the 339 special processing for arguments to %b. */ 340#if defined (HANDLE_MULTIBYTE) 341 /* Accommodate possible use of \u or \U, which can result in 342 multibyte characters */ 343 memset (mbch, '\0', sizeof (mbch)); 344 fmt += tescape (fmt, mbch, &mblen, (int *)NULL); 345 for (mbind = 0; mbind < mblen; mbind++) 346 PC (mbch[mbind]); 347#else 348 fmt += tescape (fmt, &nextch, (int *)NULL, (int *)NULL); 349 PC (nextch); 350#endif 351 fmt--; /* for loop will increment it for us again */ 352 continue; 353 } 354 355 if (*fmt != '%') 356 { 357 PC (*fmt); 358 continue; 359 } 360 361 /* ASSERT(*fmt == '%') */ 362 start = fmt++; 363 364 if (*fmt == '%') /* %% prints a % */ 365 { 366 PC ('%'); 367 continue; 368 } 369 370 /* found format specification, skip to field width */ 371 for (; *fmt && strchr(SKIP1, *fmt); ++fmt) 372 ; 373 374 /* Skip optional field width. */ 375 if (*fmt == '*') 376 { 377 fmt++; 378 have_fieldwidth = 1; 379 fieldwidth = getint (); 380 } 381 else 382 while (DIGIT (*fmt)) 383 fmt++; 384 385 /* Skip optional '.' and precision */ 386 if (*fmt == '.') 387 { 388 ++fmt; 389 if (*fmt == '*') 390 { 391 fmt++; 392 have_precision = 1; 393 precision = getint (); 394 } 395 else 396 { 397 /* Negative precisions are allowed but treated as if the 398 precision were missing; I would like to allow a leading 399 `+' in the precision number as an extension, but lots 400 of asprintf/fprintf implementations get this wrong. */ 401#if 0 402 if (*fmt == '-' || *fmt == '+') 403#else 404 if (*fmt == '-') 405#endif 406 fmt++; 407 while (DIGIT (*fmt)) 408 fmt++; 409 } 410 } 411 412 /* skip possible format modifiers */ 413 modstart = fmt; 414 while (*fmt && strchr (LENMODS, *fmt)) 415 fmt++; 416 417 if (*fmt == 0) 418 { 419 builtin_error (_("`%s': missing format character"), start); 420 PRETURN (EXECUTION_FAILURE); 421 } 422 423 convch = *fmt; 424 thisch = modstart[0]; 425 nextch = modstart[1]; 426 modstart[0] = convch; 427 modstart[1] = '\0'; 428 429 QUIT; 430 switch(convch) 431 { 432 case 'c': 433 { 434 char p; 435 436 p = getchr (); 437 PF(start, p); 438 break; 439 } 440 441 case 's': 442 { 443 char *p; 444 445 p = getstr (); 446 PF(start, p); 447 break; 448 } 449 450 case '(': 451 { 452 char *timefmt, timebuf[128], *t; 453 int n; 454 intmax_t arg; 455 time_t secs; 456 struct tm *tm; 457 458 modstart[1] = nextch; /* restore char after left paren */ 459 timefmt = xmalloc (strlen (fmt) + 3); 460 fmt++; /* skip over left paren */ 461 for (t = timefmt, n = 1; *fmt; ) 462 { 463 if (*fmt == '(') 464 n++; 465 else if (*fmt == ')') 466 n--; 467 if (n == 0) 468 break; 469 *t++ = *fmt++; 470 } 471 *t = '\0'; 472 if (*++fmt != 'T') 473 { 474 builtin_warning (_("`%c': invalid time format specification"), *fmt); 475 fmt = start; 476 free (timefmt); 477 PC (*fmt); 478 continue; 479 } 480 if (timefmt[0] == '\0') 481 { 482 timefmt[0] = '%'; 483 timefmt[1] = 'X'; /* locale-specific current time - should we use `+'? */ 484 timefmt[2] = '\0'; 485 } 486 /* argument is seconds since the epoch with special -1 and -2 */ 487 /* default argument is equivalent to -1; special case */ 488 arg = garglist ? getintmax () : -1; 489 if (arg == -1) 490 secs = NOW; /* roughly date +%s */ 491 else if (arg == -2) 492 secs = shell_start_time; /* roughly $SECONDS */ 493 else 494 secs = arg; 495#if defined (HAVE_TZSET) 496 sv_tz ("TZ"); /* XXX -- just make sure */ 497#endif 498 tm = localtime (&secs); 499 if (tm == 0) 500 { 501 secs = 0; 502 tm = localtime (&secs); 503 } 504 n = tm ? strftime (timebuf, sizeof (timebuf), timefmt, tm) : 0; 505 free (timefmt); 506 if (n == 0) 507 timebuf[0] = '\0'; 508 else 509 timebuf[sizeof(timebuf) - 1] = '\0'; 510 /* convert to %s format that preserves fieldwidth and precision */ 511 modstart[0] = 's'; 512 modstart[1] = '\0'; 513 n = printstr (start, timebuf, strlen (timebuf), fieldwidth, precision); /* XXX - %s for now */ 514 if (n < 0) 515 { 516 if (ferror (stdout) == 0) 517 { 518 sh_wrerror (); 519 clearerr (stdout); 520 } 521 PRETURN (EXECUTION_FAILURE); 522 } 523 break; 524 } 525 526 case 'n': 527 { 528 char *var; 529 530 var = getstr (); 531 if (var && *var) 532 { 533 if (legal_identifier (var)) 534 bind_var_to_int (var, tw); 535 else 536 { 537 sh_invalidid (var); 538 PRETURN (EXECUTION_FAILURE); 539 } 540 } 541 break; 542 } 543 544 case 'b': /* expand escapes in argument */ 545 { 546 char *p, *xp; 547 int rlen, r; 548 549 p = getstr (); 550 ch = rlen = r = 0; 551 xp = bexpand (p, strlen (p), &ch, &rlen); 552 553 if (xp) 554 { 555 /* Have to use printstr because of possible NUL bytes 556 in XP -- printf does not handle that well. */ 557 r = printstr (start, xp, rlen, fieldwidth, precision); 558 if (r < 0) 559 { 560 if (ferror (stdout) == 0) 561 { 562 sh_wrerror (); 563 clearerr (stdout); 564 } 565 retval = EXECUTION_FAILURE; 566 } 567 free (xp); 568 } 569 570 if (ch || r < 0) 571 PRETURN (retval); 572 break; 573 } 574 575 case 'q': /* print with shell quoting */ 576 { 577 char *p, *xp; 578 int r; 579 580 r = 0; 581 p = getstr (); 582 if (p && *p == 0) /* XXX - getstr never returns null */ 583 xp = savestring ("''"); 584 else if (ansic_shouldquote (p)) 585 xp = ansic_quote (p, 0, (int *)0); 586 else 587 xp = sh_backslash_quote (p, 0, 3); 588 if (xp) 589 { 590 /* Use printstr to get fieldwidth and precision right. */ 591 r = printstr (start, xp, strlen (xp), fieldwidth, precision); 592 if (r < 0) 593 { 594 sh_wrerror (); 595 clearerr (stdout); 596 } 597 free (xp); 598 } 599 600 if (r < 0) 601 PRETURN (EXECUTION_FAILURE); 602 break; 603 } 604 605 case 'd': 606 case 'i': 607 { 608 char *f; 609 long p; 610 intmax_t pp; 611 612 p = pp = getintmax (); 613 if (p != pp) 614 { 615 f = mklong (start, PRIdMAX, sizeof (PRIdMAX) - 2); 616 PF (f, pp); 617 } 618 else 619 { 620 /* Optimize the common case where the integer fits 621 in "long". This also works around some long 622 long and/or intmax_t library bugs in the common 623 case, e.g. glibc 2.2 x86. */ 624 f = mklong (start, "l", 1); 625 PF (f, p); 626 } 627 break; 628 } 629 630 case 'o': 631 case 'u': 632 case 'x': 633 case 'X': 634 { 635 char *f; 636 unsigned long p; 637 uintmax_t pp; 638 639 p = pp = getuintmax (); 640 if (p != pp) 641 { 642 f = mklong (start, PRIdMAX, sizeof (PRIdMAX) - 2); 643 PF (f, pp); 644 } 645 else 646 { 647 f = mklong (start, "l", 1); 648 PF (f, p); 649 } 650 break; 651 } 652 653 case 'e': 654 case 'E': 655 case 'f': 656 case 'F': 657 case 'g': 658 case 'G': 659#if defined (HAVE_PRINTF_A_FORMAT) 660 case 'a': 661 case 'A': 662#endif 663 { 664 char *f; 665 floatmax_t p; 666 667 p = getfloatmax (); 668 f = mklong (start, FLOATMAX_CONV, sizeof(FLOATMAX_CONV) - 1); 669 PF (f, p); 670 break; 671 } 672 673 /* We don't output unrecognized format characters; we print an 674 error message and return a failure exit status. */ 675 default: 676 builtin_error (_("`%c': invalid format character"), convch); 677 PRETURN (EXECUTION_FAILURE); 678 } 679 680 modstart[0] = thisch; 681 modstart[1] = nextch; 682 } 683 684 if (ferror (stdout)) 685 { 686 /* PRETURN will print error message. */ 687 PRETURN (EXECUTION_FAILURE); 688 } 689 } 690 while (garglist && garglist != list->next); 691 692 if (conversion_error) 693 retval = EXECUTION_FAILURE; 694 695 PRETURN (retval); 696} 697 698static void 699printf_erange (s) 700 char *s; 701{ 702 builtin_error (_("warning: %s: %s"), s, strerror(ERANGE)); 703} 704 705/* We duplicate a lot of what printf(3) does here. */ 706static int 707printstr (fmt, string, len, fieldwidth, precision) 708 char *fmt; /* format */ 709 char *string; /* expanded string argument */ 710 int len; /* length of expanded string */ 711 int fieldwidth; /* argument for width of `*' */ 712 int precision; /* argument for precision of `*' */ 713{ 714#if 0 715 char *s; 716#endif 717 int padlen, nc, ljust, i; 718 int fw, pr; /* fieldwidth and precision */ 719 intmax_t mfw, mpr; 720 721 if (string == 0) 722 string = ""; 723 724#if 0 725 s = fmt; 726#endif 727 if (*fmt == '%') 728 fmt++; 729 730 ljust = fw = 0; 731 pr = -1; 732 mfw = 0; 733 mpr = -1; 734 735 /* skip flags */ 736 while (strchr (SKIP1, *fmt)) 737 { 738 if (*fmt == '-') 739 ljust = 1; 740 fmt++; 741 } 742 743 /* get fieldwidth, if present. rely on caller to clamp fieldwidth at INT_MAX */ 744 if (*fmt == '*') 745 { 746 fmt++; 747 fw = fieldwidth; 748 if (fw < 0) 749 { 750 fw = -fw; 751 ljust = 1; 752 } 753 } 754 else if (DIGIT (*fmt)) 755 { 756 mfw = *fmt++ - '0'; 757 while (DIGIT (*fmt)) 758 mfw = (mfw * 10) + (*fmt++ - '0'); 759 /* Error if fieldwidth > INT_MAX here? */ 760 fw = (mfw < 0 || mfw > INT_MAX) ? INT_MAX : mfw; 761 } 762 763 /* get precision, if present */ 764 if (*fmt == '.') 765 { 766 fmt++; 767 if (*fmt == '*') 768 { 769 fmt++; 770 pr = precision; 771 } 772 else if (DIGIT (*fmt)) 773 { 774 mpr = *fmt++ - '0'; 775 while (DIGIT (*fmt)) 776 mpr = (mpr * 10) + (*fmt++ - '0'); 777 /* Error if precision > INT_MAX here? */ 778 pr = (mpr < 0 || mpr > INT_MAX) ? INT_MAX : mpr; 779 } 780 else 781 pr = 0; /* "a null digit string is treated as zero" */ 782 } 783 784#if 0 785 /* If we remove this, get rid of `s'. */ 786 if (*fmt != 'b' && *fmt != 'q') 787 { 788 internal_error (_("format parsing problem: %s"), s); 789 fw = pr = 0; 790 } 791#endif 792 793 /* chars from string to print */ 794 nc = (pr >= 0 && pr <= len) ? pr : len; 795 796 padlen = fw - nc; 797 if (padlen < 0) 798 padlen = 0; 799 if (ljust) 800 padlen = -padlen; 801 802 /* leading pad characters */ 803 for (; padlen > 0; padlen--) 804 PC (' '); 805 806 /* output NC characters from STRING */ 807 for (i = 0; i < nc; i++) 808 PC (string[i]); 809 810 /* output any necessary trailing padding */ 811 for (; padlen < 0; padlen++) 812 PC (' '); 813 814 return (ferror (stdout) ? -1 : 0); 815} 816 817/* Convert STRING by expanding the escape sequences specified by the 818 POSIX standard for printf's `%b' format string. If SAWC is non-null, 819 perform the processing appropriate for %b arguments. In particular, 820 recognize `\c' and use that as a string terminator. If we see \c, set 821 *SAWC to 1 before returning. LEN is the length of STRING. */ 822 823/* Translate a single backslash-escape sequence starting at ESTART (the 824 character after the backslash) and return the number of characters 825 consumed by the sequence. CP is the place to return the translated 826 value. *SAWC is set to 1 if the escape sequence was \c, since that means 827 to short-circuit the rest of the processing. If SAWC is null, we don't 828 do the \c short-circuiting, and \c is treated as an unrecognized escape 829 sequence; we also bypass the other processing specific to %b arguments. */ 830static int 831tescape (estart, cp, lenp, sawc) 832 char *estart; 833 char *cp; 834 int *lenp, *sawc; 835{ 836 register char *p; 837 int temp, c, evalue; 838 unsigned long uvalue; 839 840 p = estart; 841 if (lenp) 842 *lenp = 1; 843 844 switch (c = *p++) 845 { 846#if defined (__STDC__) 847 case 'a': *cp = '\a'; break; 848#else 849 case 'a': *cp = '\007'; break; 850#endif 851 852 case 'b': *cp = '\b'; break; 853 854 case 'e': 855 case 'E': *cp = '\033'; break; /* ESC -- non-ANSI */ 856 857 case 'f': *cp = '\f'; break; 858 859 case 'n': *cp = '\n'; break; 860 861 case 'r': *cp = '\r'; break; 862 863 case 't': *cp = '\t'; break; 864 865 case 'v': *cp = '\v'; break; 866 867 /* The octal escape sequences are `\0' followed by up to three octal 868 digits (if SAWC), or `\' followed by up to three octal digits (if 869 !SAWC). As an extension, we allow the latter form even if SAWC. */ 870 case '0': case '1': case '2': case '3': 871 case '4': case '5': case '6': case '7': 872 evalue = OCTVALUE (c); 873 for (temp = 2 + (!evalue && !!sawc); ISOCTAL (*p) && temp--; p++) 874 evalue = (evalue * 8) + OCTVALUE (*p); 875 *cp = evalue & 0xFF; 876 break; 877 878 /* And, as another extension, we allow \xNN, where each N is a 879 hex digit. */ 880 case 'x': 881 for (temp = 2, evalue = 0; ISXDIGIT ((unsigned char)*p) && temp--; p++) 882 evalue = (evalue * 16) + HEXVALUE (*p); 883 if (p == estart + 1) 884 { 885 builtin_error (_("missing hex digit for \\x")); 886 *cp = '\\'; 887 return 0; 888 } 889 *cp = evalue & 0xFF; 890 break; 891 892#if defined (HANDLE_MULTIBYTE) 893 case 'u': 894 case 'U': 895 temp = (c == 'u') ? 4 : 8; /* \uNNNN \UNNNNNNNN */ 896 for (uvalue = 0; ISXDIGIT ((unsigned char)*p) && temp--; p++) 897 uvalue = (uvalue * 16) + HEXVALUE (*p); 898 if (p == estart + 1) 899 { 900 builtin_error (_("missing unicode digit for \\%c"), c); 901 *cp = '\\'; 902 return 0; 903 } 904 if (uvalue <= 0x7f) /* <= 0x7f translates directly */ 905 *cp = uvalue; 906 else 907 { 908 temp = u32cconv (uvalue, cp); 909 cp[temp] = '\0'; 910 if (lenp) 911 *lenp = temp; 912 } 913 break; 914#endif 915 916 case '\\': /* \\ -> \ */ 917 *cp = c; 918 break; 919 920 /* SAWC == 0 means that \', \", and \? are recognized as escape 921 sequences, though the only processing performed is backslash 922 removal. */ 923 case '\'': case '"': case '?': 924 if (!sawc) 925 *cp = c; 926 else 927 { 928 *cp = '\\'; 929 return 0; 930 } 931 break; 932 933 case 'c': 934 if (sawc) 935 { 936 *sawc = 1; 937 break; 938 } 939 /* other backslash escapes are passed through unaltered */ 940 default: 941 *cp = '\\'; 942 return 0; 943 } 944 return (p - estart); 945} 946 947static char * 948bexpand (string, len, sawc, lenp) 949 char *string; 950 int len, *sawc, *lenp; 951{ 952 int temp; 953 char *ret, *r, *s, c; 954#if defined (HANDLE_MULTIBYTE) 955 char mbch[25]; 956 int mbind, mblen; 957#endif 958 959 if (string == 0 || len == 0) 960 { 961 if (sawc) 962 *sawc = 0; 963 if (lenp) 964 *lenp = 0; 965 ret = (char *)xmalloc (1); 966 ret[0] = '\0'; 967 return (ret); 968 } 969 970 ret = (char *)xmalloc (len + 1); 971 for (r = ret, s = string; s && *s; ) 972 { 973 c = *s++; 974 if (c != '\\' || *s == '\0') 975 { 976 *r++ = c; 977 continue; 978 } 979 temp = 0; 980#if defined (HANDLE_MULTIBYTE) 981 memset (mbch, '\0', sizeof (mbch)); 982 s += tescape (s, mbch, &mblen, &temp); 983#else 984 s += tescape (s, &c, (int *)NULL, &temp); 985#endif 986 if (temp) 987 { 988 if (sawc) 989 *sawc = 1; 990 break; 991 } 992 993#if defined (HANDLE_MULTIBYTE) 994 for (mbind = 0; mbind < mblen; mbind++) 995 *r++ = mbch[mbind]; 996#else 997 *r++ = c; 998#endif 999 } 1000 1001 *r = '\0'; 1002 if (lenp) 1003 *lenp = r - ret; 1004 return ret; 1005} 1006 1007static char * 1008vbadd (buf, blen) 1009 char *buf; 1010 int blen; 1011{ 1012 size_t nlen; 1013 1014 nlen = vblen + blen + 1; 1015 if (nlen >= vbsize) 1016 { 1017 vbsize = ((nlen + 63) >> 6) << 6; 1018 vbuf = (char *)xrealloc (vbuf, vbsize); 1019 } 1020 1021 if (blen == 1) 1022 vbuf[vblen++] = buf[0]; 1023 else if (blen > 1) 1024 { 1025 FASTCOPY (buf, vbuf + vblen, blen); 1026 vblen += blen; 1027 } 1028 vbuf[vblen] = '\0'; 1029 1030#ifdef DEBUG 1031 if (strlen (vbuf) != vblen) 1032 internal_error ("printf:vbadd: vblen (%d) != strlen (vbuf) (%d)", vblen, (int)strlen (vbuf)); 1033#endif 1034 1035 return vbuf; 1036} 1037 1038static int 1039#if defined (PREFER_STDARG) 1040vbprintf (const char *format, ...) 1041#else 1042vbprintf (format, va_alist) 1043 const char *format; 1044 va_dcl 1045#endif 1046{ 1047 va_list args; 1048 size_t nlen; 1049 int blen; 1050 1051 SH_VA_START (args, format); 1052 blen = vsnprintf (vbuf + vblen, vbsize - vblen, format, args); 1053 va_end (args); 1054 1055 nlen = vblen + blen + 1; 1056 if (nlen >= vbsize) 1057 { 1058 vbsize = ((nlen + 63) >> 6) << 6; 1059 vbuf = (char *)xrealloc (vbuf, vbsize); 1060 SH_VA_START (args, format); 1061 blen = vsnprintf (vbuf + vblen, vbsize - vblen, format, args); 1062 va_end (args); 1063 } 1064 1065 vblen += blen; 1066 vbuf[vblen] = '\0'; 1067 1068#ifdef DEBUG 1069 if (strlen (vbuf) != vblen) 1070 internal_error ("printf:vbprintf: vblen (%d) != strlen (vbuf) (%d)", vblen, (int)strlen (vbuf)); 1071#endif 1072 1073 return (blen); 1074} 1075 1076static char * 1077mklong (str, modifiers, mlen) 1078 char *str; 1079 char *modifiers; 1080 size_t mlen; 1081{ 1082 size_t len, slen; 1083 1084 slen = strlen (str); 1085 len = slen + mlen + 1; 1086 1087 if (len > conv_bufsize) 1088 { 1089 conv_bufsize = (((len + 1023) >> 10) << 10); 1090 conv_buf = (char *)xrealloc (conv_buf, conv_bufsize); 1091 } 1092 1093 FASTCOPY (str, conv_buf, slen - 1); 1094 FASTCOPY (modifiers, conv_buf + slen - 1, mlen); 1095 1096 conv_buf[len - 2] = str[slen - 1]; 1097 conv_buf[len - 1] = '\0'; 1098 return (conv_buf); 1099} 1100 1101static int 1102getchr () 1103{ 1104 int ret; 1105 1106 if (garglist == 0) 1107 return ('\0'); 1108 1109 ret = (int)garglist->word->word[0]; 1110 garglist = garglist->next; 1111 return ret; 1112} 1113 1114static char * 1115getstr () 1116{ 1117 char *ret; 1118 1119 if (garglist == 0) 1120 return (""); 1121 1122 ret = garglist->word->word; 1123 garglist = garglist->next; 1124 return ret; 1125} 1126 1127static int 1128getint () 1129{ 1130 intmax_t ret; 1131 1132 ret = getintmax (); 1133 1134 if (garglist == 0) 1135 return ret; 1136 1137 if (ret > INT_MAX) 1138 { 1139 printf_erange (garglist->word->word); 1140 ret = INT_MAX; 1141 } 1142 else if (ret < INT_MIN) 1143 { 1144 printf_erange (garglist->word->word); 1145 ret = INT_MIN; 1146 } 1147 1148 return ((int)ret); 1149} 1150 1151static intmax_t 1152getintmax () 1153{ 1154 intmax_t ret; 1155 char *ep; 1156 1157 if (garglist == 0) 1158 return (0); 1159 1160 if (garglist->word->word[0] == '\'' || garglist->word->word[0] == '"') 1161 return asciicode (); 1162 1163 errno = 0; 1164 ret = strtoimax (garglist->word->word, &ep, 0); 1165 1166 if (*ep) 1167 { 1168 sh_invalidnum (garglist->word->word); 1169 /* POSIX.2 says ``...a diagnostic message shall be written to standard 1170 error, and the utility shall not exit with a zero exit status, but 1171 shall continue processing any remaining operands and shall write the 1172 value accumulated at the time the error was detected to standard 1173 output.'' Yecch. */ 1174#if 0 1175 ret = 0; /* return partially-converted value from strtoimax */ 1176#endif 1177 conversion_error = 1; 1178 } 1179 else if (errno == ERANGE) 1180 printf_erange (garglist->word->word); 1181 1182 garglist = garglist->next; 1183 return (ret); 1184} 1185 1186static uintmax_t 1187getuintmax () 1188{ 1189 uintmax_t ret; 1190 char *ep; 1191 1192 if (garglist == 0) 1193 return (0); 1194 1195 if (garglist->word->word[0] == '\'' || garglist->word->word[0] == '"') 1196 return asciicode (); 1197 1198 errno = 0; 1199 ret = strtoumax (garglist->word->word, &ep, 0); 1200 1201 if (*ep) 1202 { 1203 sh_invalidnum (garglist->word->word); 1204#if 0 1205 /* Same POSIX.2 conversion error requirements as getintmax(). */ 1206 ret = 0; 1207#endif 1208 conversion_error = 1; 1209 } 1210 else if (errno == ERANGE) 1211 printf_erange (garglist->word->word); 1212 1213 garglist = garglist->next; 1214 return (ret); 1215} 1216 1217static floatmax_t 1218getfloatmax () 1219{ 1220 floatmax_t ret; 1221 char *ep; 1222 1223 if (garglist == 0) 1224 return (0); 1225 1226 if (garglist->word->word[0] == '\'' || garglist->word->word[0] == '"') 1227 return asciicode (); 1228 1229 errno = 0; 1230 ret = strtofltmax (garglist->word->word, &ep); 1231 1232 if (*ep) 1233 { 1234 sh_invalidnum (garglist->word->word); 1235#if 0 1236 /* Same thing about POSIX.2 conversion error requirements. */ 1237 ret = 0; 1238#endif 1239 conversion_error = 1; 1240 } 1241 else if (errno == ERANGE) 1242 printf_erange (garglist->word->word); 1243 1244 garglist = garglist->next; 1245 return (ret); 1246} 1247 1248/* NO check is needed for garglist here. */ 1249static intmax_t 1250asciicode () 1251{ 1252 register intmax_t ch; 1253#if defined (HANDLE_MULTIBYTE) 1254 wchar_t wc; 1255 size_t slen; 1256 int mblength; 1257#endif 1258 DECLARE_MBSTATE; 1259 1260#if defined (HANDLE_MULTIBYTE) 1261 slen = strlen (garglist->word->word+1); 1262 wc = 0; 1263 mblength = mbtowc (&wc, garglist->word->word+1, slen); 1264 if (mblength > 0) 1265 ch = wc; /* XXX */ 1266 else 1267#endif 1268 ch = (unsigned char)garglist->word->word[1]; 1269 1270 garglist = garglist->next; 1271 return (ch); 1272} 1273