1 /* Various declarations for language-independent pretty-print subroutines. 2 Copyright (C) 2003-2018 Free Software Foundation, Inc. 3 Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net> 4 5 This file is part of GCC. 6 7 GCC is free software; you can redistribute it and/or modify it under 8 the terms of the GNU General Public License as published by the Free 9 Software Foundation; either version 3, or (at your option) any later 10 version. 11 12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY 13 WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with GCC; see the file COPYING3. If not see 19 <http://www.gnu.org/licenses/>. */ 20 21 #include "config.h" 22 #include "system.h" 23 #include "coretypes.h" 24 #include "intl.h" 25 #include "pretty-print.h" 26 #include "diagnostic-color.h" 27 #include "selftest.h" 28 29 #if HAVE_ICONV 30 #include <iconv.h> 31 #endif 32 33 #ifdef __MINGW32__ 34 35 /* Replacement for fputs() that handles ANSI escape codes on Windows NT. 36 Contributed by: Liu Hao (lh_mouse at 126 dot com) 37 38 XXX: This file is compiled into libcommon.a that will be self-contained. 39 It looks like that these functions can be put nowhere else. */ 40 41 #include <io.h> 42 #define WIN32_LEAN_AND_MEAN 1 43 #include <windows.h> 44 45 /* Write all bytes in [s,s+n) into the specified stream. 46 Errors are ignored. */ 47 static void 48 write_all (HANDLE h, const char *s, size_t n) 49 { 50 size_t rem = n; 51 DWORD step; 52 53 while (rem != 0) 54 { 55 if (rem <= UINT_MAX) 56 step = rem; 57 else 58 step = UINT_MAX; 59 if (!WriteFile (h, s + n - rem, step, &step, NULL)) 60 break; 61 rem -= step; 62 } 63 } 64 65 /* Find the beginning of an escape sequence. 66 There are two cases: 67 1. If the sequence begins with an ESC character (0x1B) and a second 68 character X in [0x40,0x5F], returns X and stores a pointer to 69 the third character into *head. 70 2. If the sequence begins with a character X in [0x80,0x9F], returns 71 (X-0x40) and stores a pointer to the second character into *head. 72 Stores the number of ESC character(s) in *prefix_len. 73 Returns 0 if no such sequence can be found. */ 74 static int 75 find_esc_head (int *prefix_len, const char **head, const char *str) 76 { 77 int c; 78 const char *r = str; 79 int escaped = 0; 80 81 for (;;) 82 { 83 c = (unsigned char) *r; 84 if (c == 0) 85 { 86 /* Not found. */ 87 return 0; 88 } 89 if (escaped && 0x40 <= c && c <= 0x5F) 90 { 91 /* Found (case 1). */ 92 *prefix_len = 2; 93 *head = r + 1; 94 return c; 95 } 96 if (0x80 <= c && c <= 0x9F) 97 { 98 /* Found (case 2). */ 99 *prefix_len = 1; 100 *head = r + 1; 101 return c - 0x40; 102 } 103 ++r; 104 escaped = c == 0x1B; 105 } 106 } 107 108 /* Find the terminator of an escape sequence. 109 str should be the value stored in *head by a previous successful 110 call to find_esc_head(). 111 Returns 0 if no such sequence can be found. */ 112 static int 113 find_esc_terminator (const char **term, const char *str) 114 { 115 int c; 116 const char *r = str; 117 118 for (;;) 119 { 120 c = (unsigned char) *r; 121 if (c == 0) 122 { 123 /* Not found. */ 124 return 0; 125 } 126 if (0x40 <= c && c <= 0x7E) 127 { 128 /* Found. */ 129 *term = r; 130 return c; 131 } 132 ++r; 133 } 134 } 135 136 /* Handle a sequence of codes. Sequences that are invalid, reserved, 137 unrecognized or unimplemented are ignored silently. 138 There isn't much we can do because of lameness of Windows consoles. */ 139 static void 140 eat_esc_sequence (HANDLE h, int esc_code, 141 const char *esc_head, const char *esc_term) 142 { 143 /* Numbers in an escape sequence cannot be negative, because 144 a minus sign in the middle of it would have terminated it. */ 145 long n1, n2; 146 char *eptr, *delim; 147 CONSOLE_SCREEN_BUFFER_INFO sb; 148 COORD cr; 149 /* ED and EL parameters. */ 150 DWORD cnt, step; 151 long rows; 152 /* SGR parameters. */ 153 WORD attrib_add, attrib_rm; 154 const char *param; 155 156 switch (MAKEWORD (esc_code, *esc_term)) 157 { 158 /* ESC [ n1 'A' 159 Move the cursor up by n1 characters. */ 160 case MAKEWORD ('[', 'A'): 161 if (esc_head == esc_term) 162 n1 = 1; 163 else 164 { 165 n1 = strtol (esc_head, &eptr, 10); 166 if (eptr != esc_term) 167 break; 168 } 169 170 if (GetConsoleScreenBufferInfo (h, &sb)) 171 { 172 cr = sb.dwCursorPosition; 173 /* Stop at the topmost boundary. */ 174 if (cr.Y > n1) 175 cr.Y -= n1; 176 else 177 cr.Y = 0; 178 SetConsoleCursorPosition (h, cr); 179 } 180 break; 181 182 /* ESC [ n1 'B' 183 Move the cursor down by n1 characters. */ 184 case MAKEWORD ('[', 'B'): 185 if (esc_head == esc_term) 186 n1 = 1; 187 else 188 { 189 n1 = strtol (esc_head, &eptr, 10); 190 if (eptr != esc_term) 191 break; 192 } 193 194 if (GetConsoleScreenBufferInfo (h, &sb)) 195 { 196 cr = sb.dwCursorPosition; 197 /* Stop at the bottommost boundary. */ 198 if (sb.dwSize.Y - cr.Y > n1) 199 cr.Y += n1; 200 else 201 cr.Y = sb.dwSize.Y; 202 SetConsoleCursorPosition (h, cr); 203 } 204 break; 205 206 /* ESC [ n1 'C' 207 Move the cursor right by n1 characters. */ 208 case MAKEWORD ('[', 'C'): 209 if (esc_head == esc_term) 210 n1 = 1; 211 else 212 { 213 n1 = strtol (esc_head, &eptr, 10); 214 if (eptr != esc_term) 215 break; 216 } 217 218 if (GetConsoleScreenBufferInfo (h, &sb)) 219 { 220 cr = sb.dwCursorPosition; 221 /* Stop at the rightmost boundary. */ 222 if (sb.dwSize.X - cr.X > n1) 223 cr.X += n1; 224 else 225 cr.X = sb.dwSize.X; 226 SetConsoleCursorPosition (h, cr); 227 } 228 break; 229 230 /* ESC [ n1 'D' 231 Move the cursor left by n1 characters. */ 232 case MAKEWORD ('[', 'D'): 233 if (esc_head == esc_term) 234 n1 = 1; 235 else 236 { 237 n1 = strtol (esc_head, &eptr, 10); 238 if (eptr != esc_term) 239 break; 240 } 241 242 if (GetConsoleScreenBufferInfo (h, &sb)) 243 { 244 cr = sb.dwCursorPosition; 245 /* Stop at the leftmost boundary. */ 246 if (cr.X > n1) 247 cr.X -= n1; 248 else 249 cr.X = 0; 250 SetConsoleCursorPosition (h, cr); 251 } 252 break; 253 254 /* ESC [ n1 'E' 255 Move the cursor to the beginning of the n1-th line downwards. */ 256 case MAKEWORD ('[', 'E'): 257 if (esc_head == esc_term) 258 n1 = 1; 259 else 260 { 261 n1 = strtol (esc_head, &eptr, 10); 262 if (eptr != esc_term) 263 break; 264 } 265 266 if (GetConsoleScreenBufferInfo (h, &sb)) 267 { 268 cr = sb.dwCursorPosition; 269 cr.X = 0; 270 /* Stop at the bottommost boundary. */ 271 if (sb.dwSize.Y - cr.Y > n1) 272 cr.Y += n1; 273 else 274 cr.Y = sb.dwSize.Y; 275 SetConsoleCursorPosition (h, cr); 276 } 277 break; 278 279 /* ESC [ n1 'F' 280 Move the cursor to the beginning of the n1-th line upwards. */ 281 case MAKEWORD ('[', 'F'): 282 if (esc_head == esc_term) 283 n1 = 1; 284 else 285 { 286 n1 = strtol (esc_head, &eptr, 10); 287 if (eptr != esc_term) 288 break; 289 } 290 291 if (GetConsoleScreenBufferInfo (h, &sb)) 292 { 293 cr = sb.dwCursorPosition; 294 cr.X = 0; 295 /* Stop at the topmost boundary. */ 296 if (cr.Y > n1) 297 cr.Y -= n1; 298 else 299 cr.Y = 0; 300 SetConsoleCursorPosition (h, cr); 301 } 302 break; 303 304 /* ESC [ n1 'G' 305 Move the cursor to the (1-based) n1-th column. */ 306 case MAKEWORD ('[', 'G'): 307 if (esc_head == esc_term) 308 n1 = 1; 309 else 310 { 311 n1 = strtol (esc_head, &eptr, 10); 312 if (eptr != esc_term) 313 break; 314 } 315 316 if (GetConsoleScreenBufferInfo (h, &sb)) 317 { 318 cr = sb.dwCursorPosition; 319 n1 -= 1; 320 /* Stop at the leftmost or rightmost boundary. */ 321 if (n1 < 0) 322 cr.X = 0; 323 else if (n1 > sb.dwSize.X) 324 cr.X = sb.dwSize.X; 325 else 326 cr.X = n1; 327 SetConsoleCursorPosition (h, cr); 328 } 329 break; 330 331 /* ESC [ n1 ';' n2 'H' 332 ESC [ n1 ';' n2 'f' 333 Move the cursor to the (1-based) n1-th row and 334 (also 1-based) n2-th column. */ 335 case MAKEWORD ('[', 'H'): 336 case MAKEWORD ('[', 'f'): 337 if (esc_head == esc_term) 338 { 339 /* Both parameters are omitted and set to 1 by default. */ 340 n1 = 1; 341 n2 = 1; 342 } 343 else if (!(delim = (char *) memchr (esc_head, ';', 344 esc_term - esc_head))) 345 { 346 /* Only the first parameter is given. The second one is 347 set to 1 by default. */ 348 n1 = strtol (esc_head, &eptr, 10); 349 if (eptr != esc_term) 350 break; 351 n2 = 1; 352 } 353 else 354 { 355 /* Both parameters are given. The first one shall be 356 terminated by the semicolon. */ 357 n1 = strtol (esc_head, &eptr, 10); 358 if (eptr != delim) 359 break; 360 n2 = strtol (delim + 1, &eptr, 10); 361 if (eptr != esc_term) 362 break; 363 } 364 365 if (GetConsoleScreenBufferInfo (h, &sb)) 366 { 367 cr = sb.dwCursorPosition; 368 n1 -= 1; 369 n2 -= 1; 370 /* The cursor position shall be relative to the view coord of 371 the console window, which is usually smaller than the actual 372 buffer. FWIW, the 'appropriate' solution will be shrinking 373 the buffer to match the size of the console window, 374 destroying scrollback in the process. */ 375 n1 += sb.srWindow.Top; 376 n2 += sb.srWindow.Left; 377 /* Stop at the topmost or bottommost boundary. */ 378 if (n1 < 0) 379 cr.Y = 0; 380 else if (n1 > sb.dwSize.Y) 381 cr.Y = sb.dwSize.Y; 382 else 383 cr.Y = n1; 384 /* Stop at the leftmost or rightmost boundary. */ 385 if (n2 < 0) 386 cr.X = 0; 387 else if (n2 > sb.dwSize.X) 388 cr.X = sb.dwSize.X; 389 else 390 cr.X = n2; 391 SetConsoleCursorPosition (h, cr); 392 } 393 break; 394 395 /* ESC [ n1 'J' 396 Erase display. */ 397 case MAKEWORD ('[', 'J'): 398 if (esc_head == esc_term) 399 /* This is one of the very few codes whose parameters have 400 a default value of zero. */ 401 n1 = 0; 402 else 403 { 404 n1 = strtol (esc_head, &eptr, 10); 405 if (eptr != esc_term) 406 break; 407 } 408 409 if (GetConsoleScreenBufferInfo (h, &sb)) 410 { 411 /* The cursor is not necessarily in the console window, which 412 makes the behavior of this code harder to define. */ 413 switch (n1) 414 { 415 case 0: 416 /* If the cursor is in or above the window, erase from 417 it to the bottom of the window; otherwise, do nothing. */ 418 cr = sb.dwCursorPosition; 419 cnt = sb.dwSize.X - sb.dwCursorPosition.X; 420 rows = sb.srWindow.Bottom - sb.dwCursorPosition.Y; 421 break; 422 case 1: 423 /* If the cursor is in or under the window, erase from 424 it to the top of the window; otherwise, do nothing. */ 425 cr.X = 0; 426 cr.Y = sb.srWindow.Top; 427 cnt = sb.dwCursorPosition.X + 1; 428 rows = sb.dwCursorPosition.Y - sb.srWindow.Top; 429 break; 430 case 2: 431 /* Erase the entire window. */ 432 cr.X = sb.srWindow.Left; 433 cr.Y = sb.srWindow.Top; 434 cnt = 0; 435 rows = sb.srWindow.Bottom - sb.srWindow.Top + 1; 436 break; 437 default: 438 /* Erase the entire buffer. */ 439 cr.X = 0; 440 cr.Y = 0; 441 cnt = 0; 442 rows = sb.dwSize.Y; 443 break; 444 } 445 if (rows < 0) 446 break; 447 cnt += rows * sb.dwSize.X; 448 FillConsoleOutputCharacterW (h, L' ', cnt, cr, &step); 449 FillConsoleOutputAttribute (h, sb.wAttributes, cnt, cr, &step); 450 } 451 break; 452 453 /* ESC [ n1 'K' 454 Erase line. */ 455 case MAKEWORD ('[', 'K'): 456 if (esc_head == esc_term) 457 /* This is one of the very few codes whose parameters have 458 a default value of zero. */ 459 n1 = 0; 460 else 461 { 462 n1 = strtol (esc_head, &eptr, 10); 463 if (eptr != esc_term) 464 break; 465 } 466 467 if (GetConsoleScreenBufferInfo (h, &sb)) 468 { 469 switch (n1) 470 { 471 case 0: 472 /* Erase from the cursor to the end. */ 473 cr = sb.dwCursorPosition; 474 cnt = sb.dwSize.X - sb.dwCursorPosition.X; 475 break; 476 case 1: 477 /* Erase from the cursor to the beginning. */ 478 cr = sb.dwCursorPosition; 479 cr.X = 0; 480 cnt = sb.dwCursorPosition.X + 1; 481 break; 482 default: 483 /* Erase the entire line. */ 484 cr = sb.dwCursorPosition; 485 cr.X = 0; 486 cnt = sb.dwSize.X; 487 break; 488 } 489 FillConsoleOutputCharacterW (h, L' ', cnt, cr, &step); 490 FillConsoleOutputAttribute (h, sb.wAttributes, cnt, cr, &step); 491 } 492 break; 493 494 /* ESC [ n1 ';' n2 'm' 495 Set SGR parameters. Zero or more parameters will follow. */ 496 case MAKEWORD ('[', 'm'): 497 attrib_add = 0; 498 attrib_rm = 0; 499 if (esc_head == esc_term) 500 { 501 /* When no parameter is given, reset the console. */ 502 attrib_add |= (FOREGROUND_RED | FOREGROUND_GREEN 503 | FOREGROUND_BLUE); 504 attrib_rm = -1; /* Removes everything. */ 505 goto sgr_set_it; 506 } 507 param = esc_head; 508 do 509 { 510 /* Parse a parameter. */ 511 n1 = strtol (param, &eptr, 10); 512 if (*eptr != ';' && eptr != esc_term) 513 goto sgr_set_it; 514 515 switch (n1) 516 { 517 case 0: 518 /* Reset. */ 519 attrib_add |= (FOREGROUND_RED | FOREGROUND_GREEN 520 | FOREGROUND_BLUE); 521 attrib_rm = -1; /* Removes everything. */ 522 break; 523 case 1: 524 /* Bold. */ 525 attrib_add |= FOREGROUND_INTENSITY; 526 break; 527 case 4: 528 /* Underline. */ 529 attrib_add |= COMMON_LVB_UNDERSCORE; 530 break; 531 case 5: 532 /* Blink. */ 533 /* XXX: It is not BLINKING at all! */ 534 attrib_add |= BACKGROUND_INTENSITY; 535 break; 536 case 7: 537 /* Reverse. */ 538 attrib_add |= COMMON_LVB_REVERSE_VIDEO; 539 break; 540 case 22: 541 /* No bold. */ 542 attrib_add &= ~FOREGROUND_INTENSITY; 543 attrib_rm |= FOREGROUND_INTENSITY; 544 break; 545 case 24: 546 /* No underline. */ 547 attrib_add &= ~COMMON_LVB_UNDERSCORE; 548 attrib_rm |= COMMON_LVB_UNDERSCORE; 549 break; 550 case 25: 551 /* No blink. */ 552 /* XXX: It is not BLINKING at all! */ 553 attrib_add &= ~BACKGROUND_INTENSITY; 554 attrib_rm |= BACKGROUND_INTENSITY; 555 break; 556 case 27: 557 /* No reverse. */ 558 attrib_add &= ~COMMON_LVB_REVERSE_VIDEO; 559 attrib_rm |= COMMON_LVB_REVERSE_VIDEO; 560 break; 561 case 30: 562 case 31: 563 case 32: 564 case 33: 565 case 34: 566 case 35: 567 case 36: 568 case 37: 569 /* Foreground color. */ 570 attrib_add &= ~(FOREGROUND_RED | FOREGROUND_GREEN 571 | FOREGROUND_BLUE); 572 n1 -= 30; 573 if (n1 & 1) 574 attrib_add |= FOREGROUND_RED; 575 if (n1 & 2) 576 attrib_add |= FOREGROUND_GREEN; 577 if (n1 & 4) 578 attrib_add |= FOREGROUND_BLUE; 579 attrib_rm |= (FOREGROUND_RED | FOREGROUND_GREEN 580 | FOREGROUND_BLUE); 581 break; 582 case 38: 583 /* Reserved for extended foreground color. 584 Don't know how to handle parameters remaining. 585 Bail out. */ 586 goto sgr_set_it; 587 case 39: 588 /* Reset foreground color. */ 589 /* Set to grey. */ 590 attrib_add |= (FOREGROUND_RED | FOREGROUND_GREEN 591 | FOREGROUND_BLUE); 592 attrib_rm |= (FOREGROUND_RED | FOREGROUND_GREEN 593 | FOREGROUND_BLUE); 594 break; 595 case 40: 596 case 41: 597 case 42: 598 case 43: 599 case 44: 600 case 45: 601 case 46: 602 case 47: 603 /* Background color. */ 604 attrib_add &= ~(BACKGROUND_RED | BACKGROUND_GREEN 605 | BACKGROUND_BLUE); 606 n1 -= 40; 607 if (n1 & 1) 608 attrib_add |= BACKGROUND_RED; 609 if (n1 & 2) 610 attrib_add |= BACKGROUND_GREEN; 611 if (n1 & 4) 612 attrib_add |= BACKGROUND_BLUE; 613 attrib_rm |= (BACKGROUND_RED | BACKGROUND_GREEN 614 | BACKGROUND_BLUE); 615 break; 616 case 48: 617 /* Reserved for extended background color. 618 Don't know how to handle parameters remaining. 619 Bail out. */ 620 goto sgr_set_it; 621 case 49: 622 /* Reset background color. */ 623 /* Set to black. */ 624 attrib_add &= ~(BACKGROUND_RED | BACKGROUND_GREEN 625 | BACKGROUND_BLUE); 626 attrib_rm |= (BACKGROUND_RED | BACKGROUND_GREEN 627 | BACKGROUND_BLUE); 628 break; 629 } 630 631 /* Prepare the next parameter. */ 632 param = eptr + 1; 633 } 634 while (param != esc_term); 635 636 sgr_set_it: 637 /* 0xFFFF removes everything. If it is not the case, 638 care must be taken to preserve old attributes. */ 639 if (attrib_rm != 0xFFFF && GetConsoleScreenBufferInfo (h, &sb)) 640 { 641 attrib_add |= sb.wAttributes & ~attrib_rm; 642 } 643 if (attrib_add & COMMON_LVB_REVERSE_VIDEO) 644 { 645 /* COMMON_LVB_REVERSE_VIDEO is only effective for DBCS. 646 * Swap foreground and background colors by hand. 647 */ 648 attrib_add = (attrib_add & 0xFF00) 649 | ((attrib_add & 0x00F0) >> 4) 650 | ((attrib_add & 0x000F) << 4); 651 attrib_add &= ~COMMON_LVB_REVERSE_VIDEO; 652 } 653 SetConsoleTextAttribute (h, attrib_add); 654 break; 655 } 656 } 657 658 int 659 mingw_ansi_fputs (const char *str, FILE *fp) 660 { 661 const char *read = str; 662 HANDLE h; 663 DWORD mode; 664 int esc_code, prefix_len; 665 const char *esc_head, *esc_term; 666 667 h = (HANDLE) _get_osfhandle (_fileno (fp)); 668 if (h == INVALID_HANDLE_VALUE) 669 return EOF; 670 671 /* Don't mess up stdio functions with Windows APIs. */ 672 fflush (fp); 673 674 if (GetConsoleMode (h, &mode)) 675 /* If it is a console, translate ANSI escape codes as needed. */ 676 for (;;) 677 { 678 if ((esc_code = find_esc_head (&prefix_len, &esc_head, read)) == 0) 679 { 680 /* Write all remaining characters, then exit. */ 681 write_all (h, read, strlen (read)); 682 break; 683 } 684 if (find_esc_terminator (&esc_term, esc_head) == 0) 685 /* Ignore incomplete escape sequences at the moment. 686 FIXME: The escape state shall be cached for further calls 687 to this function. */ 688 break; 689 write_all (h, read, esc_head - prefix_len - read); 690 eat_esc_sequence (h, esc_code, esc_head, esc_term); 691 read = esc_term + 1; 692 } 693 else 694 /* If it is not a console, write everything as-is. */ 695 write_all (h, read, strlen (read)); 696 697 return 1; 698 } 699 700 #endif /* __MINGW32__ */ 701 702 static void pp_quoted_string (pretty_printer *, const char *, size_t = -1); 703 704 /* Overwrite the given location/range within this text_info's rich_location. 705 For use e.g. when implementing "+" in client format decoders. */ 706 707 void 708 text_info::set_location (unsigned int idx, location_t loc, bool show_caret_p) 709 { 710 gcc_checking_assert (m_richloc); 711 m_richloc->set_range (line_table, idx, loc, show_caret_p); 712 } 713 714 location_t 715 text_info::get_location (unsigned int index_of_location) const 716 { 717 gcc_checking_assert (m_richloc); 718 719 if (index_of_location == 0) 720 return m_richloc->get_loc (); 721 else 722 return UNKNOWN_LOCATION; 723 } 724 725 // Default construct an output buffer. 726 727 output_buffer::output_buffer () 728 : formatted_obstack (), 729 chunk_obstack (), 730 obstack (&formatted_obstack), 731 cur_chunk_array (), 732 stream (stderr), 733 line_length (), 734 digit_buffer (), 735 flush_p (true) 736 { 737 obstack_init (&formatted_obstack); 738 obstack_init (&chunk_obstack); 739 } 740 741 // Release resources owned by an output buffer at the end of lifetime. 742 743 output_buffer::~output_buffer () 744 { 745 obstack_free (&chunk_obstack, NULL); 746 obstack_free (&formatted_obstack, NULL); 747 } 748 749 750 /* Format an integer given by va_arg (ARG, type-specifier T) where 751 type-specifier is a precision modifier as indicated by PREC. F is 752 a string used to construct the appropriate format-specifier. */ 753 #define pp_integer_with_precision(PP, ARG, PREC, T, F) \ 754 do \ 755 switch (PREC) \ 756 { \ 757 case 0: \ 758 pp_scalar (PP, "%" F, va_arg (ARG, T)); \ 759 break; \ 760 \ 761 case 1: \ 762 pp_scalar (PP, "%l" F, va_arg (ARG, long T)); \ 763 break; \ 764 \ 765 case 2: \ 766 pp_scalar (PP, "%" HOST_LONG_LONG_FORMAT F, va_arg (ARG, long long T)); \ 767 break; \ 768 \ 769 default: \ 770 break; \ 771 } \ 772 while (0) 773 774 775 /* Subroutine of pp_set_maximum_length. Set up PRETTY-PRINTER's 776 internal maximum characters per line. */ 777 static void 778 pp_set_real_maximum_length (pretty_printer *pp) 779 { 780 /* If we're told not to wrap lines then do the obvious thing. In case 781 we'll emit prefix only once per message, it is appropriate 782 not to increase unnecessarily the line-length cut-off. */ 783 if (!pp_is_wrapping_line (pp) 784 || pp_prefixing_rule (pp) == DIAGNOSTICS_SHOW_PREFIX_ONCE 785 || pp_prefixing_rule (pp) == DIAGNOSTICS_SHOW_PREFIX_NEVER) 786 pp->maximum_length = pp_line_cutoff (pp); 787 else 788 { 789 int prefix_length = pp->prefix ? strlen (pp->prefix) : 0; 790 /* If the prefix is ridiculously too long, output at least 791 32 characters. */ 792 if (pp_line_cutoff (pp) - prefix_length < 32) 793 pp->maximum_length = pp_line_cutoff (pp) + 32; 794 else 795 pp->maximum_length = pp_line_cutoff (pp); 796 } 797 } 798 799 /* Clear PRETTY-PRINTER's output state. */ 800 static inline void 801 pp_clear_state (pretty_printer *pp) 802 { 803 pp->emitted_prefix = false; 804 pp_indentation (pp) = 0; 805 } 806 807 /* Print X to PP in decimal. */ 808 template<unsigned int N, typename T> 809 void 810 pp_wide_integer (pretty_printer *pp, const poly_int_pod<N, T> &x) 811 { 812 if (x.is_constant ()) 813 pp_wide_integer (pp, x.coeffs[0]); 814 else 815 { 816 pp_left_bracket (pp); 817 for (unsigned int i = 0; i < N; ++i) 818 { 819 if (i != 0) 820 pp_comma (pp); 821 pp_wide_integer (pp, x.coeffs[i]); 822 } 823 pp_right_bracket (pp); 824 } 825 } 826 827 template void pp_wide_integer (pretty_printer *, const poly_uint16_pod &); 828 template void pp_wide_integer (pretty_printer *, const poly_int64_pod &); 829 template void pp_wide_integer (pretty_printer *, const poly_uint64_pod &); 830 831 /* Flush the formatted text of PRETTY-PRINTER onto the attached stream. */ 832 void 833 pp_write_text_to_stream (pretty_printer *pp) 834 { 835 const char *text = pp_formatted_text (pp); 836 #ifdef __MINGW32__ 837 mingw_ansi_fputs (text, pp_buffer (pp)->stream); 838 #else 839 fputs (text, pp_buffer (pp)->stream); 840 #endif 841 pp_clear_output_area (pp); 842 } 843 844 /* As pp_write_text_to_stream, but for GraphViz label output. 845 846 Flush the formatted text of pretty-printer PP onto the attached stream. 847 Replace characters in PPF that have special meaning in a GraphViz .dot 848 file. 849 850 This routine is not very fast, but it doesn't have to be as this is only 851 be used by routines dumping intermediate representations in graph form. */ 852 853 void 854 pp_write_text_as_dot_label_to_stream (pretty_printer *pp, bool for_record) 855 { 856 const char *text = pp_formatted_text (pp); 857 const char *p = text; 858 FILE *fp = pp_buffer (pp)->stream; 859 860 for (;*p; p++) 861 { 862 bool escape_char; 863 switch (*p) 864 { 865 /* Print newlines as a left-aligned newline. */ 866 case '\n': 867 fputs ("\\l", fp); 868 escape_char = true; 869 break; 870 871 /* The following characters are only special for record-shape nodes. */ 872 case '|': 873 case '{': 874 case '}': 875 case '<': 876 case '>': 877 case ' ': 878 escape_char = for_record; 879 break; 880 881 /* The following characters always have to be escaped 882 for use in labels. */ 883 case '\\': 884 /* There is a bug in some (f.i. 2.36.0) versions of graphiz 885 ( http://www.graphviz.org/mantisbt/view.php?id=2524 ) related to 886 backslash as last char in label. Let's avoid triggering it. */ 887 gcc_assert (*(p + 1) != '\0'); 888 /* Fall through. */ 889 case '"': 890 escape_char = true; 891 break; 892 893 default: 894 escape_char = false; 895 break; 896 } 897 898 if (escape_char) 899 fputc ('\\', fp); 900 901 fputc (*p, fp); 902 } 903 904 pp_clear_output_area (pp); 905 } 906 907 /* Wrap a text delimited by START and END into PRETTY-PRINTER. */ 908 static void 909 pp_wrap_text (pretty_printer *pp, const char *start, const char *end) 910 { 911 bool wrapping_line = pp_is_wrapping_line (pp); 912 913 while (start != end) 914 { 915 /* Dump anything bordered by whitespaces. */ 916 { 917 const char *p = start; 918 while (p != end && !ISBLANK (*p) && *p != '\n') 919 ++p; 920 if (wrapping_line 921 && p - start >= pp_remaining_character_count_for_line (pp)) 922 pp_newline (pp); 923 pp_append_text (pp, start, p); 924 start = p; 925 } 926 927 if (start != end && ISBLANK (*start)) 928 { 929 pp_space (pp); 930 ++start; 931 } 932 if (start != end && *start == '\n') 933 { 934 pp_newline (pp); 935 ++start; 936 } 937 } 938 } 939 940 /* Same as pp_wrap_text but wrap text only when in line-wrapping mode. */ 941 static inline void 942 pp_maybe_wrap_text (pretty_printer *pp, const char *start, const char *end) 943 { 944 if (pp_is_wrapping_line (pp)) 945 pp_wrap_text (pp, start, end); 946 else 947 pp_append_text (pp, start, end); 948 } 949 950 /* Append to the output area of PRETTY-PRINTER a string specified by its 951 STARTing character and LENGTH. */ 952 static inline void 953 pp_append_r (pretty_printer *pp, const char *start, int length) 954 { 955 output_buffer_append_r (pp_buffer (pp), start, length); 956 } 957 958 /* Insert enough spaces into the output area of PRETTY-PRINTER to bring 959 the column position to the current indentation level, assuming that a 960 newline has just been written to the buffer. */ 961 void 962 pp_indent (pretty_printer *pp) 963 { 964 int n = pp_indentation (pp); 965 int i; 966 967 for (i = 0; i < n; ++i) 968 pp_space (pp); 969 } 970 971 /* The following format specifiers are recognized as being client independent: 972 %d, %i: (signed) integer in base ten. 973 %u: unsigned integer in base ten. 974 %o: unsigned integer in base eight. 975 %x: unsigned integer in base sixteen. 976 %ld, %li, %lo, %lu, %lx: long versions of the above. 977 %lld, %lli, %llo, %llu, %llx: long long versions. 978 %wd, %wi, %wo, %wu, %wx: HOST_WIDE_INT versions. 979 %c: character. 980 %s: string. 981 %p: pointer (printed in a host-dependent manner). 982 %r: if pp_show_color(pp), switch to color identified by const char *. 983 %R: if pp_show_color(pp), reset color. 984 %m: strerror(text->err_no) - does not consume a value from args_ptr. 985 %%: '%'. 986 %<: opening quote. 987 %>: closing quote. 988 %': apostrophe (should only be used in untranslated messages; 989 translations should use appropriate punctuation directly). 990 %.*s: a substring the length of which is specified by an argument 991 integer. 992 %Ns: likewise, but length specified as constant in the format string. 993 Flag 'q': quote formatted text (must come immediately after '%'). 994 %Z: Requires two arguments - array of int, and len. Prints elements 995 of the array. 996 997 Arguments can be used sequentially, or through %N$ resp. *N$ 998 notation Nth argument after the format string. If %N$ / *N$ 999 notation is used, it must be used for all arguments, except %m, %%, 1000 %<, %> and %', which may not have a number, as they do not consume 1001 an argument. When %M$.*N$s is used, M must be N + 1. (This may 1002 also be written %M$.*s, provided N is not otherwise used.) The 1003 format string must have conversion specifiers with argument numbers 1004 1 up to highest argument; each argument may only be used once. 1005 A format string can have at most 30 arguments. */ 1006 1007 /* Formatting phases 1 and 2: render TEXT->format_spec plus 1008 TEXT->args_ptr into a series of chunks in pp_buffer (PP)->args[]. 1009 Phase 3 is in pp_output_formatted_text. */ 1010 1011 void 1012 pp_format (pretty_printer *pp, text_info *text) 1013 { 1014 output_buffer *buffer = pp_buffer (pp); 1015 const char *p; 1016 const char **args; 1017 struct chunk_info *new_chunk_array; 1018 1019 unsigned int curarg = 0, chunk = 0, argno; 1020 pp_wrapping_mode_t old_wrapping_mode; 1021 bool any_unnumbered = false, any_numbered = false; 1022 const char **formatters[PP_NL_ARGMAX]; 1023 1024 /* Allocate a new chunk structure. */ 1025 new_chunk_array = XOBNEW (&buffer->chunk_obstack, struct chunk_info); 1026 new_chunk_array->prev = buffer->cur_chunk_array; 1027 buffer->cur_chunk_array = new_chunk_array; 1028 args = new_chunk_array->args; 1029 1030 /* Formatting phase 1: split up TEXT->format_spec into chunks in 1031 pp_buffer (PP)->args[]. Even-numbered chunks are to be output 1032 verbatim, odd-numbered chunks are format specifiers. 1033 %m, %%, %<, %>, and %' are replaced with the appropriate text at 1034 this point. */ 1035 1036 memset (formatters, 0, sizeof formatters); 1037 1038 for (p = text->format_spec; *p; ) 1039 { 1040 while (*p != '\0' && *p != '%') 1041 { 1042 obstack_1grow (&buffer->chunk_obstack, *p); 1043 p++; 1044 } 1045 1046 if (*p == '\0') 1047 break; 1048 1049 switch (*++p) 1050 { 1051 case '\0': 1052 gcc_unreachable (); 1053 1054 case '%': 1055 obstack_1grow (&buffer->chunk_obstack, '%'); 1056 p++; 1057 continue; 1058 1059 case '<': 1060 { 1061 obstack_grow (&buffer->chunk_obstack, 1062 open_quote, strlen (open_quote)); 1063 const char *colorstr 1064 = colorize_start (pp_show_color (pp), "quote"); 1065 obstack_grow (&buffer->chunk_obstack, colorstr, strlen (colorstr)); 1066 p++; 1067 continue; 1068 } 1069 1070 case '>': 1071 { 1072 const char *colorstr = colorize_stop (pp_show_color (pp)); 1073 obstack_grow (&buffer->chunk_obstack, colorstr, strlen (colorstr)); 1074 } 1075 /* FALLTHRU */ 1076 case '\'': 1077 obstack_grow (&buffer->chunk_obstack, 1078 close_quote, strlen (close_quote)); 1079 p++; 1080 continue; 1081 1082 case 'R': 1083 { 1084 const char *colorstr = colorize_stop (pp_show_color (pp)); 1085 obstack_grow (&buffer->chunk_obstack, colorstr, 1086 strlen (colorstr)); 1087 p++; 1088 continue; 1089 } 1090 1091 case 'm': 1092 { 1093 const char *errstr = xstrerror (text->err_no); 1094 obstack_grow (&buffer->chunk_obstack, errstr, strlen (errstr)); 1095 } 1096 p++; 1097 continue; 1098 1099 default: 1100 /* Handled in phase 2. Terminate the plain chunk here. */ 1101 obstack_1grow (&buffer->chunk_obstack, '\0'); 1102 gcc_assert (chunk < PP_NL_ARGMAX * 2); 1103 args[chunk++] = XOBFINISH (&buffer->chunk_obstack, const char *); 1104 break; 1105 } 1106 1107 if (ISDIGIT (*p)) 1108 { 1109 char *end; 1110 argno = strtoul (p, &end, 10) - 1; 1111 p = end; 1112 gcc_assert (*p == '$'); 1113 p++; 1114 1115 any_numbered = true; 1116 gcc_assert (!any_unnumbered); 1117 } 1118 else 1119 { 1120 argno = curarg++; 1121 any_unnumbered = true; 1122 gcc_assert (!any_numbered); 1123 } 1124 gcc_assert (argno < PP_NL_ARGMAX); 1125 gcc_assert (!formatters[argno]); 1126 formatters[argno] = &args[chunk]; 1127 do 1128 { 1129 obstack_1grow (&buffer->chunk_obstack, *p); 1130 p++; 1131 } 1132 while (strchr ("qwl+#", p[-1])); 1133 1134 if (p[-1] == '.') 1135 { 1136 /* We handle '%.Ns' and '%.*s' or '%M$.*N$s' 1137 (where M == N + 1). */ 1138 if (ISDIGIT (*p)) 1139 { 1140 do 1141 { 1142 obstack_1grow (&buffer->chunk_obstack, *p); 1143 p++; 1144 } 1145 while (ISDIGIT (p[-1])); 1146 gcc_assert (p[-1] == 's'); 1147 } 1148 else 1149 { 1150 gcc_assert (*p == '*'); 1151 obstack_1grow (&buffer->chunk_obstack, '*'); 1152 p++; 1153 1154 if (ISDIGIT (*p)) 1155 { 1156 char *end; 1157 unsigned int argno2 = strtoul (p, &end, 10) - 1; 1158 p = end; 1159 gcc_assert (argno2 == argno - 1); 1160 gcc_assert (!any_unnumbered); 1161 gcc_assert (*p == '$'); 1162 1163 p++; 1164 formatters[argno2] = formatters[argno]; 1165 } 1166 else 1167 { 1168 gcc_assert (!any_numbered); 1169 formatters[argno+1] = formatters[argno]; 1170 curarg++; 1171 } 1172 gcc_assert (*p == 's'); 1173 obstack_1grow (&buffer->chunk_obstack, 's'); 1174 p++; 1175 } 1176 } 1177 if (*p == '\0') 1178 break; 1179 1180 obstack_1grow (&buffer->chunk_obstack, '\0'); 1181 gcc_assert (chunk < PP_NL_ARGMAX * 2); 1182 args[chunk++] = XOBFINISH (&buffer->chunk_obstack, const char *); 1183 } 1184 1185 obstack_1grow (&buffer->chunk_obstack, '\0'); 1186 gcc_assert (chunk < PP_NL_ARGMAX * 2); 1187 args[chunk++] = XOBFINISH (&buffer->chunk_obstack, const char *); 1188 args[chunk] = 0; 1189 1190 /* Set output to the argument obstack, and switch line-wrapping and 1191 prefixing off. */ 1192 buffer->obstack = &buffer->chunk_obstack; 1193 old_wrapping_mode = pp_set_verbatim_wrapping (pp); 1194 1195 /* Second phase. Replace each formatter with the formatted text it 1196 corresponds to. */ 1197 1198 for (argno = 0; formatters[argno]; argno++) 1199 { 1200 int precision = 0; 1201 bool wide = false; 1202 bool plus = false; 1203 bool hash = false; 1204 bool quote = false; 1205 1206 /* We do not attempt to enforce any ordering on the modifier 1207 characters. */ 1208 1209 for (p = *formatters[argno];; p++) 1210 { 1211 switch (*p) 1212 { 1213 case 'q': 1214 gcc_assert (!quote); 1215 quote = true; 1216 continue; 1217 1218 case '+': 1219 gcc_assert (!plus); 1220 plus = true; 1221 continue; 1222 1223 case '#': 1224 gcc_assert (!hash); 1225 hash = true; 1226 continue; 1227 1228 case 'w': 1229 gcc_assert (!wide); 1230 wide = true; 1231 continue; 1232 1233 case 'l': 1234 /* We don't support precision beyond that of "long long". */ 1235 gcc_assert (precision < 2); 1236 precision++; 1237 continue; 1238 } 1239 break; 1240 } 1241 1242 gcc_assert (!wide || precision == 0); 1243 1244 if (quote) 1245 pp_begin_quote (pp, pp_show_color (pp)); 1246 1247 switch (*p) 1248 { 1249 case 'r': 1250 pp_string (pp, colorize_start (pp_show_color (pp), 1251 va_arg (*text->args_ptr, 1252 const char *))); 1253 break; 1254 1255 case 'c': 1256 { 1257 /* When quoting, print alphanumeric, punctuation, and the space 1258 character unchanged, and all others in hexadecimal with the 1259 "\x" prefix. Otherwise print them all unchanged. */ 1260 int chr = va_arg (*text->args_ptr, int); 1261 if (ISPRINT (chr) || !quote) 1262 pp_character (pp, chr); 1263 else 1264 { 1265 const char str [2] = { chr, '\0' }; 1266 pp_quoted_string (pp, str, 1); 1267 } 1268 break; 1269 } 1270 1271 case 'd': 1272 case 'i': 1273 if (wide) 1274 pp_wide_integer (pp, va_arg (*text->args_ptr, HOST_WIDE_INT)); 1275 else 1276 pp_integer_with_precision 1277 (pp, *text->args_ptr, precision, int, "d"); 1278 break; 1279 1280 case 'o': 1281 if (wide) 1282 pp_scalar (pp, "%" HOST_WIDE_INT_PRINT "o", 1283 va_arg (*text->args_ptr, unsigned HOST_WIDE_INT)); 1284 else 1285 pp_integer_with_precision 1286 (pp, *text->args_ptr, precision, unsigned, "o"); 1287 break; 1288 1289 case 's': 1290 if (quote) 1291 pp_quoted_string (pp, va_arg (*text->args_ptr, const char *)); 1292 else 1293 pp_string (pp, va_arg (*text->args_ptr, const char *)); 1294 break; 1295 1296 case 'p': 1297 pp_pointer (pp, va_arg (*text->args_ptr, void *)); 1298 break; 1299 1300 case 'u': 1301 if (wide) 1302 pp_scalar (pp, HOST_WIDE_INT_PRINT_UNSIGNED, 1303 va_arg (*text->args_ptr, unsigned HOST_WIDE_INT)); 1304 else 1305 pp_integer_with_precision 1306 (pp, *text->args_ptr, precision, unsigned, "u"); 1307 break; 1308 1309 case 'Z': 1310 { 1311 int *v = va_arg (*text->args_ptr, int *); 1312 unsigned len = va_arg (*text->args_ptr, unsigned); 1313 1314 for (unsigned i = 0; i < len; ++i) 1315 { 1316 pp_scalar (pp, "%i", v[i]); 1317 if (i < len - 1) 1318 { 1319 pp_comma (pp); 1320 pp_space (pp); 1321 } 1322 } 1323 break; 1324 } 1325 1326 case 'x': 1327 if (wide) 1328 pp_scalar (pp, HOST_WIDE_INT_PRINT_HEX, 1329 va_arg (*text->args_ptr, unsigned HOST_WIDE_INT)); 1330 else 1331 pp_integer_with_precision 1332 (pp, *text->args_ptr, precision, unsigned, "x"); 1333 break; 1334 1335 case '.': 1336 { 1337 int n; 1338 const char *s; 1339 1340 /* We handle '%.Ns' and '%.*s' or '%M$.*N$s' 1341 (where M == N + 1). The format string should be verified 1342 already from the first phase. */ 1343 p++; 1344 if (ISDIGIT (*p)) 1345 { 1346 char *end; 1347 n = strtoul (p, &end, 10); 1348 p = end; 1349 gcc_assert (*p == 's'); 1350 } 1351 else 1352 { 1353 gcc_assert (*p == '*'); 1354 p++; 1355 gcc_assert (*p == 's'); 1356 n = va_arg (*text->args_ptr, int); 1357 1358 /* This consumes a second entry in the formatters array. */ 1359 gcc_assert (formatters[argno] == formatters[argno+1]); 1360 argno++; 1361 } 1362 1363 s = va_arg (*text->args_ptr, const char *); 1364 1365 /* Append the lesser of precision and strlen (s) characters 1366 from the array (which need not be a nul-terminated string). 1367 Negative precision is treated as if it were omitted. */ 1368 size_t len = n < 0 ? strlen (s) : strnlen (s, n); 1369 1370 pp_append_text (pp, s, s + len); 1371 } 1372 break; 1373 1374 default: 1375 { 1376 bool ok; 1377 1378 /* Call the format decoder. 1379 Pass the address of "quote" so that format decoders can 1380 potentially disable printing of the closing quote 1381 (e.g. when printing "'TYPEDEF' aka 'TYPE'" in the C family 1382 of frontends). */ 1383 gcc_assert (pp_format_decoder (pp)); 1384 ok = pp_format_decoder (pp) (pp, text, p, 1385 precision, wide, plus, hash, "e, 1386 formatters[argno]); 1387 gcc_assert (ok); 1388 } 1389 } 1390 1391 if (quote) 1392 pp_end_quote (pp, pp_show_color (pp)); 1393 1394 obstack_1grow (&buffer->chunk_obstack, '\0'); 1395 *formatters[argno] = XOBFINISH (&buffer->chunk_obstack, const char *); 1396 } 1397 1398 if (CHECKING_P) 1399 for (; argno < PP_NL_ARGMAX; argno++) 1400 gcc_assert (!formatters[argno]); 1401 1402 /* If the client supplied a postprocessing object, call its "handle" 1403 hook here. */ 1404 if (pp->m_format_postprocessor) 1405 pp->m_format_postprocessor->handle (pp); 1406 1407 /* Revert to normal obstack and wrapping mode. */ 1408 buffer->obstack = &buffer->formatted_obstack; 1409 buffer->line_length = 0; 1410 pp_wrapping_mode (pp) = old_wrapping_mode; 1411 pp_clear_state (pp); 1412 } 1413 1414 /* Format of a message pointed to by TEXT. */ 1415 void 1416 pp_output_formatted_text (pretty_printer *pp) 1417 { 1418 unsigned int chunk; 1419 output_buffer *buffer = pp_buffer (pp); 1420 struct chunk_info *chunk_array = buffer->cur_chunk_array; 1421 const char **args = chunk_array->args; 1422 1423 gcc_assert (buffer->obstack == &buffer->formatted_obstack); 1424 gcc_assert (buffer->line_length == 0); 1425 1426 /* This is a third phase, first 2 phases done in pp_format_args. 1427 Now we actually print it. */ 1428 for (chunk = 0; args[chunk]; chunk++) 1429 pp_string (pp, args[chunk]); 1430 1431 /* Deallocate the chunk structure and everything after it (i.e. the 1432 associated series of formatted strings). */ 1433 buffer->cur_chunk_array = chunk_array->prev; 1434 obstack_free (&buffer->chunk_obstack, chunk_array); 1435 } 1436 1437 /* Helper subroutine of output_verbatim and verbatim. Do the appropriate 1438 settings needed by BUFFER for a verbatim formatting. */ 1439 void 1440 pp_format_verbatim (pretty_printer *pp, text_info *text) 1441 { 1442 /* Set verbatim mode. */ 1443 pp_wrapping_mode_t oldmode = pp_set_verbatim_wrapping (pp); 1444 1445 /* Do the actual formatting. */ 1446 pp_format (pp, text); 1447 pp_output_formatted_text (pp); 1448 1449 /* Restore previous settings. */ 1450 pp_wrapping_mode (pp) = oldmode; 1451 } 1452 1453 /* Flush the content of BUFFER onto the attached stream. This 1454 function does nothing unless pp->output_buffer->flush_p. */ 1455 void 1456 pp_flush (pretty_printer *pp) 1457 { 1458 pp_clear_state (pp); 1459 if (!pp->buffer->flush_p) 1460 return; 1461 pp_write_text_to_stream (pp); 1462 fflush (pp_buffer (pp)->stream); 1463 } 1464 1465 /* Flush the content of BUFFER onto the attached stream independently 1466 of the value of pp->output_buffer->flush_p. */ 1467 void 1468 pp_really_flush (pretty_printer *pp) 1469 { 1470 pp_clear_state (pp); 1471 pp_write_text_to_stream (pp); 1472 fflush (pp_buffer (pp)->stream); 1473 } 1474 1475 /* Sets the number of maximum characters per line PRETTY-PRINTER can 1476 output in line-wrapping mode. A LENGTH value 0 suppresses 1477 line-wrapping. */ 1478 void 1479 pp_set_line_maximum_length (pretty_printer *pp, int length) 1480 { 1481 pp_line_cutoff (pp) = length; 1482 pp_set_real_maximum_length (pp); 1483 } 1484 1485 /* Clear PRETTY-PRINTER output area text info. */ 1486 void 1487 pp_clear_output_area (pretty_printer *pp) 1488 { 1489 obstack_free (pp_buffer (pp)->obstack, 1490 obstack_base (pp_buffer (pp)->obstack)); 1491 pp_buffer (pp)->line_length = 0; 1492 } 1493 1494 /* Set PREFIX for PRETTY-PRINTER, taking ownership of PREFIX, which 1495 will eventually be free-ed. */ 1496 1497 void 1498 pp_set_prefix (pretty_printer *pp, char *prefix) 1499 { 1500 free (pp->prefix); 1501 pp->prefix = prefix; 1502 pp_set_real_maximum_length (pp); 1503 pp->emitted_prefix = false; 1504 pp_indentation (pp) = 0; 1505 } 1506 1507 /* Take ownership of PP's prefix, setting it to NULL. 1508 This allows clients to save, overide, and then restore an existing 1509 prefix, without it being free-ed. */ 1510 1511 char * 1512 pp_take_prefix (pretty_printer *pp) 1513 { 1514 char *result = pp->prefix; 1515 pp->prefix = NULL; 1516 return result; 1517 } 1518 1519 /* Free PRETTY-PRINTER's prefix, a previously malloc()'d string. */ 1520 void 1521 pp_destroy_prefix (pretty_printer *pp) 1522 { 1523 if (pp->prefix != NULL) 1524 { 1525 free (pp->prefix); 1526 pp->prefix = NULL; 1527 } 1528 } 1529 1530 /* Write out PRETTY-PRINTER's prefix. */ 1531 void 1532 pp_emit_prefix (pretty_printer *pp) 1533 { 1534 if (pp->prefix != NULL) 1535 { 1536 switch (pp_prefixing_rule (pp)) 1537 { 1538 default: 1539 case DIAGNOSTICS_SHOW_PREFIX_NEVER: 1540 break; 1541 1542 case DIAGNOSTICS_SHOW_PREFIX_ONCE: 1543 if (pp->emitted_prefix) 1544 { 1545 pp_indent (pp); 1546 break; 1547 } 1548 pp_indentation (pp) += 3; 1549 /* Fall through. */ 1550 1551 case DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE: 1552 { 1553 int prefix_length = strlen (pp->prefix); 1554 pp_append_r (pp, pp->prefix, prefix_length); 1555 pp->emitted_prefix = true; 1556 } 1557 break; 1558 } 1559 } 1560 } 1561 1562 /* Construct a PRETTY-PRINTER of MAXIMUM_LENGTH characters per line. */ 1563 1564 pretty_printer::pretty_printer (int maximum_length) 1565 : buffer (new (XCNEW (output_buffer)) output_buffer ()), 1566 prefix (), 1567 padding (pp_none), 1568 maximum_length (), 1569 indent_skip (), 1570 wrapping (), 1571 format_decoder (), 1572 m_format_postprocessor (NULL), 1573 emitted_prefix (), 1574 need_newline (), 1575 translate_identifiers (true), 1576 show_color () 1577 { 1578 pp_line_cutoff (this) = maximum_length; 1579 /* By default, we emit prefixes once per message. */ 1580 pp_prefixing_rule (this) = DIAGNOSTICS_SHOW_PREFIX_ONCE; 1581 pp_set_prefix (this, NULL); 1582 } 1583 1584 pretty_printer::~pretty_printer () 1585 { 1586 if (m_format_postprocessor) 1587 delete m_format_postprocessor; 1588 buffer->~output_buffer (); 1589 XDELETE (buffer); 1590 free (prefix); 1591 } 1592 1593 /* Append a string delimited by START and END to the output area of 1594 PRETTY-PRINTER. No line wrapping is done. However, if beginning a 1595 new line then emit PRETTY-PRINTER's prefix and skip any leading 1596 whitespace if appropriate. The caller must ensure that it is 1597 safe to do so. */ 1598 void 1599 pp_append_text (pretty_printer *pp, const char *start, const char *end) 1600 { 1601 /* Emit prefix and skip whitespace if we're starting a new line. */ 1602 if (pp_buffer (pp)->line_length == 0) 1603 { 1604 pp_emit_prefix (pp); 1605 if (pp_is_wrapping_line (pp)) 1606 while (start != end && *start == ' ') 1607 ++start; 1608 } 1609 pp_append_r (pp, start, end - start); 1610 } 1611 1612 /* Finishes constructing a NULL-terminated character string representing 1613 the PRETTY-PRINTED text. */ 1614 const char * 1615 pp_formatted_text (pretty_printer *pp) 1616 { 1617 return output_buffer_formatted_text (pp_buffer (pp)); 1618 } 1619 1620 /* Return a pointer to the last character emitted in PRETTY-PRINTER's 1621 output area. A NULL pointer means no character available. */ 1622 const char * 1623 pp_last_position_in_text (const pretty_printer *pp) 1624 { 1625 return output_buffer_last_position_in_text (pp_buffer (pp)); 1626 } 1627 1628 /* Return the amount of characters PRETTY-PRINTER can accept to 1629 make a full line. Meaningful only in line-wrapping mode. */ 1630 int 1631 pp_remaining_character_count_for_line (pretty_printer *pp) 1632 { 1633 return pp->maximum_length - pp_buffer (pp)->line_length; 1634 } 1635 1636 1637 /* Format a message into BUFFER a la printf. */ 1638 void 1639 pp_printf (pretty_printer *pp, const char *msg, ...) 1640 { 1641 text_info text; 1642 va_list ap; 1643 1644 va_start (ap, msg); 1645 text.err_no = errno; 1646 text.args_ptr = ≈ 1647 text.format_spec = msg; 1648 pp_format (pp, &text); 1649 pp_output_formatted_text (pp); 1650 va_end (ap); 1651 } 1652 1653 1654 /* Output MESSAGE verbatim into BUFFER. */ 1655 void 1656 pp_verbatim (pretty_printer *pp, const char *msg, ...) 1657 { 1658 text_info text; 1659 va_list ap; 1660 1661 va_start (ap, msg); 1662 text.err_no = errno; 1663 text.args_ptr = ≈ 1664 text.format_spec = msg; 1665 pp_format_verbatim (pp, &text); 1666 va_end (ap); 1667 } 1668 1669 1670 1671 /* Have PRETTY-PRINTER start a new line. */ 1672 void 1673 pp_newline (pretty_printer *pp) 1674 { 1675 obstack_1grow (pp_buffer (pp)->obstack, '\n'); 1676 pp_needs_newline (pp) = false; 1677 pp_buffer (pp)->line_length = 0; 1678 } 1679 1680 /* Have PRETTY-PRINTER add a CHARACTER. */ 1681 void 1682 pp_character (pretty_printer *pp, int c) 1683 { 1684 if (pp_is_wrapping_line (pp) 1685 && pp_remaining_character_count_for_line (pp) <= 0) 1686 { 1687 pp_newline (pp); 1688 if (ISSPACE (c)) 1689 return; 1690 } 1691 obstack_1grow (pp_buffer (pp)->obstack, c); 1692 ++pp_buffer (pp)->line_length; 1693 } 1694 1695 /* Append a STRING to the output area of PRETTY-PRINTER; the STRING may 1696 be line-wrapped if in appropriate mode. */ 1697 void 1698 pp_string (pretty_printer *pp, const char *str) 1699 { 1700 gcc_checking_assert (str); 1701 pp_maybe_wrap_text (pp, str, str + strlen (str)); 1702 } 1703 1704 /* Append the leading N characters of STRING to the output area of 1705 PRETTY-PRINTER, quoting in hexadecimal non-printable characters. 1706 Setting N = -1 is as if N were set to strlen (STRING). The STRING 1707 may be line-wrapped if in appropriate mode. */ 1708 static void 1709 pp_quoted_string (pretty_printer *pp, const char *str, size_t n /* = -1 */) 1710 { 1711 gcc_checking_assert (str); 1712 1713 const char *last = str; 1714 const char *ps; 1715 1716 /* Compute the length if not specified. */ 1717 if (n == (size_t) -1) 1718 n = strlen (str); 1719 1720 for (ps = str; n; ++ps, --n) 1721 { 1722 if (ISPRINT (*ps)) 1723 continue; 1724 1725 if (last < ps) 1726 pp_maybe_wrap_text (pp, last, ps - 1); 1727 1728 /* Append the hexadecimal value of the character. Allocate a buffer 1729 that's large enough for a 32-bit char plus the hex prefix. */ 1730 char buf [11]; 1731 int n = sprintf (buf, "\\x%02x", (unsigned char)*ps); 1732 pp_maybe_wrap_text (pp, buf, buf + n); 1733 last = ps + 1; 1734 } 1735 1736 pp_maybe_wrap_text (pp, last, ps); 1737 } 1738 1739 /* Maybe print out a whitespace if needed. */ 1740 1741 void 1742 pp_maybe_space (pretty_printer *pp) 1743 { 1744 if (pp->padding != pp_none) 1745 { 1746 pp_space (pp); 1747 pp->padding = pp_none; 1748 } 1749 } 1750 1751 // Add a newline to the pretty printer PP and flush formatted text. 1752 1753 void 1754 pp_newline_and_flush (pretty_printer *pp) 1755 { 1756 pp_newline (pp); 1757 pp_flush (pp); 1758 pp_needs_newline (pp) = false; 1759 } 1760 1761 // Add a newline to the pretty printer PP, followed by indentation. 1762 1763 void 1764 pp_newline_and_indent (pretty_printer *pp, int n) 1765 { 1766 pp_indentation (pp) += n; 1767 pp_newline (pp); 1768 pp_indent (pp); 1769 pp_needs_newline (pp) = false; 1770 } 1771 1772 // Add separator C, followed by a single whitespace. 1773 1774 void 1775 pp_separate_with (pretty_printer *pp, char c) 1776 { 1777 pp_character (pp, c); 1778 pp_space (pp); 1779 } 1780 1781 /* Add a localized open quote, and if SHOW_COLOR is true, begin colorizing 1782 using the "quote" color. */ 1783 1784 void 1785 pp_begin_quote (pretty_printer *pp, bool show_color) 1786 { 1787 pp_string (pp, open_quote); 1788 pp_string (pp, colorize_start (show_color, "quote")); 1789 } 1790 1791 /* If SHOW_COLOR is true, stop colorizing. 1792 Add a localized close quote. */ 1793 1794 void 1795 pp_end_quote (pretty_printer *pp, bool show_color) 1796 { 1797 pp_string (pp, colorize_stop (show_color)); 1798 pp_string (pp, close_quote); 1799 } 1800 1801 1802 /* The string starting at P has LEN (at least 1) bytes left; if they 1803 start with a valid UTF-8 sequence, return the length of that 1804 sequence and set *VALUE to the value of that sequence, and 1805 otherwise return 0 and set *VALUE to (unsigned int) -1. */ 1806 1807 static int 1808 decode_utf8_char (const unsigned char *p, size_t len, unsigned int *value) 1809 { 1810 unsigned int t = *p; 1811 1812 if (len == 0) 1813 abort (); 1814 if (t & 0x80) 1815 { 1816 size_t utf8_len = 0; 1817 unsigned int ch; 1818 size_t i; 1819 for (t = *p; t & 0x80; t <<= 1) 1820 utf8_len++; 1821 1822 if (utf8_len > len || utf8_len < 2 || utf8_len > 6) 1823 { 1824 *value = (unsigned int) -1; 1825 return 0; 1826 } 1827 ch = *p & ((1 << (7 - utf8_len)) - 1); 1828 for (i = 1; i < utf8_len; i++) 1829 { 1830 unsigned int u = p[i]; 1831 if ((u & 0xC0) != 0x80) 1832 { 1833 *value = (unsigned int) -1; 1834 return 0; 1835 } 1836 ch = (ch << 6) | (u & 0x3F); 1837 } 1838 if ( (ch <= 0x7F && utf8_len > 1) 1839 || (ch <= 0x7FF && utf8_len > 2) 1840 || (ch <= 0xFFFF && utf8_len > 3) 1841 || (ch <= 0x1FFFFF && utf8_len > 4) 1842 || (ch <= 0x3FFFFFF && utf8_len > 5) 1843 || (ch >= 0xD800 && ch <= 0xDFFF)) 1844 { 1845 *value = (unsigned int) -1; 1846 return 0; 1847 } 1848 *value = ch; 1849 return utf8_len; 1850 } 1851 else 1852 { 1853 *value = t; 1854 return 1; 1855 } 1856 } 1857 1858 /* Allocator for identifier_to_locale and corresponding function to 1859 free memory. */ 1860 1861 void *(*identifier_to_locale_alloc) (size_t) = xmalloc; 1862 void (*identifier_to_locale_free) (void *) = free; 1863 1864 /* Given IDENT, an identifier in the internal encoding, return a 1865 version of IDENT suitable for diagnostics in the locale character 1866 set: either IDENT itself, or a string, allocated using 1867 identifier_to_locale_alloc, converted to the locale character set 1868 and using escape sequences if not representable in the locale 1869 character set or containing control characters or invalid byte 1870 sequences. Existing backslashes in IDENT are not doubled, so the 1871 result may not uniquely specify the contents of an arbitrary byte 1872 sequence identifier. */ 1873 1874 const char * 1875 identifier_to_locale (const char *ident) 1876 { 1877 const unsigned char *uid = (const unsigned char *) ident; 1878 size_t idlen = strlen (ident); 1879 bool valid_printable_utf8 = true; 1880 bool all_ascii = true; 1881 size_t i; 1882 1883 for (i = 0; i < idlen;) 1884 { 1885 unsigned int c; 1886 size_t utf8_len = decode_utf8_char (&uid[i], idlen - i, &c); 1887 if (utf8_len == 0 || c <= 0x1F || (c >= 0x7F && c <= 0x9F)) 1888 { 1889 valid_printable_utf8 = false; 1890 break; 1891 } 1892 if (utf8_len > 1) 1893 all_ascii = false; 1894 i += utf8_len; 1895 } 1896 1897 /* If IDENT contains invalid UTF-8 sequences (which may occur with 1898 attributes putting arbitrary byte sequences in identifiers), or 1899 control characters, we use octal escape sequences for all bytes 1900 outside printable ASCII. */ 1901 if (!valid_printable_utf8) 1902 { 1903 char *ret = (char *) identifier_to_locale_alloc (4 * idlen + 1); 1904 char *p = ret; 1905 for (i = 0; i < idlen; i++) 1906 { 1907 if (uid[i] > 0x1F && uid[i] < 0x7F) 1908 *p++ = uid[i]; 1909 else 1910 { 1911 sprintf (p, "\\%03o", uid[i]); 1912 p += 4; 1913 } 1914 } 1915 *p = 0; 1916 return ret; 1917 } 1918 1919 /* Otherwise, if it is valid printable ASCII, or printable UTF-8 1920 with the locale character set being UTF-8, IDENT is used. */ 1921 if (all_ascii || locale_utf8) 1922 return ident; 1923 1924 /* Otherwise IDENT is converted to the locale character set if 1925 possible. */ 1926 #if defined ENABLE_NLS && defined HAVE_LANGINFO_CODESET && HAVE_ICONV 1927 if (locale_encoding != NULL) 1928 { 1929 iconv_t cd = iconv_open (locale_encoding, "UTF-8"); 1930 bool conversion_ok = true; 1931 char *ret = NULL; 1932 if (cd != (iconv_t) -1) 1933 { 1934 size_t ret_alloc = 4 * idlen + 1; 1935 for (;;) 1936 { 1937 /* Repeat the whole conversion process as needed with 1938 larger buffers so non-reversible transformations can 1939 always be detected. */ 1940 ICONV_CONST char *inbuf = CONST_CAST (char *, ident); 1941 char *outbuf; 1942 size_t inbytesleft = idlen; 1943 size_t outbytesleft = ret_alloc - 1; 1944 size_t iconv_ret; 1945 1946 ret = (char *) identifier_to_locale_alloc (ret_alloc); 1947 outbuf = ret; 1948 1949 if (iconv (cd, 0, 0, 0, 0) == (size_t) -1) 1950 { 1951 conversion_ok = false; 1952 break; 1953 } 1954 1955 iconv_ret = iconv (cd, &inbuf, &inbytesleft, 1956 &outbuf, &outbytesleft); 1957 if (iconv_ret == (size_t) -1 || inbytesleft != 0) 1958 { 1959 if (errno == E2BIG) 1960 { 1961 ret_alloc *= 2; 1962 identifier_to_locale_free (ret); 1963 ret = NULL; 1964 continue; 1965 } 1966 else 1967 { 1968 conversion_ok = false; 1969 break; 1970 } 1971 } 1972 else if (iconv_ret != 0) 1973 { 1974 conversion_ok = false; 1975 break; 1976 } 1977 /* Return to initial shift state. */ 1978 if (iconv (cd, 0, 0, &outbuf, &outbytesleft) == (size_t) -1) 1979 { 1980 if (errno == E2BIG) 1981 { 1982 ret_alloc *= 2; 1983 identifier_to_locale_free (ret); 1984 ret = NULL; 1985 continue; 1986 } 1987 else 1988 { 1989 conversion_ok = false; 1990 break; 1991 } 1992 } 1993 *outbuf = 0; 1994 break; 1995 } 1996 iconv_close (cd); 1997 if (conversion_ok) 1998 return ret; 1999 } 2000 } 2001 #endif 2002 2003 /* Otherwise, convert non-ASCII characters in IDENT to UCNs. */ 2004 { 2005 char *ret = (char *) identifier_to_locale_alloc (10 * idlen + 1); 2006 char *p = ret; 2007 for (i = 0; i < idlen;) 2008 { 2009 unsigned int c; 2010 size_t utf8_len = decode_utf8_char (&uid[i], idlen - i, &c); 2011 if (utf8_len == 1) 2012 *p++ = uid[i]; 2013 else 2014 { 2015 sprintf (p, "\\U%08x", c); 2016 p += 10; 2017 } 2018 i += utf8_len; 2019 } 2020 *p = 0; 2021 return ret; 2022 } 2023 } 2024 2025 #if CHECKING_P 2026 2027 namespace selftest { 2028 2029 /* Smoketest for pretty_printer. */ 2030 2031 static void 2032 test_basic_printing () 2033 { 2034 pretty_printer pp; 2035 pp_string (&pp, "hello"); 2036 pp_space (&pp); 2037 pp_string (&pp, "world"); 2038 2039 ASSERT_STREQ ("hello world", pp_formatted_text (&pp)); 2040 } 2041 2042 /* Helper function for testing pp_format. 2043 Verify that pp_format (FMT, ...) followed by pp_output_formatted_text 2044 prints EXPECTED, assuming that pp_show_color is SHOW_COLOR. */ 2045 2046 static void 2047 assert_pp_format_va (const location &loc, const char *expected, 2048 bool show_color, const char *fmt, va_list *ap) 2049 { 2050 pretty_printer pp; 2051 text_info ti; 2052 rich_location rich_loc (line_table, UNKNOWN_LOCATION); 2053 2054 ti.format_spec = fmt; 2055 ti.args_ptr = ap; 2056 ti.err_no = 0; 2057 ti.x_data = NULL; 2058 ti.m_richloc = &rich_loc; 2059 2060 pp_show_color (&pp) = show_color; 2061 pp_format (&pp, &ti); 2062 pp_output_formatted_text (&pp); 2063 ASSERT_STREQ_AT (loc, expected, pp_formatted_text (&pp)); 2064 } 2065 2066 /* Verify that pp_format (FMT, ...) followed by pp_output_formatted_text 2067 prints EXPECTED, with show_color disabled. */ 2068 2069 static void 2070 assert_pp_format (const location &loc, const char *expected, 2071 const char *fmt, ...) 2072 { 2073 va_list ap; 2074 2075 va_start (ap, fmt); 2076 assert_pp_format_va (loc, expected, false, fmt, &ap); 2077 va_end (ap); 2078 } 2079 2080 /* As above, but with colorization enabled. */ 2081 2082 static void 2083 assert_pp_format_colored (const location &loc, const char *expected, 2084 const char *fmt, ...) 2085 { 2086 /* The tests of colorization assume the default color scheme. 2087 If GCC_COLORS is set, then the colors have potentially been 2088 overridden; skip the test. */ 2089 if (getenv ("GCC_COLORS")) 2090 return; 2091 2092 va_list ap; 2093 2094 va_start (ap, fmt); 2095 assert_pp_format_va (loc, expected, true, fmt, &ap); 2096 va_end (ap); 2097 } 2098 2099 /* Helper function for calling testing pp_format, 2100 by calling assert_pp_format with various numbers of arguments. 2101 These exist mostly to avoid having to write SELFTEST_LOCATION 2102 throughout test_pp_format. */ 2103 2104 #define ASSERT_PP_FORMAT_1(EXPECTED, FMT, ARG1) \ 2105 SELFTEST_BEGIN_STMT \ 2106 assert_pp_format ((SELFTEST_LOCATION), (EXPECTED), (FMT), \ 2107 (ARG1)); \ 2108 SELFTEST_END_STMT 2109 2110 #define ASSERT_PP_FORMAT_2(EXPECTED, FMT, ARG1, ARG2) \ 2111 SELFTEST_BEGIN_STMT \ 2112 assert_pp_format ((SELFTEST_LOCATION), (EXPECTED), (FMT), \ 2113 (ARG1), (ARG2)); \ 2114 SELFTEST_END_STMT 2115 2116 #define ASSERT_PP_FORMAT_3(EXPECTED, FMT, ARG1, ARG2, ARG3) \ 2117 SELFTEST_BEGIN_STMT \ 2118 assert_pp_format ((SELFTEST_LOCATION), (EXPECTED), (FMT), \ 2119 (ARG1), (ARG2), (ARG3)); \ 2120 SELFTEST_END_STMT 2121 2122 /* Verify that pp_format works, for various format codes. */ 2123 2124 static void 2125 test_pp_format () 2126 { 2127 /* Avoid introducing locale-specific differences in the results 2128 by hardcoding open_quote and close_quote. */ 2129 const char *old_open_quote = open_quote; 2130 const char *old_close_quote = close_quote; 2131 open_quote = "`"; 2132 close_quote = "'"; 2133 2134 /* Verify that plain text is passed through unchanged. */ 2135 assert_pp_format (SELFTEST_LOCATION, "unformatted", "unformatted"); 2136 2137 /* Verify various individual format codes, in the order listed in the 2138 comment for pp_format above. For each code, we append a second 2139 argument with a known bit pattern (0x12345678), to ensure that we 2140 are consuming arguments correctly. */ 2141 ASSERT_PP_FORMAT_2 ("-27 12345678", "%d %x", -27, 0x12345678); 2142 ASSERT_PP_FORMAT_2 ("-5 12345678", "%i %x", -5, 0x12345678); 2143 ASSERT_PP_FORMAT_2 ("10 12345678", "%u %x", 10, 0x12345678); 2144 ASSERT_PP_FORMAT_2 ("17 12345678", "%o %x", 15, 0x12345678); 2145 ASSERT_PP_FORMAT_2 ("cafebabe 12345678", "%x %x", 0xcafebabe, 0x12345678); 2146 ASSERT_PP_FORMAT_2 ("-27 12345678", "%ld %x", (long)-27, 0x12345678); 2147 ASSERT_PP_FORMAT_2 ("-5 12345678", "%li %x", (long)-5, 0x12345678); 2148 ASSERT_PP_FORMAT_2 ("10 12345678", "%lu %x", (long)10, 0x12345678); 2149 ASSERT_PP_FORMAT_2 ("17 12345678", "%lo %x", (long)15, 0x12345678); 2150 ASSERT_PP_FORMAT_2 ("cafebabe 12345678", "%lx %x", (long)0xcafebabe, 2151 0x12345678); 2152 ASSERT_PP_FORMAT_2 ("-27 12345678", "%lld %x", (long long)-27, 0x12345678); 2153 ASSERT_PP_FORMAT_2 ("-5 12345678", "%lli %x", (long long)-5, 0x12345678); 2154 ASSERT_PP_FORMAT_2 ("10 12345678", "%llu %x", (long long)10, 0x12345678); 2155 ASSERT_PP_FORMAT_2 ("17 12345678", "%llo %x", (long long)15, 0x12345678); 2156 ASSERT_PP_FORMAT_2 ("cafebabe 12345678", "%llx %x", (long long)0xcafebabe, 2157 0x12345678); 2158 ASSERT_PP_FORMAT_2 ("-27 12345678", "%wd %x", (HOST_WIDE_INT)-27, 0x12345678); 2159 ASSERT_PP_FORMAT_2 ("-5 12345678", "%wi %x", (HOST_WIDE_INT)-5, 0x12345678); 2160 ASSERT_PP_FORMAT_2 ("10 12345678", "%wu %x", (unsigned HOST_WIDE_INT)10, 2161 0x12345678); 2162 ASSERT_PP_FORMAT_2 ("17 12345678", "%wo %x", (HOST_WIDE_INT)15, 0x12345678); 2163 ASSERT_PP_FORMAT_2 ("0xcafebabe 12345678", "%wx %x", (HOST_WIDE_INT)0xcafebabe, 2164 0x12345678); 2165 ASSERT_PP_FORMAT_2 ("A 12345678", "%c %x", 'A', 0x12345678); 2166 ASSERT_PP_FORMAT_2 ("hello world 12345678", "%s %x", "hello world", 2167 0x12345678); 2168 2169 /* Not nul-terminated. */ 2170 char arr[5] = { '1', '2', '3', '4', '5' }; 2171 ASSERT_PP_FORMAT_3 ("123 12345678", "%.*s %x", 3, arr, 0x12345678); 2172 ASSERT_PP_FORMAT_3 ("1234 12345678", "%.*s %x", -1, "1234", 0x12345678); 2173 ASSERT_PP_FORMAT_3 ("12345 12345678", "%.*s %x", 7, "12345", 0x12345678); 2174 2175 /* We can't test for %p; the pointer is printed in an implementation-defined 2176 manner. */ 2177 ASSERT_PP_FORMAT_2 ("normal colored normal 12345678", 2178 "normal %rcolored%R normal %x", 2179 "error", 0x12345678); 2180 assert_pp_format_colored 2181 (SELFTEST_LOCATION, 2182 "normal \33[01;31m\33[Kcolored\33[m\33[K normal 12345678", 2183 "normal %rcolored%R normal %x", "error", 0x12345678); 2184 /* TODO: 2185 %m: strerror(text->err_no) - does not consume a value from args_ptr. */ 2186 ASSERT_PP_FORMAT_1 ("% 12345678", "%% %x", 0x12345678); 2187 ASSERT_PP_FORMAT_1 ("` 12345678", "%< %x", 0x12345678); 2188 ASSERT_PP_FORMAT_1 ("' 12345678", "%> %x", 0x12345678); 2189 ASSERT_PP_FORMAT_1 ("' 12345678", "%' %x", 0x12345678); 2190 ASSERT_PP_FORMAT_3 ("abc 12345678", "%.*s %x", 3, "abcdef", 0x12345678); 2191 ASSERT_PP_FORMAT_2 ("abc 12345678", "%.3s %x", "abcdef", 0x12345678); 2192 2193 /* Verify flag 'q'. */ 2194 ASSERT_PP_FORMAT_2 ("`foo' 12345678", "%qs %x", "foo", 0x12345678); 2195 assert_pp_format_colored (SELFTEST_LOCATION, 2196 "`\33[01m\33[Kfoo\33[m\33[K' 12345678", "%qs %x", 2197 "foo", 0x12345678); 2198 2199 /* Verify %Z. */ 2200 int v[] = { 1, 2, 3 }; 2201 ASSERT_PP_FORMAT_3 ("1, 2, 3 12345678", "%Z %x", v, 3, 0x12345678); 2202 2203 int v2[] = { 0 }; 2204 ASSERT_PP_FORMAT_3 ("0 12345678", "%Z %x", v2, 1, 0x12345678); 2205 2206 /* Verify that combinations work, along with unformatted text. */ 2207 assert_pp_format (SELFTEST_LOCATION, 2208 "the quick brown fox jumps over the lazy dog", 2209 "the %s %s %s jumps over the %s %s", 2210 "quick", "brown", "fox", "lazy", "dog"); 2211 assert_pp_format (SELFTEST_LOCATION, "item 3 of 7", "item %i of %i", 3, 7); 2212 assert_pp_format (SELFTEST_LOCATION, "problem with `bar' at line 10", 2213 "problem with %qs at line %i", "bar", 10); 2214 2215 /* Restore old values of open_quote and close_quote. */ 2216 open_quote = old_open_quote; 2217 close_quote = old_close_quote; 2218 } 2219 2220 /* Run all of the selftests within this file. */ 2221 2222 void 2223 pretty_print_c_tests () 2224 { 2225 test_basic_printing (); 2226 test_pp_format (); 2227 } 2228 2229 } // namespace selftest 2230 2231 #endif /* CHECKING_P */ 2232