1 /* Output generating routines for GDB.
3 Copyright (C) 1999-2019 Free Software Foundation, Inc.
5 Contributed by Cygnus Solutions.
6 Written by Fernando Nasser for Cygnus.
8 This file is part of GDB.
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.
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.
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/>. */
24 #include "expression.h" /* For language.h */
27 #include "gdbsupport/format.h"
28 #include "cli/cli-style.h"
36 /* A header of a ui_out_table. */
42 explicit ui_out_hdr (int number
, int min_width
, ui_align alignment
,
43 const std::string
&name
, const std::string
&header
)
45 m_min_width (min_width
),
46 m_alignment (alignment
),
57 int min_width () const
62 ui_align
alignment () const
67 const std::string
&header () const
72 const std::string
&name () const
79 /* The number of the table column this header represents, 1-based. */
82 /* Minimal column width in characters. May or may not be applicable,
83 depending on the actual implementation of ui_out. */
86 /* Alignment of the content in the column. May or may not be applicable,
87 depending on the actual implementation of ui_out. */
90 /* Internal column name, used to internally refer to the column. */
93 /* Printed header text of the column. */
99 /* A level of nesting (either a list or a tuple) in a ui_out output. */
105 explicit ui_out_level (ui_out_type type
)
111 ui_out_type
type () const
116 int field_count () const
118 return m_field_count
;
121 void inc_field_count ()
128 /* The type of this level. */
131 /* Count each field; the first element is for non-list fields. */
135 /* Tables are special. Maintain a separate structure that tracks
136 their state. At present an output can only contain a single table
137 but that restriction might eventually be lifted. */
143 /* States (steps) of a table generation. */
147 /* We are generating the table headers. */
150 /* We are generating the table body. */
154 explicit ui_out_table (int entry_level
, int nr_cols
, const std::string
&id
)
155 : m_state (state::HEADERS
),
156 m_entry_level (entry_level
),
162 /* Start building the body of the table. */
166 /* Add a new header to the table. */
168 void append_header (int width
, ui_align alignment
,
169 const std::string
&col_name
, const std::string
&col_hdr
);
173 /* Extract the format information for the next header and advance
174 the header iterator. Return false if there was no next header. */
176 bool get_next_header (int *colno
, int *width
, ui_align
*alignment
,
177 const char **col_hdr
);
179 bool query_field (int colno
, int *width
, int *alignment
,
180 const char **col_name
) const;
182 state
current_state () const;
184 int entry_level () const;
190 /* The level at which each entry of the table is to be found. A row
191 (a tuple) is made up of entries. Consequently ENTRY_LEVEL is one
192 above that of the table. */
195 /* Number of table columns (as specified in the table_begin call). */
198 /* String identifying the table (as specified in the table_begin
202 /* Pointers to the column headers. */
203 std::vector
<std::unique_ptr
<ui_out_hdr
>> m_headers
;
205 /* Iterator over the headers vector, used when printing successive fields. */
206 std::vector
<std::unique_ptr
<ui_out_hdr
>>::const_iterator m_headers_iterator
;
211 void ui_out_table::start_body ()
213 if (m_state
!= state::HEADERS
)
214 internal_error (__FILE__
, __LINE__
,
215 _("extra table_body call not allowed; there must be only "
216 "one table_body after a table_begin and before a "
219 /* Check if the number of defined headers matches the number of expected
221 if (m_headers
.size () != m_nr_cols
)
222 internal_error (__FILE__
, __LINE__
,
223 _("number of headers differ from number of table "
226 m_state
= state::BODY
;
227 m_headers_iterator
= m_headers
.begin ();
232 void ui_out_table::append_header (int width
, ui_align alignment
,
233 const std::string
&col_name
,
234 const std::string
&col_hdr
)
236 if (m_state
!= state::HEADERS
)
237 internal_error (__FILE__
, __LINE__
,
238 _("table header must be specified after table_begin and "
239 "before table_body."));
241 std::unique_ptr
<ui_out_hdr
> header (new ui_out_hdr (m_headers
.size () + 1,
245 m_headers
.push_back (std::move (header
));
250 void ui_out_table::start_row ()
252 m_headers_iterator
= m_headers
.begin ();
257 bool ui_out_table::get_next_header (int *colno
, int *width
, ui_align
*alignment
,
258 const char **col_hdr
)
260 /* There may be no headers at all or we may have used all columns. */
261 if (m_headers_iterator
== m_headers
.end ())
264 ui_out_hdr
*hdr
= m_headers_iterator
->get ();
266 *colno
= hdr
->number ();
267 *width
= hdr
->min_width ();
268 *alignment
= hdr
->alignment ();
269 *col_hdr
= hdr
->header ().c_str ();
271 /* Advance the header pointer to the next entry. */
272 m_headers_iterator
++;
279 bool ui_out_table::query_field (int colno
, int *width
, int *alignment
,
280 const char **col_name
) const
282 /* Column numbers are 1-based, so convert to 0-based index. */
283 int index
= colno
- 1;
285 if (index
>= 0 && index
< m_headers
.size ())
287 ui_out_hdr
*hdr
= m_headers
[index
].get ();
289 gdb_assert (colno
== hdr
->number ());
291 *width
= hdr
->min_width ();
292 *alignment
= hdr
->alignment ();
293 *col_name
= hdr
->name ().c_str ();
303 ui_out_table::state
ui_out_table::current_state () const
310 int ui_out_table::entry_level () const
312 return m_entry_level
;
316 ui_out::level () const
318 return m_levels
.size ();
321 /* The current (inner most) level. */
324 ui_out::current_level () const
326 return m_levels
.back ().get ();
329 /* Create a new level, of TYPE. */
331 ui_out::push_level (ui_out_type type
)
333 std::unique_ptr
<ui_out_level
> level (new ui_out_level (type
));
335 m_levels
.push_back (std::move (level
));
338 /* Discard the current level. TYPE is the type of the level being
341 ui_out::pop_level (ui_out_type type
)
343 /* We had better not underflow the buffer. */
344 gdb_assert (m_levels
.size () > 0);
345 gdb_assert (current_level ()->type () == type
);
347 m_levels
.pop_back ();
350 /* Mark beginning of a table. */
353 ui_out::table_begin (int nr_cols
, int nr_rows
, const std::string
&tblid
)
355 if (m_table_up
!= nullptr)
356 internal_error (__FILE__
, __LINE__
,
357 _("tables cannot be nested; table_begin found before \
358 previous table_end."));
360 m_table_up
.reset (new ui_out_table (level () + 1, nr_cols
, tblid
));
362 do_table_begin (nr_cols
, nr_rows
, tblid
.c_str ());
366 ui_out::table_header (int width
, ui_align alignment
,
367 const std::string
&col_name
, const std::string
&col_hdr
)
369 if (m_table_up
== nullptr)
370 internal_error (__FILE__
, __LINE__
,
371 _("table_header outside a table is not valid; it must be \
372 after a table_begin and before a table_body."));
374 m_table_up
->append_header (width
, alignment
, col_name
, col_hdr
);
376 do_table_header (width
, alignment
, col_name
, col_hdr
);
380 ui_out::table_body ()
382 if (m_table_up
== nullptr)
383 internal_error (__FILE__
, __LINE__
,
384 _("table_body outside a table is not valid; it must be "
385 "after a table_begin and before a table_end."));
387 m_table_up
->start_body ();
395 if (m_table_up
== nullptr)
396 internal_error (__FILE__
, __LINE__
,
397 _("misplaced table_end or missing table_begin."));
401 m_table_up
= nullptr;
405 ui_out::begin (ui_out_type type
, const char *id
)
407 /* Be careful to verify the ``field'' before the new tuple/list is
408 pushed onto the stack. That way the containing list/table/row is
409 verified and not the newly created tuple/list. This verification
410 is needed (at least) for the case where a table row entry
411 contains either a tuple/list. For that case bookkeeping such as
412 updating the column count or advancing to the next heading still
413 needs to be performed. */
419 verify_field (&fldno
, &width
, &align
);
424 /* If the push puts us at the same level as a table row entry, we've
425 got a new table row. Put the header pointer back to the start. */
426 if (m_table_up
!= nullptr
427 && m_table_up
->current_state () == ui_out_table::state::BODY
428 && m_table_up
->entry_level () == level ())
429 m_table_up
->start_row ();
435 ui_out::end (ui_out_type type
)
443 ui_out::field_signed (const char *fldname
, LONGEST value
)
449 verify_field (&fldno
, &width
, &align
);
451 do_field_signed (fldno
, width
, align
, fldname
, value
);
455 ui_out::field_fmt_signed (int input_width
, ui_align input_align
,
456 const char *fldname
, LONGEST value
)
462 verify_field (&fldno
, &width
, &align
);
464 do_field_signed (fldno
, input_width
, input_align
, fldname
, value
);
470 ui_out::field_unsigned (const char *fldname
, ULONGEST value
)
476 verify_field (&fldno
, &width
, &align
);
478 do_field_unsigned (fldno
, width
, align
, fldname
, value
);
481 /* Documented in ui-out.h. */
484 ui_out::field_core_addr (const char *fldname
, struct gdbarch
*gdbarch
,
487 field_string (fldname
, print_core_address (gdbarch
, address
),
488 address_style
.style ());
492 ui_out::field_stream (const char *fldname
, string_file
&stream
,
493 const ui_file_style
&style
)
495 if (!stream
.empty ())
496 field_string (fldname
, stream
.c_str (), style
);
498 field_skip (fldname
);
502 /* Used to omit a field. */
505 ui_out::field_skip (const char *fldname
)
511 verify_field (&fldno
, &width
, &align
);
513 do_field_skip (fldno
, width
, align
, fldname
);
517 ui_out::field_string (const char *fldname
, const char *string
,
518 const ui_file_style
&style
)
524 verify_field (&fldno
, &width
, &align
);
526 do_field_string (fldno
, width
, align
, fldname
, string
, style
);
530 ui_out::field_string (const char *fldname
, const std::string
&string
)
532 field_string (fldname
, string
.c_str ());
537 ui_out::field_fmt (const char *fldname
, const char *format
, ...)
544 verify_field (&fldno
, &width
, &align
);
546 va_start (args
, format
);
548 do_field_fmt (fldno
, width
, align
, fldname
, ui_file_style (), format
, args
);
554 ui_out::field_fmt (const char *fldname
, const ui_file_style
&style
,
555 const char *format
, ...)
562 verify_field (&fldno
, &width
, &align
);
564 va_start (args
, format
);
566 do_field_fmt (fldno
, width
, align
, fldname
, style
, format
, args
);
572 ui_out::spaces (int numspaces
)
574 do_spaces (numspaces
);
578 ui_out::text (const char *string
)
584 ui_out::call_do_message (const ui_file_style
&style
, const char *format
,
589 va_start (args
, format
);
590 do_message (style
, format
, args
);
595 ui_out::vmessage (const ui_file_style
&in_style
, const char *format
,
598 format_pieces
fpieces (&format
, true);
600 ui_file_style style
= in_style
;
602 for (auto &&piece
: fpieces
)
604 const char *current_substring
= piece
.string
;
606 gdb_assert (piece
.n_int_args
>= 0 && piece
.n_int_args
<= 2);
607 int intvals
[2] = { 0, 0 };
608 for (int i
= 0; i
< piece
.n_int_args
; ++i
)
609 intvals
[i
] = va_arg (args
, int);
611 /* The only ones we support for now. */
612 gdb_assert (piece
.n_int_args
== 0
613 || piece
.argclass
== string_arg
614 || piece
.argclass
== int_arg
615 || piece
.argclass
== long_arg
);
617 switch (piece
.argclass
)
621 const char *str
= va_arg (args
, const char *);
622 switch (piece
.n_int_args
)
625 call_do_message (style
, current_substring
, str
);
628 call_do_message (style
, current_substring
, intvals
[0], str
);
631 call_do_message (style
, current_substring
,
632 intvals
[0], intvals
[1], str
);
637 case wide_string_arg
:
638 gdb_assert_not_reached (_("wide_string_arg not supported in vmessage"));
641 gdb_assert_not_reached (_("wide_char_arg not supported in vmessage"));
644 call_do_message (style
, current_substring
, va_arg (args
, long long));
648 int val
= va_arg (args
, int);
649 switch (piece
.n_int_args
)
652 call_do_message (style
, current_substring
, val
);
655 call_do_message (style
, current_substring
, intvals
[0], val
);
658 call_do_message (style
, current_substring
,
659 intvals
[0], intvals
[1], val
);
666 long val
= va_arg (args
, long);
667 switch (piece
.n_int_args
)
670 call_do_message (style
, current_substring
, val
);
673 call_do_message (style
, current_substring
, intvals
[0], val
);
676 call_do_message (style
, current_substring
,
677 intvals
[0], intvals
[1], val
);
683 call_do_message (style
, current_substring
, va_arg (args
, double));
685 case long_double_arg
:
686 gdb_assert_not_reached (_("long_double_arg not supported in vmessage"));
689 gdb_assert_not_reached (_("dec32float_arg not supported in vmessage"));
692 gdb_assert_not_reached (_("dec64float_arg not supported in vmessage"));
694 case dec128float_arg
:
695 gdb_assert_not_reached (_("dec128float_arg not supported in vmessage"));
698 switch (current_substring
[2])
702 gdb_assert (!test_flags (disallow_ui_out_field
));
703 base_field_s
*bf
= va_arg (args
, base_field_s
*);
706 case field_kind::SIGNED
:
708 auto *f
= (signed_field_s
*) bf
;
709 field_signed (f
->name
, f
->val
);
712 case field_kind::STRING
:
714 auto *f
= (string_field_s
*) bf
;
715 field_string (f
->name
, f
->str
);
723 styled_string_s
*ss
= va_arg (args
, styled_string_s
*);
724 call_do_message (ss
->style
, "%s", ss
->str
);
728 style
= *va_arg (args
, const ui_file_style
*);
732 void *arg
= va_arg (args
, void *);
733 gdb_assert (arg
== nullptr);
739 call_do_message (style
, current_substring
, va_arg (args
, void *));
744 /* Print a portion of the format string that has no
745 directives. Note that this will not include any ordinary
746 %-specs, but it might include "%%". That is why we use
747 call_do_message here. Also, we pass a dummy argument
748 because some platforms have modified GCC to include
749 -Wformat-security by default, which will warn here if
750 there is no argument. */
751 call_do_message (style
, current_substring
, 0);
754 internal_error (__FILE__
, __LINE__
,
755 _("failed internal consistency check"));
761 ui_out::message (const char *format
, ...)
764 va_start (args
, format
);
766 vmessage (ui_file_style (), format
, args
);
772 ui_out::wrap_hint (const char *identstring
)
774 do_wrap_hint (identstring
);
784 ui_out::redirect (ui_file
*outstream
)
786 do_redirect (outstream
);
789 /* Test the flags against the mask given. */
791 ui_out::test_flags (ui_out_flags mask
)
793 return m_flags
& mask
;
797 ui_out::is_mi_like_p () const
799 return do_is_mi_like_p ();
802 /* Verify that the field/tuple/list is correctly positioned. Return
803 the field number and corresponding alignment (if
804 available/applicable). */
807 ui_out::verify_field (int *fldno
, int *width
, ui_align
*align
)
809 ui_out_level
*current
= current_level ();
812 if (m_table_up
!= nullptr
813 && m_table_up
->current_state () != ui_out_table::state::BODY
)
815 internal_error (__FILE__
, __LINE__
,
816 _("table_body missing; table fields must be \
817 specified after table_body and inside a list."));
820 current
->inc_field_count ();
822 if (m_table_up
!= nullptr
823 && m_table_up
->current_state () == ui_out_table::state::BODY
824 && m_table_up
->entry_level () == level ()
825 && m_table_up
->get_next_header (fldno
, width
, align
, &text
))
827 if (*fldno
!= current
->field_count ())
828 internal_error (__FILE__
, __LINE__
,
829 _("ui-out internal error in handling headers."));
835 *fldno
= current
->field_count ();
839 /* Access table field parameters. */
842 ui_out::query_table_field (int colno
, int *width
, int *alignment
,
843 const char **col_name
)
845 if (m_table_up
== nullptr)
848 return m_table_up
->query_field (colno
, width
, alignment
, col_name
);
851 /* The constructor. */
853 ui_out::ui_out (ui_out_flags flags
)
856 /* Create the ui-out level #1, the default level. */
857 push_level (ui_out_type_tuple
);