Don't create empty literal pieces
[deliverable/binutils-gdb.git] / gdb / ui-out.c
CommitLineData
8b93c638 1/* Output generating routines for GDB.
349c5d5f 2
42a4f53d 3 Copyright (C) 1999-2019 Free Software Foundation, Inc.
349c5d5f 4
8b93c638
JM
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
a9762ec7 12 the Free Software Foundation; either version 3 of the License, or
8b93c638
JM
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
a9762ec7 21 along with this program. If not, see <http://www.gnu.org/licenses/>. */
8b93c638
JM
22
23#include "defs.h"
8b93c638
JM
24#include "expression.h" /* For language.h */
25#include "language.h"
26#include "ui-out.h"
e43b10e1
TT
27#include "gdbsupport/format.h"
28#include "cli/cli-style.h"
8b93c638 29
56df3084
SM
30#include <vector>
31#include <memory>
95a23284 32#include <string>
56df3084 33
ffdbe864
YQ
34namespace {
35
37e20dd6 36/* A header of a ui_out_table. */
8b93c638 37
37e20dd6
SM
38class ui_out_hdr
39{
40 public:
41
42 explicit ui_out_hdr (int number, int min_width, ui_align alignment,
43 const std::string &name, const std::string &header)
44 : m_number (number),
45 m_min_width (min_width),
46 m_alignment (alignment),
47 m_name (name),
48 m_header (header)
8b93c638 49 {
37e20dd6
SM
50 }
51
52 int number () const
53 {
54 return m_number;
55 }
56
57 int min_width () const
58 {
59 return m_min_width;
60 }
61
62 ui_align alignment () const
63 {
64 return m_alignment;
65 }
66
67 const std::string &header () const
68 {
69 return m_header;
70 }
71
72 const std::string &name () const
73 {
74 return m_name;
75 }
76
77 private:
78
79 /* The number of the table column this header represents, 1-based. */
80 int m_number;
81
82 /* Minimal column width in characters. May or may not be applicable,
83 depending on the actual implementation of ui_out. */
84 int m_min_width;
85
86 /* Alignment of the content in the column. May or may not be applicable,
87 depending on the actual implementation of ui_out. */
88 ui_align m_alignment;
89
90 /* Internal column name, used to internally refer to the column. */
91 std::string m_name;
92
93 /* Printed header text of the column. */
94 std::string m_header;
95};
8b93c638 96
ffdbe864
YQ
97} // namespace
98
909c0aa5
SM
99/* A level of nesting (either a list or a tuple) in a ui_out output. */
100
101class ui_out_level
102{
103 public:
104
105 explicit ui_out_level (ui_out_type type)
106 : m_type (type),
107 m_field_count (0)
80f49b30 108 {
909c0aa5
SM
109 }
110
111 ui_out_type type () const
112 {
113 return m_type;
114 }
115
116 int field_count () const
117 {
118 return m_field_count;
119 }
120
121 void inc_field_count ()
122 {
123 m_field_count++;
124 }
125
126 private:
127
128 /* The type of this level. */
129 ui_out_type m_type;
130
131 /* Count each field; the first element is for non-list fields. */
132 int m_field_count;
133};
80f49b30 134
bafdd3b3
AC
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. */
138
36d18bc5 139class ui_out_table
bafdd3b3 140{
36d18bc5
SM
141 public:
142
143 /* States (steps) of a table generation. */
144
145 enum class state
146 {
147 /* We are generating the table headers. */
148 HEADERS,
149
150 /* We are generating the table body. */
151 BODY,
152 };
153
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),
157 m_nr_cols (nr_cols),
158 m_id (id)
159 {
160 }
161
162 /* Start building the body of the table. */
163
164 void start_body ();
165
166 /* Add a new header to the table. */
167
168 void append_header (int width, ui_align alignment,
169 const std::string &col_name, const std::string &col_hdr);
bafdd3b3 170
36d18bc5
SM
171 void start_row ();
172
173 /* Extract the format information for the next header and advance
174 the header iterator. Return false if there was no next header. */
175
176 bool get_next_header (int *colno, int *width, ui_align *alignment,
177 const char **col_hdr);
178
179 bool query_field (int colno, int *width, int *alignment,
180 const char **col_name) const;
181
182 state current_state () const;
183
184 int entry_level () const;
185
186 private:
187
188 state m_state;
bafdd3b3 189
a6c47c14
AC
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. */
36d18bc5 193 int m_entry_level;
a6c47c14 194
bafdd3b3 195 /* Number of table columns (as specified in the table_begin call). */
36d18bc5 196 int m_nr_cols;
bafdd3b3
AC
197
198 /* String identifying the table (as specified in the table_begin
199 call). */
36d18bc5 200 std::string m_id;
bafdd3b3 201
78afa7f8 202 /* Pointers to the column headers. */
36d18bc5 203 std::vector<std::unique_ptr<ui_out_hdr>> m_headers;
bafdd3b3 204
78afa7f8 205 /* Iterator over the headers vector, used when printing successive fields. */
36d18bc5 206 std::vector<std::unique_ptr<ui_out_hdr>>::const_iterator m_headers_iterator;
bafdd3b3
AC
207};
208
36d18bc5
SM
209/* See ui-out.h. */
210
211void ui_out_table::start_body ()
212{
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 "
217 "table_end."));
218
219 /* Check if the number of defined headers matches the number of expected
220 columns. */
221 if (m_headers.size () != m_nr_cols)
222 internal_error (__FILE__, __LINE__,
223 _("number of headers differ from number of table "
224 "columns."));
225
226 m_state = state::BODY;
227 m_headers_iterator = m_headers.begin ();
228}
229
230/* See ui-out.h. */
231
232void ui_out_table::append_header (int width, ui_align alignment,
233 const std::string &col_name,
234 const std::string &col_hdr)
235{
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."));
240
241 std::unique_ptr<ui_out_hdr> header (new ui_out_hdr (m_headers.size () + 1,
242 width, alignment,
243 col_name, col_hdr));
244
245 m_headers.push_back (std::move (header));
246}
247
248/* See ui-out.h. */
249
250void ui_out_table::start_row ()
251{
252 m_headers_iterator = m_headers.begin ();
253}
254
255/* See ui-out.h. */
256
257bool ui_out_table::get_next_header (int *colno, int *width, ui_align *alignment,
258 const char **col_hdr)
259{
260 /* There may be no headers at all or we may have used all columns. */
261 if (m_headers_iterator == m_headers.end ())
262 return false;
263
264 ui_out_hdr *hdr = m_headers_iterator->get ();
265
266 *colno = hdr->number ();
267 *width = hdr->min_width ();
268 *alignment = hdr->alignment ();
269 *col_hdr = hdr->header ().c_str ();
270
271 /* Advance the header pointer to the next entry. */
272 m_headers_iterator++;
273
274 return true;
275}
276
277/* See ui-out.h. */
278
279bool ui_out_table::query_field (int colno, int *width, int *alignment,
280 const char **col_name) const
281{
282 /* Column numbers are 1-based, so convert to 0-based index. */
283 int index = colno - 1;
284
285 if (index >= 0 && index < m_headers.size ())
286 {
287 ui_out_hdr *hdr = m_headers[index].get ();
288
289 gdb_assert (colno == hdr->number ());
290
291 *width = hdr->min_width ();
292 *alignment = hdr->alignment ();
293 *col_name = hdr->name ().c_str ();
294
295 return true;
296 }
297 else
298 return false;
299}
300
301/* See ui-out.h. */
302
303ui_out_table::state ui_out_table::current_state () const
304{
305 return m_state;
306}
307
308/* See ui-out.h. */
309
310int ui_out_table::entry_level () const
311{
312 return m_entry_level;
313}
bafdd3b3 314
112e8700
SM
315int
316ui_out::level () const
317{
318 return m_levels.size ();
319}
8b93c638 320
581e13c1 321/* The current (inner most) level. */
112e8700
SM
322
323ui_out_level *
324ui_out::current_level () const
80f49b30 325{
112e8700 326 return m_levels.back ().get ();
80f49b30
AC
327}
328
33b2fac6 329/* Create a new level, of TYPE. */
112e8700
SM
330void
331ui_out::push_level (ui_out_type type)
80f49b30 332{
909c0aa5 333 std::unique_ptr<ui_out_level> level (new ui_out_level (type));
56df3084 334
112e8700 335 m_levels.push_back (std::move (level));
80f49b30
AC
336}
337
33b2fac6
SM
338/* Discard the current level. TYPE is the type of the level being
339 discarded. */
112e8700
SM
340void
341ui_out::pop_level (ui_out_type type)
80f49b30 342{
581e13c1 343 /* We had better not underflow the buffer. */
112e8700
SM
344 gdb_assert (m_levels.size () > 0);
345 gdb_assert (current_level ()->type () == type);
346
347 m_levels.pop_back ();
348}
8b93c638 349
581e13c1 350/* Mark beginning of a table. */
8b93c638 351
112e8700
SM
352void
353ui_out::table_begin (int nr_cols, int nr_rows, const std::string &tblid)
8b93c638 354{
112e8700 355 if (m_table_up != nullptr)
8e65ff28 356 internal_error (__FILE__, __LINE__,
e2e0b3e5
AC
357 _("tables cannot be nested; table_begin found before \
358previous table_end."));
8b93c638 359
112e8700 360 m_table_up.reset (new ui_out_table (level () + 1, nr_cols, tblid));
95a23284 361
112e8700 362 do_table_begin (nr_cols, nr_rows, tblid.c_str ());
8b93c638
JM
363}
364
365void
112e8700
SM
366ui_out::table_header (int width, ui_align alignment,
367 const std::string &col_name, const std::string &col_hdr)
8b93c638 368{
112e8700 369 if (m_table_up == nullptr)
8e65ff28 370 internal_error (__FILE__, __LINE__,
112e8700
SM
371 _("table_header outside a table is not valid; it must be \
372after a table_begin and before a table_body."));
77a179e7 373
112e8700 374 m_table_up->append_header (width, alignment, col_name, col_hdr);
8b93c638 375
112e8700 376 do_table_header (width, alignment, col_name, col_hdr);
8b93c638
JM
377}
378
112e8700
SM
379void
380ui_out::table_body ()
8b93c638 381{
112e8700 382 if (m_table_up == nullptr)
8e65ff28 383 internal_error (__FILE__, __LINE__,
112e8700
SM
384 _("table_body outside a table is not valid; it must be "
385 "after a table_begin and before a table_end."));
8b93c638 386
112e8700 387 m_table_up->start_body ();
36d18bc5 388
112e8700 389 do_table_body ();
8b93c638
JM
390}
391
392void
112e8700 393ui_out::table_end ()
8b93c638 394{
112e8700 395 if (m_table_up == nullptr)
8e65ff28 396 internal_error (__FILE__, __LINE__,
112e8700 397 _("misplaced table_end or missing table_begin."));
8b93c638 398
112e8700 399 do_table_end ();
8b93c638 400
112e8700 401 m_table_up = nullptr;
8b93c638
JM
402}
403
404void
112e8700 405ui_out::begin (ui_out_type type, const char *id)
8b93c638 406{
a6c47c14
AC
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. */
414 {
415 int fldno;
416 int width;
112e8700 417 ui_align align;
5d502164 418
112e8700 419 verify_field (&fldno, &width, &align);
a6c47c14
AC
420 }
421
112e8700 422 push_level (type);
a6c47c14
AC
423
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. */
112e8700
SM
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 ();
a6c47c14 430
112e8700 431 do_begin (type, id);
631ec795
AC
432}
433
631ec795 434void
112e8700 435ui_out::end (ui_out_type type)
631ec795 436{
112e8700 437 pop_level (type);
5d502164 438
112e8700 439 do_end (type);
8b93c638
JM
440}
441
8b93c638 442void
381befee 443ui_out::field_signed (const char *fldname, LONGEST value)
8b93c638
JM
444{
445 int fldno;
446 int width;
112e8700 447 ui_align align;
8b93c638 448
112e8700 449 verify_field (&fldno, &width, &align);
8b93c638 450
381befee 451 do_field_signed (fldno, width, align, fldname, value);
8b93c638
JM
452}
453
52c6a6ac 454void
381befee
TT
455ui_out::field_fmt_signed (int input_width, ui_align input_align,
456 const char *fldname, LONGEST value)
52c6a6ac
JJ
457{
458 int fldno;
459 int width;
112e8700 460 ui_align align;
52c6a6ac 461
112e8700 462 verify_field (&fldno, &width, &align);
52c6a6ac 463
381befee 464 do_field_signed (fldno, input_width, input_align, fldname, value);
52c6a6ac
JJ
465}
466
1f77b012
TT
467/* See ui-out.h. */
468
469void
470ui_out::field_unsigned (const char *fldname, ULONGEST value)
471{
472 int fldno;
473 int width;
474 ui_align align;
475
476 verify_field (&fldno, &width, &align);
477
478 do_field_unsigned (fldno, width, align, fldname, value);
479}
480
15230f37
TJB
481/* Documented in ui-out.h. */
482
8b93c638 483void
112e8700
SM
484ui_out::field_core_addr (const char *fldname, struct gdbarch *gdbarch,
485 CORE_ADDR address)
8b93c638 486{
35fb8261 487 field_string (fldname, print_core_address (gdbarch, address),
e43b10e1 488 address_style.style ());
8b93c638
JM
489}
490
491void
cbe56571 492ui_out::field_stream (const char *fldname, string_file &stream,
e43b10e1 493 const ui_file_style &style)
8b93c638 494{
d7e74731 495 if (!stream.empty ())
cbe56571 496 field_string (fldname, stream.c_str (), style);
8b93c638 497 else
112e8700 498 field_skip (fldname);
d7e74731 499 stream.clear ();
8b93c638
JM
500}
501
581e13c1 502/* Used to omit a field. */
8b93c638
JM
503
504void
112e8700 505ui_out::field_skip (const char *fldname)
8b93c638
JM
506{
507 int fldno;
508 int width;
112e8700 509 ui_align align;
8b93c638 510
112e8700 511 verify_field (&fldno, &width, &align);
8b93c638 512
112e8700 513 do_field_skip (fldno, width, align, fldname);
8b93c638
JM
514}
515
516void
cbe56571 517ui_out::field_string (const char *fldname, const char *string,
e43b10e1 518 const ui_file_style &style)
8b93c638
JM
519{
520 int fldno;
521 int width;
112e8700 522 ui_align align;
8b93c638 523
112e8700 524 verify_field (&fldno, &width, &align);
8b93c638 525
cbe56571 526 do_field_string (fldno, width, align, fldname, string, style);
8b93c638
JM
527}
528
6fb16ce6
SM
529void
530ui_out::field_string (const char *fldname, const std::string &string)
531{
532 field_string (fldname, string.c_str ());
533}
534
8b93c638
JM
535/* VARARGS */
536void
112e8700 537ui_out::field_fmt (const char *fldname, const char *format, ...)
8b93c638
JM
538{
539 va_list args;
540 int fldno;
541 int width;
112e8700 542 ui_align align;
8b93c638 543
112e8700 544 verify_field (&fldno, &width, &align);
8b93c638
JM
545
546 va_start (args, format);
547
112e8700 548 do_field_fmt (fldno, width, align, fldname, format, args);
8b93c638
JM
549
550 va_end (args);
551}
552
553void
112e8700 554ui_out::spaces (int numspaces)
8b93c638 555{
112e8700 556 do_spaces (numspaces);
8b93c638
JM
557}
558
559void
112e8700 560ui_out::text (const char *string)
8b93c638 561{
112e8700 562 do_text (string);
8b93c638
JM
563}
564
565void
112e8700 566ui_out::message (const char *format, ...)
8b93c638
JM
567{
568 va_list args;
569
570 va_start (args, format);
112e8700 571 do_message (format, args);
8b93c638
JM
572 va_end (args);
573}
574
8b93c638 575void
112e8700 576ui_out::wrap_hint (const char *identstring)
8b93c638 577{
112e8700 578 do_wrap_hint (identstring);
8b93c638
JM
579}
580
581void
112e8700 582ui_out::flush ()
8b93c638 583{
112e8700 584 do_flush ();
8b93c638
JM
585}
586
7becfd03 587void
112e8700 588ui_out::redirect (ui_file *outstream)
0fac0b41 589{
7becfd03 590 do_redirect (outstream);
0fac0b41
DJ
591}
592
581e13c1 593/* Test the flags against the mask given. */
112e8700
SM
594ui_out_flags
595ui_out::test_flags (ui_out_flags mask)
8b93c638 596{
112e8700 597 return m_flags & mask;
8b93c638
JM
598}
599
112e8700 600bool
4904c3c6 601ui_out::is_mi_like_p () const
8b93c638 602{
112e8700 603 return do_is_mi_like_p ();
0fac0b41
DJ
604}
605
a6c47c14
AC
606/* Verify that the field/tuple/list is correctly positioned. Return
607 the field number and corresponding alignment (if
608 available/applicable). */
8b93c638 609
112e8700
SM
610void
611ui_out::verify_field (int *fldno, int *width, ui_align *align)
8b93c638 612{
112e8700 613 ui_out_level *current = current_level ();
c5209615 614 const char *text;
a6c47c14 615
112e8700
SM
616 if (m_table_up != nullptr
617 && m_table_up->current_state () != ui_out_table::state::BODY)
8b93c638 618 {
77a179e7
SM
619 internal_error (__FILE__, __LINE__,
620 _("table_body missing; table fields must be \
e2e0b3e5 621specified after table_body and inside a list."));
8b93c638 622 }
8b93c638 623
909c0aa5 624 current->inc_field_count ();
8b93c638 625
112e8700
SM
626 if (m_table_up != nullptr
627 && m_table_up->current_state () == ui_out_table::state::BODY
628 && m_table_up->entry_level () == level ()
629 && m_table_up->get_next_header (fldno, width, align, &text))
8b93c638 630 {
909c0aa5 631 if (*fldno != current->field_count ())
8e65ff28 632 internal_error (__FILE__, __LINE__,
e2e0b3e5 633 _("ui-out internal error in handling headers."));
8b93c638
JM
634 }
635 else
636 {
637 *width = 0;
638 *align = ui_noalign;
909c0aa5 639 *fldno = current->field_count ();
8b93c638
JM
640 }
641}
642
170b53b2 643/* Access table field parameters. */
112e8700
SM
644
645bool
646ui_out::query_table_field (int colno, int *width, int *alignment,
647 const char **col_name)
170b53b2 648{
112e8700
SM
649 if (m_table_up == nullptr)
650 return false;
170b53b2 651
112e8700 652 return m_table_up->query_field (colno, width, alignment, col_name);
170b53b2
UW
653}
654
112e8700 655/* The constructor. */
8b93c638 656
112e8700
SM
657ui_out::ui_out (ui_out_flags flags)
658: m_flags (flags)
8b93c638 659{
33b2fac6 660 /* Create the ui-out level #1, the default level. */
112e8700
SM
661 push_level (ui_out_type_tuple);
662}
54eb231c 663
112e8700
SM
664ui_out::~ui_out ()
665{
8b93c638 666}
This page took 2.062362 seconds and 4 git commands to generate.