15796c8dcSSimon Schubert /* Output generating routines for GDB CLI.
25796c8dcSSimon Schubert
3*ef5ccd6cSJohn Marino Copyright (C) 1999-2013 Free Software Foundation, Inc.
45796c8dcSSimon Schubert
55796c8dcSSimon Schubert Contributed by Cygnus Solutions.
65796c8dcSSimon Schubert Written by Fernando Nasser for Cygnus.
75796c8dcSSimon Schubert
85796c8dcSSimon Schubert This file is part of GDB.
95796c8dcSSimon Schubert
105796c8dcSSimon Schubert This program is free software; you can redistribute it and/or modify
115796c8dcSSimon Schubert it under the terms of the GNU General Public License as published by
125796c8dcSSimon Schubert the Free Software Foundation; either version 3 of the License, or
135796c8dcSSimon Schubert (at your option) any later version.
145796c8dcSSimon Schubert
155796c8dcSSimon Schubert This program is distributed in the hope that it will be useful,
165796c8dcSSimon Schubert but WITHOUT ANY WARRANTY; without even the implied warranty of
175796c8dcSSimon Schubert MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
185796c8dcSSimon Schubert GNU General Public License for more details.
195796c8dcSSimon Schubert
205796c8dcSSimon Schubert You should have received a copy of the GNU General Public License
215796c8dcSSimon Schubert along with this program. If not, see <http://www.gnu.org/licenses/>. */
225796c8dcSSimon Schubert
235796c8dcSSimon Schubert #include "defs.h"
245796c8dcSSimon Schubert #include "ui-out.h"
255796c8dcSSimon Schubert #include "cli-out.h"
265796c8dcSSimon Schubert #include "gdb_string.h"
275796c8dcSSimon Schubert #include "gdb_assert.h"
28c50c785cSJohn Marino #include "vec.h"
295796c8dcSSimon Schubert
30cf7f2e2dSJohn Marino typedef struct cli_ui_out_data cli_out_data;
315796c8dcSSimon Schubert
325796c8dcSSimon Schubert
335796c8dcSSimon Schubert /* Prototypes for local functions */
345796c8dcSSimon Schubert
35cf7f2e2dSJohn Marino static void cli_text (struct ui_out *uiout, const char *string);
365796c8dcSSimon Schubert
375796c8dcSSimon Schubert static void field_separator (void);
385796c8dcSSimon Schubert
395796c8dcSSimon Schubert static void out_field_fmt (struct ui_out *uiout, int fldno,
405796c8dcSSimon Schubert const char *fldname,
41cf7f2e2dSJohn Marino const char *format,...) ATTRIBUTE_PRINTF (4, 5);
425796c8dcSSimon Schubert
43cf7f2e2dSJohn Marino /* These are the CLI output functions */
445796c8dcSSimon Schubert
455796c8dcSSimon Schubert /* Mark beginning of a table */
465796c8dcSSimon Schubert
47cf7f2e2dSJohn Marino static void
cli_table_begin(struct ui_out * uiout,int nbrofcols,int nr_rows,const char * tblid)485796c8dcSSimon Schubert cli_table_begin (struct ui_out *uiout, int nbrofcols,
495796c8dcSSimon Schubert int nr_rows,
505796c8dcSSimon Schubert const char *tblid)
515796c8dcSSimon Schubert {
525796c8dcSSimon Schubert cli_out_data *data = ui_out_data (uiout);
53cf7f2e2dSJohn Marino
545796c8dcSSimon Schubert if (nr_rows == 0)
555796c8dcSSimon Schubert data->suppress_output = 1;
565796c8dcSSimon Schubert else
575796c8dcSSimon Schubert /* Only the table suppresses the output and, fortunately, a table
585796c8dcSSimon Schubert is not a recursive data structure. */
595796c8dcSSimon Schubert gdb_assert (data->suppress_output == 0);
605796c8dcSSimon Schubert }
615796c8dcSSimon Schubert
625796c8dcSSimon Schubert /* Mark beginning of a table body */
635796c8dcSSimon Schubert
64cf7f2e2dSJohn Marino static void
cli_table_body(struct ui_out * uiout)655796c8dcSSimon Schubert cli_table_body (struct ui_out *uiout)
665796c8dcSSimon Schubert {
675796c8dcSSimon Schubert cli_out_data *data = ui_out_data (uiout);
68cf7f2e2dSJohn Marino
695796c8dcSSimon Schubert if (data->suppress_output)
705796c8dcSSimon Schubert return;
715796c8dcSSimon Schubert /* first, close the table header line */
725796c8dcSSimon Schubert cli_text (uiout, "\n");
735796c8dcSSimon Schubert }
745796c8dcSSimon Schubert
755796c8dcSSimon Schubert /* Mark end of a table */
765796c8dcSSimon Schubert
77cf7f2e2dSJohn Marino static void
cli_table_end(struct ui_out * uiout)785796c8dcSSimon Schubert cli_table_end (struct ui_out *uiout)
795796c8dcSSimon Schubert {
805796c8dcSSimon Schubert cli_out_data *data = ui_out_data (uiout);
81cf7f2e2dSJohn Marino
825796c8dcSSimon Schubert data->suppress_output = 0;
835796c8dcSSimon Schubert }
845796c8dcSSimon Schubert
855796c8dcSSimon Schubert /* Specify table header */
865796c8dcSSimon Schubert
87cf7f2e2dSJohn Marino static void
cli_table_header(struct ui_out * uiout,int width,enum ui_align alignment,const char * col_name,const char * colhdr)885796c8dcSSimon Schubert cli_table_header (struct ui_out *uiout, int width, enum ui_align alignment,
895796c8dcSSimon Schubert const char *col_name,
905796c8dcSSimon Schubert const char *colhdr)
915796c8dcSSimon Schubert {
925796c8dcSSimon Schubert cli_out_data *data = ui_out_data (uiout);
93cf7f2e2dSJohn Marino
945796c8dcSSimon Schubert if (data->suppress_output)
955796c8dcSSimon Schubert return;
96cf7f2e2dSJohn Marino
97cf7f2e2dSJohn Marino /* Always go through the function pointer (virtual function call).
98cf7f2e2dSJohn Marino We may have been extended. */
99cf7f2e2dSJohn Marino uo_field_string (uiout, 0, width, alignment, 0, colhdr);
1005796c8dcSSimon Schubert }
1015796c8dcSSimon Schubert
1025796c8dcSSimon Schubert /* Mark beginning of a list */
1035796c8dcSSimon Schubert
104cf7f2e2dSJohn Marino static void
cli_begin(struct ui_out * uiout,enum ui_out_type type,int level,const char * id)1055796c8dcSSimon Schubert cli_begin (struct ui_out *uiout,
1065796c8dcSSimon Schubert enum ui_out_type type,
1075796c8dcSSimon Schubert int level,
1085796c8dcSSimon Schubert const char *id)
1095796c8dcSSimon Schubert {
1105796c8dcSSimon Schubert cli_out_data *data = ui_out_data (uiout);
111cf7f2e2dSJohn Marino
1125796c8dcSSimon Schubert if (data->suppress_output)
1135796c8dcSSimon Schubert return;
1145796c8dcSSimon Schubert }
1155796c8dcSSimon Schubert
1165796c8dcSSimon Schubert /* Mark end of a list */
1175796c8dcSSimon Schubert
118cf7f2e2dSJohn Marino static void
cli_end(struct ui_out * uiout,enum ui_out_type type,int level)1195796c8dcSSimon Schubert cli_end (struct ui_out *uiout,
1205796c8dcSSimon Schubert enum ui_out_type type,
1215796c8dcSSimon Schubert int level)
1225796c8dcSSimon Schubert {
1235796c8dcSSimon Schubert cli_out_data *data = ui_out_data (uiout);
124cf7f2e2dSJohn Marino
1255796c8dcSSimon Schubert if (data->suppress_output)
1265796c8dcSSimon Schubert return;
1275796c8dcSSimon Schubert }
1285796c8dcSSimon Schubert
1295796c8dcSSimon Schubert /* output an int field */
1305796c8dcSSimon Schubert
131cf7f2e2dSJohn Marino static void
cli_field_int(struct ui_out * uiout,int fldno,int width,enum ui_align alignment,const char * fldname,int value)1325796c8dcSSimon Schubert cli_field_int (struct ui_out *uiout, int fldno, int width,
1335796c8dcSSimon Schubert enum ui_align alignment,
1345796c8dcSSimon Schubert const char *fldname, int value)
1355796c8dcSSimon Schubert {
1365796c8dcSSimon Schubert char buffer[20]; /* FIXME: how many chars long a %d can become? */
1375796c8dcSSimon Schubert cli_out_data *data = ui_out_data (uiout);
138cf7f2e2dSJohn Marino
1395796c8dcSSimon Schubert if (data->suppress_output)
1405796c8dcSSimon Schubert return;
141*ef5ccd6cSJohn Marino xsnprintf (buffer, sizeof (buffer), "%d", value);
142cf7f2e2dSJohn Marino
143cf7f2e2dSJohn Marino /* Always go through the function pointer (virtual function call).
144cf7f2e2dSJohn Marino We may have been extended. */
145cf7f2e2dSJohn Marino uo_field_string (uiout, fldno, width, alignment, fldname, buffer);
1465796c8dcSSimon Schubert }
1475796c8dcSSimon Schubert
1485796c8dcSSimon Schubert /* used to ommit a field */
1495796c8dcSSimon Schubert
150cf7f2e2dSJohn Marino static void
cli_field_skip(struct ui_out * uiout,int fldno,int width,enum ui_align alignment,const char * fldname)1515796c8dcSSimon Schubert cli_field_skip (struct ui_out *uiout, int fldno, int width,
1525796c8dcSSimon Schubert enum ui_align alignment,
1535796c8dcSSimon Schubert const char *fldname)
1545796c8dcSSimon Schubert {
1555796c8dcSSimon Schubert cli_out_data *data = ui_out_data (uiout);
156cf7f2e2dSJohn Marino
1575796c8dcSSimon Schubert if (data->suppress_output)
1585796c8dcSSimon Schubert return;
159cf7f2e2dSJohn Marino
160cf7f2e2dSJohn Marino /* Always go through the function pointer (virtual function call).
161cf7f2e2dSJohn Marino We may have been extended. */
162cf7f2e2dSJohn Marino uo_field_string (uiout, fldno, width, alignment, fldname, "");
1635796c8dcSSimon Schubert }
1645796c8dcSSimon Schubert
1655796c8dcSSimon Schubert /* other specific cli_field_* end up here so alignment and field
1665796c8dcSSimon Schubert separators are both handled by cli_field_string */
1675796c8dcSSimon Schubert
168cf7f2e2dSJohn Marino static void
cli_field_string(struct ui_out * uiout,int fldno,int width,enum ui_align align,const char * fldname,const char * string)1695796c8dcSSimon Schubert cli_field_string (struct ui_out *uiout,
1705796c8dcSSimon Schubert int fldno,
1715796c8dcSSimon Schubert int width,
1725796c8dcSSimon Schubert enum ui_align align,
1735796c8dcSSimon Schubert const char *fldname,
1745796c8dcSSimon Schubert const char *string)
1755796c8dcSSimon Schubert {
1765796c8dcSSimon Schubert int before = 0;
1775796c8dcSSimon Schubert int after = 0;
1785796c8dcSSimon Schubert cli_out_data *data = ui_out_data (uiout);
179cf7f2e2dSJohn Marino
1805796c8dcSSimon Schubert if (data->suppress_output)
1815796c8dcSSimon Schubert return;
1825796c8dcSSimon Schubert
1835796c8dcSSimon Schubert if ((align != ui_noalign) && string)
1845796c8dcSSimon Schubert {
1855796c8dcSSimon Schubert before = width - strlen (string);
1865796c8dcSSimon Schubert if (before <= 0)
1875796c8dcSSimon Schubert before = 0;
1885796c8dcSSimon Schubert else
1895796c8dcSSimon Schubert {
1905796c8dcSSimon Schubert if (align == ui_right)
1915796c8dcSSimon Schubert after = 0;
1925796c8dcSSimon Schubert else if (align == ui_left)
1935796c8dcSSimon Schubert {
1945796c8dcSSimon Schubert after = before;
1955796c8dcSSimon Schubert before = 0;
1965796c8dcSSimon Schubert }
1975796c8dcSSimon Schubert else
1985796c8dcSSimon Schubert /* ui_center */
1995796c8dcSSimon Schubert {
2005796c8dcSSimon Schubert after = before / 2;
2015796c8dcSSimon Schubert before -= after;
2025796c8dcSSimon Schubert }
2035796c8dcSSimon Schubert }
2045796c8dcSSimon Schubert }
2055796c8dcSSimon Schubert
2065796c8dcSSimon Schubert if (before)
2075796c8dcSSimon Schubert ui_out_spaces (uiout, before);
2085796c8dcSSimon Schubert if (string)
2095796c8dcSSimon Schubert out_field_fmt (uiout, fldno, fldname, "%s", string);
2105796c8dcSSimon Schubert if (after)
2115796c8dcSSimon Schubert ui_out_spaces (uiout, after);
2125796c8dcSSimon Schubert
2135796c8dcSSimon Schubert if (align != ui_noalign)
2145796c8dcSSimon Schubert field_separator ();
2155796c8dcSSimon Schubert }
2165796c8dcSSimon Schubert
2175796c8dcSSimon Schubert /* This is the only field function that does not align. */
2185796c8dcSSimon Schubert
219cf7f2e2dSJohn Marino static void ATTRIBUTE_PRINTF (6, 0)
cli_field_fmt(struct ui_out * uiout,int fldno,int width,enum ui_align align,const char * fldname,const char * format,va_list args)2205796c8dcSSimon Schubert cli_field_fmt (struct ui_out *uiout, int fldno,
2215796c8dcSSimon Schubert int width, enum ui_align align,
2225796c8dcSSimon Schubert const char *fldname,
2235796c8dcSSimon Schubert const char *format,
2245796c8dcSSimon Schubert va_list args)
2255796c8dcSSimon Schubert {
2265796c8dcSSimon Schubert cli_out_data *data = ui_out_data (uiout);
227c50c785cSJohn Marino struct ui_file *stream;
228cf7f2e2dSJohn Marino
2295796c8dcSSimon Schubert if (data->suppress_output)
2305796c8dcSSimon Schubert return;
2315796c8dcSSimon Schubert
232c50c785cSJohn Marino stream = VEC_last (ui_filep, data->streams);
233c50c785cSJohn Marino vfprintf_filtered (stream, format, args);
2345796c8dcSSimon Schubert
2355796c8dcSSimon Schubert if (align != ui_noalign)
2365796c8dcSSimon Schubert field_separator ();
2375796c8dcSSimon Schubert }
2385796c8dcSSimon Schubert
239cf7f2e2dSJohn Marino static void
cli_spaces(struct ui_out * uiout,int numspaces)2405796c8dcSSimon Schubert cli_spaces (struct ui_out *uiout, int numspaces)
2415796c8dcSSimon Schubert {
2425796c8dcSSimon Schubert cli_out_data *data = ui_out_data (uiout);
243c50c785cSJohn Marino struct ui_file *stream;
244cf7f2e2dSJohn Marino
2455796c8dcSSimon Schubert if (data->suppress_output)
2465796c8dcSSimon Schubert return;
247c50c785cSJohn Marino
248c50c785cSJohn Marino stream = VEC_last (ui_filep, data->streams);
249c50c785cSJohn Marino print_spaces_filtered (numspaces, stream);
2505796c8dcSSimon Schubert }
2515796c8dcSSimon Schubert
252cf7f2e2dSJohn Marino static void
cli_text(struct ui_out * uiout,const char * string)2535796c8dcSSimon Schubert cli_text (struct ui_out *uiout, const char *string)
2545796c8dcSSimon Schubert {
2555796c8dcSSimon Schubert cli_out_data *data = ui_out_data (uiout);
256c50c785cSJohn Marino struct ui_file *stream;
257cf7f2e2dSJohn Marino
2585796c8dcSSimon Schubert if (data->suppress_output)
2595796c8dcSSimon Schubert return;
260c50c785cSJohn Marino
261c50c785cSJohn Marino stream = VEC_last (ui_filep, data->streams);
262c50c785cSJohn Marino fputs_filtered (string, stream);
2635796c8dcSSimon Schubert }
2645796c8dcSSimon Schubert
265cf7f2e2dSJohn Marino static void ATTRIBUTE_PRINTF (3, 0)
cli_message(struct ui_out * uiout,int verbosity,const char * format,va_list args)2665796c8dcSSimon Schubert cli_message (struct ui_out *uiout, int verbosity,
2675796c8dcSSimon Schubert const char *format, va_list args)
2685796c8dcSSimon Schubert {
2695796c8dcSSimon Schubert cli_out_data *data = ui_out_data (uiout);
270cf7f2e2dSJohn Marino
2715796c8dcSSimon Schubert if (data->suppress_output)
2725796c8dcSSimon Schubert return;
273c50c785cSJohn Marino
2745796c8dcSSimon Schubert if (ui_out_get_verblvl (uiout) >= verbosity)
275c50c785cSJohn Marino {
276c50c785cSJohn Marino struct ui_file *stream = VEC_last (ui_filep, data->streams);
277c50c785cSJohn Marino
278c50c785cSJohn Marino vfprintf_unfiltered (stream, format, args);
279c50c785cSJohn Marino }
2805796c8dcSSimon Schubert }
2815796c8dcSSimon Schubert
282cf7f2e2dSJohn Marino static void
cli_wrap_hint(struct ui_out * uiout,char * identstring)2835796c8dcSSimon Schubert cli_wrap_hint (struct ui_out *uiout, char *identstring)
2845796c8dcSSimon Schubert {
2855796c8dcSSimon Schubert cli_out_data *data = ui_out_data (uiout);
286cf7f2e2dSJohn Marino
2875796c8dcSSimon Schubert if (data->suppress_output)
2885796c8dcSSimon Schubert return;
2895796c8dcSSimon Schubert wrap_here (identstring);
2905796c8dcSSimon Schubert }
2915796c8dcSSimon Schubert
292cf7f2e2dSJohn Marino static void
cli_flush(struct ui_out * uiout)2935796c8dcSSimon Schubert cli_flush (struct ui_out *uiout)
2945796c8dcSSimon Schubert {
2955796c8dcSSimon Schubert cli_out_data *data = ui_out_data (uiout);
296c50c785cSJohn Marino struct ui_file *stream = VEC_last (ui_filep, data->streams);
297cf7f2e2dSJohn Marino
298c50c785cSJohn Marino gdb_flush (stream);
2995796c8dcSSimon Schubert }
3005796c8dcSSimon Schubert
301c50c785cSJohn Marino /* OUTSTREAM as non-NULL will push OUTSTREAM on the stack of output streams
302c50c785cSJohn Marino and make it therefore active. OUTSTREAM as NULL will pop the last pushed
303c50c785cSJohn Marino output stream; it is an internal error if it does not exist. */
304c50c785cSJohn Marino
305cf7f2e2dSJohn Marino static int
cli_redirect(struct ui_out * uiout,struct ui_file * outstream)3065796c8dcSSimon Schubert cli_redirect (struct ui_out *uiout, struct ui_file *outstream)
3075796c8dcSSimon Schubert {
308cf7f2e2dSJohn Marino cli_out_data *data = ui_out_data (uiout);
309cf7f2e2dSJohn Marino
3105796c8dcSSimon Schubert if (outstream != NULL)
311c50c785cSJohn Marino VEC_safe_push (ui_filep, data->streams, outstream);
312c50c785cSJohn Marino else
313c50c785cSJohn Marino VEC_pop (ui_filep, data->streams);
3145796c8dcSSimon Schubert
3155796c8dcSSimon Schubert return 0;
3165796c8dcSSimon Schubert }
3175796c8dcSSimon Schubert
3185796c8dcSSimon Schubert /* local functions */
3195796c8dcSSimon Schubert
3205796c8dcSSimon Schubert /* Like cli_field_fmt, but takes a variable number of args
3215796c8dcSSimon Schubert and makes a va_list and does not insert a separator. */
3225796c8dcSSimon Schubert
3235796c8dcSSimon Schubert /* VARARGS */
3245796c8dcSSimon Schubert static void
out_field_fmt(struct ui_out * uiout,int fldno,const char * fldname,const char * format,...)3255796c8dcSSimon Schubert out_field_fmt (struct ui_out *uiout, int fldno,
3265796c8dcSSimon Schubert const char *fldname,
3275796c8dcSSimon Schubert const char *format,...)
3285796c8dcSSimon Schubert {
3295796c8dcSSimon Schubert cli_out_data *data = ui_out_data (uiout);
330c50c785cSJohn Marino struct ui_file *stream = VEC_last (ui_filep, data->streams);
3315796c8dcSSimon Schubert va_list args;
3325796c8dcSSimon Schubert
3335796c8dcSSimon Schubert va_start (args, format);
334c50c785cSJohn Marino vfprintf_filtered (stream, format, args);
3355796c8dcSSimon Schubert
3365796c8dcSSimon Schubert va_end (args);
3375796c8dcSSimon Schubert }
3385796c8dcSSimon Schubert
3395796c8dcSSimon Schubert /* Access to ui_out format private members. */
3405796c8dcSSimon Schubert
3415796c8dcSSimon Schubert static void
field_separator(void)3425796c8dcSSimon Schubert field_separator (void)
3435796c8dcSSimon Schubert {
344a45ae5f8SJohn Marino cli_out_data *data = ui_out_data (current_uiout);
345c50c785cSJohn Marino struct ui_file *stream = VEC_last (ui_filep, data->streams);
346cf7f2e2dSJohn Marino
347c50c785cSJohn Marino fputc_filtered (' ', stream);
3485796c8dcSSimon Schubert }
3495796c8dcSSimon Schubert
350cf7f2e2dSJohn Marino /* This is the CLI ui-out implementation functions vector */
351cf7f2e2dSJohn Marino
352cf7f2e2dSJohn Marino /* FIXME: This can be initialized dynamically after default is set to
353cf7f2e2dSJohn Marino handle initial output in main.c */
354cf7f2e2dSJohn Marino
355cf7f2e2dSJohn Marino struct ui_out_impl cli_ui_out_impl =
356cf7f2e2dSJohn Marino {
357cf7f2e2dSJohn Marino cli_table_begin,
358cf7f2e2dSJohn Marino cli_table_body,
359cf7f2e2dSJohn Marino cli_table_end,
360cf7f2e2dSJohn Marino cli_table_header,
361cf7f2e2dSJohn Marino cli_begin,
362cf7f2e2dSJohn Marino cli_end,
363cf7f2e2dSJohn Marino cli_field_int,
364cf7f2e2dSJohn Marino cli_field_skip,
365cf7f2e2dSJohn Marino cli_field_string,
366cf7f2e2dSJohn Marino cli_field_fmt,
367cf7f2e2dSJohn Marino cli_spaces,
368cf7f2e2dSJohn Marino cli_text,
369cf7f2e2dSJohn Marino cli_message,
370cf7f2e2dSJohn Marino cli_wrap_hint,
371cf7f2e2dSJohn Marino cli_flush,
372cf7f2e2dSJohn Marino cli_redirect,
373*ef5ccd6cSJohn Marino 0,
374cf7f2e2dSJohn Marino 0, /* Does not need MI hacks (i.e. needs CLI hacks). */
375cf7f2e2dSJohn Marino };
376cf7f2e2dSJohn Marino
377cf7f2e2dSJohn Marino /* Constructor for a `cli_out_data' object. */
378cf7f2e2dSJohn Marino
379cf7f2e2dSJohn Marino void
cli_out_data_ctor(cli_out_data * self,struct ui_file * stream)380cf7f2e2dSJohn Marino cli_out_data_ctor (cli_out_data *self, struct ui_file *stream)
381cf7f2e2dSJohn Marino {
382c50c785cSJohn Marino gdb_assert (stream != NULL);
383c50c785cSJohn Marino
384c50c785cSJohn Marino self->streams = NULL;
385c50c785cSJohn Marino VEC_safe_push (ui_filep, self->streams, stream);
386c50c785cSJohn Marino
387cf7f2e2dSJohn Marino self->suppress_output = 0;
388cf7f2e2dSJohn Marino }
389cf7f2e2dSJohn Marino
390cf7f2e2dSJohn Marino /* Initialize private members at startup. */
3915796c8dcSSimon Schubert
3925796c8dcSSimon Schubert struct ui_out *
cli_out_new(struct ui_file * stream)3935796c8dcSSimon Schubert cli_out_new (struct ui_file *stream)
3945796c8dcSSimon Schubert {
3955796c8dcSSimon Schubert int flags = ui_source_list;
3965796c8dcSSimon Schubert cli_out_data *data = XMALLOC (cli_out_data);
397cf7f2e2dSJohn Marino
398cf7f2e2dSJohn Marino cli_out_data_ctor (data, stream);
3995796c8dcSSimon Schubert return ui_out_new (&cli_ui_out_impl, data, flags);
4005796c8dcSSimon Schubert }
4015796c8dcSSimon Schubert
4025796c8dcSSimon Schubert struct ui_file *
cli_out_set_stream(struct ui_out * uiout,struct ui_file * stream)4035796c8dcSSimon Schubert cli_out_set_stream (struct ui_out *uiout, struct ui_file *stream)
4045796c8dcSSimon Schubert {
4055796c8dcSSimon Schubert cli_out_data *data = ui_out_data (uiout);
406c50c785cSJohn Marino struct ui_file *old;
407cf7f2e2dSJohn Marino
408c50c785cSJohn Marino old = VEC_pop (ui_filep, data->streams);
409c50c785cSJohn Marino VEC_quick_push (ui_filep, data->streams, stream);
410c50c785cSJohn Marino
4115796c8dcSSimon Schubert return old;
4125796c8dcSSimon Schubert }
413