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 SetConsoleTextAttribute (h, attrib_add); 644 break; 645 } 646 } 647 648 int 649 mingw_ansi_fputs (const char *str, FILE *fp) 650 { 651 const char *read = str; 652 HANDLE h; 653 DWORD mode; 654 int esc_code, prefix_len; 655 const char *esc_head, *esc_term; 656 657 h = (HANDLE) _get_osfhandle (_fileno (fp)); 658 if (h == INVALID_HANDLE_VALUE) 659 return EOF; 660 661 /* Don't mess up stdio functions with Windows APIs. */ 662 fflush (fp); 663 664 if (GetConsoleMode (h, &mode)) 665 /* If it is a console, translate ANSI escape codes as needed. */ 666 for (;;) 667 { 668 if ((esc_code = find_esc_head (&prefix_len, &esc_head, read)) == 0) 669 { 670 /* Write all remaining characters, then exit. */ 671 write_all (h, read, strlen (read)); 672 break; 673 } 674 if (find_esc_terminator (&esc_term, esc_head) == 0) 675 /* Ignore incomplete escape sequences at the moment. 676 FIXME: The escape state shall be cached for further calls 677 to this function. */ 678 break; 679 write_all (h, read, esc_head - prefix_len - read); 680 eat_esc_sequence (h, esc_code, esc_head, esc_term); 681 read = esc_term + 1; 682 } 683 else 684 /* If it is not a console, write everything as-is. */ 685 write_all (h, read, strlen (read)); 686 687 _close ((intptr_t) h); 688 return 1; 689 } 690 691 #endif /* __MINGW32__ */ 692 693 static void pp_quoted_string (pretty_printer *, const char *, size_t = -1); 694 695 /* Overwrite the given location/range within this text_info's rich_location. 696 For use e.g. when implementing "+" in client format decoders. */ 697 698 void 699 text_info::set_location (unsigned int idx, location_t loc, bool show_caret_p) 700 { 701 gcc_checking_assert (m_richloc); 702 m_richloc->set_range (line_table, idx, loc, show_caret_p); 703 } 704 705 location_t 706 text_info::get_location (unsigned int index_of_location) const 707 { 708 gcc_checking_assert (m_richloc); 709 710 if (index_of_location == 0) 711 return m_richloc->get_loc (); 712 else 713 return UNKNOWN_LOCATION; 714 } 715 716 // Default construct an output buffer. 717 718 output_buffer::output_buffer () 719 : formatted_obstack (), 720 chunk_obstack (), 721 obstack (&formatted_obstack), 722 cur_chunk_array (), 723 stream (stderr), 724 line_length (), 725 digit_buffer (), 726 flush_p (true) 727 { 728 obstack_init (&formatted_obstack); 729 obstack_init (&chunk_obstack); 730 } 731 732 // Release resources owned by an output buffer at the end of lifetime. 733 734 output_buffer::~output_buffer () 735 { 736 obstack_free (&chunk_obstack, NULL); 737 obstack_free (&formatted_obstack, NULL); 738 } 739 740 741 /* Format an integer given by va_arg (ARG, type-specifier T) where 742 type-specifier is a precision modifier as indicated by PREC. F is 743 a string used to construct the appropriate format-specifier. */ 744 #define pp_integer_with_precision(PP, ARG, PREC, T, F) \ 745 do \ 746 switch (PREC) \ 747 { \ 748 case 0: \ 749 pp_scalar (PP, "%" F, va_arg (ARG, T)); \ 750 break; \ 751 \ 752 case 1: \ 753 pp_scalar (PP, "%l" F, va_arg (ARG, long T)); \ 754 break; \ 755 \ 756 case 2: \ 757 pp_scalar (PP, "%" HOST_LONG_LONG_FORMAT F, va_arg (ARG, long long T)); \ 758 break; \ 759 \ 760 default: \ 761 break; \ 762 } \ 763 while (0) 764 765 766 /* Subroutine of pp_set_maximum_length. Set up PRETTY-PRINTER's 767 internal maximum characters per line. */ 768 static void 769 pp_set_real_maximum_length (pretty_printer *pp) 770 { 771 /* If we're told not to wrap lines then do the obvious thing. In case 772 we'll emit prefix only once per message, it is appropriate 773 not to increase unnecessarily the line-length cut-off. */ 774 if (!pp_is_wrapping_line (pp) 775 || pp_prefixing_rule (pp) == DIAGNOSTICS_SHOW_PREFIX_ONCE 776 || pp_prefixing_rule (pp) == DIAGNOSTICS_SHOW_PREFIX_NEVER) 777 pp->maximum_length = pp_line_cutoff (pp); 778 else 779 { 780 int prefix_length = pp->prefix ? strlen (pp->prefix) : 0; 781 /* If the prefix is ridiculously too long, output at least 782 32 characters. */ 783 if (pp_line_cutoff (pp) - prefix_length < 32) 784 pp->maximum_length = pp_line_cutoff (pp) + 32; 785 else 786 pp->maximum_length = pp_line_cutoff (pp); 787 } 788 } 789 790 /* Clear PRETTY-PRINTER's output state. */ 791 static inline void 792 pp_clear_state (pretty_printer *pp) 793 { 794 pp->emitted_prefix = false; 795 pp_indentation (pp) = 0; 796 } 797 798 /* Print X to PP in decimal. */ 799 template<unsigned int N, typename T> 800 void 801 pp_wide_integer (pretty_printer *pp, const poly_int_pod<N, T> &x) 802 { 803 if (x.is_constant ()) 804 pp_wide_integer (pp, x.coeffs[0]); 805 else 806 { 807 pp_left_bracket (pp); 808 for (unsigned int i = 0; i < N; ++i) 809 { 810 if (i != 0) 811 pp_comma (pp); 812 pp_wide_integer (pp, x.coeffs[i]); 813 } 814 pp_right_bracket (pp); 815 } 816 } 817 818 template void pp_wide_integer (pretty_printer *, const poly_uint16_pod &); 819 template void pp_wide_integer (pretty_printer *, const poly_int64_pod &); 820 template void pp_wide_integer (pretty_printer *, const poly_uint64_pod &); 821 822 /* Flush the formatted text of PRETTY-PRINTER onto the attached stream. */ 823 void 824 pp_write_text_to_stream (pretty_printer *pp) 825 { 826 const char *text = pp_formatted_text (pp); 827 #ifdef __MINGW32__ 828 mingw_ansi_fputs (text, pp_buffer (pp)->stream); 829 #else 830 fputs (text, pp_buffer (pp)->stream); 831 #endif 832 pp_clear_output_area (pp); 833 } 834 835 /* As pp_write_text_to_stream, but for GraphViz label output. 836 837 Flush the formatted text of pretty-printer PP onto the attached stream. 838 Replace characters in PPF that have special meaning in a GraphViz .dot 839 file. 840 841 This routine is not very fast, but it doesn't have to be as this is only 842 be used by routines dumping intermediate representations in graph form. */ 843 844 void 845 pp_write_text_as_dot_label_to_stream (pretty_printer *pp, bool for_record) 846 { 847 const char *text = pp_formatted_text (pp); 848 const char *p = text; 849 FILE *fp = pp_buffer (pp)->stream; 850 851 for (;*p; p++) 852 { 853 bool escape_char; 854 switch (*p) 855 { 856 /* Print newlines as a left-aligned newline. */ 857 case '\n': 858 fputs ("\\l", fp); 859 escape_char = true; 860 break; 861 862 /* The following characters are only special for record-shape nodes. */ 863 case '|': 864 case '{': 865 case '}': 866 case '<': 867 case '>': 868 case ' ': 869 escape_char = for_record; 870 break; 871 872 /* The following characters always have to be escaped 873 for use in labels. */ 874 case '\\': 875 /* There is a bug in some (f.i. 2.36.0) versions of graphiz 876 ( http://www.graphviz.org/mantisbt/view.php?id=2524 ) related to 877 backslash as last char in label. Let's avoid triggering it. */ 878 gcc_assert (*(p + 1) != '\0'); 879 /* Fall through. */ 880 case '"': 881 escape_char = true; 882 break; 883 884 default: 885 escape_char = false; 886 break; 887 } 888 889 if (escape_char) 890 fputc ('\\', fp); 891 892 fputc (*p, fp); 893 } 894 895 pp_clear_output_area (pp); 896 } 897 898 /* Wrap a text delimited by START and END into PRETTY-PRINTER. */ 899 static void 900 pp_wrap_text (pretty_printer *pp, const char *start, const char *end) 901 { 902 bool wrapping_line = pp_is_wrapping_line (pp); 903 904 while (start != end) 905 { 906 /* Dump anything bordered by whitespaces. */ 907 { 908 const char *p = start; 909 while (p != end && !ISBLANK (*p) && *p != '\n') 910 ++p; 911 if (wrapping_line 912 && p - start >= pp_remaining_character_count_for_line (pp)) 913 pp_newline (pp); 914 pp_append_text (pp, start, p); 915 start = p; 916 } 917 918 if (start != end && ISBLANK (*start)) 919 { 920 pp_space (pp); 921 ++start; 922 } 923 if (start != end && *start == '\n') 924 { 925 pp_newline (pp); 926 ++start; 927 } 928 } 929 } 930 931 /* Same as pp_wrap_text but wrap text only when in line-wrapping mode. */ 932 static inline void 933 pp_maybe_wrap_text (pretty_printer *pp, const char *start, const char *end) 934 { 935 if (pp_is_wrapping_line (pp)) 936 pp_wrap_text (pp, start, end); 937 else 938 pp_append_text (pp, start, end); 939 } 940 941 /* Append to the output area of PRETTY-PRINTER a string specified by its 942 STARTing character and LENGTH. */ 943 static inline void 944 pp_append_r (pretty_printer *pp, const char *start, int length) 945 { 946 output_buffer_append_r (pp_buffer (pp), start, length); 947 } 948 949 /* Insert enough spaces into the output area of PRETTY-PRINTER to bring 950 the column position to the current indentation level, assuming that a 951 newline has just been written to the buffer. */ 952 void 953 pp_indent (pretty_printer *pp) 954 { 955 int n = pp_indentation (pp); 956 int i; 957 958 for (i = 0; i < n; ++i) 959 pp_space (pp); 960 } 961 962 /* The following format specifiers are recognized as being client independent: 963 %d, %i: (signed) integer in base ten. 964 %u: unsigned integer in base ten. 965 %o: unsigned integer in base eight. 966 %x: unsigned integer in base sixteen. 967 %ld, %li, %lo, %lu, %lx: long versions of the above. 968 %lld, %lli, %llo, %llu, %llx: long long versions. 969 %wd, %wi, %wo, %wu, %wx: HOST_WIDE_INT versions. 970 %c: character. 971 %s: string. 972 %p: pointer (printed in a host-dependent manner). 973 %r: if pp_show_color(pp), switch to color identified by const char *. 974 %R: if pp_show_color(pp), reset color. 975 %m: strerror(text->err_no) - does not consume a value from args_ptr. 976 %%: '%'. 977 %<: opening quote. 978 %>: closing quote. 979 %': apostrophe (should only be used in untranslated messages; 980 translations should use appropriate punctuation directly). 981 %.*s: a substring the length of which is specified by an argument 982 integer. 983 %Ns: likewise, but length specified as constant in the format string. 984 Flag 'q': quote formatted text (must come immediately after '%'). 985 %Z: Requires two arguments - array of int, and len. Prints elements 986 of the array. 987 988 Arguments can be used sequentially, or through %N$ resp. *N$ 989 notation Nth argument after the format string. If %N$ / *N$ 990 notation is used, it must be used for all arguments, except %m, %%, 991 %<, %> and %', which may not have a number, as they do not consume 992 an argument. When %M$.*N$s is used, M must be N + 1. (This may 993 also be written %M$.*s, provided N is not otherwise used.) The 994 format string must have conversion specifiers with argument numbers 995 1 up to highest argument; each argument may only be used once. 996 A format string can have at most 30 arguments. */ 997 998 /* Formatting phases 1 and 2: render TEXT->format_spec plus 999 TEXT->args_ptr into a series of chunks in pp_buffer (PP)->args[]. 1000 Phase 3 is in pp_output_formatted_text. */ 1001 1002 void 1003 pp_format (pretty_printer *pp, text_info *text) 1004 { 1005 output_buffer *buffer = pp_buffer (pp); 1006 const char *p; 1007 const char **args; 1008 struct chunk_info *new_chunk_array; 1009 1010 unsigned int curarg = 0, chunk = 0, argno; 1011 pp_wrapping_mode_t old_wrapping_mode; 1012 bool any_unnumbered = false, any_numbered = false; 1013 const char **formatters[PP_NL_ARGMAX]; 1014 1015 /* Allocate a new chunk structure. */ 1016 new_chunk_array = XOBNEW (&buffer->chunk_obstack, struct chunk_info); 1017 new_chunk_array->prev = buffer->cur_chunk_array; 1018 buffer->cur_chunk_array = new_chunk_array; 1019 args = new_chunk_array->args; 1020 1021 /* Formatting phase 1: split up TEXT->format_spec into chunks in 1022 pp_buffer (PP)->args[]. Even-numbered chunks are to be output 1023 verbatim, odd-numbered chunks are format specifiers. 1024 %m, %%, %<, %>, and %' are replaced with the appropriate text at 1025 this point. */ 1026 1027 memset (formatters, 0, sizeof formatters); 1028 1029 for (p = text->format_spec; *p; ) 1030 { 1031 while (*p != '\0' && *p != '%') 1032 { 1033 obstack_1grow (&buffer->chunk_obstack, *p); 1034 p++; 1035 } 1036 1037 if (*p == '\0') 1038 break; 1039 1040 switch (*++p) 1041 { 1042 case '\0': 1043 gcc_unreachable (); 1044 1045 case '%': 1046 obstack_1grow (&buffer->chunk_obstack, '%'); 1047 p++; 1048 continue; 1049 1050 case '<': 1051 { 1052 obstack_grow (&buffer->chunk_obstack, 1053 open_quote, strlen (open_quote)); 1054 const char *colorstr 1055 = colorize_start (pp_show_color (pp), "quote"); 1056 obstack_grow (&buffer->chunk_obstack, colorstr, strlen (colorstr)); 1057 p++; 1058 continue; 1059 } 1060 1061 case '>': 1062 { 1063 const char *colorstr = colorize_stop (pp_show_color (pp)); 1064 obstack_grow (&buffer->chunk_obstack, colorstr, strlen (colorstr)); 1065 } 1066 /* FALLTHRU */ 1067 case '\'': 1068 obstack_grow (&buffer->chunk_obstack, 1069 close_quote, strlen (close_quote)); 1070 p++; 1071 continue; 1072 1073 case 'R': 1074 { 1075 const char *colorstr = colorize_stop (pp_show_color (pp)); 1076 obstack_grow (&buffer->chunk_obstack, colorstr, 1077 strlen (colorstr)); 1078 p++; 1079 continue; 1080 } 1081 1082 case 'm': 1083 { 1084 const char *errstr = xstrerror (text->err_no); 1085 obstack_grow (&buffer->chunk_obstack, errstr, strlen (errstr)); 1086 } 1087 p++; 1088 continue; 1089 1090 default: 1091 /* Handled in phase 2. Terminate the plain chunk here. */ 1092 obstack_1grow (&buffer->chunk_obstack, '\0'); 1093 gcc_assert (chunk < PP_NL_ARGMAX * 2); 1094 args[chunk++] = XOBFINISH (&buffer->chunk_obstack, const char *); 1095 break; 1096 } 1097 1098 if (ISDIGIT (*p)) 1099 { 1100 char *end; 1101 argno = strtoul (p, &end, 10) - 1; 1102 p = end; 1103 gcc_assert (*p == '$'); 1104 p++; 1105 1106 any_numbered = true; 1107 gcc_assert (!any_unnumbered); 1108 } 1109 else 1110 { 1111 argno = curarg++; 1112 any_unnumbered = true; 1113 gcc_assert (!any_numbered); 1114 } 1115 gcc_assert (argno < PP_NL_ARGMAX); 1116 gcc_assert (!formatters[argno]); 1117 formatters[argno] = &args[chunk]; 1118 do 1119 { 1120 obstack_1grow (&buffer->chunk_obstack, *p); 1121 p++; 1122 } 1123 while (strchr ("qwl+#", p[-1])); 1124 1125 if (p[-1] == '.') 1126 { 1127 /* We handle '%.Ns' and '%.*s' or '%M$.*N$s' 1128 (where M == N + 1). */ 1129 if (ISDIGIT (*p)) 1130 { 1131 do 1132 { 1133 obstack_1grow (&buffer->chunk_obstack, *p); 1134 p++; 1135 } 1136 while (ISDIGIT (p[-1])); 1137 gcc_assert (p[-1] == 's'); 1138 } 1139 else 1140 { 1141 gcc_assert (*p == '*'); 1142 obstack_1grow (&buffer->chunk_obstack, '*'); 1143 p++; 1144 1145 if (ISDIGIT (*p)) 1146 { 1147 char *end; 1148 unsigned int argno2 = strtoul (p, &end, 10) - 1; 1149 p = end; 1150 gcc_assert (argno2 == argno - 1); 1151 gcc_assert (!any_unnumbered); 1152 gcc_assert (*p == '$'); 1153 1154 p++; 1155 formatters[argno2] = formatters[argno]; 1156 } 1157 else 1158 { 1159 gcc_assert (!any_numbered); 1160 formatters[argno+1] = formatters[argno]; 1161 curarg++; 1162 } 1163 gcc_assert (*p == 's'); 1164 obstack_1grow (&buffer->chunk_obstack, 's'); 1165 p++; 1166 } 1167 } 1168 if (*p == '\0') 1169 break; 1170 1171 obstack_1grow (&buffer->chunk_obstack, '\0'); 1172 gcc_assert (chunk < PP_NL_ARGMAX * 2); 1173 args[chunk++] = XOBFINISH (&buffer->chunk_obstack, const char *); 1174 } 1175 1176 obstack_1grow (&buffer->chunk_obstack, '\0'); 1177 gcc_assert (chunk < PP_NL_ARGMAX * 2); 1178 args[chunk++] = XOBFINISH (&buffer->chunk_obstack, const char *); 1179 args[chunk] = 0; 1180 1181 /* Set output to the argument obstack, and switch line-wrapping and 1182 prefixing off. */ 1183 buffer->obstack = &buffer->chunk_obstack; 1184 old_wrapping_mode = pp_set_verbatim_wrapping (pp); 1185 1186 /* Second phase. Replace each formatter with the formatted text it 1187 corresponds to. */ 1188 1189 for (argno = 0; formatters[argno]; argno++) 1190 { 1191 int precision = 0; 1192 bool wide = false; 1193 bool plus = false; 1194 bool hash = false; 1195 bool quote = false; 1196 1197 /* We do not attempt to enforce any ordering on the modifier 1198 characters. */ 1199 1200 for (p = *formatters[argno];; p++) 1201 { 1202 switch (*p) 1203 { 1204 case 'q': 1205 gcc_assert (!quote); 1206 quote = true; 1207 continue; 1208 1209 case '+': 1210 gcc_assert (!plus); 1211 plus = true; 1212 continue; 1213 1214 case '#': 1215 gcc_assert (!hash); 1216 hash = true; 1217 continue; 1218 1219 case 'w': 1220 gcc_assert (!wide); 1221 wide = true; 1222 continue; 1223 1224 case 'l': 1225 /* We don't support precision beyond that of "long long". */ 1226 gcc_assert (precision < 2); 1227 precision++; 1228 continue; 1229 } 1230 break; 1231 } 1232 1233 gcc_assert (!wide || precision == 0); 1234 1235 if (quote) 1236 pp_begin_quote (pp, pp_show_color (pp)); 1237 1238 switch (*p) 1239 { 1240 case 'r': 1241 pp_string (pp, colorize_start (pp_show_color (pp), 1242 va_arg (*text->args_ptr, 1243 const char *))); 1244 break; 1245 1246 case 'c': 1247 { 1248 /* When quoting, print alphanumeric, punctuation, and the space 1249 character unchanged, and all others in hexadecimal with the 1250 "\x" prefix. Otherwise print them all unchanged. */ 1251 int chr = va_arg (*text->args_ptr, int); 1252 if (ISPRINT (chr) || !quote) 1253 pp_character (pp, chr); 1254 else 1255 { 1256 const char str [2] = { chr, '\0' }; 1257 pp_quoted_string (pp, str, 1); 1258 } 1259 break; 1260 } 1261 1262 case 'd': 1263 case 'i': 1264 if (wide) 1265 pp_wide_integer (pp, va_arg (*text->args_ptr, HOST_WIDE_INT)); 1266 else 1267 pp_integer_with_precision 1268 (pp, *text->args_ptr, precision, int, "d"); 1269 break; 1270 1271 case 'o': 1272 if (wide) 1273 pp_scalar (pp, "%" HOST_WIDE_INT_PRINT "o", 1274 va_arg (*text->args_ptr, unsigned HOST_WIDE_INT)); 1275 else 1276 pp_integer_with_precision 1277 (pp, *text->args_ptr, precision, unsigned, "o"); 1278 break; 1279 1280 case 's': 1281 if (quote) 1282 pp_quoted_string (pp, va_arg (*text->args_ptr, const char *)); 1283 else 1284 pp_string (pp, va_arg (*text->args_ptr, const char *)); 1285 break; 1286 1287 case 'p': 1288 pp_pointer (pp, va_arg (*text->args_ptr, void *)); 1289 break; 1290 1291 case 'u': 1292 if (wide) 1293 pp_scalar (pp, HOST_WIDE_INT_PRINT_UNSIGNED, 1294 va_arg (*text->args_ptr, unsigned HOST_WIDE_INT)); 1295 else 1296 pp_integer_with_precision 1297 (pp, *text->args_ptr, precision, unsigned, "u"); 1298 break; 1299 1300 case 'Z': 1301 { 1302 int *v = va_arg (*text->args_ptr, int *); 1303 unsigned len = va_arg (*text->args_ptr, unsigned); 1304 1305 for (unsigned i = 0; i < len; ++i) 1306 { 1307 pp_scalar (pp, "%i", v[i]); 1308 if (i < len - 1) 1309 { 1310 pp_comma (pp); 1311 pp_space (pp); 1312 } 1313 } 1314 break; 1315 } 1316 1317 case 'x': 1318 if (wide) 1319 pp_scalar (pp, HOST_WIDE_INT_PRINT_HEX, 1320 va_arg (*text->args_ptr, unsigned HOST_WIDE_INT)); 1321 else 1322 pp_integer_with_precision 1323 (pp, *text->args_ptr, precision, unsigned, "x"); 1324 break; 1325 1326 case '.': 1327 { 1328 int n; 1329 const char *s; 1330 1331 /* We handle '%.Ns' and '%.*s' or '%M$.*N$s' 1332 (where M == N + 1). The format string should be verified 1333 already from the first phase. */ 1334 p++; 1335 if (ISDIGIT (*p)) 1336 { 1337 char *end; 1338 n = strtoul (p, &end, 10); 1339 p = end; 1340 gcc_assert (*p == 's'); 1341 } 1342 else 1343 { 1344 gcc_assert (*p == '*'); 1345 p++; 1346 gcc_assert (*p == 's'); 1347 n = va_arg (*text->args_ptr, int); 1348 1349 /* This consumes a second entry in the formatters array. */ 1350 gcc_assert (formatters[argno] == formatters[argno+1]); 1351 argno++; 1352 } 1353 1354 s = va_arg (*text->args_ptr, const char *); 1355 1356 /* Append the lesser of precision and strlen (s) characters 1357 from the array (which need not be a nul-terminated string). 1358 Negative precision is treated as if it were omitted. */ 1359 size_t len = n < 0 ? strlen (s) : strnlen (s, n); 1360 1361 pp_append_text (pp, s, s + len); 1362 } 1363 break; 1364 1365 default: 1366 { 1367 bool ok; 1368 1369 /* Call the format decoder. 1370 Pass the address of "quote" so that format decoders can 1371 potentially disable printing of the closing quote 1372 (e.g. when printing "'TYPEDEF' aka 'TYPE'" in the C family 1373 of frontends). */ 1374 gcc_assert (pp_format_decoder (pp)); 1375 ok = pp_format_decoder (pp) (pp, text, p, 1376 precision, wide, plus, hash, "e, 1377 formatters[argno]); 1378 gcc_assert (ok); 1379 } 1380 } 1381 1382 if (quote) 1383 pp_end_quote (pp, pp_show_color (pp)); 1384 1385 obstack_1grow (&buffer->chunk_obstack, '\0'); 1386 *formatters[argno] = XOBFINISH (&buffer->chunk_obstack, const char *); 1387 } 1388 1389 if (CHECKING_P) 1390 for (; argno < PP_NL_ARGMAX; argno++) 1391 gcc_assert (!formatters[argno]); 1392 1393 /* If the client supplied a postprocessing object, call its "handle" 1394 hook here. */ 1395 if (pp->m_format_postprocessor) 1396 pp->m_format_postprocessor->handle (pp); 1397 1398 /* Revert to normal obstack and wrapping mode. */ 1399 buffer->obstack = &buffer->formatted_obstack; 1400 buffer->line_length = 0; 1401 pp_wrapping_mode (pp) = old_wrapping_mode; 1402 pp_clear_state (pp); 1403 } 1404 1405 /* Format of a message pointed to by TEXT. */ 1406 void 1407 pp_output_formatted_text (pretty_printer *pp) 1408 { 1409 unsigned int chunk; 1410 output_buffer *buffer = pp_buffer (pp); 1411 struct chunk_info *chunk_array = buffer->cur_chunk_array; 1412 const char **args = chunk_array->args; 1413 1414 gcc_assert (buffer->obstack == &buffer->formatted_obstack); 1415 gcc_assert (buffer->line_length == 0); 1416 1417 /* This is a third phase, first 2 phases done in pp_format_args. 1418 Now we actually print it. */ 1419 for (chunk = 0; args[chunk]; chunk++) 1420 pp_string (pp, args[chunk]); 1421 1422 /* Deallocate the chunk structure and everything after it (i.e. the 1423 associated series of formatted strings). */ 1424 buffer->cur_chunk_array = chunk_array->prev; 1425 obstack_free (&buffer->chunk_obstack, chunk_array); 1426 } 1427 1428 /* Helper subroutine of output_verbatim and verbatim. Do the appropriate 1429 settings needed by BUFFER for a verbatim formatting. */ 1430 void 1431 pp_format_verbatim (pretty_printer *pp, text_info *text) 1432 { 1433 /* Set verbatim mode. */ 1434 pp_wrapping_mode_t oldmode = pp_set_verbatim_wrapping (pp); 1435 1436 /* Do the actual formatting. */ 1437 pp_format (pp, text); 1438 pp_output_formatted_text (pp); 1439 1440 /* Restore previous settings. */ 1441 pp_wrapping_mode (pp) = oldmode; 1442 } 1443 1444 /* Flush the content of BUFFER onto the attached stream. This 1445 function does nothing unless pp->output_buffer->flush_p. */ 1446 void 1447 pp_flush (pretty_printer *pp) 1448 { 1449 pp_clear_state (pp); 1450 if (!pp->buffer->flush_p) 1451 return; 1452 pp_write_text_to_stream (pp); 1453 fflush (pp_buffer (pp)->stream); 1454 } 1455 1456 /* Flush the content of BUFFER onto the attached stream independently 1457 of the value of pp->output_buffer->flush_p. */ 1458 void 1459 pp_really_flush (pretty_printer *pp) 1460 { 1461 pp_clear_state (pp); 1462 pp_write_text_to_stream (pp); 1463 fflush (pp_buffer (pp)->stream); 1464 } 1465 1466 /* Sets the number of maximum characters per line PRETTY-PRINTER can 1467 output in line-wrapping mode. A LENGTH value 0 suppresses 1468 line-wrapping. */ 1469 void 1470 pp_set_line_maximum_length (pretty_printer *pp, int length) 1471 { 1472 pp_line_cutoff (pp) = length; 1473 pp_set_real_maximum_length (pp); 1474 } 1475 1476 /* Clear PRETTY-PRINTER output area text info. */ 1477 void 1478 pp_clear_output_area (pretty_printer *pp) 1479 { 1480 obstack_free (pp_buffer (pp)->obstack, 1481 obstack_base (pp_buffer (pp)->obstack)); 1482 pp_buffer (pp)->line_length = 0; 1483 } 1484 1485 /* Set PREFIX for PRETTY-PRINTER. */ 1486 void 1487 pp_set_prefix (pretty_printer *pp, const char *prefix) 1488 { 1489 pp->prefix = prefix; 1490 pp_set_real_maximum_length (pp); 1491 pp->emitted_prefix = false; 1492 pp_indentation (pp) = 0; 1493 } 1494 1495 /* Free PRETTY-PRINTER's prefix, a previously malloc()'d string. */ 1496 void 1497 pp_destroy_prefix (pretty_printer *pp) 1498 { 1499 if (pp->prefix != NULL) 1500 { 1501 free (CONST_CAST (char *, pp->prefix)); 1502 pp->prefix = NULL; 1503 } 1504 } 1505 1506 /* Write out PRETTY-PRINTER's prefix. */ 1507 void 1508 pp_emit_prefix (pretty_printer *pp) 1509 { 1510 if (pp->prefix != NULL) 1511 { 1512 switch (pp_prefixing_rule (pp)) 1513 { 1514 default: 1515 case DIAGNOSTICS_SHOW_PREFIX_NEVER: 1516 break; 1517 1518 case DIAGNOSTICS_SHOW_PREFIX_ONCE: 1519 if (pp->emitted_prefix) 1520 { 1521 pp_indent (pp); 1522 break; 1523 } 1524 pp_indentation (pp) += 3; 1525 /* Fall through. */ 1526 1527 case DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE: 1528 { 1529 int prefix_length = strlen (pp->prefix); 1530 pp_append_r (pp, pp->prefix, prefix_length); 1531 pp->emitted_prefix = true; 1532 } 1533 break; 1534 } 1535 } 1536 } 1537 1538 /* Construct a PRETTY-PRINTER with PREFIX and of MAXIMUM_LENGTH 1539 characters per line. */ 1540 1541 pretty_printer::pretty_printer (const char *p, int l) 1542 : buffer (new (XCNEW (output_buffer)) output_buffer ()), 1543 prefix (), 1544 padding (pp_none), 1545 maximum_length (), 1546 indent_skip (), 1547 wrapping (), 1548 format_decoder (), 1549 m_format_postprocessor (NULL), 1550 emitted_prefix (), 1551 need_newline (), 1552 translate_identifiers (true), 1553 show_color () 1554 { 1555 pp_line_cutoff (this) = l; 1556 /* By default, we emit prefixes once per message. */ 1557 pp_prefixing_rule (this) = DIAGNOSTICS_SHOW_PREFIX_ONCE; 1558 pp_set_prefix (this, p); 1559 } 1560 1561 pretty_printer::~pretty_printer () 1562 { 1563 if (m_format_postprocessor) 1564 delete m_format_postprocessor; 1565 buffer->~output_buffer (); 1566 XDELETE (buffer); 1567 } 1568 1569 /* Append a string delimited by START and END to the output area of 1570 PRETTY-PRINTER. No line wrapping is done. However, if beginning a 1571 new line then emit PRETTY-PRINTER's prefix and skip any leading 1572 whitespace if appropriate. The caller must ensure that it is 1573 safe to do so. */ 1574 void 1575 pp_append_text (pretty_printer *pp, const char *start, const char *end) 1576 { 1577 /* Emit prefix and skip whitespace if we're starting a new line. */ 1578 if (pp_buffer (pp)->line_length == 0) 1579 { 1580 pp_emit_prefix (pp); 1581 if (pp_is_wrapping_line (pp)) 1582 while (start != end && *start == ' ') 1583 ++start; 1584 } 1585 pp_append_r (pp, start, end - start); 1586 } 1587 1588 /* Finishes constructing a NULL-terminated character string representing 1589 the PRETTY-PRINTED text. */ 1590 const char * 1591 pp_formatted_text (pretty_printer *pp) 1592 { 1593 return output_buffer_formatted_text (pp_buffer (pp)); 1594 } 1595 1596 /* Return a pointer to the last character emitted in PRETTY-PRINTER's 1597 output area. A NULL pointer means no character available. */ 1598 const char * 1599 pp_last_position_in_text (const pretty_printer *pp) 1600 { 1601 return output_buffer_last_position_in_text (pp_buffer (pp)); 1602 } 1603 1604 /* Return the amount of characters PRETTY-PRINTER can accept to 1605 make a full line. Meaningful only in line-wrapping mode. */ 1606 int 1607 pp_remaining_character_count_for_line (pretty_printer *pp) 1608 { 1609 return pp->maximum_length - pp_buffer (pp)->line_length; 1610 } 1611 1612 1613 /* Format a message into BUFFER a la printf. */ 1614 void 1615 pp_printf (pretty_printer *pp, const char *msg, ...) 1616 { 1617 text_info text; 1618 va_list ap; 1619 1620 va_start (ap, msg); 1621 text.err_no = errno; 1622 text.args_ptr = ≈ 1623 text.format_spec = msg; 1624 pp_format (pp, &text); 1625 pp_output_formatted_text (pp); 1626 va_end (ap); 1627 } 1628 1629 1630 /* Output MESSAGE verbatim into BUFFER. */ 1631 void 1632 pp_verbatim (pretty_printer *pp, const char *msg, ...) 1633 { 1634 text_info text; 1635 va_list ap; 1636 1637 va_start (ap, msg); 1638 text.err_no = errno; 1639 text.args_ptr = ≈ 1640 text.format_spec = msg; 1641 pp_format_verbatim (pp, &text); 1642 va_end (ap); 1643 } 1644 1645 1646 1647 /* Have PRETTY-PRINTER start a new line. */ 1648 void 1649 pp_newline (pretty_printer *pp) 1650 { 1651 obstack_1grow (pp_buffer (pp)->obstack, '\n'); 1652 pp_needs_newline (pp) = false; 1653 pp_buffer (pp)->line_length = 0; 1654 } 1655 1656 /* Have PRETTY-PRINTER add a CHARACTER. */ 1657 void 1658 pp_character (pretty_printer *pp, int c) 1659 { 1660 if (pp_is_wrapping_line (pp) 1661 && pp_remaining_character_count_for_line (pp) <= 0) 1662 { 1663 pp_newline (pp); 1664 if (ISSPACE (c)) 1665 return; 1666 } 1667 obstack_1grow (pp_buffer (pp)->obstack, c); 1668 ++pp_buffer (pp)->line_length; 1669 } 1670 1671 /* Append a STRING to the output area of PRETTY-PRINTER; the STRING may 1672 be line-wrapped if in appropriate mode. */ 1673 void 1674 pp_string (pretty_printer *pp, const char *str) 1675 { 1676 gcc_checking_assert (str); 1677 pp_maybe_wrap_text (pp, str, str + strlen (str)); 1678 } 1679 1680 /* Append the leading N characters of STRING to the output area of 1681 PRETTY-PRINTER, quoting in hexadecimal non-printable characters. 1682 Setting N = -1 is as if N were set to strlen (STRING). The STRING 1683 may be line-wrapped if in appropriate mode. */ 1684 static void 1685 pp_quoted_string (pretty_printer *pp, const char *str, size_t n /* = -1 */) 1686 { 1687 gcc_checking_assert (str); 1688 1689 const char *last = str; 1690 const char *ps; 1691 1692 /* Compute the length if not specified. */ 1693 if (n == (size_t) -1) 1694 n = strlen (str); 1695 1696 for (ps = str; n; ++ps, --n) 1697 { 1698 if (ISPRINT (*ps)) 1699 continue; 1700 1701 if (last < ps) 1702 pp_maybe_wrap_text (pp, last, ps - 1); 1703 1704 /* Append the hexadecimal value of the character. Allocate a buffer 1705 that's large enough for a 32-bit char plus the hex prefix. */ 1706 char buf [11]; 1707 int n = sprintf (buf, "\\x%02x", (unsigned char)*ps); 1708 pp_maybe_wrap_text (pp, buf, buf + n); 1709 last = ps + 1; 1710 } 1711 1712 pp_maybe_wrap_text (pp, last, ps); 1713 } 1714 1715 /* Maybe print out a whitespace if needed. */ 1716 1717 void 1718 pp_maybe_space (pretty_printer *pp) 1719 { 1720 if (pp->padding != pp_none) 1721 { 1722 pp_space (pp); 1723 pp->padding = pp_none; 1724 } 1725 } 1726 1727 // Add a newline to the pretty printer PP and flush formatted text. 1728 1729 void 1730 pp_newline_and_flush (pretty_printer *pp) 1731 { 1732 pp_newline (pp); 1733 pp_flush (pp); 1734 pp_needs_newline (pp) = false; 1735 } 1736 1737 // Add a newline to the pretty printer PP, followed by indentation. 1738 1739 void 1740 pp_newline_and_indent (pretty_printer *pp, int n) 1741 { 1742 pp_indentation (pp) += n; 1743 pp_newline (pp); 1744 pp_indent (pp); 1745 pp_needs_newline (pp) = false; 1746 } 1747 1748 // Add separator C, followed by a single whitespace. 1749 1750 void 1751 pp_separate_with (pretty_printer *pp, char c) 1752 { 1753 pp_character (pp, c); 1754 pp_space (pp); 1755 } 1756 1757 /* Add a localized open quote, and if SHOW_COLOR is true, begin colorizing 1758 using the "quote" color. */ 1759 1760 void 1761 pp_begin_quote (pretty_printer *pp, bool show_color) 1762 { 1763 pp_string (pp, open_quote); 1764 pp_string (pp, colorize_start (show_color, "quote")); 1765 } 1766 1767 /* If SHOW_COLOR is true, stop colorizing. 1768 Add a localized close quote. */ 1769 1770 void 1771 pp_end_quote (pretty_printer *pp, bool show_color) 1772 { 1773 pp_string (pp, colorize_stop (show_color)); 1774 pp_string (pp, close_quote); 1775 } 1776 1777 1778 /* The string starting at P has LEN (at least 1) bytes left; if they 1779 start with a valid UTF-8 sequence, return the length of that 1780 sequence and set *VALUE to the value of that sequence, and 1781 otherwise return 0 and set *VALUE to (unsigned int) -1. */ 1782 1783 static int 1784 decode_utf8_char (const unsigned char *p, size_t len, unsigned int *value) 1785 { 1786 unsigned int t = *p; 1787 1788 if (len == 0) 1789 abort (); 1790 if (t & 0x80) 1791 { 1792 size_t utf8_len = 0; 1793 unsigned int ch; 1794 size_t i; 1795 for (t = *p; t & 0x80; t <<= 1) 1796 utf8_len++; 1797 1798 if (utf8_len > len || utf8_len < 2 || utf8_len > 6) 1799 { 1800 *value = (unsigned int) -1; 1801 return 0; 1802 } 1803 ch = *p & ((1 << (7 - utf8_len)) - 1); 1804 for (i = 1; i < utf8_len; i++) 1805 { 1806 unsigned int u = p[i]; 1807 if ((u & 0xC0) != 0x80) 1808 { 1809 *value = (unsigned int) -1; 1810 return 0; 1811 } 1812 ch = (ch << 6) | (u & 0x3F); 1813 } 1814 if ( (ch <= 0x7F && utf8_len > 1) 1815 || (ch <= 0x7FF && utf8_len > 2) 1816 || (ch <= 0xFFFF && utf8_len > 3) 1817 || (ch <= 0x1FFFFF && utf8_len > 4) 1818 || (ch <= 0x3FFFFFF && utf8_len > 5) 1819 || (ch >= 0xD800 && ch <= 0xDFFF)) 1820 { 1821 *value = (unsigned int) -1; 1822 return 0; 1823 } 1824 *value = ch; 1825 return utf8_len; 1826 } 1827 else 1828 { 1829 *value = t; 1830 return 1; 1831 } 1832 } 1833 1834 /* Allocator for identifier_to_locale and corresponding function to 1835 free memory. */ 1836 1837 void *(*identifier_to_locale_alloc) (size_t) = xmalloc; 1838 void (*identifier_to_locale_free) (void *) = free; 1839 1840 /* Given IDENT, an identifier in the internal encoding, return a 1841 version of IDENT suitable for diagnostics in the locale character 1842 set: either IDENT itself, or a string, allocated using 1843 identifier_to_locale_alloc, converted to the locale character set 1844 and using escape sequences if not representable in the locale 1845 character set or containing control characters or invalid byte 1846 sequences. Existing backslashes in IDENT are not doubled, so the 1847 result may not uniquely specify the contents of an arbitrary byte 1848 sequence identifier. */ 1849 1850 const char * 1851 identifier_to_locale (const char *ident) 1852 { 1853 const unsigned char *uid = (const unsigned char *) ident; 1854 size_t idlen = strlen (ident); 1855 bool valid_printable_utf8 = true; 1856 bool all_ascii = true; 1857 size_t i; 1858 1859 for (i = 0; i < idlen;) 1860 { 1861 unsigned int c; 1862 size_t utf8_len = decode_utf8_char (&uid[i], idlen - i, &c); 1863 if (utf8_len == 0 || c <= 0x1F || (c >= 0x7F && c <= 0x9F)) 1864 { 1865 valid_printable_utf8 = false; 1866 break; 1867 } 1868 if (utf8_len > 1) 1869 all_ascii = false; 1870 i += utf8_len; 1871 } 1872 1873 /* If IDENT contains invalid UTF-8 sequences (which may occur with 1874 attributes putting arbitrary byte sequences in identifiers), or 1875 control characters, we use octal escape sequences for all bytes 1876 outside printable ASCII. */ 1877 if (!valid_printable_utf8) 1878 { 1879 char *ret = (char *) identifier_to_locale_alloc (4 * idlen + 1); 1880 char *p = ret; 1881 for (i = 0; i < idlen; i++) 1882 { 1883 if (uid[i] > 0x1F && uid[i] < 0x7F) 1884 *p++ = uid[i]; 1885 else 1886 { 1887 sprintf (p, "\\%03o", uid[i]); 1888 p += 4; 1889 } 1890 } 1891 *p = 0; 1892 return ret; 1893 } 1894 1895 /* Otherwise, if it is valid printable ASCII, or printable UTF-8 1896 with the locale character set being UTF-8, IDENT is used. */ 1897 if (all_ascii || locale_utf8) 1898 return ident; 1899 1900 /* Otherwise IDENT is converted to the locale character set if 1901 possible. */ 1902 #if defined ENABLE_NLS && defined HAVE_LANGINFO_CODESET && HAVE_ICONV 1903 if (locale_encoding != NULL) 1904 { 1905 iconv_t cd = iconv_open (locale_encoding, "UTF-8"); 1906 bool conversion_ok = true; 1907 char *ret = NULL; 1908 if (cd != (iconv_t) -1) 1909 { 1910 size_t ret_alloc = 4 * idlen + 1; 1911 for (;;) 1912 { 1913 /* Repeat the whole conversion process as needed with 1914 larger buffers so non-reversible transformations can 1915 always be detected. */ 1916 ICONV_CONST char *inbuf = CONST_CAST (char *, ident); 1917 char *outbuf; 1918 size_t inbytesleft = idlen; 1919 size_t outbytesleft = ret_alloc - 1; 1920 size_t iconv_ret; 1921 1922 ret = (char *) identifier_to_locale_alloc (ret_alloc); 1923 outbuf = ret; 1924 1925 if (iconv (cd, 0, 0, 0, 0) == (size_t) -1) 1926 { 1927 conversion_ok = false; 1928 break; 1929 } 1930 1931 iconv_ret = iconv (cd, &inbuf, &inbytesleft, 1932 &outbuf, &outbytesleft); 1933 if (iconv_ret == (size_t) -1 || inbytesleft != 0) 1934 { 1935 if (errno == E2BIG) 1936 { 1937 ret_alloc *= 2; 1938 identifier_to_locale_free (ret); 1939 ret = NULL; 1940 continue; 1941 } 1942 else 1943 { 1944 conversion_ok = false; 1945 break; 1946 } 1947 } 1948 else if (iconv_ret != 0) 1949 { 1950 conversion_ok = false; 1951 break; 1952 } 1953 /* Return to initial shift state. */ 1954 if (iconv (cd, 0, 0, &outbuf, &outbytesleft) == (size_t) -1) 1955 { 1956 if (errno == E2BIG) 1957 { 1958 ret_alloc *= 2; 1959 identifier_to_locale_free (ret); 1960 ret = NULL; 1961 continue; 1962 } 1963 else 1964 { 1965 conversion_ok = false; 1966 break; 1967 } 1968 } 1969 *outbuf = 0; 1970 break; 1971 } 1972 iconv_close (cd); 1973 if (conversion_ok) 1974 return ret; 1975 } 1976 } 1977 #endif 1978 1979 /* Otherwise, convert non-ASCII characters in IDENT to UCNs. */ 1980 { 1981 char *ret = (char *) identifier_to_locale_alloc (10 * idlen + 1); 1982 char *p = ret; 1983 for (i = 0; i < idlen;) 1984 { 1985 unsigned int c; 1986 size_t utf8_len = decode_utf8_char (&uid[i], idlen - i, &c); 1987 if (utf8_len == 1) 1988 *p++ = uid[i]; 1989 else 1990 { 1991 sprintf (p, "\\U%08x", c); 1992 p += 10; 1993 } 1994 i += utf8_len; 1995 } 1996 *p = 0; 1997 return ret; 1998 } 1999 } 2000 2001 #if CHECKING_P 2002 2003 namespace selftest { 2004 2005 /* Smoketest for pretty_printer. */ 2006 2007 static void 2008 test_basic_printing () 2009 { 2010 pretty_printer pp; 2011 pp_string (&pp, "hello"); 2012 pp_space (&pp); 2013 pp_string (&pp, "world"); 2014 2015 ASSERT_STREQ ("hello world", pp_formatted_text (&pp)); 2016 } 2017 2018 /* Helper function for testing pp_format. 2019 Verify that pp_format (FMT, ...) followed by pp_output_formatted_text 2020 prints EXPECTED, assuming that pp_show_color is SHOW_COLOR. */ 2021 2022 static void 2023 assert_pp_format_va (const location &loc, const char *expected, 2024 bool show_color, const char *fmt, va_list *ap) 2025 { 2026 pretty_printer pp; 2027 text_info ti; 2028 rich_location rich_loc (line_table, UNKNOWN_LOCATION); 2029 2030 ti.format_spec = fmt; 2031 ti.args_ptr = ap; 2032 ti.err_no = 0; 2033 ti.x_data = NULL; 2034 ti.m_richloc = &rich_loc; 2035 2036 pp_show_color (&pp) = show_color; 2037 pp_format (&pp, &ti); 2038 pp_output_formatted_text (&pp); 2039 ASSERT_STREQ_AT (loc, expected, pp_formatted_text (&pp)); 2040 } 2041 2042 /* Verify that pp_format (FMT, ...) followed by pp_output_formatted_text 2043 prints EXPECTED, with show_color disabled. */ 2044 2045 static void 2046 assert_pp_format (const location &loc, const char *expected, 2047 const char *fmt, ...) 2048 { 2049 va_list ap; 2050 2051 va_start (ap, fmt); 2052 assert_pp_format_va (loc, expected, false, fmt, &ap); 2053 va_end (ap); 2054 } 2055 2056 /* As above, but with colorization enabled. */ 2057 2058 static void 2059 assert_pp_format_colored (const location &loc, const char *expected, 2060 const char *fmt, ...) 2061 { 2062 /* The tests of colorization assume the default color scheme. 2063 If GCC_COLORS is set, then the colors have potentially been 2064 overridden; skip the test. */ 2065 if (getenv ("GCC_COLORS")) 2066 return; 2067 2068 va_list ap; 2069 2070 va_start (ap, fmt); 2071 assert_pp_format_va (loc, expected, true, fmt, &ap); 2072 va_end (ap); 2073 } 2074 2075 /* Helper function for calling testing pp_format, 2076 by calling assert_pp_format with various numbers of arguments. 2077 These exist mostly to avoid having to write SELFTEST_LOCATION 2078 throughout test_pp_format. */ 2079 2080 #define ASSERT_PP_FORMAT_1(EXPECTED, FMT, ARG1) \ 2081 SELFTEST_BEGIN_STMT \ 2082 assert_pp_format ((SELFTEST_LOCATION), (EXPECTED), (FMT), \ 2083 (ARG1)); \ 2084 SELFTEST_END_STMT 2085 2086 #define ASSERT_PP_FORMAT_2(EXPECTED, FMT, ARG1, ARG2) \ 2087 SELFTEST_BEGIN_STMT \ 2088 assert_pp_format ((SELFTEST_LOCATION), (EXPECTED), (FMT), \ 2089 (ARG1), (ARG2)); \ 2090 SELFTEST_END_STMT 2091 2092 #define ASSERT_PP_FORMAT_3(EXPECTED, FMT, ARG1, ARG2, ARG3) \ 2093 SELFTEST_BEGIN_STMT \ 2094 assert_pp_format ((SELFTEST_LOCATION), (EXPECTED), (FMT), \ 2095 (ARG1), (ARG2), (ARG3)); \ 2096 SELFTEST_END_STMT 2097 2098 /* Verify that pp_format works, for various format codes. */ 2099 2100 static void 2101 test_pp_format () 2102 { 2103 /* Avoid introducing locale-specific differences in the results 2104 by hardcoding open_quote and close_quote. */ 2105 const char *old_open_quote = open_quote; 2106 const char *old_close_quote = close_quote; 2107 open_quote = "`"; 2108 close_quote = "'"; 2109 2110 /* Verify that plain text is passed through unchanged. */ 2111 assert_pp_format (SELFTEST_LOCATION, "unformatted", "unformatted"); 2112 2113 /* Verify various individual format codes, in the order listed in the 2114 comment for pp_format above. For each code, we append a second 2115 argument with a known bit pattern (0x12345678), to ensure that we 2116 are consuming arguments correctly. */ 2117 ASSERT_PP_FORMAT_2 ("-27 12345678", "%d %x", -27, 0x12345678); 2118 ASSERT_PP_FORMAT_2 ("-5 12345678", "%i %x", -5, 0x12345678); 2119 ASSERT_PP_FORMAT_2 ("10 12345678", "%u %x", 10, 0x12345678); 2120 ASSERT_PP_FORMAT_2 ("17 12345678", "%o %x", 15, 0x12345678); 2121 ASSERT_PP_FORMAT_2 ("cafebabe 12345678", "%x %x", 0xcafebabe, 0x12345678); 2122 ASSERT_PP_FORMAT_2 ("-27 12345678", "%ld %x", (long)-27, 0x12345678); 2123 ASSERT_PP_FORMAT_2 ("-5 12345678", "%li %x", (long)-5, 0x12345678); 2124 ASSERT_PP_FORMAT_2 ("10 12345678", "%lu %x", (long)10, 0x12345678); 2125 ASSERT_PP_FORMAT_2 ("17 12345678", "%lo %x", (long)15, 0x12345678); 2126 ASSERT_PP_FORMAT_2 ("cafebabe 12345678", "%lx %x", (long)0xcafebabe, 2127 0x12345678); 2128 ASSERT_PP_FORMAT_2 ("-27 12345678", "%lld %x", (long long)-27, 0x12345678); 2129 ASSERT_PP_FORMAT_2 ("-5 12345678", "%lli %x", (long long)-5, 0x12345678); 2130 ASSERT_PP_FORMAT_2 ("10 12345678", "%llu %x", (long long)10, 0x12345678); 2131 ASSERT_PP_FORMAT_2 ("17 12345678", "%llo %x", (long long)15, 0x12345678); 2132 ASSERT_PP_FORMAT_2 ("cafebabe 12345678", "%llx %x", (long long)0xcafebabe, 2133 0x12345678); 2134 ASSERT_PP_FORMAT_2 ("-27 12345678", "%wd %x", (HOST_WIDE_INT)-27, 0x12345678); 2135 ASSERT_PP_FORMAT_2 ("-5 12345678", "%wi %x", (HOST_WIDE_INT)-5, 0x12345678); 2136 ASSERT_PP_FORMAT_2 ("10 12345678", "%wu %x", (unsigned HOST_WIDE_INT)10, 2137 0x12345678); 2138 ASSERT_PP_FORMAT_2 ("17 12345678", "%wo %x", (HOST_WIDE_INT)15, 0x12345678); 2139 ASSERT_PP_FORMAT_2 ("0xcafebabe 12345678", "%wx %x", (HOST_WIDE_INT)0xcafebabe, 2140 0x12345678); 2141 ASSERT_PP_FORMAT_2 ("A 12345678", "%c %x", 'A', 0x12345678); 2142 ASSERT_PP_FORMAT_2 ("hello world 12345678", "%s %x", "hello world", 2143 0x12345678); 2144 2145 /* Not nul-terminated. */ 2146 char arr[5] = { '1', '2', '3', '4', '5' }; 2147 ASSERT_PP_FORMAT_3 ("123 12345678", "%.*s %x", 3, arr, 0x12345678); 2148 ASSERT_PP_FORMAT_3 ("1234 12345678", "%.*s %x", -1, "1234", 0x12345678); 2149 ASSERT_PP_FORMAT_3 ("12345 12345678", "%.*s %x", 7, "12345", 0x12345678); 2150 2151 /* We can't test for %p; the pointer is printed in an implementation-defined 2152 manner. */ 2153 ASSERT_PP_FORMAT_2 ("normal colored normal 12345678", 2154 "normal %rcolored%R normal %x", 2155 "error", 0x12345678); 2156 assert_pp_format_colored 2157 (SELFTEST_LOCATION, 2158 "normal \33[01;31m\33[Kcolored\33[m\33[K normal 12345678", 2159 "normal %rcolored%R normal %x", "error", 0x12345678); 2160 /* TODO: 2161 %m: strerror(text->err_no) - does not consume a value from args_ptr. */ 2162 ASSERT_PP_FORMAT_1 ("% 12345678", "%% %x", 0x12345678); 2163 ASSERT_PP_FORMAT_1 ("` 12345678", "%< %x", 0x12345678); 2164 ASSERT_PP_FORMAT_1 ("' 12345678", "%> %x", 0x12345678); 2165 ASSERT_PP_FORMAT_1 ("' 12345678", "%' %x", 0x12345678); 2166 ASSERT_PP_FORMAT_3 ("abc 12345678", "%.*s %x", 3, "abcdef", 0x12345678); 2167 ASSERT_PP_FORMAT_2 ("abc 12345678", "%.3s %x", "abcdef", 0x12345678); 2168 2169 /* Verify flag 'q'. */ 2170 ASSERT_PP_FORMAT_2 ("`foo' 12345678", "%qs %x", "foo", 0x12345678); 2171 assert_pp_format_colored (SELFTEST_LOCATION, 2172 "`\33[01m\33[Kfoo\33[m\33[K' 12345678", "%qs %x", 2173 "foo", 0x12345678); 2174 2175 /* Verify %Z. */ 2176 int v[] = { 1, 2, 3 }; 2177 ASSERT_PP_FORMAT_3 ("1, 2, 3 12345678", "%Z %x", v, 3, 0x12345678); 2178 2179 int v2[] = { 0 }; 2180 ASSERT_PP_FORMAT_3 ("0 12345678", "%Z %x", v2, 1, 0x12345678); 2181 2182 /* Verify that combinations work, along with unformatted text. */ 2183 assert_pp_format (SELFTEST_LOCATION, 2184 "the quick brown fox jumps over the lazy dog", 2185 "the %s %s %s jumps over the %s %s", 2186 "quick", "brown", "fox", "lazy", "dog"); 2187 assert_pp_format (SELFTEST_LOCATION, "item 3 of 7", "item %i of %i", 3, 7); 2188 assert_pp_format (SELFTEST_LOCATION, "problem with `bar' at line 10", 2189 "problem with %qs at line %i", "bar", 10); 2190 2191 /* Restore old values of open_quote and close_quote. */ 2192 open_quote = old_open_quote; 2193 close_quote = old_close_quote; 2194 } 2195 2196 /* Run all of the selftests within this file. */ 2197 2198 void 2199 pretty_print_c_tests () 2200 { 2201 test_basic_printing (); 2202 test_pp_format (); 2203 } 2204 2205 } // namespace selftest 2206 2207 #endif /* CHECKING_P */ 2208