1/* Output generating routines for GDB. 2 3 Copyright (C) 1999-2020 Free Software Foundation, Inc. 4 5 Contributed by Cygnus Solutions. 6 Written by Fernando Nasser for Cygnus. 7 8 This file is part of GDB. 9 10 This program is free software; you can redistribute it and/or modify 11 it under the terms of the GNU General Public License as published by 12 the Free Software Foundation; either version 3 of the License, or 13 (at your option) any later version. 14 15 This program is distributed in the hope that it will be useful, 16 but WITHOUT ANY WARRANTY; without even the implied warranty of 17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 GNU General Public License for more details. 19 20 You should have received a copy of the GNU General Public License 21 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 22 23#include "defs.h" 24#include "expression.h" /* For language.h */ 25#include "language.h" 26#include "ui-out.h" 27#include "gdbsupport/format.h" 28#include "cli/cli-style.h" 29#include "diagnostics.h" 30 31#include <vector> 32#include <memory> 33#include <string> 34 35namespace { 36 37/* A header of a ui_out_table. */ 38 39class ui_out_hdr 40{ 41 public: 42 43 explicit ui_out_hdr (int number, int min_width, ui_align alignment, 44 const std::string &name, const std::string &header) 45 : m_number (number), 46 m_min_width (min_width), 47 m_alignment (alignment), 48 m_name (name), 49 m_header (header) 50 { 51 } 52 53 int number () const 54 { 55 return m_number; 56 } 57 58 int min_width () const 59 { 60 return m_min_width; 61 } 62 63 ui_align alignment () const 64 { 65 return m_alignment; 66 } 67 68 const std::string &header () const 69 { 70 return m_header; 71 } 72 73 const std::string &name () const 74 { 75 return m_name; 76 } 77 78 private: 79 80 /* The number of the table column this header represents, 1-based. */ 81 int m_number; 82 83 /* Minimal column width in characters. May or may not be applicable, 84 depending on the actual implementation of ui_out. */ 85 int m_min_width; 86 87 /* Alignment of the content in the column. May or may not be applicable, 88 depending on the actual implementation of ui_out. */ 89 ui_align m_alignment; 90 91 /* Internal column name, used to internally refer to the column. */ 92 std::string m_name; 93 94 /* Printed header text of the column. */ 95 std::string m_header; 96}; 97 98} // namespace 99 100/* A level of nesting (either a list or a tuple) in a ui_out output. */ 101 102class ui_out_level 103{ 104 public: 105 106 explicit ui_out_level (ui_out_type type) 107 : m_type (type), 108 m_field_count (0) 109 { 110 } 111 112 ui_out_type type () const 113 { 114 return m_type; 115 } 116 117 int field_count () const 118 { 119 return m_field_count; 120 } 121 122 void inc_field_count () 123 { 124 m_field_count++; 125 } 126 127 private: 128 129 /* The type of this level. */ 130 ui_out_type m_type; 131 132 /* Count each field; the first element is for non-list fields. */ 133 int m_field_count; 134}; 135 136/* Tables are special. Maintain a separate structure that tracks 137 their state. At present an output can only contain a single table 138 but that restriction might eventually be lifted. */ 139 140class ui_out_table 141{ 142 public: 143 144 /* States (steps) of a table generation. */ 145 146 enum class state 147 { 148 /* We are generating the table headers. */ 149 HEADERS, 150 151 /* We are generating the table body. */ 152 BODY, 153 }; 154 155 explicit ui_out_table (int entry_level, int nr_cols, const std::string &id) 156 : m_state (state::HEADERS), 157 m_entry_level (entry_level), 158 m_nr_cols (nr_cols), 159 m_id (id) 160 { 161 } 162 163 /* Start building the body of the table. */ 164 165 void start_body (); 166 167 /* Add a new header to the table. */ 168 169 void append_header (int width, ui_align alignment, 170 const std::string &col_name, const std::string &col_hdr); 171 172 void start_row (); 173 174 /* Extract the format information for the next header and advance 175 the header iterator. Return false if there was no next header. */ 176 177 bool get_next_header (int *colno, int *width, ui_align *alignment, 178 const char **col_hdr); 179 180 bool query_field (int colno, int *width, int *alignment, 181 const char **col_name) const; 182 183 state current_state () const; 184 185 int entry_level () const; 186 187 private: 188 189 state m_state; 190 191 /* The level at which each entry of the table is to be found. A row 192 (a tuple) is made up of entries. Consequently ENTRY_LEVEL is one 193 above that of the table. */ 194 int m_entry_level; 195 196 /* Number of table columns (as specified in the table_begin call). */ 197 int m_nr_cols; 198 199 /* String identifying the table (as specified in the table_begin 200 call). */ 201 std::string m_id; 202 203 /* Pointers to the column headers. */ 204 std::vector<std::unique_ptr<ui_out_hdr>> m_headers; 205 206 /* Iterator over the headers vector, used when printing successive fields. */ 207 std::vector<std::unique_ptr<ui_out_hdr>>::const_iterator m_headers_iterator; 208}; 209 210/* See ui-out.h. */ 211 212void ui_out_table::start_body () 213{ 214 if (m_state != state::HEADERS) 215 internal_error (__FILE__, __LINE__, 216 _("extra table_body call not allowed; there must be only " 217 "one table_body after a table_begin and before a " 218 "table_end.")); 219 220 /* Check if the number of defined headers matches the number of expected 221 columns. */ 222 if (m_headers.size () != m_nr_cols) 223 internal_error (__FILE__, __LINE__, 224 _("number of headers differ from number of table " 225 "columns.")); 226 227 m_state = state::BODY; 228 m_headers_iterator = m_headers.begin (); 229} 230 231/* See ui-out.h. */ 232 233void ui_out_table::append_header (int width, ui_align alignment, 234 const std::string &col_name, 235 const std::string &col_hdr) 236{ 237 if (m_state != state::HEADERS) 238 internal_error (__FILE__, __LINE__, 239 _("table header must be specified after table_begin and " 240 "before table_body.")); 241 242 std::unique_ptr<ui_out_hdr> header (new ui_out_hdr (m_headers.size () + 1, 243 width, alignment, 244 col_name, col_hdr)); 245 246 m_headers.push_back (std::move (header)); 247} 248 249/* See ui-out.h. */ 250 251void ui_out_table::start_row () 252{ 253 m_headers_iterator = m_headers.begin (); 254} 255 256/* See ui-out.h. */ 257 258bool ui_out_table::get_next_header (int *colno, int *width, ui_align *alignment, 259 const char **col_hdr) 260{ 261 /* There may be no headers at all or we may have used all columns. */ 262 if (m_headers_iterator == m_headers.end ()) 263 return false; 264 265 ui_out_hdr *hdr = m_headers_iterator->get (); 266 267 *colno = hdr->number (); 268 *width = hdr->min_width (); 269 *alignment = hdr->alignment (); 270 *col_hdr = hdr->header ().c_str (); 271 272 /* Advance the header pointer to the next entry. */ 273 m_headers_iterator++; 274 275 return true; 276} 277 278/* See ui-out.h. */ 279 280bool ui_out_table::query_field (int colno, int *width, int *alignment, 281 const char **col_name) const 282{ 283 /* Column numbers are 1-based, so convert to 0-based index. */ 284 int index = colno - 1; 285 286 if (index >= 0 && index < m_headers.size ()) 287 { 288 ui_out_hdr *hdr = m_headers[index].get (); 289 290 gdb_assert (colno == hdr->number ()); 291 292 *width = hdr->min_width (); 293 *alignment = hdr->alignment (); 294 *col_name = hdr->name ().c_str (); 295 296 return true; 297 } 298 else 299 return false; 300} 301 302/* See ui-out.h. */ 303 304ui_out_table::state ui_out_table::current_state () const 305{ 306 return m_state; 307} 308 309/* See ui-out.h. */ 310 311int ui_out_table::entry_level () const 312{ 313 return m_entry_level; 314} 315 316int 317ui_out::level () const 318{ 319 return m_levels.size (); 320} 321 322/* The current (inner most) level. */ 323 324ui_out_level * 325ui_out::current_level () const 326{ 327 return m_levels.back ().get (); 328} 329 330/* Create a new level, of TYPE. */ 331void 332ui_out::push_level (ui_out_type type) 333{ 334 std::unique_ptr<ui_out_level> level (new ui_out_level (type)); 335 336 m_levels.push_back (std::move (level)); 337} 338 339/* Discard the current level. TYPE is the type of the level being 340 discarded. */ 341void 342ui_out::pop_level (ui_out_type type) 343{ 344 /* We had better not underflow the buffer. */ 345 gdb_assert (m_levels.size () > 0); 346 gdb_assert (current_level ()->type () == type); 347 348 m_levels.pop_back (); 349} 350 351/* Mark beginning of a table. */ 352 353void 354ui_out::table_begin (int nr_cols, int nr_rows, const std::string &tblid) 355{ 356 if (m_table_up != nullptr) 357 internal_error (__FILE__, __LINE__, 358 _("tables cannot be nested; table_begin found before \ 359previous table_end.")); 360 361 m_table_up.reset (new ui_out_table (level () + 1, nr_cols, tblid)); 362 363 do_table_begin (nr_cols, nr_rows, tblid.c_str ()); 364} 365 366void 367ui_out::table_header (int width, ui_align alignment, 368 const std::string &col_name, const std::string &col_hdr) 369{ 370 if (m_table_up == nullptr) 371 internal_error (__FILE__, __LINE__, 372 _("table_header outside a table is not valid; it must be \ 373after a table_begin and before a table_body.")); 374 375 m_table_up->append_header (width, alignment, col_name, col_hdr); 376 377 do_table_header (width, alignment, col_name, col_hdr); 378} 379 380void 381ui_out::table_body () 382{ 383 if (m_table_up == nullptr) 384 internal_error (__FILE__, __LINE__, 385 _("table_body outside a table is not valid; it must be " 386 "after a table_begin and before a table_end.")); 387 388 m_table_up->start_body (); 389 390 do_table_body (); 391} 392 393void 394ui_out::table_end () 395{ 396 if (m_table_up == nullptr) 397 internal_error (__FILE__, __LINE__, 398 _("misplaced table_end or missing table_begin.")); 399 400 do_table_end (); 401 402 m_table_up = nullptr; 403} 404 405void 406ui_out::begin (ui_out_type type, const char *id) 407{ 408 /* Be careful to verify the ``field'' before the new tuple/list is 409 pushed onto the stack. That way the containing list/table/row is 410 verified and not the newly created tuple/list. This verification 411 is needed (at least) for the case where a table row entry 412 contains either a tuple/list. For that case bookkeeping such as 413 updating the column count or advancing to the next heading still 414 needs to be performed. */ 415 { 416 int fldno; 417 int width; 418 ui_align align; 419 420 verify_field (&fldno, &width, &align); 421 } 422 423 push_level (type); 424 425 /* If the push puts us at the same level as a table row entry, we've 426 got a new table row. Put the header pointer back to the start. */ 427 if (m_table_up != nullptr 428 && m_table_up->current_state () == ui_out_table::state::BODY 429 && m_table_up->entry_level () == level ()) 430 m_table_up->start_row (); 431 432 do_begin (type, id); 433} 434 435void 436ui_out::end (ui_out_type type) 437{ 438 pop_level (type); 439 440 do_end (type); 441} 442 443void 444ui_out::field_signed (const char *fldname, LONGEST value) 445{ 446 int fldno; 447 int width; 448 ui_align align; 449 450 verify_field (&fldno, &width, &align); 451 452 do_field_signed (fldno, width, align, fldname, value); 453} 454 455void 456ui_out::field_fmt_signed (int input_width, ui_align input_align, 457 const char *fldname, LONGEST value) 458{ 459 int fldno; 460 int width; 461 ui_align align; 462 463 verify_field (&fldno, &width, &align); 464 465 do_field_signed (fldno, input_width, input_align, fldname, value); 466} 467 468/* See ui-out.h. */ 469 470void 471ui_out::field_unsigned (const char *fldname, ULONGEST value) 472{ 473 int fldno; 474 int width; 475 ui_align align; 476 477 verify_field (&fldno, &width, &align); 478 479 do_field_unsigned (fldno, width, align, fldname, value); 480} 481 482/* Documented in ui-out.h. */ 483 484void 485ui_out::field_core_addr (const char *fldname, struct gdbarch *gdbarch, 486 CORE_ADDR address) 487{ 488 field_string (fldname, print_core_address (gdbarch, address), 489 address_style.style ()); 490} 491 492void 493ui_out::field_stream (const char *fldname, string_file &stream, 494 const ui_file_style &style) 495{ 496 if (!stream.empty ()) 497 field_string (fldname, stream.c_str (), style); 498 else 499 field_skip (fldname); 500 stream.clear (); 501} 502 503/* Used to omit a field. */ 504 505void 506ui_out::field_skip (const char *fldname) 507{ 508 int fldno; 509 int width; 510 ui_align align; 511 512 verify_field (&fldno, &width, &align); 513 514 do_field_skip (fldno, width, align, fldname); 515} 516 517void 518ui_out::field_string (const char *fldname, const char *string, 519 const ui_file_style &style) 520{ 521 int fldno; 522 int width; 523 ui_align align; 524 525 verify_field (&fldno, &width, &align); 526 527 do_field_string (fldno, width, align, fldname, string, style); 528} 529 530void 531ui_out::field_string (const char *fldname, const std::string &string) 532{ 533 field_string (fldname, string.c_str ()); 534} 535 536/* VARARGS */ 537void 538ui_out::field_fmt (const char *fldname, const char *format, ...) 539{ 540 va_list args; 541 int fldno; 542 int width; 543 ui_align align; 544 545 verify_field (&fldno, &width, &align); 546 547 va_start (args, format); 548 549 do_field_fmt (fldno, width, align, fldname, ui_file_style (), format, args); 550 551 va_end (args); 552} 553 554void 555ui_out::field_fmt (const char *fldname, const ui_file_style &style, 556 const char *format, ...) 557{ 558 va_list args; 559 int fldno; 560 int width; 561 ui_align align; 562 563 verify_field (&fldno, &width, &align); 564 565 va_start (args, format); 566 567 do_field_fmt (fldno, width, align, fldname, style, format, args); 568 569 va_end (args); 570} 571 572void 573ui_out::spaces (int numspaces) 574{ 575 do_spaces (numspaces); 576} 577 578void 579ui_out::text (const char *string) 580{ 581 do_text (string); 582} 583 584void 585ui_out::call_do_message (const ui_file_style &style, const char *format, 586 ...) 587{ 588 va_list args; 589 590 va_start (args, format); 591 592 /* Since call_do_message is only used as a helper of vmessage, silence the 593 warning here once instead of at all call sites in vmessage, if we were 594 to put a "format" attribute on call_do_message. */ 595 DIAGNOSTIC_PUSH 596 DIAGNOSTIC_IGNORE_FORMAT_NONLITERAL 597 do_message (style, format, args); 598 DIAGNOSTIC_POP 599 600 va_end (args); 601} 602 603void 604ui_out::vmessage (const ui_file_style &in_style, const char *format, 605 va_list args) 606{ 607 format_pieces fpieces (&format, true); 608 609 ui_file_style style = in_style; 610 611 for (auto &&piece : fpieces) 612 { 613 const char *current_substring = piece.string; 614 615 gdb_assert (piece.n_int_args >= 0 && piece.n_int_args <= 2); 616 int intvals[2] = { 0, 0 }; 617 for (int i = 0; i < piece.n_int_args; ++i) 618 intvals[i] = va_arg (args, int); 619 620 /* The only ones we support for now. */ 621 gdb_assert (piece.n_int_args == 0 622 || piece.argclass == string_arg 623 || piece.argclass == int_arg 624 || piece.argclass == long_arg); 625 626 switch (piece.argclass) 627 { 628 case string_arg: 629 { 630 const char *str = va_arg (args, const char *); 631 switch (piece.n_int_args) 632 { 633 case 0: 634 call_do_message (style, current_substring, str); 635 break; 636 case 1: 637 call_do_message (style, current_substring, intvals[0], str); 638 break; 639 case 2: 640 call_do_message (style, current_substring, 641 intvals[0], intvals[1], str); 642 break; 643 } 644 } 645 break; 646 case wide_string_arg: 647 gdb_assert_not_reached (_("wide_string_arg not supported in vmessage")); 648 break; 649 case wide_char_arg: 650 gdb_assert_not_reached (_("wide_char_arg not supported in vmessage")); 651 break; 652 case long_long_arg: 653 call_do_message (style, current_substring, va_arg (args, long long)); 654 break; 655 case int_arg: 656 { 657 int val = va_arg (args, int); 658 switch (piece.n_int_args) 659 { 660 case 0: 661 call_do_message (style, current_substring, val); 662 break; 663 case 1: 664 call_do_message (style, current_substring, intvals[0], val); 665 break; 666 case 2: 667 call_do_message (style, current_substring, 668 intvals[0], intvals[1], val); 669 break; 670 } 671 } 672 break; 673 case long_arg: 674 { 675 long val = va_arg (args, long); 676 switch (piece.n_int_args) 677 { 678 case 0: 679 call_do_message (style, current_substring, val); 680 break; 681 case 1: 682 call_do_message (style, current_substring, intvals[0], val); 683 break; 684 case 2: 685 call_do_message (style, current_substring, 686 intvals[0], intvals[1], val); 687 break; 688 } 689 } 690 break; 691 case size_t_arg: 692 { 693 size_t val = va_arg (args, size_t); 694 switch (piece.n_int_args) 695 { 696 case 0: 697 call_do_message (style, current_substring, val); 698 break; 699 case 1: 700 call_do_message (style, current_substring, intvals[0], val); 701 break; 702 case 2: 703 call_do_message (style, current_substring, 704 intvals[0], intvals[1], val); 705 break; 706 } 707 } 708 break; 709 case double_arg: 710 call_do_message (style, current_substring, va_arg (args, double)); 711 break; 712 case long_double_arg: 713 gdb_assert_not_reached (_("long_double_arg not supported in vmessage")); 714 break; 715 case dec32float_arg: 716 gdb_assert_not_reached (_("dec32float_arg not supported in vmessage")); 717 break; 718 case dec64float_arg: 719 gdb_assert_not_reached (_("dec64float_arg not supported in vmessage")); 720 break; 721 case dec128float_arg: 722 gdb_assert_not_reached (_("dec128float_arg not supported in vmessage")); 723 break; 724 case ptr_arg: 725 switch (current_substring[2]) 726 { 727 case 'F': 728 { 729 gdb_assert (!test_flags (disallow_ui_out_field)); 730 base_field_s *bf = va_arg (args, base_field_s *); 731 switch (bf->kind) 732 { 733 case field_kind::FIELD_SIGNED: 734 { 735 auto *f = (signed_field_s *) bf; 736 field_signed (f->name, f->val); 737 } 738 break; 739 case field_kind::FIELD_STRING: 740 { 741 auto *f = (string_field_s *) bf; 742 field_string (f->name, f->str); 743 } 744 break; 745 } 746 } 747 break; 748 case 's': 749 { 750 styled_string_s *ss = va_arg (args, styled_string_s *); 751 call_do_message (ss->style, "%s", ss->str); 752 } 753 break; 754 case '[': 755 style = *va_arg (args, const ui_file_style *); 756 break; 757 case ']': 758 { 759 void *arg = va_arg (args, void *); 760 gdb_assert (arg == nullptr); 761 762 style = {}; 763 } 764 break; 765 default: 766 call_do_message (style, current_substring, va_arg (args, void *)); 767 break; 768 } 769 break; 770 case literal_piece: 771 /* Print a portion of the format string that has no 772 directives. Note that this will not include any ordinary 773 %-specs, but it might include "%%". That is why we use 774 call_do_message here. Also, we pass a dummy argument 775 because some platforms have modified GCC to include 776 -Wformat-security by default, which will warn here if 777 there is no argument. */ 778 call_do_message (style, current_substring, 0); 779 break; 780 default: 781 internal_error (__FILE__, __LINE__, 782 _("failed internal consistency check")); 783 } 784 } 785} 786 787void 788ui_out::message (const char *format, ...) 789{ 790 va_list args; 791 va_start (args, format); 792 793 vmessage (ui_file_style (), format, args); 794 795 va_end (args); 796} 797 798void 799ui_out::wrap_hint (const char *identstring) 800{ 801 do_wrap_hint (identstring); 802} 803 804void 805ui_out::flush () 806{ 807 do_flush (); 808} 809 810void 811ui_out::redirect (ui_file *outstream) 812{ 813 do_redirect (outstream); 814} 815 816/* Test the flags against the mask given. */ 817ui_out_flags 818ui_out::test_flags (ui_out_flags mask) 819{ 820 return m_flags & mask; 821} 822 823bool 824ui_out::is_mi_like_p () const 825{ 826 return do_is_mi_like_p (); 827} 828 829/* Verify that the field/tuple/list is correctly positioned. Return 830 the field number and corresponding alignment (if 831 available/applicable). */ 832 833void 834ui_out::verify_field (int *fldno, int *width, ui_align *align) 835{ 836 ui_out_level *current = current_level (); 837 const char *text; 838 839 if (m_table_up != nullptr 840 && m_table_up->current_state () != ui_out_table::state::BODY) 841 { 842 internal_error (__FILE__, __LINE__, 843 _("table_body missing; table fields must be \ 844specified after table_body and inside a list.")); 845 } 846 847 current->inc_field_count (); 848 849 if (m_table_up != nullptr 850 && m_table_up->current_state () == ui_out_table::state::BODY 851 && m_table_up->entry_level () == level () 852 && m_table_up->get_next_header (fldno, width, align, &text)) 853 { 854 if (*fldno != current->field_count ()) 855 internal_error (__FILE__, __LINE__, 856 _("ui-out internal error in handling headers.")); 857 } 858 else 859 { 860 *width = 0; 861 *align = ui_noalign; 862 *fldno = current->field_count (); 863 } 864} 865 866/* Access table field parameters. */ 867 868bool 869ui_out::query_table_field (int colno, int *width, int *alignment, 870 const char **col_name) 871{ 872 if (m_table_up == nullptr) 873 return false; 874 875 return m_table_up->query_field (colno, width, alignment, col_name); 876} 877 878/* The constructor. */ 879 880ui_out::ui_out (ui_out_flags flags) 881: m_flags (flags) 882{ 883 /* Create the ui-out level #1, the default level. */ 884 push_level (ui_out_type_tuple); 885} 886 887ui_out::~ui_out () 888{ 889} 890