1 /* Output generating routines for GDB CLI. 2 3 Copyright 1999, 2000, 2002, 2003 Free Software Foundation, Inc. 4 5 Contributed by Cygnus Solutions. 6 Written by Fernando Nasser for Cygnus. 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 2 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, write to the Free Software 22 Foundation, Inc., 59 Temple Place - Suite 330, 23 Boston, MA 02111-1307, USA. */ 24 25 #include "defs.h" 26 #include "ui-out.h" 27 #include "cli-out.h" 28 #include "gdb_string.h" 29 #include "gdb_assert.h" 30 31 struct ui_out_data 32 { 33 struct ui_file *stream; 34 struct ui_file *original_stream; 35 int suppress_output; 36 }; 37 typedef struct ui_out_data cli_out_data; 38 39 /* These are the CLI output functions */ 40 41 static void cli_table_begin (struct ui_out *uiout, int nbrofcols, 42 int nr_rows, const char *tblid); 43 static void cli_table_body (struct ui_out *uiout); 44 static void cli_table_end (struct ui_out *uiout); 45 static void cli_table_header (struct ui_out *uiout, int width, 46 enum ui_align alig, const char *col_name, 47 const char *colhdr); 48 static void cli_begin (struct ui_out *uiout, enum ui_out_type type, 49 int level, const char *lstid); 50 static void cli_end (struct ui_out *uiout, enum ui_out_type type, int level); 51 static void cli_field_int (struct ui_out *uiout, int fldno, int width, 52 enum ui_align alig, const char *fldname, int value); 53 static void cli_field_skip (struct ui_out *uiout, int fldno, int width, 54 enum ui_align alig, const char *fldname); 55 static void cli_field_string (struct ui_out *uiout, int fldno, int width, 56 enum ui_align alig, const char *fldname, 57 const char *string); 58 static void cli_field_fmt (struct ui_out *uiout, int fldno, 59 int width, enum ui_align align, 60 const char *fldname, const char *format, 61 va_list args); 62 static void cli_spaces (struct ui_out *uiout, int numspaces); 63 static void cli_text (struct ui_out *uiout, const char *string); 64 static void cli_message (struct ui_out *uiout, int verbosity, 65 const char *format, va_list args); 66 static void cli_wrap_hint (struct ui_out *uiout, char *identstring); 67 static void cli_flush (struct ui_out *uiout); 68 static int cli_redirect (struct ui_out *uiout, struct ui_file *outstream); 69 70 /* This is the CLI ui-out implementation functions vector */ 71 72 /* FIXME: This can be initialized dynamically after default is set to 73 handle initial output in main.c */ 74 75 static struct ui_out_impl cli_ui_out_impl = 76 { 77 cli_table_begin, 78 cli_table_body, 79 cli_table_end, 80 cli_table_header, 81 cli_begin, 82 cli_end, 83 cli_field_int, 84 cli_field_skip, 85 cli_field_string, 86 cli_field_fmt, 87 cli_spaces, 88 cli_text, 89 cli_message, 90 cli_wrap_hint, 91 cli_flush, 92 cli_redirect, 93 0, /* Does not need MI hacks (i.e. needs CLI hacks). */ 94 }; 95 96 /* Prototypes for local functions */ 97 98 extern void _initialize_cli_out (void); 99 100 static void field_separator (void); 101 102 static void out_field_fmt (struct ui_out *uiout, int fldno, 103 const char *fldname, 104 const char *format,...); 105 106 /* local variables */ 107 108 /* (none yet) */ 109 110 /* Mark beginning of a table */ 111 112 void 113 cli_table_begin (struct ui_out *uiout, int nbrofcols, 114 int nr_rows, 115 const char *tblid) 116 { 117 cli_out_data *data = ui_out_data (uiout); 118 if (nr_rows == 0) 119 data->suppress_output = 1; 120 else 121 /* Only the table suppresses the output and, fortunately, a table 122 is not a recursive data structure. */ 123 gdb_assert (data->suppress_output == 0); 124 } 125 126 /* Mark beginning of a table body */ 127 128 void 129 cli_table_body (struct ui_out *uiout) 130 { 131 cli_out_data *data = ui_out_data (uiout); 132 if (data->suppress_output) 133 return; 134 /* first, close the table header line */ 135 cli_text (uiout, "\n"); 136 } 137 138 /* Mark end of a table */ 139 140 void 141 cli_table_end (struct ui_out *uiout) 142 { 143 cli_out_data *data = ui_out_data (uiout); 144 data->suppress_output = 0; 145 } 146 147 /* Specify table header */ 148 149 void 150 cli_table_header (struct ui_out *uiout, int width, enum ui_align alignment, 151 const char *col_name, 152 const char *colhdr) 153 { 154 cli_out_data *data = ui_out_data (uiout); 155 if (data->suppress_output) 156 return; 157 cli_field_string (uiout, 0, width, alignment, 0, colhdr); 158 } 159 160 /* Mark beginning of a list */ 161 162 void 163 cli_begin (struct ui_out *uiout, 164 enum ui_out_type type, 165 int level, 166 const char *id) 167 { 168 cli_out_data *data = ui_out_data (uiout); 169 if (data->suppress_output) 170 return; 171 } 172 173 /* Mark end of a list */ 174 175 void 176 cli_end (struct ui_out *uiout, 177 enum ui_out_type type, 178 int level) 179 { 180 cli_out_data *data = ui_out_data (uiout); 181 if (data->suppress_output) 182 return; 183 } 184 185 /* output an int field */ 186 187 void 188 cli_field_int (struct ui_out *uiout, int fldno, int width, 189 enum ui_align alignment, 190 const char *fldname, int value) 191 { 192 char buffer[20]; /* FIXME: how many chars long a %d can become? */ 193 194 cli_out_data *data = ui_out_data (uiout); 195 if (data->suppress_output) 196 return; 197 sprintf (buffer, "%d", value); 198 cli_field_string (uiout, fldno, width, alignment, fldname, buffer); 199 } 200 201 /* used to ommit a field */ 202 203 void 204 cli_field_skip (struct ui_out *uiout, int fldno, int width, 205 enum ui_align alignment, 206 const char *fldname) 207 { 208 cli_out_data *data = ui_out_data (uiout); 209 if (data->suppress_output) 210 return; 211 cli_field_string (uiout, fldno, width, alignment, fldname, ""); 212 } 213 214 /* other specific cli_field_* end up here so alignment and field 215 separators are both handled by cli_field_string */ 216 217 void 218 cli_field_string (struct ui_out *uiout, 219 int fldno, 220 int width, 221 enum ui_align align, 222 const char *fldname, 223 const char *string) 224 { 225 int before = 0; 226 int after = 0; 227 228 cli_out_data *data = ui_out_data (uiout); 229 if (data->suppress_output) 230 return; 231 232 if ((align != ui_noalign) && string) 233 { 234 before = width - strlen (string); 235 if (before <= 0) 236 before = 0; 237 else 238 { 239 if (align == ui_right) 240 after = 0; 241 else if (align == ui_left) 242 { 243 after = before; 244 before = 0; 245 } 246 else 247 /* ui_center */ 248 { 249 after = before / 2; 250 before -= after; 251 } 252 } 253 } 254 255 if (before) 256 ui_out_spaces (uiout, before); 257 if (string) 258 out_field_fmt (uiout, fldno, fldname, "%s", string); 259 if (after) 260 ui_out_spaces (uiout, after); 261 262 if (align != ui_noalign) 263 field_separator (); 264 } 265 266 /* This is the only field function that does not align */ 267 268 void 269 cli_field_fmt (struct ui_out *uiout, int fldno, 270 int width, enum ui_align align, 271 const char *fldname, 272 const char *format, 273 va_list args) 274 { 275 cli_out_data *data = ui_out_data (uiout); 276 if (data->suppress_output) 277 return; 278 279 vfprintf_filtered (data->stream, format, args); 280 281 if (align != ui_noalign) 282 field_separator (); 283 } 284 285 void 286 cli_spaces (struct ui_out *uiout, int numspaces) 287 { 288 cli_out_data *data = ui_out_data (uiout); 289 if (data->suppress_output) 290 return; 291 print_spaces_filtered (numspaces, data->stream); 292 } 293 294 void 295 cli_text (struct ui_out *uiout, const char *string) 296 { 297 cli_out_data *data = ui_out_data (uiout); 298 if (data->suppress_output) 299 return; 300 fputs_filtered (string, data->stream); 301 } 302 303 void 304 cli_message (struct ui_out *uiout, int verbosity, 305 const char *format, va_list args) 306 { 307 cli_out_data *data = ui_out_data (uiout); 308 if (data->suppress_output) 309 return; 310 if (ui_out_get_verblvl (uiout) >= verbosity) 311 vfprintf_unfiltered (data->stream, format, args); 312 } 313 314 void 315 cli_wrap_hint (struct ui_out *uiout, char *identstring) 316 { 317 cli_out_data *data = ui_out_data (uiout); 318 if (data->suppress_output) 319 return; 320 wrap_here (identstring); 321 } 322 323 void 324 cli_flush (struct ui_out *uiout) 325 { 326 cli_out_data *data = ui_out_data (uiout); 327 gdb_flush (data->stream); 328 } 329 330 int 331 cli_redirect (struct ui_out *uiout, struct ui_file *outstream) 332 { 333 struct ui_out_data *data = ui_out_data (uiout); 334 if (outstream != NULL) 335 { 336 data->original_stream = data->stream; 337 data->stream = outstream; 338 } 339 else if (data->original_stream != NULL) 340 { 341 data->stream = data->original_stream; 342 data->original_stream = NULL; 343 } 344 345 return 0; 346 } 347 348 /* local functions */ 349 350 /* Like cli_field_fmt, but takes a variable number of args 351 and makes a va_list and does not insert a separator */ 352 353 /* VARARGS */ 354 static void 355 out_field_fmt (struct ui_out *uiout, int fldno, 356 const char *fldname, 357 const char *format,...) 358 { 359 cli_out_data *data = ui_out_data (uiout); 360 va_list args; 361 362 va_start (args, format); 363 vfprintf_filtered (data->stream, format, args); 364 365 va_end (args); 366 } 367 368 /* access to ui_out format private members */ 369 370 static void 371 field_separator (void) 372 { 373 cli_out_data *data = ui_out_data (uiout); 374 fputc_filtered (' ', data->stream); 375 } 376 377 /* initalize private members at startup */ 378 379 struct ui_out * 380 cli_out_new (struct ui_file *stream) 381 { 382 int flags = ui_source_list; 383 384 cli_out_data *data = XMALLOC (cli_out_data); 385 data->stream = stream; 386 data->original_stream = NULL; 387 data->suppress_output = 0; 388 return ui_out_new (&cli_ui_out_impl, data, flags); 389 } 390 391 struct ui_file * 392 cli_out_set_stream (struct ui_out *uiout, struct ui_file *stream) 393 { 394 cli_out_data *data = ui_out_data (uiout); 395 struct ui_file *old = data->stream; 396 data->stream = stream; 397 return old; 398 } 399 400 /* standard gdb initialization hook */ 401 void 402 _initialize_cli_out (void) 403 { 404 /* nothing needs to be done */ 405 } 406