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