X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fcli-out.c;h=0c982cb2e6d7ccf64f50342b1b9ce4e7eb7f1a46;hb=825c8ef28fc669bdf4eab64b43d7a64761fbd677;hp=bd079f250bb8eccdbcff469443ee94fd21475b07;hpb=349c5d5f6c08699c3e433b28e2beaa24b65a63b0;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/cli-out.c b/gdb/cli-out.c index bd079f250b..0c982cb2e6 100644 --- a/gdb/cli-out.c +++ b/gdb/cli-out.c @@ -1,6 +1,6 @@ /* Output generating routines for GDB CLI. - Copyright 1999, 2000, 2002 Free Software Foundation, Inc. + Copyright (C) 1999-2016 Free Software Foundation, Inc. Contributed by Cygnus Solutions. Written by Fernando Nasser for Cygnus. @@ -9,7 +9,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -18,113 +18,64 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + along with this program. If not, see . */ #include "defs.h" #include "ui-out.h" #include "cli-out.h" -#include "gdb_string.h" -#include "gdb_assert.h" +#include "completer.h" +#include "vec.h" +#include "readline/readline.h" -struct ui_out_data - { - struct ui_file *stream; - int suppress_output; - }; - -/* These are the CLI output functions */ - -static void cli_table_begin (struct ui_out *uiout, int nbrofcols, - int nr_rows, const char *tblid); -static void cli_table_body (struct ui_out *uiout); -static void cli_table_end (struct ui_out *uiout); -static void cli_table_header (struct ui_out *uiout, int width, - enum ui_align alig, const char *col_name, - const char *colhdr); -static void cli_begin (struct ui_out *uiout, enum ui_out_type type, - int level, const char *lstid); -static void cli_end (struct ui_out *uiout, enum ui_out_type type, int level); -static void cli_field_int (struct ui_out *uiout, int fldno, int width, - enum ui_align alig, const char *fldname, int value); -static void cli_field_skip (struct ui_out *uiout, int fldno, int width, - enum ui_align alig, const char *fldname); -static void cli_field_string (struct ui_out *uiout, int fldno, int width, - enum ui_align alig, const char *fldname, - const char *string); -static void cli_field_fmt (struct ui_out *uiout, int fldno, - int width, enum ui_align align, - const char *fldname, const char *format, - va_list args); -static void cli_spaces (struct ui_out *uiout, int numspaces); -static void cli_text (struct ui_out *uiout, const char *string); -static void cli_message (struct ui_out *uiout, int verbosity, - const char *format, va_list args); -static void cli_wrap_hint (struct ui_out *uiout, char *identstring); -static void cli_flush (struct ui_out *uiout); - -/* This is the CLI ui-out implementation functions vector */ - -/* FIXME: This can be initialized dynamically after default is set to - handle initial output in main.c */ - -static struct ui_out_impl cli_ui_out_impl = -{ - cli_table_begin, - cli_table_body, - cli_table_end, - cli_table_header, - cli_begin, - cli_end, - cli_field_int, - cli_field_skip, - cli_field_string, - cli_field_fmt, - cli_spaces, - cli_text, - cli_message, - cli_wrap_hint, - cli_flush, - 0, /* Does not need MI hacks (i.e. needs CLI hacks). */ -}; +typedef struct cli_ui_out_data cli_out_data; /* Prototypes for local functions */ -extern void _initialize_cli_out (void); +static void cli_text (struct ui_out *uiout, const char *string); static void field_separator (void); static void out_field_fmt (struct ui_out *uiout, int fldno, const char *fldname, - const char *format,...); + const char *format,...) ATTRIBUTE_PRINTF (4, 5); + +/* The destructor. */ + +static void +cli_uiout_dtor (struct ui_out *ui_out) +{ + cli_out_data *data = (cli_out_data *) ui_out_data (ui_out); -/* local variables */ + VEC_free (ui_filep, data->streams); + xfree (data); +} -/* (none yet) */ +/* These are the CLI output functions */ /* Mark beginning of a table */ -void +static void cli_table_begin (struct ui_out *uiout, int nbrofcols, int nr_rows, const char *tblid) { - struct ui_out_data *data = ui_out_data (uiout); + cli_out_data *data = (cli_out_data *) ui_out_data (uiout); + if (nr_rows == 0) data->suppress_output = 1; else - /* Only the table suppresses the output and, fortunatly, a table - is not a recursive data structure. */ + /* Only the table suppresses the output and, fortunately, a table + is not a recursive data structure. */ gdb_assert (data->suppress_output == 0); } /* Mark beginning of a table body */ -void +static void cli_table_body (struct ui_out *uiout) { - struct ui_out_data *data = ui_out_data (uiout); + cli_out_data *data = (cli_out_data *) ui_out_data (uiout); + if (data->suppress_output) return; /* first, close the table header line */ @@ -133,84 +84,98 @@ cli_table_body (struct ui_out *uiout) /* Mark end of a table */ -void +static void cli_table_end (struct ui_out *uiout) { - struct ui_out_data *data = ui_out_data (uiout); + cli_out_data *data = (cli_out_data *) ui_out_data (uiout); + data->suppress_output = 0; } /* Specify table header */ -void +static void cli_table_header (struct ui_out *uiout, int width, enum ui_align alignment, const char *col_name, const char *colhdr) { - struct ui_out_data *data = ui_out_data (uiout); + cli_out_data *data = (cli_out_data *) ui_out_data (uiout); + if (data->suppress_output) return; - cli_field_string (uiout, 0, width, alignment, 0, colhdr); + + /* Always go through the function pointer (virtual function call). + We may have been extended. */ + uo_field_string (uiout, 0, width, alignment, 0, colhdr); } /* Mark beginning of a list */ -void +static void cli_begin (struct ui_out *uiout, enum ui_out_type type, int level, const char *id) { - struct ui_out_data *data = ui_out_data (uiout); + cli_out_data *data = (cli_out_data *) ui_out_data (uiout); + if (data->suppress_output) return; } /* Mark end of a list */ -void +static void cli_end (struct ui_out *uiout, enum ui_out_type type, int level) { - struct ui_out_data *data = ui_out_data (uiout); + cli_out_data *data = (cli_out_data *) ui_out_data (uiout); + if (data->suppress_output) return; } /* output an int field */ -void +static void cli_field_int (struct ui_out *uiout, int fldno, int width, enum ui_align alignment, const char *fldname, int value) { - char buffer[20]; /* FIXME: how many chars long a %d can become? */ + char buffer[20]; /* FIXME: how many chars long a %d can become? */ + cli_out_data *data = (cli_out_data *) ui_out_data (uiout); - struct ui_out_data *data = ui_out_data (uiout); if (data->suppress_output) return; - sprintf (buffer, "%d", value); - cli_field_string (uiout, fldno, width, alignment, fldname, buffer); + xsnprintf (buffer, sizeof (buffer), "%d", value); + + /* Always go through the function pointer (virtual function call). + We may have been extended. */ + uo_field_string (uiout, fldno, width, alignment, fldname, buffer); } /* used to ommit a field */ -void +static void cli_field_skip (struct ui_out *uiout, int fldno, int width, enum ui_align alignment, const char *fldname) { - struct ui_out_data *data = ui_out_data (uiout); + cli_out_data *data = (cli_out_data *) ui_out_data (uiout); + if (data->suppress_output) return; - cli_field_string (uiout, fldno, width, alignment, fldname, ""); + + /* Always go through the function pointer (virtual function call). + We may have been extended. */ + uo_field_string (uiout, fldno, width, alignment, fldname, ""); } /* other specific cli_field_* end up here so alignment and field separators are both handled by cli_field_string */ -void +static void cli_field_string (struct ui_out *uiout, int fldno, int width, @@ -220,8 +185,8 @@ cli_field_string (struct ui_out *uiout, { int before = 0; int after = 0; + cli_out_data *data = (cli_out_data *) ui_out_data (uiout); - struct ui_out_data *data = ui_out_data (uiout); if (data->suppress_output) return; @@ -259,74 +224,111 @@ cli_field_string (struct ui_out *uiout, field_separator (); } -/* This is the only field function that does not align */ +/* This is the only field function that does not align. */ -void +static void ATTRIBUTE_PRINTF (6, 0) cli_field_fmt (struct ui_out *uiout, int fldno, int width, enum ui_align align, const char *fldname, const char *format, va_list args) { - struct ui_out_data *data = ui_out_data (uiout); + cli_out_data *data = (cli_out_data *) ui_out_data (uiout); + struct ui_file *stream; + if (data->suppress_output) return; - vfprintf_filtered (data->stream, format, args); + stream = VEC_last (ui_filep, data->streams); + vfprintf_filtered (stream, format, args); if (align != ui_noalign) field_separator (); } -void +static void cli_spaces (struct ui_out *uiout, int numspaces) { - struct ui_out_data *data = ui_out_data (uiout); + cli_out_data *data = (cli_out_data *) ui_out_data (uiout); + struct ui_file *stream; + if (data->suppress_output) return; - print_spaces_filtered (numspaces, data->stream); + + stream = VEC_last (ui_filep, data->streams); + print_spaces_filtered (numspaces, stream); } -void +static void cli_text (struct ui_out *uiout, const char *string) { - struct ui_out_data *data = ui_out_data (uiout); + cli_out_data *data = (cli_out_data *) ui_out_data (uiout); + struct ui_file *stream; + if (data->suppress_output) return; - fputs_filtered (string, data->stream); + + stream = VEC_last (ui_filep, data->streams); + fputs_filtered (string, stream); } -void +static void ATTRIBUTE_PRINTF (3, 0) cli_message (struct ui_out *uiout, int verbosity, const char *format, va_list args) { - struct ui_out_data *data = ui_out_data (uiout); + cli_out_data *data = (cli_out_data *) ui_out_data (uiout); + if (data->suppress_output) return; + if (ui_out_get_verblvl (uiout) >= verbosity) - vfprintf_unfiltered (data->stream, format, args); + { + struct ui_file *stream = VEC_last (ui_filep, data->streams); + + vfprintf_unfiltered (stream, format, args); + } } -void +static void cli_wrap_hint (struct ui_out *uiout, char *identstring) { - struct ui_out_data *data = ui_out_data (uiout); + cli_out_data *data = (cli_out_data *) ui_out_data (uiout); + if (data->suppress_output) return; wrap_here (identstring); } -void +static void cli_flush (struct ui_out *uiout) { - struct ui_out_data *data = ui_out_data (uiout); - gdb_flush (data->stream); + cli_out_data *data = (cli_out_data *) ui_out_data (uiout); + struct ui_file *stream = VEC_last (ui_filep, data->streams); + + gdb_flush (stream); +} + +/* OUTSTREAM as non-NULL will push OUTSTREAM on the stack of output streams + and make it therefore active. OUTSTREAM as NULL will pop the last pushed + output stream; it is an internal error if it does not exist. */ + +static int +cli_redirect (struct ui_out *uiout, struct ui_file *outstream) +{ + cli_out_data *data = (cli_out_data *) ui_out_data (uiout); + + if (outstream != NULL) + VEC_safe_push (ui_filep, data->streams, outstream); + else + VEC_pop (ui_filep, data->streams); + + return 0; } /* local functions */ /* Like cli_field_fmt, but takes a variable number of args - and makes a va_list and does not insert a separator */ + and makes a va_list and does not insert a separator. */ /* VARARGS */ static void @@ -334,40 +336,165 @@ out_field_fmt (struct ui_out *uiout, int fldno, const char *fldname, const char *format,...) { - struct ui_out_data *data = ui_out_data (uiout); + cli_out_data *data = (cli_out_data *) ui_out_data (uiout); + struct ui_file *stream = VEC_last (ui_filep, data->streams); va_list args; va_start (args, format); - vfprintf_filtered (data->stream, format, args); + vfprintf_filtered (stream, format, args); va_end (args); } -/* access to ui_out format private members */ +/* Access to ui_out format private members. */ static void field_separator (void) { - struct ui_out_data *data = ui_out_data (uiout); - fputc_filtered (' ', data->stream); + cli_out_data *data = (cli_out_data *) ui_out_data (current_uiout); + struct ui_file *stream = VEC_last (ui_filep, data->streams); + + fputc_filtered (' ', stream); +} + +/* This is the CLI ui-out implementation functions vector */ + +const struct ui_out_impl cli_ui_out_impl = +{ + cli_table_begin, + cli_table_body, + cli_table_end, + cli_table_header, + cli_begin, + cli_end, + cli_field_int, + cli_field_skip, + cli_field_string, + cli_field_fmt, + cli_spaces, + cli_text, + cli_message, + cli_wrap_hint, + cli_flush, + cli_redirect, + cli_uiout_dtor, + 0, /* Does not need MI hacks (i.e. needs CLI hacks). */ +}; + +/* Constructor for a `cli_out_data' object. */ + +void +cli_out_data_ctor (cli_out_data *self, struct ui_file *stream) +{ + gdb_assert (stream != NULL); + + self->streams = NULL; + VEC_safe_push (ui_filep, self->streams, stream); + + self->suppress_output = 0; } -/* initalize private members at startup */ +/* Initialize private members at startup. */ struct ui_out * cli_out_new (struct ui_file *stream) { int flags = ui_source_list; + cli_out_data *data = XNEW (cli_out_data); - struct ui_out_data *data = XMALLOC (struct ui_out_data); - data->stream = stream; - data->suppress_output = 0; + cli_out_data_ctor (data, stream); return ui_out_new (&cli_ui_out_impl, data, flags); } -/* standard gdb initialization hook */ +struct ui_file * +cli_out_set_stream (struct ui_out *uiout, struct ui_file *stream) +{ + cli_out_data *data = (cli_out_data *) ui_out_data (uiout); + struct ui_file *old; + + old = VEC_pop (ui_filep, data->streams); + VEC_quick_push (ui_filep, data->streams, stream); + + return old; +} + +/* CLI interface to display tab-completion matches. */ + +/* CLI version of displayer.crlf. */ + +static void +cli_mld_crlf (const struct match_list_displayer *displayer) +{ + rl_crlf (); +} + +/* CLI version of displayer.putch. */ + +static void +cli_mld_putch (const struct match_list_displayer *displayer, int ch) +{ + putc (ch, rl_outstream); +} + +/* CLI version of displayer.puts. */ + +static void +cli_mld_puts (const struct match_list_displayer *displayer, const char *s) +{ + fputs (s, rl_outstream); +} + +/* CLI version of displayer.flush. */ + +static void +cli_mld_flush (const struct match_list_displayer *displayer) +{ + fflush (rl_outstream); +} + +EXTERN_C void _rl_erase_entire_line (void); + +/* CLI version of displayer.erase_entire_line. */ + +static void +cli_mld_erase_entire_line (const struct match_list_displayer *displayer) +{ + _rl_erase_entire_line (); +} + +/* CLI version of displayer.beep. */ + +static void +cli_mld_beep (const struct match_list_displayer *displayer) +{ + rl_ding (); +} + +/* CLI version of displayer.read_key. */ + +static int +cli_mld_read_key (const struct match_list_displayer *displayer) +{ + return rl_read_key (); +} + +/* CLI version of rl_completion_display_matches_hook. + See gdb_display_match_list for a description of the arguments. */ + void -_initialize_cli_out (void) +cli_display_match_list (char **matches, int len, int max) { - /* nothing needs to be done */ + struct match_list_displayer displayer; + + rl_get_screen_size (&displayer.height, &displayer.width); + displayer.crlf = cli_mld_crlf; + displayer.putch = cli_mld_putch; + displayer.puts = cli_mld_puts; + displayer.flush = cli_mld_flush; + displayer.erase_entire_line = cli_mld_erase_entire_line; + displayer.beep = cli_mld_beep; + displayer.read_key = cli_mld_read_key; + + gdb_display_match_list (matches, len, max, &displayer); + rl_forced_update_display (); }