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