GDB (API)
|
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 }