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