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