Make struct symbol inherit from general_symbol_info
[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"
284782de 29#include "diagnostics.h"
8b93c638 30
56df3084
SM
31#include <vector>
32#include <memory>
95a23284 33#include <string>
56df3084 34
ffdbe864
YQ
35namespace {
36
37e20dd6 37/* A header of a ui_out_table. */
8b93c638 38
37e20dd6
SM
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)
8b93c638 50 {
37e20dd6
SM
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};
8b93c638 97
ffdbe864
YQ
98} // namespace
99
909c0aa5
SM
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)
80f49b30 109 {
909c0aa5
SM
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};
80f49b30 135
bafdd3b3
AC
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
36d18bc5 140class ui_out_table
bafdd3b3 141{
36d18bc5
SM
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);
bafdd3b3 171
36d18bc5
SM
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;
bafdd3b3 190
a6c47c14
AC
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. */
36d18bc5 194 int m_entry_level;
a6c47c14 195
bafdd3b3 196 /* Number of table columns (as specified in the table_begin call). */
36d18bc5 197 int m_nr_cols;
bafdd3b3
AC
198
199 /* String identifying the table (as specified in the table_begin
200 call). */
36d18bc5 201 std::string m_id;
bafdd3b3 202
78afa7f8 203 /* Pointers to the column headers. */
36d18bc5 204 std::vector<std::unique_ptr<ui_out_hdr>> m_headers;
bafdd3b3 205
78afa7f8 206 /* Iterator over the headers vector, used when printing successive fields. */
36d18bc5 207 std::vector<std::unique_ptr<ui_out_hdr>>::const_iterator m_headers_iterator;
bafdd3b3
AC
208};
209
36d18bc5
SM
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}
bafdd3b3 315
112e8700
SM
316int
317ui_out::level () const
318{
319 return m_levels.size ();
320}
8b93c638 321
581e13c1 322/* The current (inner most) level. */
112e8700
SM
323
324ui_out_level *
325ui_out::current_level () const
80f49b30 326{
112e8700 327 return m_levels.back ().get ();
80f49b30
AC
328}
329
33b2fac6 330/* Create a new level, of TYPE. */
112e8700
SM
331void
332ui_out::push_level (ui_out_type type)
80f49b30 333{
909c0aa5 334 std::unique_ptr<ui_out_level> level (new ui_out_level (type));
56df3084 335
112e8700 336 m_levels.push_back (std::move (level));
80f49b30
AC
337}
338
33b2fac6
SM
339/* Discard the current level. TYPE is the type of the level being
340 discarded. */
112e8700
SM
341void
342ui_out::pop_level (ui_out_type type)
80f49b30 343{
581e13c1 344 /* We had better not underflow the buffer. */
112e8700
SM
345 gdb_assert (m_levels.size () > 0);
346 gdb_assert (current_level ()->type () == type);
347
348 m_levels.pop_back ();
349}
8b93c638 350
581e13c1 351/* Mark beginning of a table. */
8b93c638 352
112e8700
SM
353void
354ui_out::table_begin (int nr_cols, int nr_rows, const std::string &tblid)
8b93c638 355{
112e8700 356 if (m_table_up != nullptr)
8e65ff28 357 internal_error (__FILE__, __LINE__,
e2e0b3e5
AC
358 _("tables cannot be nested; table_begin found before \
359previous table_end."));
8b93c638 360
112e8700 361 m_table_up.reset (new ui_out_table (level () + 1, nr_cols, tblid));
95a23284 362
112e8700 363 do_table_begin (nr_cols, nr_rows, tblid.c_str ());
8b93c638
JM
364}
365
366void
112e8700
SM
367ui_out::table_header (int width, ui_align alignment,
368 const std::string &col_name, const std::string &col_hdr)
8b93c638 369{
112e8700 370 if (m_table_up == nullptr)
8e65ff28 371 internal_error (__FILE__, __LINE__,
112e8700
SM
372 _("table_header outside a table is not valid; it must be \
373after a table_begin and before a table_body."));
77a179e7 374
112e8700 375 m_table_up->append_header (width, alignment, col_name, col_hdr);
8b93c638 376
112e8700 377 do_table_header (width, alignment, col_name, col_hdr);
8b93c638
JM
378}
379
112e8700
SM
380void
381ui_out::table_body ()
8b93c638 382{
112e8700 383 if (m_table_up == nullptr)
8e65ff28 384 internal_error (__FILE__, __LINE__,
112e8700
SM
385 _("table_body outside a table is not valid; it must be "
386 "after a table_begin and before a table_end."));
8b93c638 387
112e8700 388 m_table_up->start_body ();
36d18bc5 389
112e8700 390 do_table_body ();
8b93c638
JM
391}
392
393void
112e8700 394ui_out::table_end ()
8b93c638 395{
112e8700 396 if (m_table_up == nullptr)
8e65ff28 397 internal_error (__FILE__, __LINE__,
112e8700 398 _("misplaced table_end or missing table_begin."));
8b93c638 399
112e8700 400 do_table_end ();
8b93c638 401
112e8700 402 m_table_up = nullptr;
8b93c638
JM
403}
404
405void
112e8700 406ui_out::begin (ui_out_type type, const char *id)
8b93c638 407{
a6c47c14
AC
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;
112e8700 418 ui_align align;
5d502164 419
112e8700 420 verify_field (&fldno, &width, &align);
a6c47c14
AC
421 }
422
112e8700 423 push_level (type);
a6c47c14
AC
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. */
112e8700
SM
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 ();
a6c47c14 431
112e8700 432 do_begin (type, id);
631ec795
AC
433}
434
631ec795 435void
112e8700 436ui_out::end (ui_out_type type)
631ec795 437{
112e8700 438 pop_level (type);
5d502164 439
112e8700 440 do_end (type);
8b93c638
JM
441}
442
8b93c638 443void
381befee 444ui_out::field_signed (const char *fldname, LONGEST value)
8b93c638
JM
445{
446 int fldno;
447 int width;
112e8700 448 ui_align align;
8b93c638 449
112e8700 450 verify_field (&fldno, &width, &align);
8b93c638 451
381befee 452 do_field_signed (fldno, width, align, fldname, value);
8b93c638
JM
453}
454
52c6a6ac 455void
381befee
TT
456ui_out::field_fmt_signed (int input_width, ui_align input_align,
457 const char *fldname, LONGEST value)
52c6a6ac
JJ
458{
459 int fldno;
460 int width;
112e8700 461 ui_align align;
52c6a6ac 462
112e8700 463 verify_field (&fldno, &width, &align);
52c6a6ac 464
381befee 465 do_field_signed (fldno, input_width, input_align, fldname, value);
52c6a6ac
JJ
466}
467
1f77b012
TT
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
15230f37
TJB
482/* Documented in ui-out.h. */
483
8b93c638 484void
112e8700
SM
485ui_out::field_core_addr (const char *fldname, struct gdbarch *gdbarch,
486 CORE_ADDR address)
8b93c638 487{
35fb8261 488 field_string (fldname, print_core_address (gdbarch, address),
e43b10e1 489 address_style.style ());
8b93c638
JM
490}
491
492void
cbe56571 493ui_out::field_stream (const char *fldname, string_file &stream,
e43b10e1 494 const ui_file_style &style)
8b93c638 495{
d7e74731 496 if (!stream.empty ())
cbe56571 497 field_string (fldname, stream.c_str (), style);
8b93c638 498 else
112e8700 499 field_skip (fldname);
d7e74731 500 stream.clear ();
8b93c638
JM
501}
502
581e13c1 503/* Used to omit a field. */
8b93c638
JM
504
505void
112e8700 506ui_out::field_skip (const char *fldname)
8b93c638
JM
507{
508 int fldno;
509 int width;
112e8700 510 ui_align align;
8b93c638 511
112e8700 512 verify_field (&fldno, &width, &align);
8b93c638 513
112e8700 514 do_field_skip (fldno, width, align, fldname);
8b93c638
JM
515}
516
517void
cbe56571 518ui_out::field_string (const char *fldname, const char *string,
e43b10e1 519 const ui_file_style &style)
8b93c638
JM
520{
521 int fldno;
522 int width;
112e8700 523 ui_align align;
8b93c638 524
112e8700 525 verify_field (&fldno, &width, &align);
8b93c638 526
cbe56571 527 do_field_string (fldno, width, align, fldname, string, style);
8b93c638
JM
528}
529
6fb16ce6
SM
530void
531ui_out::field_string (const char *fldname, const std::string &string)
532{
533 field_string (fldname, string.c_str ());
534}
535
8b93c638
JM
536/* VARARGS */
537void
112e8700 538ui_out::field_fmt (const char *fldname, const char *format, ...)
8b93c638
JM
539{
540 va_list args;
541 int fldno;
542 int width;
112e8700 543 ui_align align;
8b93c638 544
112e8700 545 verify_field (&fldno, &width, &align);
8b93c638
JM
546
547 va_start (args, format);
548
7f6aba03
TT
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);
8b93c638
JM
568
569 va_end (args);
570}
571
572void
112e8700 573ui_out::spaces (int numspaces)
8b93c638 574{
112e8700 575 do_spaces (numspaces);
8b93c638
JM
576}
577
578void
112e8700 579ui_out::text (const char *string)
8b93c638 580{
112e8700 581 do_text (string);
8b93c638
JM
582}
583
584void
2a3c1174
PA
585ui_out::call_do_message (const ui_file_style &style, const char *format,
586 ...)
8b93c638
JM
587{
588 va_list args;
589
590 va_start (args, format);
284782de
SM
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
2a3c1174 597 do_message (style, format, args);
284782de
SM
598 DIAGNOSTIC_POP
599
2a3c1174
PA
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 double_arg:
692 call_do_message (style, current_substring, va_arg (args, double));
693 break;
694 case long_double_arg:
695 gdb_assert_not_reached (_("long_double_arg not supported in vmessage"));
696 break;
697 case dec32float_arg:
698 gdb_assert_not_reached (_("dec32float_arg not supported in vmessage"));
699 break;
700 case dec64float_arg:
701 gdb_assert_not_reached (_("dec64float_arg not supported in vmessage"));
702 break;
703 case dec128float_arg:
704 gdb_assert_not_reached (_("dec128float_arg not supported in vmessage"));
705 break;
706 case ptr_arg:
707 switch (current_substring[2])
708 {
709 case 'F':
710 {
711 gdb_assert (!test_flags (disallow_ui_out_field));
712 base_field_s *bf = va_arg (args, base_field_s *);
713 switch (bf->kind)
714 {
715 case field_kind::SIGNED:
716 {
717 auto *f = (signed_field_s *) bf;
718 field_signed (f->name, f->val);
719 }
720 break;
721 case field_kind::STRING:
722 {
723 auto *f = (string_field_s *) bf;
724 field_string (f->name, f->str);
725 }
726 break;
727 }
728 }
729 break;
730 case 's':
731 {
732 styled_string_s *ss = va_arg (args, styled_string_s *);
733 call_do_message (ss->style, "%s", ss->str);
734 }
735 break;
736 case '[':
737 style = *va_arg (args, const ui_file_style *);
738 break;
739 case ']':
740 {
741 void *arg = va_arg (args, void *);
742 gdb_assert (arg == nullptr);
743
744 style = {};
745 }
746 break;
747 default:
748 call_do_message (style, current_substring, va_arg (args, void *));
749 break;
750 }
751 break;
752 case literal_piece:
753 /* Print a portion of the format string that has no
754 directives. Note that this will not include any ordinary
755 %-specs, but it might include "%%". That is why we use
756 call_do_message here. Also, we pass a dummy argument
757 because some platforms have modified GCC to include
758 -Wformat-security by default, which will warn here if
759 there is no argument. */
760 call_do_message (style, current_substring, 0);
761 break;
762 default:
763 internal_error (__FILE__, __LINE__,
764 _("failed internal consistency check"));
765 }
766 }
767}
768
769void
770ui_out::message (const char *format, ...)
771{
772 va_list args;
773 va_start (args, format);
774
775 vmessage (ui_file_style (), format, args);
776
8b93c638
JM
777 va_end (args);
778}
779
8b93c638 780void
112e8700 781ui_out::wrap_hint (const char *identstring)
8b93c638 782{
112e8700 783 do_wrap_hint (identstring);
8b93c638
JM
784}
785
786void
112e8700 787ui_out::flush ()
8b93c638 788{
112e8700 789 do_flush ();
8b93c638
JM
790}
791
7becfd03 792void
112e8700 793ui_out::redirect (ui_file *outstream)
0fac0b41 794{
7becfd03 795 do_redirect (outstream);
0fac0b41
DJ
796}
797
581e13c1 798/* Test the flags against the mask given. */
112e8700
SM
799ui_out_flags
800ui_out::test_flags (ui_out_flags mask)
8b93c638 801{
112e8700 802 return m_flags & mask;
8b93c638
JM
803}
804
112e8700 805bool
4904c3c6 806ui_out::is_mi_like_p () const
8b93c638 807{
112e8700 808 return do_is_mi_like_p ();
0fac0b41
DJ
809}
810
a6c47c14
AC
811/* Verify that the field/tuple/list is correctly positioned. Return
812 the field number and corresponding alignment (if
813 available/applicable). */
8b93c638 814
112e8700
SM
815void
816ui_out::verify_field (int *fldno, int *width, ui_align *align)
8b93c638 817{
112e8700 818 ui_out_level *current = current_level ();
c5209615 819 const char *text;
a6c47c14 820
112e8700
SM
821 if (m_table_up != nullptr
822 && m_table_up->current_state () != ui_out_table::state::BODY)
8b93c638 823 {
77a179e7
SM
824 internal_error (__FILE__, __LINE__,
825 _("table_body missing; table fields must be \
e2e0b3e5 826specified after table_body and inside a list."));
8b93c638 827 }
8b93c638 828
909c0aa5 829 current->inc_field_count ();
8b93c638 830
112e8700
SM
831 if (m_table_up != nullptr
832 && m_table_up->current_state () == ui_out_table::state::BODY
833 && m_table_up->entry_level () == level ()
834 && m_table_up->get_next_header (fldno, width, align, &text))
8b93c638 835 {
909c0aa5 836 if (*fldno != current->field_count ())
8e65ff28 837 internal_error (__FILE__, __LINE__,
e2e0b3e5 838 _("ui-out internal error in handling headers."));
8b93c638
JM
839 }
840 else
841 {
842 *width = 0;
843 *align = ui_noalign;
909c0aa5 844 *fldno = current->field_count ();
8b93c638
JM
845 }
846}
847
170b53b2 848/* Access table field parameters. */
112e8700
SM
849
850bool
851ui_out::query_table_field (int colno, int *width, int *alignment,
852 const char **col_name)
170b53b2 853{
112e8700
SM
854 if (m_table_up == nullptr)
855 return false;
170b53b2 856
112e8700 857 return m_table_up->query_field (colno, width, alignment, col_name);
170b53b2
UW
858}
859
112e8700 860/* The constructor. */
8b93c638 861
112e8700
SM
862ui_out::ui_out (ui_out_flags flags)
863: m_flags (flags)
8b93c638 864{
33b2fac6 865 /* Create the ui-out level #1, the default level. */
112e8700
SM
866 push_level (ui_out_type_tuple);
867}
54eb231c 868
112e8700
SM
869ui_out::~ui_out ()
870{
8b93c638 871}
This page took 3.076367 seconds and 4 git commands to generate.