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