gdb/mi/mi-out.c - gdb

Global variables defined

Data types defined

Functions defined

Source code

  1. /* MI Command Set - output generating routines.

  2.    Copyright (C) 2000-2015 Free Software Foundation, Inc.

  3.    Contributed by Cygnus Solutions (a Red Hat company).

  4.    This file is part of GDB.

  5.    This program is free software; you can redistribute it and/or modify
  6.    it under the terms of the GNU General Public License as published by
  7.    the Free Software Foundation; either version 3 of the License, or
  8.    (at your option) any later version.

  9.    This program is distributed in the hope that it will be useful,
  10.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.    GNU General Public License for more details.

  13.    You should have received a copy of the GNU General Public License
  14.    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

  15. #include "defs.h"
  16. #include "ui-out.h"
  17. #include "mi-out.h"

  18. struct ui_out_data
  19.   {
  20.     int suppress_field_separator;
  21.     int suppress_output;
  22.     int mi_version;
  23.     struct ui_file *buffer;
  24.     struct ui_file *original_buffer;
  25.   };
  26. typedef struct ui_out_data mi_out_data;

  27. /* These are the MI output functions */

  28. static void mi_table_begin (struct ui_out *uiout, int nbrofcols,
  29.                             int nr_rows, const char *tblid);
  30. static void mi_table_body (struct ui_out *uiout);
  31. static void mi_table_end (struct ui_out *uiout);
  32. static void mi_table_header (struct ui_out *uiout, int width,
  33.                              enum ui_align alig, const char *col_name,
  34.                              const char *colhdr);
  35. static void mi_begin (struct ui_out *uiout, enum ui_out_type type,
  36.                       int level, const char *id);
  37. static void mi_end (struct ui_out *uiout, enum ui_out_type type, int level);
  38. static void mi_field_int (struct ui_out *uiout, int fldno, int width,
  39.                           enum ui_align alig, const char *fldname, int value);
  40. static void mi_field_skip (struct ui_out *uiout, int fldno, int width,
  41.                            enum ui_align alig, const char *fldname);
  42. static void mi_field_string (struct ui_out *uiout, int fldno, int width,
  43.                              enum ui_align alig, const char *fldname,
  44.                              const char *string);
  45. static void mi_field_fmt (struct ui_out *uiout, int fldno,
  46.                           int width, enum ui_align align,
  47.                           const char *fldname, const char *format,
  48.                           va_list args) ATTRIBUTE_PRINTF (6, 0);
  49. static void mi_spaces (struct ui_out *uiout, int numspaces);
  50. static void mi_text (struct ui_out *uiout, const char *string);
  51. static void mi_message (struct ui_out *uiout, int verbosity,
  52.                         const char *format, va_list args)
  53.      ATTRIBUTE_PRINTF (3, 0);
  54. static void mi_wrap_hint (struct ui_out *uiout, char *identstring);
  55. static void mi_flush (struct ui_out *uiout);
  56. static int mi_redirect (struct ui_out *uiout, struct ui_file *outstream);

  57. /* This is the MI ui-out implementation functions vector */

  58. static const struct ui_out_impl mi_ui_out_impl =
  59. {
  60.   mi_table_begin,
  61.   mi_table_body,
  62.   mi_table_end,
  63.   mi_table_header,
  64.   mi_begin,
  65.   mi_end,
  66.   mi_field_int,
  67.   mi_field_skip,
  68.   mi_field_string,
  69.   mi_field_fmt,
  70.   mi_spaces,
  71.   mi_text,
  72.   mi_message,
  73.   mi_wrap_hint,
  74.   mi_flush,
  75.   mi_redirect,
  76.   0,
  77.   1, /* Needs MI hacks.  */
  78. };

  79. /* Prototypes for local functions */

  80. extern void _initialize_mi_out (void);
  81. static void field_separator (struct ui_out *uiout);
  82. static void mi_open (struct ui_out *uiout, const char *name,
  83.                      enum ui_out_type type);
  84. static void mi_close (struct ui_out *uiout, enum ui_out_type type);

  85. /* Mark beginning of a table.  */

  86. void
  87. mi_table_begin (struct ui_out *uiout,
  88.                 int nr_cols,
  89.                 int nr_rows,
  90.                 const char *tblid)
  91. {
  92.   mi_open (uiout, tblid, ui_out_type_tuple);
  93.   mi_field_int (uiout, -1, -1, -1, "nr_rows", nr_rows);
  94.   mi_field_int (uiout, -1, -1, -1, "nr_cols", nr_cols);
  95.   mi_open (uiout, "hdr", ui_out_type_list);
  96. }

  97. /* Mark beginning of a table body.  */

  98. void
  99. mi_table_body (struct ui_out *uiout)
  100. {
  101.   mi_out_data *data = ui_out_data (uiout);

  102.   if (data->suppress_output)
  103.     return;
  104.   /* close the table header line if there were any headers */
  105.   mi_close (uiout, ui_out_type_list);
  106.   mi_open (uiout, "body", ui_out_type_list);
  107. }

  108. /* Mark end of a table.  */

  109. void
  110. mi_table_end (struct ui_out *uiout)
  111. {
  112.   mi_out_data *data = ui_out_data (uiout);

  113.   data->suppress_output = 0;
  114.   mi_close (uiout, ui_out_type_list); /* body */
  115.   mi_close (uiout, ui_out_type_tuple);
  116. }

  117. /* Specify table header.  */

  118. void
  119. mi_table_header (struct ui_out *uiout, int width, enum ui_align alignment,
  120.                  const char *col_name, const char *colhdr)
  121. {
  122.   mi_out_data *data = ui_out_data (uiout);

  123.   if (data->suppress_output)
  124.     return;

  125.   mi_open (uiout, NULL, ui_out_type_tuple);
  126.   mi_field_int (uiout, 0, 0, 0, "width", width);
  127.   mi_field_int (uiout, 0, 0, 0, "alignment", alignment);
  128.   mi_field_string (uiout, 0, 0, 0, "col_name", col_name);
  129.   mi_field_string (uiout, 0, width, alignment, "colhdr", colhdr);
  130.   mi_close (uiout, ui_out_type_tuple);
  131. }

  132. /* Mark beginning of a list.  */

  133. void
  134. mi_begin (struct ui_out *uiout, enum ui_out_type type, int level,
  135.           const char *id)
  136. {
  137.   mi_out_data *data = ui_out_data (uiout);

  138.   if (data->suppress_output)
  139.     return;

  140.   mi_open (uiout, id, type);
  141. }

  142. /* Mark end of a list.  */

  143. void
  144. mi_end (struct ui_out *uiout, enum ui_out_type type, int level)
  145. {
  146.   mi_out_data *data = ui_out_data (uiout);

  147.   if (data->suppress_output)
  148.     return;

  149.   mi_close (uiout, type);
  150. }

  151. /* Output an int field.  */

  152. static void
  153. mi_field_int (struct ui_out *uiout, int fldno, int width,
  154.               enum ui_align alignment, const char *fldname, int value)
  155. {
  156.   char buffer[20];        /* FIXME: how many chars long a %d can become? */
  157.   mi_out_data *data = ui_out_data (uiout);

  158.   if (data->suppress_output)
  159.     return;

  160.   xsnprintf (buffer, sizeof (buffer), "%d", value);
  161.   mi_field_string (uiout, fldno, width, alignment, fldname, buffer);
  162. }

  163. /* Used to omit a field.  */

  164. void
  165. mi_field_skip (struct ui_out *uiout, int fldno, int width,
  166.                enum ui_align alignment, const char *fldname)
  167. {
  168. }

  169. /* Other specific mi_field_* end up here so alignment and field
  170.    separators are both handled by mi_field_string. */

  171. void
  172. mi_field_string (struct ui_out *uiout, int fldno, int width,
  173.                  enum ui_align align, const char *fldname, const char *string)
  174. {
  175.   mi_out_data *data = ui_out_data (uiout);

  176.   if (data->suppress_output)
  177.     return;

  178.   field_separator (uiout);
  179.   if (fldname)
  180.     fprintf_unfiltered (data->buffer, "%s=", fldname);
  181.   fprintf_unfiltered (data->buffer, "\"");
  182.   if (string)
  183.     fputstr_unfiltered (string, '"', data->buffer);
  184.   fprintf_unfiltered (data->buffer, "\"");
  185. }

  186. /* This is the only field function that does not align.  */

  187. void
  188. mi_field_fmt (struct ui_out *uiout, int fldno, int width,
  189.               enum ui_align align, const char *fldname,
  190.               const char *format, va_list args)
  191. {
  192.   mi_out_data *data = ui_out_data (uiout);

  193.   if (data->suppress_output)
  194.     return;

  195.   field_separator (uiout);
  196.   if (fldname)
  197.     fprintf_unfiltered (data->buffer, "%s=\"", fldname);
  198.   else
  199.     fputs_unfiltered ("\"", data->buffer);
  200.   vfprintf_unfiltered (data->buffer, format, args);
  201.   fputs_unfiltered ("\"", data->buffer);
  202. }

  203. void
  204. mi_spaces (struct ui_out *uiout, int numspaces)
  205. {
  206. }

  207. void
  208. mi_text (struct ui_out *uiout, const char *string)
  209. {
  210. }

  211. void
  212. mi_message (struct ui_out *uiout, int verbosity,
  213.             const char *format, va_list args)
  214. {
  215. }

  216. void
  217. mi_wrap_hint (struct ui_out *uiout, char *identstring)
  218. {
  219.   wrap_here (identstring);
  220. }

  221. void
  222. mi_flush (struct ui_out *uiout)
  223. {
  224.   mi_out_data *data = ui_out_data (uiout);

  225.   gdb_flush (data->buffer);
  226. }

  227. int
  228. mi_redirect (struct ui_out *uiout, struct ui_file *outstream)
  229. {
  230.   mi_out_data *data = ui_out_data (uiout);

  231.   if (outstream != NULL)
  232.     {
  233.       data->original_buffer = data->buffer;
  234.       data->buffer = outstream;
  235.     }
  236.   else if (data->original_buffer != NULL)
  237.     {
  238.       data->buffer = data->original_buffer;
  239.       data->original_buffer = NULL;
  240.     }

  241.   return 0;
  242. }

  243. /* local functions */

  244. /* access to ui_out format private members */

  245. static void
  246. field_separator (struct ui_out *uiout)
  247. {
  248.   mi_out_data *data = ui_out_data (uiout);

  249.   if (data->suppress_field_separator)
  250.     data->suppress_field_separator = 0;
  251.   else
  252.     fputc_unfiltered (',', data->buffer);
  253. }

  254. static void
  255. mi_open (struct ui_out *uiout, const char *name, enum ui_out_type type)
  256. {
  257.   mi_out_data *data = ui_out_data (uiout);

  258.   field_separator (uiout);
  259.   data->suppress_field_separator = 1;
  260.   if (name)
  261.     fprintf_unfiltered (data->buffer, "%s=", name);
  262.   switch (type)
  263.     {
  264.     case ui_out_type_tuple:
  265.       fputc_unfiltered ('{', data->buffer);
  266.       break;
  267.     case ui_out_type_list:
  268.       fputc_unfiltered ('[', data->buffer);
  269.       break;
  270.     default:
  271.       internal_error (__FILE__, __LINE__, _("bad switch"));
  272.     }
  273. }

  274. static void
  275. mi_close (struct ui_out *uiout, enum ui_out_type type)
  276. {
  277.   mi_out_data *data = ui_out_data (uiout);

  278.   switch (type)
  279.     {
  280.     case ui_out_type_tuple:
  281.       fputc_unfiltered ('}', data->buffer);
  282.       break;
  283.     case ui_out_type_list:
  284.       fputc_unfiltered (']', data->buffer);
  285.       break;
  286.     default:
  287.       internal_error (__FILE__, __LINE__, _("bad switch"));
  288.     }
  289.   data->suppress_field_separator = 0;
  290. }

  291. /* Add a string to the buffer.  */

  292. void
  293. mi_out_buffered (struct ui_out *uiout, char *string)
  294. {
  295.   mi_out_data *data = ui_out_data (uiout);

  296.   fprintf_unfiltered (data->buffer, "%s", string);
  297. }

  298. /* Clear the buffer.  */

  299. void
  300. mi_out_rewind (struct ui_out *uiout)
  301. {
  302.   mi_out_data *data = ui_out_data (uiout);

  303.   ui_file_rewind (data->buffer);
  304. }

  305. /* Dump the buffer onto the specified stream.  */

  306. void
  307. mi_out_put (struct ui_out *uiout, struct ui_file *stream)
  308. {
  309.   mi_out_data *data = ui_out_data (uiout);

  310.   ui_file_put (data->buffer, ui_file_write_for_put, stream);
  311.   ui_file_rewind (data->buffer);
  312. }

  313. /* Return the current MI version.  */

  314. int
  315. mi_version (struct ui_out *uiout)
  316. {
  317.   mi_out_data *data = ui_out_data (uiout);

  318.   return data->mi_version;
  319. }

  320. /* Initialize private members at startup.  */

  321. struct ui_out *
  322. mi_out_new (int mi_version)
  323. {
  324.   int flags = 0;

  325.   mi_out_data *data = XNEW (mi_out_data);
  326.   data->suppress_field_separator = 0;
  327.   data->suppress_output = 0;
  328.   data->mi_version = mi_version;
  329.   /* FIXME: This code should be using a ``string_file'' and not the
  330.      TUI buffer hack. */
  331.   data->buffer = mem_fileopen ();
  332.   return ui_out_new (&mi_ui_out_impl, data, flags);
  333. }