]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/ui-out.c
Fix internal error when relaxing branches to STT_SECTION symbols.
[thirdparty/binutils-gdb.git] / gdb / ui-out.c
CommitLineData
8b93c638 1/* Output generating routines for GDB.
349c5d5f 2
618f726f 3 Copyright (C) 1999-2016 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
8b93c638
JM
32/* table header structures */
33
34struct ui_out_hdr
35 {
36 int colno;
37 int width;
f486487f 38 enum ui_align alignment;
b25959ec 39 char *col_name;
8b93c638
JM
40 char *colhdr;
41 struct ui_out_hdr *next;
42 };
43
80f49b30
AC
44struct ui_out_level
45 {
581e13c1 46 /* Count each field; the first element is for non-list fields. */
80f49b30 47 int field_count;
581e13c1 48 /* The type of this level. */
631ec795 49 enum ui_out_type type;
80f49b30
AC
50 };
51
54eb231c 52
bafdd3b3
AC
53/* Tables are special. Maintain a separate structure that tracks
54 their state. At present an output can only contain a single table
55 but that restriction might eventually be lifted. */
56
57struct ui_out_table
58{
59 /* If on, a table is being generated. */
60 int flag;
61
62 /* If on, the body of a table is being generated. If off, the table
63 header is being generated. */
64 int body_flag;
65
a6c47c14
AC
66 /* The level at which each entry of the table is to be found. A row
67 (a tuple) is made up of entries. Consequently ENTRY_LEVEL is one
68 above that of the table. */
69 int entry_level;
70
bafdd3b3
AC
71 /* Number of table columns (as specified in the table_begin call). */
72 int columns;
73
74 /* String identifying the table (as specified in the table_begin
75 call). */
95a23284 76 std::string id;
bafdd3b3
AC
77
78 /* Points to the first table header (if any). */
79 struct ui_out_hdr *header_first;
80
81 /* Points to the last table header (if any). */
82 struct ui_out_hdr *header_last;
83
84 /* Points to header of NEXT column to format. */
85 struct ui_out_hdr *header_next;
86
87};
88
89
8b93c638 90/* The ui_out structure */
8b93c638
JM
91
92struct ui_out
93 {
94 int flags;
581e13c1 95 /* Specific implementation of ui-out. */
89de4da4 96 const struct ui_out_impl *impl;
0a8fce9a 97 void *data;
8b93c638 98
54eb231c 99 /* Current level. */
80f49b30 100 int level;
54eb231c
PM
101
102 /* Vector to store and track the ui-out levels. */
56df3084 103 std::vector<std::unique_ptr<ui_out_level>> levels;
8b93c638 104
bafdd3b3
AC
105 /* A table, if any. At present only a single table is supported. */
106 struct ui_out_table table;
8b93c638
JM
107 };
108
581e13c1 109/* The current (inner most) level. */
80f49b30
AC
110static struct ui_out_level *
111current_level (struct ui_out *uiout)
112{
56df3084 113 return uiout->levels[uiout->level].get ();
80f49b30
AC
114}
115
581e13c1 116/* Create a new level, of TYPE. Return the new level's index. */
80f49b30
AC
117static int
118push_level (struct ui_out *uiout,
49d06418 119 enum ui_out_type type)
80f49b30 120{
56df3084 121 std::unique_ptr<ui_out_level> current (new ui_out_level ());
5d502164 122
80f49b30 123 current->field_count = 0;
631ec795 124 current->type = type;
56df3084
SM
125
126 uiout->level++;
127 uiout->levels.push_back (std::move (current));
128
80f49b30
AC
129 return uiout->level;
130}
131
132/* Discard the current level, return the discarded level's index.
581e13c1 133 TYPE is the type of the level being discarded. */
80f49b30 134static int
631ec795
AC
135pop_level (struct ui_out *uiout,
136 enum ui_out_type type)
80f49b30 137{
581e13c1 138 /* We had better not underflow the buffer. */
54eb231c 139 gdb_assert (uiout->level > 0);
631ec795 140 gdb_assert (current_level (uiout)->type == type);
56df3084
SM
141
142 uiout->levels.pop_back ();
80f49b30 143 uiout->level--;
56df3084 144
80f49b30
AC
145 return uiout->level + 1;
146}
147
581e13c1 148/* These are the interfaces to implementation functions. */
8b93c638 149
88379baf 150static void uo_table_begin (struct ui_out *uiout, int nbrofcols,
d63f1d40 151 int nr_rows, const char *tblid);
8b93c638
JM
152static void uo_table_body (struct ui_out *uiout);
153static void uo_table_end (struct ui_out *uiout);
154static void uo_table_header (struct ui_out *uiout, int width,
b25959ec
AC
155 enum ui_align align, const char *col_name,
156 const char *colhdr);
631ec795
AC
157static void uo_begin (struct ui_out *uiout,
158 enum ui_out_type type,
159 int level, const char *id);
160static void uo_end (struct ui_out *uiout,
161 enum ui_out_type type,
162 int level);
8b93c638 163static void uo_field_int (struct ui_out *uiout, int fldno, int width,
88379baf 164 enum ui_align align, const char *fldname, int value);
8b93c638 165static void uo_field_skip (struct ui_out *uiout, int fldno, int width,
88379baf 166 enum ui_align align, const char *fldname);
8b93c638 167static void uo_field_fmt (struct ui_out *uiout, int fldno, int width,
88379baf 168 enum ui_align align, const char *fldname,
bee0189a 169 const char *format, va_list args)
a0b31db1 170 ATTRIBUTE_PRINTF (6, 0);
8b93c638 171static void uo_spaces (struct ui_out *uiout, int numspaces);
88379baf 172static void uo_text (struct ui_out *uiout, const char *string);
7fb048a2 173static void uo_message (struct ui_out *uiout,
bee0189a 174 const char *format, va_list args)
7fb048a2 175 ATTRIBUTE_PRINTF (2, 0);
d2c0eef4 176static void uo_wrap_hint (struct ui_out *uiout, const char *identstring);
8b93c638 177static void uo_flush (struct ui_out *uiout);
0fac0b41 178static int uo_redirect (struct ui_out *uiout, struct ui_file *outstream);
8b93c638
JM
179
180/* Prototypes for local functions */
181
88379baf 182static void append_header_to_list (struct ui_out *uiout, int width,
f486487f 183 enum ui_align alignment, const char *col_name,
b25959ec 184 const char *colhdr);
bafdd3b3 185static int get_next_header (struct ui_out *uiout, int *colno, int *width,
f486487f 186 enum ui_align *alignment, char **colhdr);
8b93c638 187static void clear_header_list (struct ui_out *uiout);
b65a2bd9 188static void clear_table (struct ui_out *uiout);
a6c47c14 189static void verify_field (struct ui_out *uiout, int *fldno, int *width,
f486487f 190 enum ui_align *align);
8b93c638 191
8b93c638
JM
192/* exported functions (ui_out API) */
193
581e13c1 194/* Mark beginning of a table. */
8b93c638 195
3b31d625 196static void
88379baf 197ui_out_table_begin (struct ui_out *uiout, int nbrofcols,
95a23284 198 int nr_rows, const std::string &tblid)
8b93c638 199{
bafdd3b3 200 if (uiout->table.flag)
8e65ff28 201 internal_error (__FILE__, __LINE__,
e2e0b3e5
AC
202 _("tables cannot be nested; table_begin found before \
203previous table_end."));
8b93c638 204
bafdd3b3
AC
205 uiout->table.flag = 1;
206 uiout->table.body_flag = 0;
a6c47c14 207 uiout->table.entry_level = uiout->level + 1;
bafdd3b3 208 uiout->table.columns = nbrofcols;
95a23284
SM
209 uiout->table.id = tblid;
210
8b93c638
JM
211 clear_header_list (uiout);
212
95a23284 213 uo_table_begin (uiout, nbrofcols, nr_rows, uiout->table.id.c_str ());
8b93c638
JM
214}
215
216void
fba45db2 217ui_out_table_body (struct ui_out *uiout)
8b93c638 218{
bafdd3b3 219 if (!uiout->table.flag)
8e65ff28 220 internal_error (__FILE__, __LINE__,
e2e0b3e5
AC
221 _("table_body outside a table is not valid; it must be \
222after a table_begin and before a table_end."));
bafdd3b3 223 if (uiout->table.body_flag)
8e65ff28 224 internal_error (__FILE__, __LINE__,
e2e0b3e5
AC
225 _("extra table_body call not allowed; there must be \
226only one table_body after a table_begin and before a table_end."));
bafdd3b3 227 if (uiout->table.header_next->colno != uiout->table.columns)
8e65ff28 228 internal_error (__FILE__, __LINE__,
e2e0b3e5
AC
229 _("number of headers differ from number of table \
230columns."));
8b93c638 231
bafdd3b3
AC
232 uiout->table.body_flag = 1;
233 uiout->table.header_next = uiout->table.header_first;
8b93c638
JM
234
235 uo_table_body (uiout);
236}
237
3b31d625 238static void
fba45db2 239ui_out_table_end (struct ui_out *uiout)
8b93c638 240{
bafdd3b3 241 if (!uiout->table.flag)
8e65ff28 242 internal_error (__FILE__, __LINE__,
e2e0b3e5 243 _("misplaced table_end or missing table_begin."));
8b93c638 244
a6c47c14 245 uiout->table.entry_level = 0;
bafdd3b3
AC
246 uiout->table.body_flag = 0;
247 uiout->table.flag = 0;
8b93c638
JM
248
249 uo_table_end (uiout);
b65a2bd9 250 clear_table (uiout);
8b93c638
JM
251}
252
253void
fba45db2 254ui_out_table_header (struct ui_out *uiout, int width, enum ui_align alignment,
b25959ec 255 const char *col_name,
88379baf 256 const char *colhdr)
8b93c638 257{
bafdd3b3 258 if (!uiout->table.flag || uiout->table.body_flag)
8e65ff28 259 internal_error (__FILE__, __LINE__,
e2e0b3e5
AC
260 _("table header must be specified after table_begin \
261and before table_body."));
8b93c638 262
b25959ec 263 append_header_to_list (uiout, width, alignment, col_name, colhdr);
8b93c638 264
b25959ec 265 uo_table_header (uiout, width, alignment, col_name, colhdr);
8b93c638
JM
266}
267
3b31d625
EZ
268static void
269do_cleanup_table_end (void *data)
270{
19ba03f4 271 struct ui_out *ui_out = (struct ui_out *) data;
3b31d625
EZ
272
273 ui_out_table_end (ui_out);
274}
275
276struct cleanup *
277make_cleanup_ui_out_table_begin_end (struct ui_out *ui_out, int nr_cols,
278 int nr_rows, const char *tblid)
279{
280 ui_out_table_begin (ui_out, nr_cols, nr_rows, tblid);
281 return make_cleanup (do_cleanup_table_end, ui_out);
282}
283
8b93c638 284void
631ec795
AC
285ui_out_begin (struct ui_out *uiout,
286 enum ui_out_type type,
287 const char *id)
8b93c638 288{
80f49b30 289 int new_level;
5d502164 290
bafdd3b3 291 if (uiout->table.flag && !uiout->table.body_flag)
8e65ff28 292 internal_error (__FILE__, __LINE__,
e2e0b3e5
AC
293 _("table header or table_body expected; lists must be \
294specified after table_body."));
a6c47c14
AC
295
296 /* Be careful to verify the ``field'' before the new tuple/list is
297 pushed onto the stack. That way the containing list/table/row is
298 verified and not the newly created tuple/list. This verification
299 is needed (at least) for the case where a table row entry
300 contains either a tuple/list. For that case bookkeeping such as
301 updating the column count or advancing to the next heading still
302 needs to be performed. */
303 {
304 int fldno;
305 int width;
f486487f 306 enum ui_align align;
5d502164 307
a6c47c14
AC
308 verify_field (uiout, &fldno, &width, &align);
309 }
310
49d06418 311 new_level = push_level (uiout, type);
a6c47c14
AC
312
313 /* If the push puts us at the same level as a table row entry, we've
314 got a new table row. Put the header pointer back to the start. */
315 if (uiout->table.body_flag
316 && uiout->table.entry_level == new_level)
bafdd3b3 317 uiout->table.header_next = uiout->table.header_first;
a6c47c14 318
631ec795
AC
319 uo_begin (uiout, type, new_level, id);
320}
321
631ec795
AC
322void
323ui_out_end (struct ui_out *uiout,
324 enum ui_out_type type)
325{
326 int old_level = pop_level (uiout, type);
5d502164 327
631ec795 328 uo_end (uiout, type, old_level);
8b93c638
JM
329}
330
127431f9
AC
331struct ui_out_end_cleanup_data
332{
333 struct ui_out *uiout;
334 enum ui_out_type type;
335};
336
e6e0bfab 337static void
127431f9
AC
338do_cleanup_end (void *data)
339{
19ba03f4
SM
340 struct ui_out_end_cleanup_data *end_cleanup_data
341 = (struct ui_out_end_cleanup_data *) data;
5d502164 342
127431f9
AC
343 ui_out_end (end_cleanup_data->uiout, end_cleanup_data->type);
344 xfree (end_cleanup_data);
345}
346
347static struct cleanup *
348make_cleanup_ui_out_end (struct ui_out *uiout,
349 enum ui_out_type type)
350{
351 struct ui_out_end_cleanup_data *end_cleanup_data;
5d502164 352
70ba0933 353 end_cleanup_data = XNEW (struct ui_out_end_cleanup_data);
127431f9
AC
354 end_cleanup_data->uiout = uiout;
355 end_cleanup_data->type = type;
356 return make_cleanup (do_cleanup_end, end_cleanup_data);
357}
358
e6e0bfab 359struct cleanup *
666547aa
AC
360make_cleanup_ui_out_tuple_begin_end (struct ui_out *uiout,
361 const char *id)
362{
3b31d625 363 ui_out_begin (uiout, ui_out_type_tuple, id);
666547aa
AC
364 return make_cleanup_ui_out_end (uiout, ui_out_type_tuple);
365}
366
367struct cleanup *
6b28c186
AC
368make_cleanup_ui_out_list_begin_end (struct ui_out *uiout,
369 const char *id)
e6e0bfab 370{
3b31d625 371 ui_out_begin (uiout, ui_out_type_list, id);
127431f9 372 return make_cleanup_ui_out_end (uiout, ui_out_type_list);
e6e0bfab
MK
373}
374
8b93c638 375void
88379baf
AC
376ui_out_field_int (struct ui_out *uiout,
377 const char *fldname,
378 int value)
8b93c638
JM
379{
380 int fldno;
381 int width;
f486487f 382 enum ui_align align;
8b93c638 383
a6c47c14 384 verify_field (uiout, &fldno, &width, &align);
8b93c638
JM
385
386 uo_field_int (uiout, fldno, width, align, fldname, value);
387}
388
52c6a6ac
JJ
389void
390ui_out_field_fmt_int (struct ui_out *uiout,
391 int input_width,
392 enum ui_align input_align,
393 const char *fldname,
394 int value)
395{
396 int fldno;
397 int width;
f486487f 398 enum ui_align align;
52c6a6ac
JJ
399
400 verify_field (uiout, &fldno, &width, &align);
401
402 uo_field_int (uiout, fldno, input_width, input_align, fldname, value);
403}
404
15230f37
TJB
405/* Documented in ui-out.h. */
406
8b93c638 407void
88379baf
AC
408ui_out_field_core_addr (struct ui_out *uiout,
409 const char *fldname,
5af949e3 410 struct gdbarch *gdbarch,
88379baf 411 CORE_ADDR address)
8b93c638 412{
f1310107
TJB
413 ui_out_field_string (uiout, fldname,
414 print_core_address (gdbarch, address));
8b93c638
JM
415}
416
417void
88379baf
AC
418ui_out_field_stream (struct ui_out *uiout,
419 const char *fldname,
f99d8bf4 420 struct ui_file *stream)
8b93c638 421{
56dbf317 422 std::string buffer = ui_file_as_string (stream);
5d502164 423
56dbf317
PA
424 if (!buffer.empty ())
425 ui_out_field_string (uiout, fldname, buffer.c_str ());
8b93c638
JM
426 else
427 ui_out_field_skip (uiout, fldname);
f99d8bf4 428 ui_file_rewind (stream);
8b93c638
JM
429}
430
581e13c1 431/* Used to omit a field. */
8b93c638
JM
432
433void
88379baf
AC
434ui_out_field_skip (struct ui_out *uiout,
435 const char *fldname)
8b93c638
JM
436{
437 int fldno;
438 int width;
f486487f 439 enum ui_align align;
8b93c638 440
a6c47c14 441 verify_field (uiout, &fldno, &width, &align);
8b93c638
JM
442
443 uo_field_skip (uiout, fldno, width, align, fldname);
444}
445
446void
447ui_out_field_string (struct ui_out *uiout,
88379baf 448 const char *fldname,
8b93c638
JM
449 const char *string)
450{
451 int fldno;
452 int width;
f486487f 453 enum ui_align align;
8b93c638 454
a6c47c14 455 verify_field (uiout, &fldno, &width, &align);
8b93c638
JM
456
457 uo_field_string (uiout, fldno, width, align, fldname, string);
458}
459
460/* VARARGS */
461void
88379baf
AC
462ui_out_field_fmt (struct ui_out *uiout,
463 const char *fldname,
464 const char *format, ...)
8b93c638
JM
465{
466 va_list args;
467 int fldno;
468 int width;
f486487f 469 enum ui_align align;
8b93c638 470
581e13c1 471 /* Will not align, but has to call anyway. */
a6c47c14 472 verify_field (uiout, &fldno, &width, &align);
8b93c638
JM
473
474 va_start (args, format);
475
476 uo_field_fmt (uiout, fldno, width, align, fldname, format, args);
477
478 va_end (args);
479}
480
481void
fba45db2 482ui_out_spaces (struct ui_out *uiout, int numspaces)
8b93c638
JM
483{
484 uo_spaces (uiout, numspaces);
485}
486
487void
88379baf
AC
488ui_out_text (struct ui_out *uiout,
489 const char *string)
8b93c638
JM
490{
491 uo_text (uiout, string);
492}
493
494void
7fb048a2 495ui_out_message (struct ui_out *uiout, const char *format, ...)
8b93c638
JM
496{
497 va_list args;
498
499 va_start (args, format);
7fb048a2 500 uo_message (uiout, format, args);
8b93c638
JM
501 va_end (args);
502}
503
8b93c638 504void
d2c0eef4 505ui_out_wrap_hint (struct ui_out *uiout, const char *identstring)
8b93c638
JM
506{
507 uo_wrap_hint (uiout, identstring);
508}
509
510void
fba45db2 511ui_out_flush (struct ui_out *uiout)
8b93c638
JM
512{
513 uo_flush (uiout);
514}
515
0fac0b41
DJ
516int
517ui_out_redirect (struct ui_out *uiout, struct ui_file *outstream)
518{
519 return uo_redirect (uiout, outstream);
520}
521
581e13c1 522/* Test the flags against the mask given. */
8b93c638 523int
fba45db2 524ui_out_test_flags (struct ui_out *uiout, int mask)
8b93c638
JM
525{
526 return (uiout->flags & mask);
527}
528
9dc5e2a9
AC
529int
530ui_out_is_mi_like_p (struct ui_out *uiout)
531{
532 return uiout->impl->is_mi_like_p;
533}
534
581e13c1 535/* Interface to the implementation functions. */
8b93c638
JM
536
537void
88379baf 538uo_table_begin (struct ui_out *uiout, int nbrofcols,
d63f1d40 539 int nr_rows,
88379baf 540 const char *tblid)
8b93c638
JM
541{
542 if (!uiout->impl->table_begin)
543 return;
d63f1d40 544 uiout->impl->table_begin (uiout, nbrofcols, nr_rows, tblid);
8b93c638
JM
545}
546
547void
548uo_table_body (struct ui_out *uiout)
549{
550 if (!uiout->impl->table_body)
551 return;
552 uiout->impl->table_body (uiout);
553}
554
555void
556uo_table_end (struct ui_out *uiout)
557{
558 if (!uiout->impl->table_end)
559 return;
560 uiout->impl->table_end (uiout);
561}
562
563void
88379baf 564uo_table_header (struct ui_out *uiout, int width, enum ui_align align,
b25959ec 565 const char *col_name,
88379baf 566 const char *colhdr)
8b93c638
JM
567{
568 if (!uiout->impl->table_header)
569 return;
b25959ec 570 uiout->impl->table_header (uiout, width, align, col_name, colhdr);
8b93c638
JM
571}
572
b65a2bd9
SCR
573/* Clear the table associated with UIOUT. */
574
575static void
576clear_table (struct ui_out *uiout)
577{
95a23284 578 uiout->table.id.clear ();
b65a2bd9
SCR
579 clear_header_list (uiout);
580}
581
8b93c638 582void
631ec795
AC
583uo_begin (struct ui_out *uiout,
584 enum ui_out_type type,
585 int level,
586 const char *id)
8b93c638 587{
631ec795 588 if (uiout->impl->begin == NULL)
8b93c638 589 return;
631ec795 590 uiout->impl->begin (uiout, type, level, id);
8b93c638
JM
591}
592
593void
631ec795
AC
594uo_end (struct ui_out *uiout,
595 enum ui_out_type type,
596 int level)
8b93c638 597{
631ec795 598 if (uiout->impl->end == NULL)
8b93c638 599 return;
631ec795 600 uiout->impl->end (uiout, type, level);
8b93c638
JM
601}
602
603void
88379baf
AC
604uo_field_int (struct ui_out *uiout, int fldno, int width, enum ui_align align,
605 const char *fldname,
606 int value)
8b93c638
JM
607{
608 if (!uiout->impl->field_int)
609 return;
610 uiout->impl->field_int (uiout, fldno, width, align, fldname, value);
611}
612
613void
88379baf
AC
614uo_field_skip (struct ui_out *uiout, int fldno, int width, enum ui_align align,
615 const char *fldname)
8b93c638
JM
616{
617 if (!uiout->impl->field_skip)
618 return;
619 uiout->impl->field_skip (uiout, fldno, width, align, fldname);
620}
621
622void
623uo_field_string (struct ui_out *uiout, int fldno, int width,
88379baf
AC
624 enum ui_align align,
625 const char *fldname,
626 const char *string)
8b93c638
JM
627{
628 if (!uiout->impl->field_string)
629 return;
630 uiout->impl->field_string (uiout, fldno, width, align, fldname, string);
631}
632
633void
88379baf
AC
634uo_field_fmt (struct ui_out *uiout, int fldno, int width, enum ui_align align,
635 const char *fldname,
636 const char *format,
637 va_list args)
8b93c638
JM
638{
639 if (!uiout->impl->field_fmt)
640 return;
641 uiout->impl->field_fmt (uiout, fldno, width, align, fldname, format, args);
642}
643
644void
645uo_spaces (struct ui_out *uiout, int numspaces)
646{
647 if (!uiout->impl->spaces)
648 return;
649 uiout->impl->spaces (uiout, numspaces);
650}
651
652void
88379baf
AC
653uo_text (struct ui_out *uiout,
654 const char *string)
8b93c638
JM
655{
656 if (!uiout->impl->text)
657 return;
658 uiout->impl->text (uiout, string);
659}
660
661void
7fb048a2 662uo_message (struct ui_out *uiout,
88379baf
AC
663 const char *format,
664 va_list args)
8b93c638
JM
665{
666 if (!uiout->impl->message)
667 return;
7fb048a2 668 uiout->impl->message (uiout, format, args);
8b93c638
JM
669}
670
671void
d2c0eef4 672uo_wrap_hint (struct ui_out *uiout, const char *identstring)
8b93c638
JM
673{
674 if (!uiout->impl->wrap_hint)
675 return;
676 uiout->impl->wrap_hint (uiout, identstring);
677}
678
679void
680uo_flush (struct ui_out *uiout)
681{
682 if (!uiout->impl->flush)
683 return;
684 uiout->impl->flush (uiout);
685}
686
0fac0b41
DJ
687int
688uo_redirect (struct ui_out *uiout, struct ui_file *outstream)
689{
690 if (!uiout->impl->redirect)
691 return -1;
82bbe65a 692 return uiout->impl->redirect (uiout, outstream);
0fac0b41
DJ
693}
694
8b93c638
JM
695/* local functions */
696
581e13c1 697/* List of column headers manipulation routines. */
8b93c638
JM
698
699static void
fba45db2 700clear_header_list (struct ui_out *uiout)
8b93c638 701{
bafdd3b3 702 while (uiout->table.header_first != NULL)
8b93c638 703 {
bafdd3b3
AC
704 uiout->table.header_next = uiout->table.header_first;
705 uiout->table.header_first = uiout->table.header_first->next;
71bdabee
KS
706 xfree (uiout->table.header_next->colhdr);
707 xfree (uiout->table.header_next->col_name);
5486f164 708 delete uiout->table.header_next;
8b93c638 709 }
5486f164 710
bafdd3b3
AC
711 gdb_assert (uiout->table.header_first == NULL);
712 uiout->table.header_last = NULL;
713 uiout->table.header_next = NULL;
8b93c638
JM
714}
715
716static void
717append_header_to_list (struct ui_out *uiout,
718 int width,
f486487f 719 enum ui_align alignment,
b25959ec 720 const char *col_name,
88379baf 721 const char *colhdr)
8b93c638
JM
722{
723 struct ui_out_hdr *temphdr;
724
5486f164 725 temphdr = new ui_out_hdr ();
8b93c638
JM
726 temphdr->width = width;
727 temphdr->alignment = alignment;
44db85f8
MS
728 /* We have to copy the column title as the original may be an
729 automatic. */
8b93c638 730 if (colhdr != NULL)
b25959ec
AC
731 temphdr->colhdr = xstrdup (colhdr);
732 else
733 temphdr->colhdr = NULL;
44db85f8 734
b25959ec 735 if (col_name != NULL)
44db85f8
MS
736 temphdr->col_name = xstrdup (col_name);
737 else if (colhdr != NULL)
b25959ec
AC
738 temphdr->col_name = xstrdup (colhdr);
739 else
44db85f8
MS
740 temphdr->col_name = NULL;
741
8b93c638 742 temphdr->next = NULL;
bafdd3b3 743 if (uiout->table.header_first == NULL)
8b93c638
JM
744 {
745 temphdr->colno = 1;
bafdd3b3
AC
746 uiout->table.header_first = temphdr;
747 uiout->table.header_last = temphdr;
8b93c638
JM
748 }
749 else
750 {
bafdd3b3
AC
751 temphdr->colno = uiout->table.header_last->colno + 1;
752 uiout->table.header_last->next = temphdr;
753 uiout->table.header_last = temphdr;
8b93c638 754 }
bafdd3b3 755 uiout->table.header_next = uiout->table.header_last;
8b93c638
JM
756}
757
7a9dd1b2 758/* Extract the format information for the NEXT header and advance
bafdd3b3 759 the header pointer. Return 0 if there was no next header. */
8b93c638
JM
760
761static int
bafdd3b3 762get_next_header (struct ui_out *uiout,
8b93c638
JM
763 int *colno,
764 int *width,
f486487f 765 enum ui_align *alignment,
8b93c638
JM
766 char **colhdr)
767{
bafdd3b3
AC
768 /* There may be no headers at all or we may have used all columns. */
769 if (uiout->table.header_next == NULL)
8b93c638 770 return 0;
bafdd3b3
AC
771 *colno = uiout->table.header_next->colno;
772 *width = uiout->table.header_next->width;
773 *alignment = uiout->table.header_next->alignment;
774 *colhdr = uiout->table.header_next->colhdr;
775 /* Advance the header pointer to the next entry. */
776 uiout->table.header_next = uiout->table.header_next->next;
8b93c638
JM
777 return 1;
778}
779
a6c47c14
AC
780
781/* Verify that the field/tuple/list is correctly positioned. Return
782 the field number and corresponding alignment (if
783 available/applicable). */
8b93c638
JM
784
785static void
f486487f
SM
786verify_field (struct ui_out *uiout, int *fldno, int *width,
787 enum ui_align *align)
8b93c638 788{
a6c47c14
AC
789 struct ui_out_level *current = current_level (uiout);
790 char *text;
791
bafdd3b3 792 if (uiout->table.flag)
8b93c638 793 {
bafdd3b3 794 if (!uiout->table.body_flag)
8e65ff28 795 internal_error (__FILE__, __LINE__,
e2e0b3e5
AC
796 _("table_body missing; table fields must be \
797specified after table_body and inside a list."));
a6c47c14
AC
798 /* NOTE: cagney/2001-12-08: There was a check here to ensure
799 that this code was only executed when uiout->level was
800 greater than zero. That no longer applies - this code is run
801 before each table row tuple is started and at that point the
802 level is zero. */
8b93c638 803 }
8b93c638 804
a6c47c14 805 current->field_count += 1;
8b93c638 806
a6c47c14
AC
807 if (uiout->table.body_flag
808 && uiout->table.entry_level == uiout->level
809 && get_next_header (uiout, fldno, width, align, &text))
8b93c638 810 {
a6c47c14 811 if (*fldno != current->field_count)
8e65ff28 812 internal_error (__FILE__, __LINE__,
e2e0b3e5 813 _("ui-out internal error in handling headers."));
8b93c638
JM
814 }
815 else
816 {
817 *width = 0;
818 *align = ui_noalign;
a6c47c14 819 *fldno = current->field_count;
8b93c638
JM
820 }
821}
822
a6c47c14 823
581e13c1 824/* Access to ui-out members data. */
8b93c638 825
0a8fce9a 826void *
8b93c638
JM
827ui_out_data (struct ui_out *uiout)
828{
829 return uiout->data;
830}
831
170b53b2
UW
832/* Access table field parameters. */
833int
834ui_out_query_field (struct ui_out *uiout, int colno,
835 int *width, int *alignment, char **col_name)
836{
837 struct ui_out_hdr *hdr;
838
839 if (!uiout->table.flag)
840 return 0;
841
842 for (hdr = uiout->table.header_first; hdr; hdr = hdr->next)
843 if (hdr->colno == colno)
844 {
845 *width = hdr->width;
846 *alignment = hdr->alignment;
847 *col_name = hdr->col_name;
848 return 1;
849 }
850
851 return 0;
852}
853
26c4b26f 854/* Initialize private members at startup. */
8b93c638
JM
855
856struct ui_out *
89de4da4 857ui_out_new (const struct ui_out_impl *impl, void *data,
8b93c638
JM
858 int flags)
859{
5486f164 860 struct ui_out *uiout = new ui_out ();
56df3084 861 std::unique_ptr<ui_out_level> current (new ui_out_level ());
5d502164 862
8b93c638
JM
863 uiout->data = data;
864 uiout->impl = impl;
865 uiout->flags = flags;
bafdd3b3
AC
866 uiout->table.flag = 0;
867 uiout->table.body_flag = 0;
80f49b30 868 uiout->level = 0;
54eb231c
PM
869
870 /* Create uiout->level 0, the default level. */
871 current->type = ui_out_type_tuple;
872 current->field_count = 0;
56df3084 873 uiout->levels.push_back (std::move (current));
54eb231c 874
bafdd3b3
AC
875 uiout->table.header_first = NULL;
876 uiout->table.header_last = NULL;
877 uiout->table.header_next = NULL;
8b93c638
JM
878 return uiout;
879}