xref: /dragonfly/contrib/gdb-7/gdb/mi/mi-out.c (revision 52f9f0d9)
1 /* MI Command Set - output generating routines.
2 
3    Copyright (C) 2000, 2002-2005, 2007-2012 Free Software Foundation,
4    Inc.
5 
6    Contributed by Cygnus Solutions (a Red Hat company).
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 "ui-out.h"
25 #include "mi-out.h"
26 
27 struct ui_out_data
28   {
29     int suppress_field_separator;
30     int suppress_output;
31     int mi_version;
32     struct ui_file *buffer;
33     struct ui_file *original_buffer;
34   };
35 typedef struct ui_out_data mi_out_data;
36 
37 /* These are the MI output functions */
38 
39 static void mi_table_begin (struct ui_out *uiout, int nbrofcols,
40 			    int nr_rows, const char *tblid);
41 static void mi_table_body (struct ui_out *uiout);
42 static void mi_table_end (struct ui_out *uiout);
43 static void mi_table_header (struct ui_out *uiout, int width,
44 			     enum ui_align alig, const char *col_name,
45 			     const char *colhdr);
46 static void mi_begin (struct ui_out *uiout, enum ui_out_type type,
47 		      int level, const char *id);
48 static void mi_end (struct ui_out *uiout, enum ui_out_type type, int level);
49 static void mi_field_int (struct ui_out *uiout, int fldno, int width,
50 			  enum ui_align alig, const char *fldname, int value);
51 static void mi_field_skip (struct ui_out *uiout, int fldno, int width,
52 			   enum ui_align alig, const char *fldname);
53 static void mi_field_string (struct ui_out *uiout, int fldno, int width,
54 			     enum ui_align alig, const char *fldname,
55 			     const char *string);
56 static void mi_field_fmt (struct ui_out *uiout, int fldno,
57 			  int width, enum ui_align align,
58 			  const char *fldname, const char *format,
59 			  va_list args) ATTRIBUTE_PRINTF (6, 0);
60 static void mi_spaces (struct ui_out *uiout, int numspaces);
61 static void mi_text (struct ui_out *uiout, const char *string);
62 static void mi_message (struct ui_out *uiout, int verbosity,
63 			const char *format, va_list args)
64      ATTRIBUTE_PRINTF (3, 0);
65 static void mi_wrap_hint (struct ui_out *uiout, char *identstring);
66 static void mi_flush (struct ui_out *uiout);
67 static int mi_redirect (struct ui_out *uiout, struct ui_file *outstream);
68 
69 /* This is the MI ui-out implementation functions vector */
70 
71 /* FIXME: This can be initialized dynamically after default is set to
72    handle initial output in main.c */
73 
74 struct ui_out_impl mi_ui_out_impl =
75 {
76   mi_table_begin,
77   mi_table_body,
78   mi_table_end,
79   mi_table_header,
80   mi_begin,
81   mi_end,
82   mi_field_int,
83   mi_field_skip,
84   mi_field_string,
85   mi_field_fmt,
86   mi_spaces,
87   mi_text,
88   mi_message,
89   mi_wrap_hint,
90   mi_flush,
91   mi_redirect,
92   1, /* Needs MI hacks.  */
93 };
94 
95 /* Prototypes for local functions */
96 
97 extern void _initialize_mi_out (void);
98 static void field_separator (struct ui_out *uiout);
99 static void mi_open (struct ui_out *uiout, const char *name,
100 		     enum ui_out_type type);
101 static void mi_close (struct ui_out *uiout, enum ui_out_type type);
102 
103 /* Mark beginning of a table */
104 
105 void
106 mi_table_begin (struct ui_out *uiout,
107 		int nr_cols,
108 		int nr_rows,
109 		const char *tblid)
110 {
111   mi_open (uiout, tblid, ui_out_type_tuple);
112   mi_field_int (uiout, -1/*fldno*/, -1/*width*/, -1/*alin*/,
113 		"nr_rows", nr_rows);
114   mi_field_int (uiout, -1/*fldno*/, -1/*width*/, -1/*alin*/,
115 		"nr_cols", nr_cols);
116   mi_open (uiout, "hdr", ui_out_type_list);
117 }
118 
119 /* Mark beginning of a table body */
120 
121 void
122 mi_table_body (struct ui_out *uiout)
123 {
124   mi_out_data *data = ui_out_data (uiout);
125 
126   if (data->suppress_output)
127     return;
128   /* close the table header line if there were any headers */
129   mi_close (uiout, ui_out_type_list);
130   mi_open (uiout, "body", ui_out_type_list);
131 }
132 
133 /* Mark end of a table */
134 
135 void
136 mi_table_end (struct ui_out *uiout)
137 {
138   mi_out_data *data = ui_out_data (uiout);
139 
140   data->suppress_output = 0;
141   mi_close (uiout, ui_out_type_list); /* body */
142   mi_close (uiout, ui_out_type_tuple);
143 }
144 
145 /* Specify table header */
146 
147 void
148 mi_table_header (struct ui_out *uiout, int width, enum ui_align alignment,
149 		 const char *col_name,
150 		 const char *colhdr)
151 {
152   mi_out_data *data = ui_out_data (uiout);
153 
154   if (data->suppress_output)
155     return;
156   mi_open (uiout, NULL, ui_out_type_tuple);
157   mi_field_int (uiout, 0, 0, 0, "width", width);
158   mi_field_int (uiout, 0, 0, 0, "alignment", alignment);
159   mi_field_string (uiout, 0, 0, 0, "col_name", col_name);
160   mi_field_string (uiout, 0, width, alignment, "colhdr", colhdr);
161   mi_close (uiout, ui_out_type_tuple);
162 }
163 
164 /* Mark beginning of a list */
165 
166 void
167 mi_begin (struct ui_out *uiout,
168 	  enum ui_out_type type,
169 	  int level,
170 	  const char *id)
171 {
172   mi_out_data *data = ui_out_data (uiout);
173 
174   if (data->suppress_output)
175     return;
176   mi_open (uiout, id, type);
177 }
178 
179 /* Mark end of a list */
180 
181 void
182 mi_end (struct ui_out *uiout,
183 	enum ui_out_type type,
184 	int level)
185 {
186   mi_out_data *data = ui_out_data (uiout);
187 
188   if (data->suppress_output)
189     return;
190   mi_close (uiout, type);
191 }
192 
193 /* output an int field */
194 
195 void
196 mi_field_int (struct ui_out *uiout, int fldno, int width,
197               enum ui_align alignment, const char *fldname, int value)
198 {
199   char buffer[20];	/* FIXME: how many chars long a %d can become? */
200   mi_out_data *data = ui_out_data (uiout);
201 
202   if (data->suppress_output)
203     return;
204 
205   sprintf (buffer, "%d", value);
206   mi_field_string (uiout, fldno, width, alignment, fldname, buffer);
207 }
208 
209 /* used to ommit a field */
210 
211 void
212 mi_field_skip (struct ui_out *uiout, int fldno, int width,
213                enum ui_align alignment, const char *fldname)
214 {
215 }
216 
217 /* other specific mi_field_* end up here so alignment and field
218    separators are both handled by mi_field_string */
219 
220 void
221 mi_field_string (struct ui_out *uiout,
222 		 int fldno,
223 		 int width,
224 		 enum ui_align align,
225 		 const char *fldname,
226 		 const char *string)
227 {
228   mi_out_data *data = ui_out_data (uiout);
229 
230   if (data->suppress_output)
231     return;
232   field_separator (uiout);
233   if (fldname)
234     fprintf_unfiltered (data->buffer, "%s=", fldname);
235   fprintf_unfiltered (data->buffer, "\"");
236   if (string)
237     fputstr_unfiltered (string, '"', data->buffer);
238   fprintf_unfiltered (data->buffer, "\"");
239 }
240 
241 /* This is the only field function that does not align */
242 
243 void
244 mi_field_fmt (struct ui_out *uiout, int fldno,
245 	      int width, enum ui_align align,
246 	      const char *fldname,
247 	      const char *format,
248 	      va_list args)
249 {
250   mi_out_data *data = ui_out_data (uiout);
251 
252   if (data->suppress_output)
253     return;
254   field_separator (uiout);
255   if (fldname)
256     fprintf_unfiltered (data->buffer, "%s=\"", fldname);
257   else
258     fputs_unfiltered ("\"", data->buffer);
259   vfprintf_unfiltered (data->buffer, format, args);
260   fputs_unfiltered ("\"", data->buffer);
261 }
262 
263 void
264 mi_spaces (struct ui_out *uiout, int numspaces)
265 {
266 }
267 
268 void
269 mi_text (struct ui_out *uiout, const char *string)
270 {
271 }
272 
273 void
274 mi_message (struct ui_out *uiout, int verbosity,
275 	    const char *format,
276 	    va_list args)
277 {
278 }
279 
280 void
281 mi_wrap_hint (struct ui_out *uiout, char *identstring)
282 {
283   wrap_here (identstring);
284 }
285 
286 void
287 mi_flush (struct ui_out *uiout)
288 {
289   mi_out_data *data = ui_out_data (uiout);
290 
291   gdb_flush (data->buffer);
292 }
293 
294 int
295 mi_redirect (struct ui_out *uiout, struct ui_file *outstream)
296 {
297   mi_out_data *data = ui_out_data (uiout);
298 
299   if (outstream != NULL)
300     {
301       data->original_buffer = data->buffer;
302       data->buffer = outstream;
303     }
304   else if (data->original_buffer != NULL)
305     {
306       data->buffer = data->original_buffer;
307       data->original_buffer = NULL;
308     }
309 
310   return 0;
311 }
312 
313 /* local functions */
314 
315 /* access to ui_out format private members */
316 
317 static void
318 field_separator (struct ui_out *uiout)
319 {
320   mi_out_data *data = ui_out_data (uiout);
321 
322   if (data->suppress_field_separator)
323     data->suppress_field_separator = 0;
324   else
325     fputc_unfiltered (',', data->buffer);
326 }
327 
328 static void
329 mi_open (struct ui_out *uiout,
330 	 const char *name,
331 	 enum ui_out_type type)
332 {
333   mi_out_data *data = ui_out_data (uiout);
334 
335   field_separator (uiout);
336   data->suppress_field_separator = 1;
337   if (name)
338     fprintf_unfiltered (data->buffer, "%s=", name);
339   switch (type)
340     {
341     case ui_out_type_tuple:
342       fputc_unfiltered ('{', data->buffer);
343       break;
344     case ui_out_type_list:
345       fputc_unfiltered ('[', data->buffer);
346       break;
347     default:
348       internal_error (__FILE__, __LINE__, _("bad switch"));
349     }
350 }
351 
352 static void
353 mi_close (struct ui_out *uiout,
354 	  enum ui_out_type type)
355 {
356   mi_out_data *data = ui_out_data (uiout);
357 
358   switch (type)
359     {
360     case ui_out_type_tuple:
361       fputc_unfiltered ('}', data->buffer);
362       break;
363     case ui_out_type_list:
364       fputc_unfiltered (']', data->buffer);
365       break;
366     default:
367       internal_error (__FILE__, __LINE__, _("bad switch"));
368     }
369   data->suppress_field_separator = 0;
370 }
371 
372 /* add a string to the buffer */
373 
374 void
375 mi_out_buffered (struct ui_out *uiout, char *string)
376 {
377   mi_out_data *data = ui_out_data (uiout);
378 
379   fprintf_unfiltered (data->buffer, "%s", string);
380 }
381 
382 /* clear the buffer */
383 
384 void
385 mi_out_rewind (struct ui_out *uiout)
386 {
387   mi_out_data *data = ui_out_data (uiout);
388 
389   ui_file_rewind (data->buffer);
390 }
391 
392 /* dump the buffer onto the specified stream */
393 
394 static void
395 do_write (void *data, const char *buffer, long length_buffer)
396 {
397   ui_file_write (data, buffer, length_buffer);
398 }
399 
400 void
401 mi_out_put (struct ui_out *uiout,
402 	    struct ui_file *stream)
403 {
404   mi_out_data *data = ui_out_data (uiout);
405 
406   ui_file_put (data->buffer, do_write, stream);
407   ui_file_rewind (data->buffer);
408 }
409 
410 /* Current MI version.  */
411 
412 int
413 mi_version (struct ui_out *uiout)
414 {
415   mi_out_data *data = ui_out_data (uiout);
416 
417   return data->mi_version;
418 }
419 
420 /* initalize private members at startup */
421 
422 struct ui_out *
423 mi_out_new (int mi_version)
424 {
425   int flags = 0;
426 
427   mi_out_data *data = XMALLOC (mi_out_data);
428   data->suppress_field_separator = 0;
429   data->suppress_output = 0;
430   data->mi_version = mi_version;
431   /* FIXME: This code should be using a ``string_file'' and not the
432      TUI buffer hack. */
433   data->buffer = mem_fileopen ();
434   return ui_out_new (&mi_ui_out_impl, data, flags);
435 }
436 
437 /* standard gdb initialization hook */
438 void
439 _initialize_mi_out (void)
440 {
441   /* nothing happens here */
442 }
443