1130803Smarcel/* Output generating routines for GDB CLI. 2130803Smarcel 3130803Smarcel Copyright 1999, 2000, 2001, 2002, 2003 Free Software Foundation, 4130803Smarcel Inc. 5130803Smarcel 6130803Smarcel Contributed by Cygnus Solutions. 7130803Smarcel Written by Fernando Nasser for Cygnus. 8130803Smarcel 9130803Smarcel This file is part of GDB. 10130803Smarcel 11130803Smarcel This program is free software; you can redistribute it and/or modify 12130803Smarcel it under the terms of the GNU General Public License as published by 13130803Smarcel the Free Software Foundation; either version 2 of the License, or 14130803Smarcel (at your option) any later version. 15130803Smarcel 16130803Smarcel This program is distributed in the hope that it will be useful, 17130803Smarcel but WITHOUT ANY WARRANTY; without even the implied warranty of 18130803Smarcel MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19130803Smarcel GNU General Public License for more details. 20130803Smarcel 21130803Smarcel You should have received a copy of the GNU General Public License 22130803Smarcel along with this program; if not, write to the Free Software 23130803Smarcel Foundation, Inc., 59 Temple Place - Suite 330, 24130803Smarcel Boston, MA 02111-1307, USA. */ 25130803Smarcel 26130803Smarcel#include "defs.h" 27130803Smarcel#include "ui-out.h" 28130803Smarcel#include "tui.h" 29130803Smarcel#include "gdb_string.h" 30130803Smarcel#include "gdb_assert.h" 31130803Smarcel 32130803Smarcelstruct ui_out_data 33130803Smarcel { 34130803Smarcel struct ui_file *stream; 35130803Smarcel int suppress_output; 36130803Smarcel int line; 37130803Smarcel int start_of_line; 38130803Smarcel }; 39130803Smarceltypedef struct ui_out_data tui_out_data; 40130803Smarcel 41130803Smarcel/* These are the CLI output functions */ 42130803Smarcel 43130803Smarcelstatic void tui_table_begin (struct ui_out *uiout, int nbrofcols, 44130803Smarcel int nr_rows, const char *tblid); 45130803Smarcelstatic void tui_table_body (struct ui_out *uiout); 46130803Smarcelstatic void tui_table_end (struct ui_out *uiout); 47130803Smarcelstatic void tui_table_header (struct ui_out *uiout, int width, 48130803Smarcel enum ui_align alig, const char *col_name, 49130803Smarcel const char *colhdr); 50130803Smarcelstatic void tui_begin (struct ui_out *uiout, enum ui_out_type type, 51130803Smarcel int level, const char *lstid); 52130803Smarcelstatic void tui_end (struct ui_out *uiout, enum ui_out_type type, int level); 53130803Smarcelstatic void tui_field_int (struct ui_out *uiout, int fldno, int width, 54130803Smarcel enum ui_align alig, const char *fldname, int value); 55130803Smarcelstatic void tui_field_skip (struct ui_out *uiout, int fldno, int width, 56130803Smarcel enum ui_align alig, const char *fldname); 57130803Smarcelstatic void tui_field_string (struct ui_out *uiout, int fldno, int width, 58130803Smarcel enum ui_align alig, const char *fldname, 59130803Smarcel const char *string); 60130803Smarcelstatic void tui_field_fmt (struct ui_out *uiout, int fldno, 61130803Smarcel int width, enum ui_align align, 62130803Smarcel const char *fldname, const char *format, 63130803Smarcel va_list args); 64130803Smarcelstatic void tui_spaces (struct ui_out *uiout, int numspaces); 65130803Smarcelstatic void tui_text (struct ui_out *uiout, const char *string); 66130803Smarcelstatic void tui_message (struct ui_out *uiout, int verbosity, 67130803Smarcel const char *format, va_list args); 68130803Smarcelstatic void tui_wrap_hint (struct ui_out *uiout, char *identstring); 69130803Smarcelstatic void tui_flush (struct ui_out *uiout); 70130803Smarcel 71130803Smarcel/* This is the CLI ui-out implementation functions vector */ 72130803Smarcel 73130803Smarcel/* FIXME: This can be initialized dynamically after default is set to 74130803Smarcel handle initial output in main.c */ 75130803Smarcel 76130803Smarcelstatic struct ui_out_impl tui_ui_out_impl = 77130803Smarcel{ 78130803Smarcel tui_table_begin, 79130803Smarcel tui_table_body, 80130803Smarcel tui_table_end, 81130803Smarcel tui_table_header, 82130803Smarcel tui_begin, 83130803Smarcel tui_end, 84130803Smarcel tui_field_int, 85130803Smarcel tui_field_skip, 86130803Smarcel tui_field_string, 87130803Smarcel tui_field_fmt, 88130803Smarcel tui_spaces, 89130803Smarcel tui_text, 90130803Smarcel tui_message, 91130803Smarcel tui_wrap_hint, 92130803Smarcel tui_flush, 93130803Smarcel NULL, 94130803Smarcel 0, /* Does not need MI hacks (i.e. needs CLI hacks). */ 95130803Smarcel}; 96130803Smarcel 97130803Smarcel/* Prototypes for local functions */ 98130803Smarcel 99130803Smarcelextern void _initialize_tui_out (void); 100130803Smarcel 101130803Smarcelstatic void field_separator (void); 102130803Smarcel 103130803Smarcelstatic void out_field_fmt (struct ui_out *uiout, int fldno, 104130803Smarcel const char *fldname, 105130803Smarcel const char *format,...); 106130803Smarcel 107130803Smarcel/* local variables */ 108130803Smarcel 109130803Smarcel/* (none yet) */ 110130803Smarcel 111130803Smarcel/* Mark beginning of a table */ 112130803Smarcel 113130803Smarcelvoid 114130803Smarceltui_table_begin (struct ui_out *uiout, int nbrofcols, 115130803Smarcel int nr_rows, 116130803Smarcel const char *tblid) 117130803Smarcel{ 118130803Smarcel tui_out_data *data = ui_out_data (uiout); 119130803Smarcel if (nr_rows == 0) 120130803Smarcel data->suppress_output = 1; 121130803Smarcel else 122130803Smarcel /* Only the table suppresses the output and, fortunately, a table 123130803Smarcel is not a recursive data structure. */ 124130803Smarcel gdb_assert (data->suppress_output == 0); 125130803Smarcel} 126130803Smarcel 127130803Smarcel/* Mark beginning of a table body */ 128130803Smarcel 129130803Smarcelvoid 130130803Smarceltui_table_body (struct ui_out *uiout) 131130803Smarcel{ 132130803Smarcel tui_out_data *data = ui_out_data (uiout); 133130803Smarcel if (data->suppress_output) 134130803Smarcel return; 135130803Smarcel /* first, close the table header line */ 136130803Smarcel tui_text (uiout, "\n"); 137130803Smarcel} 138130803Smarcel 139130803Smarcel/* Mark end of a table */ 140130803Smarcel 141130803Smarcelvoid 142130803Smarceltui_table_end (struct ui_out *uiout) 143130803Smarcel{ 144130803Smarcel tui_out_data *data = ui_out_data (uiout); 145130803Smarcel data->suppress_output = 0; 146130803Smarcel} 147130803Smarcel 148130803Smarcel/* Specify table header */ 149130803Smarcel 150130803Smarcelvoid 151130803Smarceltui_table_header (struct ui_out *uiout, int width, enum ui_align alignment, 152130803Smarcel const char *col_name, 153130803Smarcel const char *colhdr) 154130803Smarcel{ 155130803Smarcel tui_out_data *data = ui_out_data (uiout); 156130803Smarcel if (data->suppress_output) 157130803Smarcel return; 158130803Smarcel tui_field_string (uiout, 0, width, alignment, 0, colhdr); 159130803Smarcel} 160130803Smarcel 161130803Smarcel/* Mark beginning of a list */ 162130803Smarcel 163130803Smarcelvoid 164130803Smarceltui_begin (struct ui_out *uiout, 165130803Smarcel enum ui_out_type type, 166130803Smarcel int level, 167130803Smarcel const char *id) 168130803Smarcel{ 169130803Smarcel tui_out_data *data = ui_out_data (uiout); 170130803Smarcel if (data->suppress_output) 171130803Smarcel return; 172130803Smarcel} 173130803Smarcel 174130803Smarcel/* Mark end of a list */ 175130803Smarcel 176130803Smarcelvoid 177130803Smarceltui_end (struct ui_out *uiout, 178130803Smarcel enum ui_out_type type, 179130803Smarcel int level) 180130803Smarcel{ 181130803Smarcel tui_out_data *data = ui_out_data (uiout); 182130803Smarcel if (data->suppress_output) 183130803Smarcel return; 184130803Smarcel} 185130803Smarcel 186130803Smarcel/* output an int field */ 187130803Smarcel 188130803Smarcelvoid 189130803Smarceltui_field_int (struct ui_out *uiout, int fldno, int width, 190130803Smarcel enum ui_align alignment, 191130803Smarcel const char *fldname, int value) 192130803Smarcel{ 193130803Smarcel char buffer[20]; /* FIXME: how many chars long a %d can become? */ 194130803Smarcel 195130803Smarcel tui_out_data *data = ui_out_data (uiout); 196130803Smarcel if (data->suppress_output) 197130803Smarcel return; 198130803Smarcel 199130803Smarcel /* Don't print line number, keep it for later. */ 200130803Smarcel if (data->start_of_line == 0 && strcmp (fldname, "line") == 0) 201130803Smarcel { 202130803Smarcel data->start_of_line ++; 203130803Smarcel data->line = value; 204130803Smarcel return; 205130803Smarcel } 206130803Smarcel data->start_of_line ++; 207130803Smarcel sprintf (buffer, "%d", value); 208130803Smarcel tui_field_string (uiout, fldno, width, alignment, fldname, buffer); 209130803Smarcel} 210130803Smarcel 211130803Smarcel/* used to ommit a field */ 212130803Smarcel 213130803Smarcelvoid 214130803Smarceltui_field_skip (struct ui_out *uiout, int fldno, int width, 215130803Smarcel enum ui_align alignment, 216130803Smarcel const char *fldname) 217130803Smarcel{ 218130803Smarcel tui_out_data *data = ui_out_data (uiout); 219130803Smarcel if (data->suppress_output) 220130803Smarcel return; 221130803Smarcel tui_field_string (uiout, fldno, width, alignment, fldname, ""); 222130803Smarcel} 223130803Smarcel 224130803Smarcel/* other specific tui_field_* end up here so alignment and field 225130803Smarcel separators are both handled by tui_field_string */ 226130803Smarcel 227130803Smarcelvoid 228130803Smarceltui_field_string (struct ui_out *uiout, 229130803Smarcel int fldno, 230130803Smarcel int width, 231130803Smarcel enum ui_align align, 232130803Smarcel const char *fldname, 233130803Smarcel const char *string) 234130803Smarcel{ 235130803Smarcel int before = 0; 236130803Smarcel int after = 0; 237130803Smarcel 238130803Smarcel tui_out_data *data = ui_out_data (uiout); 239130803Smarcel if (data->suppress_output) 240130803Smarcel return; 241130803Smarcel 242130803Smarcel if (fldname && data->line > 0 && strcmp (fldname, "file") == 0) 243130803Smarcel { 244130803Smarcel data->start_of_line ++; 245130803Smarcel if (data->line > 0) 246130803Smarcel { 247130803Smarcel tui_show_source (string, data->line); 248130803Smarcel } 249130803Smarcel return; 250130803Smarcel } 251130803Smarcel 252130803Smarcel data->start_of_line ++; 253130803Smarcel if ((align != ui_noalign) && string) 254130803Smarcel { 255130803Smarcel before = width - strlen (string); 256130803Smarcel if (before <= 0) 257130803Smarcel before = 0; 258130803Smarcel else 259130803Smarcel { 260130803Smarcel if (align == ui_right) 261130803Smarcel after = 0; 262130803Smarcel else if (align == ui_left) 263130803Smarcel { 264130803Smarcel after = before; 265130803Smarcel before = 0; 266130803Smarcel } 267130803Smarcel else 268130803Smarcel /* ui_center */ 269130803Smarcel { 270130803Smarcel after = before / 2; 271130803Smarcel before -= after; 272130803Smarcel } 273130803Smarcel } 274130803Smarcel } 275130803Smarcel 276130803Smarcel if (before) 277130803Smarcel ui_out_spaces (uiout, before); 278130803Smarcel if (string) 279130803Smarcel out_field_fmt (uiout, fldno, fldname, "%s", string); 280130803Smarcel if (after) 281130803Smarcel ui_out_spaces (uiout, after); 282130803Smarcel 283130803Smarcel if (align != ui_noalign) 284130803Smarcel field_separator (); 285130803Smarcel} 286130803Smarcel 287130803Smarcel/* This is the only field function that does not align */ 288130803Smarcel 289130803Smarcelvoid 290130803Smarceltui_field_fmt (struct ui_out *uiout, int fldno, 291130803Smarcel int width, enum ui_align align, 292130803Smarcel const char *fldname, 293130803Smarcel const char *format, 294130803Smarcel va_list args) 295130803Smarcel{ 296130803Smarcel tui_out_data *data = ui_out_data (uiout); 297130803Smarcel if (data->suppress_output) 298130803Smarcel return; 299130803Smarcel 300130803Smarcel data->start_of_line ++; 301130803Smarcel vfprintf_filtered (data->stream, format, args); 302130803Smarcel 303130803Smarcel if (align != ui_noalign) 304130803Smarcel field_separator (); 305130803Smarcel} 306130803Smarcel 307130803Smarcelvoid 308130803Smarceltui_spaces (struct ui_out *uiout, int numspaces) 309130803Smarcel{ 310130803Smarcel tui_out_data *data = ui_out_data (uiout); 311130803Smarcel if (data->suppress_output) 312130803Smarcel return; 313130803Smarcel print_spaces_filtered (numspaces, data->stream); 314130803Smarcel} 315130803Smarcel 316130803Smarcelvoid 317130803Smarceltui_text (struct ui_out *uiout, const char *string) 318130803Smarcel{ 319130803Smarcel tui_out_data *data = ui_out_data (uiout); 320130803Smarcel if (data->suppress_output) 321130803Smarcel return; 322130803Smarcel data->start_of_line ++; 323130803Smarcel if (data->line > 0) 324130803Smarcel { 325130803Smarcel if (strchr (string, '\n') != 0) 326130803Smarcel { 327130803Smarcel data->line = -1; 328130803Smarcel data->start_of_line = 0; 329130803Smarcel } 330130803Smarcel return; 331130803Smarcel } 332130803Smarcel if (strchr (string, '\n')) 333130803Smarcel data->start_of_line = 0; 334130803Smarcel fputs_filtered (string, data->stream); 335130803Smarcel} 336130803Smarcel 337130803Smarcelvoid 338130803Smarceltui_message (struct ui_out *uiout, int verbosity, 339130803Smarcel const char *format, va_list args) 340130803Smarcel{ 341130803Smarcel tui_out_data *data = ui_out_data (uiout); 342130803Smarcel if (data->suppress_output) 343130803Smarcel return; 344130803Smarcel if (ui_out_get_verblvl (uiout) >= verbosity) 345130803Smarcel vfprintf_unfiltered (data->stream, format, args); 346130803Smarcel} 347130803Smarcel 348130803Smarcelvoid 349130803Smarceltui_wrap_hint (struct ui_out *uiout, char *identstring) 350130803Smarcel{ 351130803Smarcel tui_out_data *data = ui_out_data (uiout); 352130803Smarcel if (data->suppress_output) 353130803Smarcel return; 354130803Smarcel wrap_here (identstring); 355130803Smarcel} 356130803Smarcel 357130803Smarcelvoid 358130803Smarceltui_flush (struct ui_out *uiout) 359130803Smarcel{ 360130803Smarcel tui_out_data *data = ui_out_data (uiout); 361130803Smarcel gdb_flush (data->stream); 362130803Smarcel} 363130803Smarcel 364130803Smarcel/* local functions */ 365130803Smarcel 366130803Smarcel/* Like tui_field_fmt, but takes a variable number of args 367130803Smarcel and makes a va_list and does not insert a separator */ 368130803Smarcel 369130803Smarcel/* VARARGS */ 370130803Smarcelstatic void 371130803Smarcelout_field_fmt (struct ui_out *uiout, int fldno, 372130803Smarcel const char *fldname, 373130803Smarcel const char *format,...) 374130803Smarcel{ 375130803Smarcel tui_out_data *data = ui_out_data (uiout); 376130803Smarcel va_list args; 377130803Smarcel 378130803Smarcel va_start (args, format); 379130803Smarcel vfprintf_filtered (data->stream, format, args); 380130803Smarcel 381130803Smarcel va_end (args); 382130803Smarcel} 383130803Smarcel 384130803Smarcel/* access to ui_out format private members */ 385130803Smarcel 386130803Smarcelstatic void 387130803Smarcelfield_separator (void) 388130803Smarcel{ 389130803Smarcel tui_out_data *data = ui_out_data (uiout); 390130803Smarcel fputc_filtered (' ', data->stream); 391130803Smarcel} 392130803Smarcel 393130803Smarcel/* initalize private members at startup */ 394130803Smarcel 395130803Smarcelstruct ui_out * 396130803Smarceltui_out_new (struct ui_file *stream) 397130803Smarcel{ 398130803Smarcel int flags = 0; 399130803Smarcel 400130803Smarcel tui_out_data *data = XMALLOC (tui_out_data); 401130803Smarcel data->stream = stream; 402130803Smarcel data->suppress_output = 0; 403130803Smarcel data->line = -1; 404130803Smarcel data->start_of_line = 0; 405130803Smarcel return ui_out_new (&tui_ui_out_impl, data, flags); 406130803Smarcel} 407130803Smarcel 408130803Smarcel/* standard gdb initialization hook */ 409130803Smarcelvoid 410130803Smarcel_initialize_tui_out (void) 411130803Smarcel{ 412130803Smarcel /* nothing needs to be done */ 413130803Smarcel} 414