1*b725ae77Skettenis /* Output generating routines for GDB CLI.
2*b725ae77Skettenis
3*b725ae77Skettenis Copyright 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
4*b725ae77Skettenis
5*b725ae77Skettenis Contributed by Cygnus Solutions.
6*b725ae77Skettenis Written by Fernando Nasser for Cygnus.
7*b725ae77Skettenis
8*b725ae77Skettenis This file is part of GDB.
9*b725ae77Skettenis
10*b725ae77Skettenis This program is free software; you can redistribute it and/or modify
11*b725ae77Skettenis it under the terms of the GNU General Public License as published by
12*b725ae77Skettenis the Free Software Foundation; either version 2 of the License, or
13*b725ae77Skettenis (at your option) any later version.
14*b725ae77Skettenis
15*b725ae77Skettenis This program is distributed in the hope that it will be useful,
16*b725ae77Skettenis but WITHOUT ANY WARRANTY; without even the implied warranty of
17*b725ae77Skettenis MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18*b725ae77Skettenis GNU General Public License for more details.
19*b725ae77Skettenis
20*b725ae77Skettenis You should have received a copy of the GNU General Public License
21*b725ae77Skettenis along with this program; if not, write to the Free Software
22*b725ae77Skettenis Foundation, Inc., 59 Temple Place - Suite 330,
23*b725ae77Skettenis Boston, MA 02111-1307, USA. */
24*b725ae77Skettenis
25*b725ae77Skettenis #include "defs.h"
26*b725ae77Skettenis #include "ui-out.h"
27*b725ae77Skettenis #include "cli-out.h"
28*b725ae77Skettenis #include "gdb_string.h"
29*b725ae77Skettenis #include "gdb_assert.h"
30*b725ae77Skettenis
31*b725ae77Skettenis struct ui_out_data
32*b725ae77Skettenis {
33*b725ae77Skettenis struct ui_file *stream;
34*b725ae77Skettenis struct ui_file *original_stream;
35*b725ae77Skettenis int suppress_output;
36*b725ae77Skettenis };
37*b725ae77Skettenis typedef struct ui_out_data cli_out_data;
38*b725ae77Skettenis
39*b725ae77Skettenis /* These are the CLI output functions */
40*b725ae77Skettenis
41*b725ae77Skettenis static void cli_table_begin (struct ui_out *uiout, int nbrofcols,
42*b725ae77Skettenis int nr_rows, const char *tblid);
43*b725ae77Skettenis static void cli_table_body (struct ui_out *uiout);
44*b725ae77Skettenis static void cli_table_end (struct ui_out *uiout);
45*b725ae77Skettenis static void cli_table_header (struct ui_out *uiout, int width,
46*b725ae77Skettenis enum ui_align alig, const char *col_name,
47*b725ae77Skettenis const char *colhdr);
48*b725ae77Skettenis static void cli_begin (struct ui_out *uiout, enum ui_out_type type,
49*b725ae77Skettenis int level, const char *lstid);
50*b725ae77Skettenis static void cli_end (struct ui_out *uiout, enum ui_out_type type, int level);
51*b725ae77Skettenis static void cli_field_int (struct ui_out *uiout, int fldno, int width,
52*b725ae77Skettenis enum ui_align alig, const char *fldname, int value);
53*b725ae77Skettenis static void cli_field_skip (struct ui_out *uiout, int fldno, int width,
54*b725ae77Skettenis enum ui_align alig, const char *fldname);
55*b725ae77Skettenis static void cli_field_string (struct ui_out *uiout, int fldno, int width,
56*b725ae77Skettenis enum ui_align alig, const char *fldname,
57*b725ae77Skettenis const char *string);
58*b725ae77Skettenis static void cli_field_fmt (struct ui_out *uiout, int fldno,
59*b725ae77Skettenis int width, enum ui_align align,
60*b725ae77Skettenis const char *fldname, const char *format,
61*b725ae77Skettenis va_list args);
62*b725ae77Skettenis static void cli_spaces (struct ui_out *uiout, int numspaces);
63*b725ae77Skettenis static void cli_text (struct ui_out *uiout, const char *string);
64*b725ae77Skettenis static void cli_message (struct ui_out *uiout, int verbosity,
65*b725ae77Skettenis const char *format, va_list args);
66*b725ae77Skettenis static void cli_wrap_hint (struct ui_out *uiout, char *identstring);
67*b725ae77Skettenis static void cli_flush (struct ui_out *uiout);
68*b725ae77Skettenis static int cli_redirect (struct ui_out *uiout, struct ui_file *outstream);
69*b725ae77Skettenis
70*b725ae77Skettenis /* This is the CLI ui-out implementation functions vector */
71*b725ae77Skettenis
72*b725ae77Skettenis /* FIXME: This can be initialized dynamically after default is set to
73*b725ae77Skettenis handle initial output in main.c */
74*b725ae77Skettenis
75*b725ae77Skettenis static struct ui_out_impl cli_ui_out_impl =
76*b725ae77Skettenis {
77*b725ae77Skettenis cli_table_begin,
78*b725ae77Skettenis cli_table_body,
79*b725ae77Skettenis cli_table_end,
80*b725ae77Skettenis cli_table_header,
81*b725ae77Skettenis cli_begin,
82*b725ae77Skettenis cli_end,
83*b725ae77Skettenis cli_field_int,
84*b725ae77Skettenis cli_field_skip,
85*b725ae77Skettenis cli_field_string,
86*b725ae77Skettenis cli_field_fmt,
87*b725ae77Skettenis cli_spaces,
88*b725ae77Skettenis cli_text,
89*b725ae77Skettenis cli_message,
90*b725ae77Skettenis cli_wrap_hint,
91*b725ae77Skettenis cli_flush,
92*b725ae77Skettenis cli_redirect,
93*b725ae77Skettenis 0, /* Does not need MI hacks (i.e. needs CLI hacks). */
94*b725ae77Skettenis };
95*b725ae77Skettenis
96*b725ae77Skettenis /* Prototypes for local functions */
97*b725ae77Skettenis
98*b725ae77Skettenis extern void _initialize_cli_out (void);
99*b725ae77Skettenis
100*b725ae77Skettenis static void field_separator (void);
101*b725ae77Skettenis
102*b725ae77Skettenis static void out_field_fmt (struct ui_out *uiout, int fldno,
103*b725ae77Skettenis const char *fldname,
104*b725ae77Skettenis const char *format,...);
105*b725ae77Skettenis
106*b725ae77Skettenis /* local variables */
107*b725ae77Skettenis
108*b725ae77Skettenis /* (none yet) */
109*b725ae77Skettenis
110*b725ae77Skettenis /* Mark beginning of a table */
111*b725ae77Skettenis
112*b725ae77Skettenis void
cli_table_begin(struct ui_out * uiout,int nbrofcols,int nr_rows,const char * tblid)113*b725ae77Skettenis cli_table_begin (struct ui_out *uiout, int nbrofcols,
114*b725ae77Skettenis int nr_rows,
115*b725ae77Skettenis const char *tblid)
116*b725ae77Skettenis {
117*b725ae77Skettenis cli_out_data *data = ui_out_data (uiout);
118*b725ae77Skettenis if (nr_rows == 0)
119*b725ae77Skettenis data->suppress_output = 1;
120*b725ae77Skettenis else
121*b725ae77Skettenis /* Only the table suppresses the output and, fortunately, a table
122*b725ae77Skettenis is not a recursive data structure. */
123*b725ae77Skettenis gdb_assert (data->suppress_output == 0);
124*b725ae77Skettenis }
125*b725ae77Skettenis
126*b725ae77Skettenis /* Mark beginning of a table body */
127*b725ae77Skettenis
128*b725ae77Skettenis void
cli_table_body(struct ui_out * uiout)129*b725ae77Skettenis cli_table_body (struct ui_out *uiout)
130*b725ae77Skettenis {
131*b725ae77Skettenis cli_out_data *data = ui_out_data (uiout);
132*b725ae77Skettenis if (data->suppress_output)
133*b725ae77Skettenis return;
134*b725ae77Skettenis /* first, close the table header line */
135*b725ae77Skettenis cli_text (uiout, "\n");
136*b725ae77Skettenis }
137*b725ae77Skettenis
138*b725ae77Skettenis /* Mark end of a table */
139*b725ae77Skettenis
140*b725ae77Skettenis void
cli_table_end(struct ui_out * uiout)141*b725ae77Skettenis cli_table_end (struct ui_out *uiout)
142*b725ae77Skettenis {
143*b725ae77Skettenis cli_out_data *data = ui_out_data (uiout);
144*b725ae77Skettenis data->suppress_output = 0;
145*b725ae77Skettenis }
146*b725ae77Skettenis
147*b725ae77Skettenis /* Specify table header */
148*b725ae77Skettenis
149*b725ae77Skettenis void
cli_table_header(struct ui_out * uiout,int width,enum ui_align alignment,const char * col_name,const char * colhdr)150*b725ae77Skettenis cli_table_header (struct ui_out *uiout, int width, enum ui_align alignment,
151*b725ae77Skettenis const char *col_name,
152*b725ae77Skettenis const char *colhdr)
153*b725ae77Skettenis {
154*b725ae77Skettenis cli_out_data *data = ui_out_data (uiout);
155*b725ae77Skettenis if (data->suppress_output)
156*b725ae77Skettenis return;
157*b725ae77Skettenis cli_field_string (uiout, 0, width, alignment, 0, colhdr);
158*b725ae77Skettenis }
159*b725ae77Skettenis
160*b725ae77Skettenis /* Mark beginning of a list */
161*b725ae77Skettenis
162*b725ae77Skettenis void
cli_begin(struct ui_out * uiout,enum ui_out_type type,int level,const char * id)163*b725ae77Skettenis cli_begin (struct ui_out *uiout,
164*b725ae77Skettenis enum ui_out_type type,
165*b725ae77Skettenis int level,
166*b725ae77Skettenis const char *id)
167*b725ae77Skettenis {
168*b725ae77Skettenis cli_out_data *data = ui_out_data (uiout);
169*b725ae77Skettenis if (data->suppress_output)
170*b725ae77Skettenis return;
171*b725ae77Skettenis }
172*b725ae77Skettenis
173*b725ae77Skettenis /* Mark end of a list */
174*b725ae77Skettenis
175*b725ae77Skettenis void
cli_end(struct ui_out * uiout,enum ui_out_type type,int level)176*b725ae77Skettenis cli_end (struct ui_out *uiout,
177*b725ae77Skettenis enum ui_out_type type,
178*b725ae77Skettenis int level)
179*b725ae77Skettenis {
180*b725ae77Skettenis cli_out_data *data = ui_out_data (uiout);
181*b725ae77Skettenis if (data->suppress_output)
182*b725ae77Skettenis return;
183*b725ae77Skettenis }
184*b725ae77Skettenis
185*b725ae77Skettenis /* output an int field */
186*b725ae77Skettenis
187*b725ae77Skettenis void
cli_field_int(struct ui_out * uiout,int fldno,int width,enum ui_align alignment,const char * fldname,int value)188*b725ae77Skettenis cli_field_int (struct ui_out *uiout, int fldno, int width,
189*b725ae77Skettenis enum ui_align alignment,
190*b725ae77Skettenis const char *fldname, int value)
191*b725ae77Skettenis {
192*b725ae77Skettenis char buffer[20]; /* FIXME: how many chars long a %d can become? */
193*b725ae77Skettenis
194*b725ae77Skettenis cli_out_data *data = ui_out_data (uiout);
195*b725ae77Skettenis if (data->suppress_output)
196*b725ae77Skettenis return;
197*b725ae77Skettenis sprintf (buffer, "%d", value);
198*b725ae77Skettenis cli_field_string (uiout, fldno, width, alignment, fldname, buffer);
199*b725ae77Skettenis }
200*b725ae77Skettenis
201*b725ae77Skettenis /* used to ommit a field */
202*b725ae77Skettenis
203*b725ae77Skettenis void
cli_field_skip(struct ui_out * uiout,int fldno,int width,enum ui_align alignment,const char * fldname)204*b725ae77Skettenis cli_field_skip (struct ui_out *uiout, int fldno, int width,
205*b725ae77Skettenis enum ui_align alignment,
206*b725ae77Skettenis const char *fldname)
207*b725ae77Skettenis {
208*b725ae77Skettenis cli_out_data *data = ui_out_data (uiout);
209*b725ae77Skettenis if (data->suppress_output)
210*b725ae77Skettenis return;
211*b725ae77Skettenis cli_field_string (uiout, fldno, width, alignment, fldname, "");
212*b725ae77Skettenis }
213*b725ae77Skettenis
214*b725ae77Skettenis /* other specific cli_field_* end up here so alignment and field
215*b725ae77Skettenis separators are both handled by cli_field_string */
216*b725ae77Skettenis
217*b725ae77Skettenis void
cli_field_string(struct ui_out * uiout,int fldno,int width,enum ui_align align,const char * fldname,const char * string)218*b725ae77Skettenis cli_field_string (struct ui_out *uiout,
219*b725ae77Skettenis int fldno,
220*b725ae77Skettenis int width,
221*b725ae77Skettenis enum ui_align align,
222*b725ae77Skettenis const char *fldname,
223*b725ae77Skettenis const char *string)
224*b725ae77Skettenis {
225*b725ae77Skettenis int before = 0;
226*b725ae77Skettenis int after = 0;
227*b725ae77Skettenis
228*b725ae77Skettenis cli_out_data *data = ui_out_data (uiout);
229*b725ae77Skettenis if (data->suppress_output)
230*b725ae77Skettenis return;
231*b725ae77Skettenis
232*b725ae77Skettenis if ((align != ui_noalign) && string)
233*b725ae77Skettenis {
234*b725ae77Skettenis before = width - strlen (string);
235*b725ae77Skettenis if (before <= 0)
236*b725ae77Skettenis before = 0;
237*b725ae77Skettenis else
238*b725ae77Skettenis {
239*b725ae77Skettenis if (align == ui_right)
240*b725ae77Skettenis after = 0;
241*b725ae77Skettenis else if (align == ui_left)
242*b725ae77Skettenis {
243*b725ae77Skettenis after = before;
244*b725ae77Skettenis before = 0;
245*b725ae77Skettenis }
246*b725ae77Skettenis else
247*b725ae77Skettenis /* ui_center */
248*b725ae77Skettenis {
249*b725ae77Skettenis after = before / 2;
250*b725ae77Skettenis before -= after;
251*b725ae77Skettenis }
252*b725ae77Skettenis }
253*b725ae77Skettenis }
254*b725ae77Skettenis
255*b725ae77Skettenis if (before)
256*b725ae77Skettenis ui_out_spaces (uiout, before);
257*b725ae77Skettenis if (string)
258*b725ae77Skettenis out_field_fmt (uiout, fldno, fldname, "%s", string);
259*b725ae77Skettenis if (after)
260*b725ae77Skettenis ui_out_spaces (uiout, after);
261*b725ae77Skettenis
262*b725ae77Skettenis if (align != ui_noalign)
263*b725ae77Skettenis field_separator ();
264*b725ae77Skettenis }
265*b725ae77Skettenis
266*b725ae77Skettenis /* This is the only field function that does not align */
267*b725ae77Skettenis
268*b725ae77Skettenis void
cli_field_fmt(struct ui_out * uiout,int fldno,int width,enum ui_align align,const char * fldname,const char * format,va_list args)269*b725ae77Skettenis cli_field_fmt (struct ui_out *uiout, int fldno,
270*b725ae77Skettenis int width, enum ui_align align,
271*b725ae77Skettenis const char *fldname,
272*b725ae77Skettenis const char *format,
273*b725ae77Skettenis va_list args)
274*b725ae77Skettenis {
275*b725ae77Skettenis cli_out_data *data = ui_out_data (uiout);
276*b725ae77Skettenis if (data->suppress_output)
277*b725ae77Skettenis return;
278*b725ae77Skettenis
279*b725ae77Skettenis vfprintf_filtered (data->stream, format, args);
280*b725ae77Skettenis
281*b725ae77Skettenis if (align != ui_noalign)
282*b725ae77Skettenis field_separator ();
283*b725ae77Skettenis }
284*b725ae77Skettenis
285*b725ae77Skettenis void
cli_spaces(struct ui_out * uiout,int numspaces)286*b725ae77Skettenis cli_spaces (struct ui_out *uiout, int numspaces)
287*b725ae77Skettenis {
288*b725ae77Skettenis cli_out_data *data = ui_out_data (uiout);
289*b725ae77Skettenis if (data->suppress_output)
290*b725ae77Skettenis return;
291*b725ae77Skettenis print_spaces_filtered (numspaces, data->stream);
292*b725ae77Skettenis }
293*b725ae77Skettenis
294*b725ae77Skettenis void
cli_text(struct ui_out * uiout,const char * string)295*b725ae77Skettenis cli_text (struct ui_out *uiout, const char *string)
296*b725ae77Skettenis {
297*b725ae77Skettenis cli_out_data *data = ui_out_data (uiout);
298*b725ae77Skettenis if (data->suppress_output)
299*b725ae77Skettenis return;
300*b725ae77Skettenis fputs_filtered (string, data->stream);
301*b725ae77Skettenis }
302*b725ae77Skettenis
303*b725ae77Skettenis void
cli_message(struct ui_out * uiout,int verbosity,const char * format,va_list args)304*b725ae77Skettenis cli_message (struct ui_out *uiout, int verbosity,
305*b725ae77Skettenis const char *format, va_list args)
306*b725ae77Skettenis {
307*b725ae77Skettenis cli_out_data *data = ui_out_data (uiout);
308*b725ae77Skettenis if (data->suppress_output)
309*b725ae77Skettenis return;
310*b725ae77Skettenis if (ui_out_get_verblvl (uiout) >= verbosity)
311*b725ae77Skettenis vfprintf_unfiltered (data->stream, format, args);
312*b725ae77Skettenis }
313*b725ae77Skettenis
314*b725ae77Skettenis void
cli_wrap_hint(struct ui_out * uiout,char * identstring)315*b725ae77Skettenis cli_wrap_hint (struct ui_out *uiout, char *identstring)
316*b725ae77Skettenis {
317*b725ae77Skettenis cli_out_data *data = ui_out_data (uiout);
318*b725ae77Skettenis if (data->suppress_output)
319*b725ae77Skettenis return;
320*b725ae77Skettenis wrap_here (identstring);
321*b725ae77Skettenis }
322*b725ae77Skettenis
323*b725ae77Skettenis void
cli_flush(struct ui_out * uiout)324*b725ae77Skettenis cli_flush (struct ui_out *uiout)
325*b725ae77Skettenis {
326*b725ae77Skettenis cli_out_data *data = ui_out_data (uiout);
327*b725ae77Skettenis gdb_flush (data->stream);
328*b725ae77Skettenis }
329*b725ae77Skettenis
330*b725ae77Skettenis int
cli_redirect(struct ui_out * uiout,struct ui_file * outstream)331*b725ae77Skettenis cli_redirect (struct ui_out *uiout, struct ui_file *outstream)
332*b725ae77Skettenis {
333*b725ae77Skettenis struct ui_out_data *data = ui_out_data (uiout);
334*b725ae77Skettenis if (outstream != NULL)
335*b725ae77Skettenis {
336*b725ae77Skettenis data->original_stream = data->stream;
337*b725ae77Skettenis data->stream = outstream;
338*b725ae77Skettenis }
339*b725ae77Skettenis else if (data->original_stream != NULL)
340*b725ae77Skettenis {
341*b725ae77Skettenis data->stream = data->original_stream;
342*b725ae77Skettenis data->original_stream = NULL;
343*b725ae77Skettenis }
344*b725ae77Skettenis
345*b725ae77Skettenis return 0;
346*b725ae77Skettenis }
347*b725ae77Skettenis
348*b725ae77Skettenis /* local functions */
349*b725ae77Skettenis
350*b725ae77Skettenis /* Like cli_field_fmt, but takes a variable number of args
351*b725ae77Skettenis and makes a va_list and does not insert a separator */
352*b725ae77Skettenis
353*b725ae77Skettenis /* VARARGS */
354*b725ae77Skettenis static void
out_field_fmt(struct ui_out * uiout,int fldno,const char * fldname,const char * format,...)355*b725ae77Skettenis out_field_fmt (struct ui_out *uiout, int fldno,
356*b725ae77Skettenis const char *fldname,
357*b725ae77Skettenis const char *format,...)
358*b725ae77Skettenis {
359*b725ae77Skettenis cli_out_data *data = ui_out_data (uiout);
360*b725ae77Skettenis va_list args;
361*b725ae77Skettenis
362*b725ae77Skettenis va_start (args, format);
363*b725ae77Skettenis vfprintf_filtered (data->stream, format, args);
364*b725ae77Skettenis
365*b725ae77Skettenis va_end (args);
366*b725ae77Skettenis }
367*b725ae77Skettenis
368*b725ae77Skettenis /* access to ui_out format private members */
369*b725ae77Skettenis
370*b725ae77Skettenis static void
field_separator(void)371*b725ae77Skettenis field_separator (void)
372*b725ae77Skettenis {
373*b725ae77Skettenis cli_out_data *data = ui_out_data (uiout);
374*b725ae77Skettenis fputc_filtered (' ', data->stream);
375*b725ae77Skettenis }
376*b725ae77Skettenis
377*b725ae77Skettenis /* initalize private members at startup */
378*b725ae77Skettenis
379*b725ae77Skettenis struct ui_out *
cli_out_new(struct ui_file * stream)380*b725ae77Skettenis cli_out_new (struct ui_file *stream)
381*b725ae77Skettenis {
382*b725ae77Skettenis int flags = ui_source_list;
383*b725ae77Skettenis
384*b725ae77Skettenis cli_out_data *data = XMALLOC (cli_out_data);
385*b725ae77Skettenis data->stream = stream;
386*b725ae77Skettenis data->original_stream = NULL;
387*b725ae77Skettenis data->suppress_output = 0;
388*b725ae77Skettenis return ui_out_new (&cli_ui_out_impl, data, flags);
389*b725ae77Skettenis }
390*b725ae77Skettenis
391*b725ae77Skettenis struct ui_file *
cli_out_set_stream(struct ui_out * uiout,struct ui_file * stream)392*b725ae77Skettenis cli_out_set_stream (struct ui_out *uiout, struct ui_file *stream)
393*b725ae77Skettenis {
394*b725ae77Skettenis cli_out_data *data = ui_out_data (uiout);
395*b725ae77Skettenis struct ui_file *old = data->stream;
396*b725ae77Skettenis data->stream = stream;
397*b725ae77Skettenis return old;
398*b725ae77Skettenis }
399*b725ae77Skettenis
400*b725ae77Skettenis /* standard gdb initialization hook */
401*b725ae77Skettenis void
_initialize_cli_out(void)402*b725ae77Skettenis _initialize_cli_out (void)
403*b725ae77Skettenis {
404*b725ae77Skettenis /* nothing needs to be done */
405*b725ae77Skettenis }
406