Fix build failure on macOS
[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;
e06f3d6e
AB
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;
2a3c1174
PA
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 {
28ce7b07 733 case field_kind::FIELD_SIGNED:
2a3c1174
PA
734 {
735 auto *f = (signed_field_s *) bf;
736 field_signed (f->name, f->val);
737 }
738 break;
28ce7b07 739 case field_kind::FIELD_STRING:
2a3c1174
PA
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
8b93c638
JM
795 va_end (args);
796}
797
8b93c638 798void
112e8700 799ui_out::wrap_hint (const char *identstring)
8b93c638 800{
112e8700 801 do_wrap_hint (identstring);
8b93c638
JM
802}
803
804void
112e8700 805ui_out::flush ()
8b93c638 806{
112e8700 807 do_flush ();
8b93c638
JM
808}
809
7becfd03 810void
112e8700 811ui_out::redirect (ui_file *outstream)
0fac0b41 812{
7becfd03 813 do_redirect (outstream);
0fac0b41
DJ
814}
815
581e13c1 816/* Test the flags against the mask given. */
112e8700
SM
817ui_out_flags
818ui_out::test_flags (ui_out_flags mask)
8b93c638 819{
112e8700 820 return m_flags & mask;
8b93c638
JM
821}
822
112e8700 823bool
4904c3c6 824ui_out::is_mi_like_p () const
8b93c638 825{
112e8700 826 return do_is_mi_like_p ();
0fac0b41
DJ
827}
828
a6c47c14
AC
829/* Verify that the field/tuple/list is correctly positioned. Return
830 the field number and corresponding alignment (if
831 available/applicable). */
8b93c638 832
112e8700
SM
833void
834ui_out::verify_field (int *fldno, int *width, ui_align *align)
8b93c638 835{
112e8700 836 ui_out_level *current = current_level ();
c5209615 837 const char *text;
a6c47c14 838
112e8700
SM
839 if (m_table_up != nullptr
840 && m_table_up->current_state () != ui_out_table::state::BODY)
8b93c638 841 {
77a179e7
SM
842 internal_error (__FILE__, __LINE__,
843 _("table_body missing; table fields must be \
e2e0b3e5 844specified after table_body and inside a list."));
8b93c638 845 }
8b93c638 846
909c0aa5 847 current->inc_field_count ();
8b93c638 848
112e8700
SM
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))
8b93c638 853 {
909c0aa5 854 if (*fldno != current->field_count ())
8e65ff28 855 internal_error (__FILE__, __LINE__,
e2e0b3e5 856 _("ui-out internal error in handling headers."));
8b93c638
JM
857 }
858 else
859 {
860 *width = 0;
861 *align = ui_noalign;
909c0aa5 862 *fldno = current->field_count ();
8b93c638
JM
863 }
864}
865
170b53b2 866/* Access table field parameters. */
112e8700
SM
867
868bool
869ui_out::query_table_field (int colno, int *width, int *alignment,
870 const char **col_name)
170b53b2 871{
112e8700
SM
872 if (m_table_up == nullptr)
873 return false;
170b53b2 874
112e8700 875 return m_table_up->query_field (colno, width, alignment, col_name);
170b53b2
UW
876}
877
112e8700 878/* The constructor. */
8b93c638 879
112e8700
SM
880ui_out::ui_out (ui_out_flags flags)
881: m_flags (flags)
8b93c638 882{
33b2fac6 883 /* Create the ui-out level #1, the default level. */
112e8700
SM
884 push_level (ui_out_type_tuple);
885}
54eb231c 886
112e8700
SM
887ui_out::~ui_out ()
888{
8b93c638 889}
This page took 2.296813 seconds and 4 git commands to generate.