GDB (API)
/home/stan/gdb/src/gdb/mi/mi-out.c
Go to the documentation of this file.
00001 /* MI Command Set - output generating routines.
00002 
00003    Copyright (C) 2000-2013 Free Software Foundation, Inc.
00004 
00005    Contributed by Cygnus Solutions (a Red Hat company).
00006 
00007    This file is part of GDB.
00008 
00009    This program is free software; you can redistribute it and/or modify
00010    it under the terms of the GNU General Public License as published by
00011    the Free Software Foundation; either version 3 of the License, or
00012    (at your option) any later version.
00013 
00014    This program is distributed in the hope that it will be useful,
00015    but WITHOUT ANY WARRANTY; without even the implied warranty of
00016    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017    GNU General Public License for more details.
00018 
00019    You should have received a copy of the GNU General Public License
00020    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
00021 
00022 #include "defs.h"
00023 #include "ui-out.h"
00024 #include "mi-out.h"
00025 
00026 struct ui_out_data
00027   {
00028     int suppress_field_separator;
00029     int suppress_output;
00030     int mi_version;
00031     struct ui_file *buffer;
00032     struct ui_file *original_buffer;
00033   };
00034 typedef struct ui_out_data mi_out_data;
00035 
00036 /* These are the MI output functions */
00037 
00038 static void mi_table_begin (struct ui_out *uiout, int nbrofcols,
00039                             int nr_rows, const char *tblid);
00040 static void mi_table_body (struct ui_out *uiout);
00041 static void mi_table_end (struct ui_out *uiout);
00042 static void mi_table_header (struct ui_out *uiout, int width,
00043                              enum ui_align alig, const char *col_name,
00044                              const char *colhdr);
00045 static void mi_begin (struct ui_out *uiout, enum ui_out_type type,
00046                       int level, const char *id);
00047 static void mi_end (struct ui_out *uiout, enum ui_out_type type, int level);
00048 static void mi_field_int (struct ui_out *uiout, int fldno, int width,
00049                           enum ui_align alig, const char *fldname, int value);
00050 static void mi_field_skip (struct ui_out *uiout, int fldno, int width,
00051                            enum ui_align alig, const char *fldname);
00052 static void mi_field_string (struct ui_out *uiout, int fldno, int width,
00053                              enum ui_align alig, const char *fldname,
00054                              const char *string);
00055 static void mi_field_fmt (struct ui_out *uiout, int fldno,
00056                           int width, enum ui_align align,
00057                           const char *fldname, const char *format,
00058                           va_list args) ATTRIBUTE_PRINTF (6, 0);
00059 static void mi_spaces (struct ui_out *uiout, int numspaces);
00060 static void mi_text (struct ui_out *uiout, const char *string);
00061 static void mi_message (struct ui_out *uiout, int verbosity,
00062                         const char *format, va_list args)
00063      ATTRIBUTE_PRINTF (3, 0);
00064 static void mi_wrap_hint (struct ui_out *uiout, char *identstring);
00065 static void mi_flush (struct ui_out *uiout);
00066 static int mi_redirect (struct ui_out *uiout, struct ui_file *outstream);
00067 
00068 /* This is the MI ui-out implementation functions vector */
00069 
00070 /* FIXME: This can be initialized dynamically after default is set to
00071    handle initial output in main.c */
00072 
00073 struct ui_out_impl mi_ui_out_impl =
00074 {
00075   mi_table_begin,
00076   mi_table_body,
00077   mi_table_end,
00078   mi_table_header,
00079   mi_begin,
00080   mi_end,
00081   mi_field_int,
00082   mi_field_skip,
00083   mi_field_string,
00084   mi_field_fmt,
00085   mi_spaces,
00086   mi_text,
00087   mi_message,
00088   mi_wrap_hint,
00089   mi_flush,
00090   mi_redirect,
00091   0,
00092   1, /* Needs MI hacks.  */
00093 };
00094 
00095 /* Prototypes for local functions */
00096 
00097 extern void _initialize_mi_out (void);
00098 static void field_separator (struct ui_out *uiout);
00099 static void mi_open (struct ui_out *uiout, const char *name,
00100                      enum ui_out_type type);
00101 static void mi_close (struct ui_out *uiout, enum ui_out_type type);
00102 
00103 /* Mark beginning of a table.  */
00104 
00105 void
00106 mi_table_begin (struct ui_out *uiout,
00107                 int nr_cols,
00108                 int nr_rows,
00109                 const char *tblid)
00110 {
00111   mi_open (uiout, tblid, ui_out_type_tuple);
00112   mi_field_int (uiout, -1, -1, -1, "nr_rows", nr_rows);
00113   mi_field_int (uiout, -1, -1, -1, "nr_cols", nr_cols);
00114   mi_open (uiout, "hdr", ui_out_type_list);
00115 }
00116 
00117 /* Mark beginning of a table body.  */
00118 
00119 void
00120 mi_table_body (struct ui_out *uiout)
00121 {
00122   mi_out_data *data = ui_out_data (uiout);
00123 
00124   if (data->suppress_output)
00125     return;
00126   /* close the table header line if there were any headers */
00127   mi_close (uiout, ui_out_type_list);
00128   mi_open (uiout, "body", ui_out_type_list);
00129 }
00130 
00131 /* Mark end of a table.  */
00132 
00133 void
00134 mi_table_end (struct ui_out *uiout)
00135 {
00136   mi_out_data *data = ui_out_data (uiout);
00137 
00138   data->suppress_output = 0;
00139   mi_close (uiout, ui_out_type_list); /* body */
00140   mi_close (uiout, ui_out_type_tuple);
00141 }
00142 
00143 /* Specify table header.  */
00144 
00145 void
00146 mi_table_header (struct ui_out *uiout, int width, enum ui_align alignment,
00147                  const char *col_name, const char *colhdr)
00148 {
00149   mi_out_data *data = ui_out_data (uiout);
00150 
00151   if (data->suppress_output)
00152     return;
00153 
00154   mi_open (uiout, NULL, ui_out_type_tuple);
00155   mi_field_int (uiout, 0, 0, 0, "width", width);
00156   mi_field_int (uiout, 0, 0, 0, "alignment", alignment);
00157   mi_field_string (uiout, 0, 0, 0, "col_name", col_name);
00158   mi_field_string (uiout, 0, width, alignment, "colhdr", colhdr);
00159   mi_close (uiout, ui_out_type_tuple);
00160 }
00161 
00162 /* Mark beginning of a list.  */
00163 
00164 void
00165 mi_begin (struct ui_out *uiout, enum ui_out_type type, int level,
00166           const char *id)
00167 {
00168   mi_out_data *data = ui_out_data (uiout);
00169 
00170   if (data->suppress_output)
00171     return;
00172 
00173   mi_open (uiout, id, type);
00174 }
00175 
00176 /* Mark end of a list.  */
00177 
00178 void
00179 mi_end (struct ui_out *uiout, enum ui_out_type type, int level)
00180 {
00181   mi_out_data *data = ui_out_data (uiout);
00182 
00183   if (data->suppress_output)
00184     return;
00185 
00186   mi_close (uiout, type);
00187 }
00188 
00189 /* Output an int field.  */
00190 
00191 static void
00192 mi_field_int (struct ui_out *uiout, int fldno, int width,
00193               enum ui_align alignment, const char *fldname, int value)
00194 {
00195   char buffer[20];      /* FIXME: how many chars long a %d can become? */
00196   mi_out_data *data = ui_out_data (uiout);
00197 
00198   if (data->suppress_output)
00199     return;
00200 
00201   xsnprintf (buffer, sizeof (buffer), "%d", value);
00202   mi_field_string (uiout, fldno, width, alignment, fldname, buffer);
00203 }
00204 
00205 /* Used to omit a field.  */
00206 
00207 void
00208 mi_field_skip (struct ui_out *uiout, int fldno, int width,
00209                enum ui_align alignment, const char *fldname)
00210 {
00211 }
00212 
00213 /* Other specific mi_field_* end up here so alignment and field
00214    separators are both handled by mi_field_string. */
00215 
00216 void
00217 mi_field_string (struct ui_out *uiout, int fldno, int width,
00218                  enum ui_align align, const char *fldname, const char *string)
00219 {
00220   mi_out_data *data = ui_out_data (uiout);
00221 
00222   if (data->suppress_output)
00223     return;
00224 
00225   field_separator (uiout);
00226   if (fldname)
00227     fprintf_unfiltered (data->buffer, "%s=", fldname);
00228   fprintf_unfiltered (data->buffer, "\"");
00229   if (string)
00230     fputstr_unfiltered (string, '"', data->buffer);
00231   fprintf_unfiltered (data->buffer, "\"");
00232 }
00233 
00234 /* This is the only field function that does not align.  */
00235 
00236 void
00237 mi_field_fmt (struct ui_out *uiout, int fldno, int width,
00238               enum ui_align align, const char *fldname,
00239               const char *format, va_list args)
00240 {
00241   mi_out_data *data = ui_out_data (uiout);
00242 
00243   if (data->suppress_output)
00244     return;
00245 
00246   field_separator (uiout);
00247   if (fldname)
00248     fprintf_unfiltered (data->buffer, "%s=\"", fldname);
00249   else
00250     fputs_unfiltered ("\"", data->buffer);
00251   vfprintf_unfiltered (data->buffer, format, args);
00252   fputs_unfiltered ("\"", data->buffer);
00253 }
00254 
00255 void
00256 mi_spaces (struct ui_out *uiout, int numspaces)
00257 {
00258 }
00259 
00260 void
00261 mi_text (struct ui_out *uiout, const char *string)
00262 {
00263 }
00264 
00265 void
00266 mi_message (struct ui_out *uiout, int verbosity,
00267             const char *format, va_list args)
00268 {
00269 }
00270 
00271 void
00272 mi_wrap_hint (struct ui_out *uiout, char *identstring)
00273 {
00274   wrap_here (identstring);
00275 }
00276 
00277 void
00278 mi_flush (struct ui_out *uiout)
00279 {
00280   mi_out_data *data = ui_out_data (uiout);
00281 
00282   gdb_flush (data->buffer);
00283 }
00284 
00285 int
00286 mi_redirect (struct ui_out *uiout, struct ui_file *outstream)
00287 {
00288   mi_out_data *data = ui_out_data (uiout);
00289 
00290   if (outstream != NULL)
00291     {
00292       data->original_buffer = data->buffer;
00293       data->buffer = outstream;
00294     }
00295   else if (data->original_buffer != NULL)
00296     {
00297       data->buffer = data->original_buffer;
00298       data->original_buffer = NULL;
00299     }
00300 
00301   return 0;
00302 }
00303 
00304 /* local functions */
00305 
00306 /* access to ui_out format private members */
00307 
00308 static void
00309 field_separator (struct ui_out *uiout)
00310 {
00311   mi_out_data *data = ui_out_data (uiout);
00312 
00313   if (data->suppress_field_separator)
00314     data->suppress_field_separator = 0;
00315   else
00316     fputc_unfiltered (',', data->buffer);
00317 }
00318 
00319 static void
00320 mi_open (struct ui_out *uiout, const char *name, enum ui_out_type type)
00321 {
00322   mi_out_data *data = ui_out_data (uiout);
00323 
00324   field_separator (uiout);
00325   data->suppress_field_separator = 1;
00326   if (name)
00327     fprintf_unfiltered (data->buffer, "%s=", name);
00328   switch (type)
00329     {
00330     case ui_out_type_tuple:
00331       fputc_unfiltered ('{', data->buffer);
00332       break;
00333     case ui_out_type_list:
00334       fputc_unfiltered ('[', data->buffer);
00335       break;
00336     default:
00337       internal_error (__FILE__, __LINE__, _("bad switch"));
00338     }
00339 }
00340 
00341 static void
00342 mi_close (struct ui_out *uiout, enum ui_out_type type)
00343 {
00344   mi_out_data *data = ui_out_data (uiout);
00345 
00346   switch (type)
00347     {
00348     case ui_out_type_tuple:
00349       fputc_unfiltered ('}', data->buffer);
00350       break;
00351     case ui_out_type_list:
00352       fputc_unfiltered (']', data->buffer);
00353       break;
00354     default:
00355       internal_error (__FILE__, __LINE__, _("bad switch"));
00356     }
00357   data->suppress_field_separator = 0;
00358 }
00359 
00360 /* Add a string to the buffer.  */
00361 
00362 void
00363 mi_out_buffered (struct ui_out *uiout, char *string)
00364 {
00365   mi_out_data *data = ui_out_data (uiout);
00366 
00367   fprintf_unfiltered (data->buffer, "%s", string);
00368 }
00369 
00370 /* Clear the buffer.  */
00371 
00372 void
00373 mi_out_rewind (struct ui_out *uiout)
00374 {
00375   mi_out_data *data = ui_out_data (uiout);
00376 
00377   ui_file_rewind (data->buffer);
00378 }
00379 
00380 /* Dump the buffer onto the specified stream.  */
00381 
00382 static void
00383 do_write (void *data, const char *buffer, long length_buffer)
00384 {
00385   ui_file_write (data, buffer, length_buffer);
00386 }
00387 
00388 void
00389 mi_out_put (struct ui_out *uiout, struct ui_file *stream)
00390 {
00391   mi_out_data *data = ui_out_data (uiout);
00392 
00393   ui_file_put (data->buffer, do_write, stream);
00394   ui_file_rewind (data->buffer);
00395 }
00396 
00397 /* Return the current MI version.  */
00398 
00399 int
00400 mi_version (struct ui_out *uiout)
00401 {
00402   mi_out_data *data = ui_out_data (uiout);
00403 
00404   return data->mi_version;
00405 }
00406 
00407 /* Initialize private members at startup.  */
00408 
00409 struct ui_out *
00410 mi_out_new (int mi_version)
00411 {
00412   int flags = 0;
00413 
00414   mi_out_data *data = XMALLOC (mi_out_data);
00415   data->suppress_field_separator = 0;
00416   data->suppress_output = 0;
00417   data->mi_version = mi_version;
00418   /* FIXME: This code should be using a ``string_file'' and not the
00419      TUI buffer hack. */
00420   data->buffer = mem_fileopen ();
00421   return ui_out_new (&mi_ui_out_impl, data, flags);
00422 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines