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