Compare commits

...

4 Commits

Author SHA1 Message Date
Pedro Alves
5f6d441b51 show_commands 2017-11-07 13:04:42 +00:00
Pedro Alves
598364c2a4 x_command 2017-11-07 12:49:41 +00:00
Pedro Alves
5e772ff776 set_current_sal 2017-11-07 12:27:00 +00:00
Pedro Alves
bd16eda92d saved_command_line 2017-11-07 12:09:06 +00:00
6 changed files with 310 additions and 203 deletions

View File

@@ -634,8 +634,8 @@ command_line_append_input_line (struct buffer *cmd_line_buffer, char *rl)
If REPEAT, handle command repetitions: If REPEAT, handle command repetitions:
- If the input command line is NOT empty, the command returned is - If the input command line is NOT empty, the command returned is
copied into the global 'saved_command_line' var so that it can copied into the 'ui->saved_command_line' var so that it can be
be repeated later. repeated later.
- OTOH, if the input command line IS empty, return the previously - OTOH, if the input command line IS empty, return the previously
saved command instead of the empty input line. saved command instead of the empty input line.
@@ -671,9 +671,9 @@ handle_line_of_input (struct buffer *cmd_line_buffer,
#define SERVER_COMMAND_PREFIX "server " #define SERVER_COMMAND_PREFIX "server "
if (startswith (cmd, SERVER_COMMAND_PREFIX)) if (startswith (cmd, SERVER_COMMAND_PREFIX))
{ {
/* Note that we don't set `saved_command_line'. Between this /* Note that we don't set `ui->saved_command_line'. Between
and the check in dont_repeat, this insures that repeating this and the check in dont_repeat, this insures that
will still do the right thing. */ repeating will still do the right thing. */
return cmd + strlen (SERVER_COMMAND_PREFIX); return cmd + strlen (SERVER_COMMAND_PREFIX);
} }
@@ -713,7 +713,7 @@ handle_line_of_input (struct buffer *cmd_line_buffer,
for (p1 = cmd; *p1 == ' ' || *p1 == '\t'; p1++) for (p1 = cmd; *p1 == ' ' || *p1 == '\t'; p1++)
; ;
if (repeat && *p1 == '\0') if (repeat && *p1 == '\0')
return saved_command_line; return ui->saved_command_line;
/* Add command to history if appropriate. Note: lines consisting /* Add command to history if appropriate. Note: lines consisting
solely of comments are also added to the command history. This solely of comments are also added to the command history. This
@@ -728,9 +728,9 @@ handle_line_of_input (struct buffer *cmd_line_buffer,
/* Save into global buffer if appropriate. */ /* Save into global buffer if appropriate. */
if (repeat) if (repeat)
{ {
xfree (saved_command_line); xfree (ui->saved_command_line);
saved_command_line = xstrdup (cmd); ui->saved_command_line = xstrdup (cmd);
return saved_command_line; return ui->saved_command_line;
} }
else else
return cmd; return cmd;

View File

@@ -522,8 +522,6 @@ captured_main_1 (struct captured_main_args *context)
notice_open_fds (); notice_open_fds ();
save_original_signals_state (); save_original_signals_state ();
saved_command_line = (char *) xstrdup ("");
#ifdef __MINGW32__ #ifdef __MINGW32__
/* Ensure stderr is unbuffered. A Cygwin pty or pipe is implemented /* Ensure stderr is unbuffered. A Cygwin pty or pipe is implemented
as a Windows pipe, and Windows buffers on pipes. */ as a Windows pipe, and Windows buffers on pipes. */

View File

@@ -49,37 +49,50 @@
#include "format.h" #include "format.h"
#include "source.h" #include "source.h"
#include "common/byte-vector.h" #include "common/byte-vector.h"
#include "top.h"
#ifdef TUI #ifdef TUI
#include "tui/tui.h" /* For tui_active et al. */ #include "tui/tui.h" /* For tui_active et al. */
#endif #endif
/* Last specified output format. */ struct current_printcmd_info
{
/* Last specified output format. */
char last_format = 0;
static char last_format = 0; /* Last specified examination size. 'b', 'h', 'w' or `q'. */
char last_size = 'w';
/* Last specified examination size. 'b', 'h', 'w' or `q'. */ /* Default address to examine next, and associated architecture. */
struct gdbarch *next_gdbarch;
CORE_ADDR next_address;
static char last_size = 'w'; /* Last address examined. */
CORE_ADDR last_examine_address;
/* Default address to examine next, and associated architecture. */ /* Contents of last address examined. This is not valid past the
end of the `x' command! */
struct value *last_examine_value;
};
static struct gdbarch *next_gdbarch; static current_printcmd_info &
static CORE_ADDR next_address; get_current_printcmd_info ()
{
if (current_ui->curr_printcmd_info == NULL)
current_ui->curr_printcmd_info = new current_printcmd_info ();
return *current_ui->curr_printcmd_info;
}
void
delete_current_printcmd_info (struct ui *ui)
{
delete ui->curr_printcmd_info;
}
/* Number of delay instructions following current disassembled insn. */ /* Number of delay instructions following current disassembled insn. */
static int branch_delay_insns; static int branch_delay_insns;
/* Last address examined. */
static CORE_ADDR last_examine_address;
/* Contents of last address examined.
This is not valid past the end of the `x' command! */
static struct value *last_examine_value;
/* Largest offset between a symbolic value and an address, that will be /* Largest offset between a symbolic value and an address, that will be
printed as `0x1234 <symbol+offset>'. */ printed as `0x1234 <symbol+offset>'. */
@@ -279,8 +292,10 @@ print_formatted (struct value *val, int size,
struct type *type = check_typedef (value_type (val)); struct type *type = check_typedef (value_type (val));
int len = TYPE_LENGTH (type); int len = TYPE_LENGTH (type);
current_printcmd_info &ci = get_current_printcmd_info ();
if (VALUE_LVAL (val) == lval_memory) if (VALUE_LVAL (val) == lval_memory)
next_address = value_address (val) + len; ci.next_address = value_address (val) + len;
if (size) if (size)
{ {
@@ -290,20 +305,20 @@ print_formatted (struct value *val, int size,
{ {
struct type *elttype = value_type (val); struct type *elttype = value_type (val);
next_address = (value_address (val) ci.next_address = (value_address (val)
+ val_print_string (elttype, NULL, + val_print_string (elttype, NULL,
value_address (val), -1, value_address (val), -1,
stream, options) * len); stream, options) * len);
} }
return; return;
case 'i': case 'i':
/* We often wrap here if there are long symbolic names. */ /* We often wrap here if there are long symbolic names. */
wrap_here (" "); wrap_here (" ");
next_address = (value_address (val) ci.next_address = (value_address (val)
+ gdb_print_insn (get_type_arch (type), + gdb_print_insn (get_type_arch (type),
value_address (val), stream, value_address (val), stream,
&branch_delay_insns)); &branch_delay_insns));
return; return;
} }
} }
@@ -500,10 +515,13 @@ set_next_address (struct gdbarch *gdbarch, CORE_ADDR addr)
{ {
struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr; struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
next_gdbarch = gdbarch; current_printcmd_info &ci = get_current_printcmd_info ();
next_address = addr;
/* Make address available to the user as $_. */ ci.next_gdbarch = gdbarch;
ci.next_address = addr;
/* Make address available to the user as $_. FIXME: should instead
be a computed val, so that it works Per-UI. */
set_internalvar (lookup_internalvar ("_"), set_internalvar (lookup_internalvar ("_"),
value_from_pointer (ptr_type, addr)); value_from_pointer (ptr_type, addr));
} }
@@ -976,8 +994,11 @@ do_examine (struct format_data fmt, struct gdbarch *gdbarch, CORE_ADDR addr)
format = fmt.format; format = fmt.format;
size = fmt.size; size = fmt.size;
count = fmt.count; count = fmt.count;
next_gdbarch = gdbarch;
next_address = addr; current_printcmd_info &ci = get_current_printcmd_info ();
ci.next_gdbarch = gdbarch;
ci.next_address = addr;
/* Instruction format implies fetch single bytes /* Instruction format implies fetch single bytes
regardless of the specified size. regardless of the specified size.
@@ -989,11 +1010,11 @@ do_examine (struct format_data fmt, struct gdbarch *gdbarch, CORE_ADDR addr)
if (size == 'a') if (size == 'a')
{ {
/* Pick the appropriate size for an address. */ /* Pick the appropriate size for an address. */
if (gdbarch_ptr_bit (next_gdbarch) == 64) if (gdbarch_ptr_bit (ci.next_gdbarch) == 64)
size = 'g'; size = 'g';
else if (gdbarch_ptr_bit (next_gdbarch) == 32) else if (gdbarch_ptr_bit (ci.next_gdbarch) == 32)
size = 'w'; size = 'w';
else if (gdbarch_ptr_bit (next_gdbarch) == 16) else if (gdbarch_ptr_bit (ci.next_gdbarch) == 16)
size = 'h'; size = 'h';
else else
/* Bad value for gdbarch_ptr_bit. */ /* Bad value for gdbarch_ptr_bit. */
@@ -1002,13 +1023,13 @@ do_examine (struct format_data fmt, struct gdbarch *gdbarch, CORE_ADDR addr)
} }
if (size == 'b') if (size == 'b')
val_type = builtin_type (next_gdbarch)->builtin_int8; val_type = builtin_type (ci.next_gdbarch)->builtin_int8;
else if (size == 'h') else if (size == 'h')
val_type = builtin_type (next_gdbarch)->builtin_int16; val_type = builtin_type (ci.next_gdbarch)->builtin_int16;
else if (size == 'w') else if (size == 'w')
val_type = builtin_type (next_gdbarch)->builtin_int32; val_type = builtin_type (ci.next_gdbarch)->builtin_int32;
else if (size == 'g') else if (size == 'g')
val_type = builtin_type (next_gdbarch)->builtin_int64; val_type = builtin_type (ci.next_gdbarch)->builtin_int64;
if (format == 's') if (format == 's')
{ {
@@ -1017,9 +1038,9 @@ do_examine (struct format_data fmt, struct gdbarch *gdbarch, CORE_ADDR addr)
/* Search for "char16_t" or "char32_t" types or fall back to 8-bit char /* Search for "char16_t" or "char32_t" types or fall back to 8-bit char
if type is not found. */ if type is not found. */
if (size == 'h') if (size == 'h')
char_type = builtin_type (next_gdbarch)->builtin_char16; char_type = builtin_type (ci.next_gdbarch)->builtin_char16;
else if (size == 'w') else if (size == 'w')
char_type = builtin_type (next_gdbarch)->builtin_char32; char_type = builtin_type (ci.next_gdbarch)->builtin_char32;
if (char_type) if (char_type)
val_type = char_type; val_type = char_type;
else else
@@ -1028,7 +1049,7 @@ do_examine (struct format_data fmt, struct gdbarch *gdbarch, CORE_ADDR addr)
warning (_("Unable to display strings with " warning (_("Unable to display strings with "
"size '%c', using 'b' instead."), size); "size '%c', using 'b' instead."), size);
size = 'b'; size = 'b';
val_type = builtin_type (next_gdbarch)->builtin_int8; val_type = builtin_type (ci.next_gdbarch)->builtin_int8;
} }
} }
@@ -1051,26 +1072,26 @@ do_examine (struct format_data fmt, struct gdbarch *gdbarch, CORE_ADDR addr)
count = -count; count = -count;
if (format == 'i') if (format == 'i')
{ {
next_address = find_instruction_backward (gdbarch, addr, count, ci.next_address = find_instruction_backward (gdbarch, addr, count,
&count); &count);
} }
else if (format == 's') else if (format == 's')
{ {
next_address = find_string_backward (gdbarch, addr, count, ci.next_address = find_string_backward (gdbarch, addr, count,
TYPE_LENGTH (val_type), TYPE_LENGTH (val_type),
&opts, &count); &opts, &count);
} }
else else
{ {
next_address = addr - count * TYPE_LENGTH (val_type); ci.next_address = addr - count * TYPE_LENGTH (val_type);
} }
/* The following call to print_formatted updates next_address in every /* The following call to print_formatted updates next_address in every
iteration. In backward case, we store the start address here iteration. In backward case, we store the start address here
and update next_address with it before exiting the function. */ and update next_address with it before exiting the function. */
addr_rewound = (format == 's' addr_rewound = (format == 's'
? next_address - TYPE_LENGTH (val_type) ? ci.next_address - TYPE_LENGTH (val_type)
: next_address); : ci.next_address);
need_to_update_next_address = 1; need_to_update_next_address = 1;
} }
@@ -1081,8 +1102,8 @@ do_examine (struct format_data fmt, struct gdbarch *gdbarch, CORE_ADDR addr)
{ {
QUIT; QUIT;
if (format == 'i') if (format == 'i')
fputs_filtered (pc_prefix (next_address), gdb_stdout); fputs_filtered (pc_prefix (ci.next_address), gdb_stdout);
print_address (next_gdbarch, next_address, gdb_stdout); print_address (ci.next_gdbarch, ci.next_address, gdb_stdout);
printf_filtered (":"); printf_filtered (":");
for (i = maxelts; for (i = maxelts;
i > 0 && count > 0; i > 0 && count > 0;
@@ -1091,10 +1112,10 @@ do_examine (struct format_data fmt, struct gdbarch *gdbarch, CORE_ADDR addr)
printf_filtered ("\t"); printf_filtered ("\t");
/* Note that print_formatted sets next_address for the next /* Note that print_formatted sets next_address for the next
object. */ object. */
last_examine_address = next_address; ci.last_examine_address = ci.next_address;
if (last_examine_value) if (ci.last_examine_value)
value_free (last_examine_value); value_free (ci.last_examine_value);
/* The value to be displayed is not fetched greedily. /* The value to be displayed is not fetched greedily.
Instead, to avoid the possibility of a fetched value not Instead, to avoid the possibility of a fetched value not
@@ -1105,12 +1126,12 @@ do_examine (struct format_data fmt, struct gdbarch *gdbarch, CORE_ADDR addr)
the disassembler be modified so that LAST_EXAMINE_VALUE the disassembler be modified so that LAST_EXAMINE_VALUE
is left with the byte sequence from the last complete is left with the byte sequence from the last complete
instruction fetched from memory? */ instruction fetched from memory? */
last_examine_value = value_at_lazy (val_type, next_address); ci.last_examine_value = value_at_lazy (val_type, ci.next_address);
if (last_examine_value) if (ci.last_examine_value)
release_value (last_examine_value); release_value (ci.last_examine_value);
print_formatted (last_examine_value, size, &opts, gdb_stdout); print_formatted (ci.last_examine_value, size, &opts, gdb_stdout);
/* Display any branch delay slots following the final insn. */ /* Display any branch delay slots following the final insn. */
if (format == 'i' && count == 1) if (format == 'i' && count == 1)
@@ -1121,7 +1142,7 @@ do_examine (struct format_data fmt, struct gdbarch *gdbarch, CORE_ADDR addr)
} }
if (need_to_update_next_address) if (need_to_update_next_address)
next_address = addr_rewound; ci.next_address = addr_rewound;
} }
static void static void
@@ -1149,9 +1170,12 @@ print_command_parse_format (const char **expp, const char *cmdname,
if (exp && *exp == '/') if (exp && *exp == '/')
{ {
exp++; exp++;
*fmtp = decode_format (&exp, last_format, 0);
current_printcmd_info &ci = get_current_printcmd_info ();
*fmtp = decode_format (&exp, ci.last_format, 0);
validate_format (*fmtp, cmdname); validate_format (*fmtp, cmdname);
last_format = fmtp->format; ci.last_format = fmtp->format;
} }
else else
{ {
@@ -1624,8 +1648,10 @@ x_command (char *exp, int from_tty)
struct format_data fmt; struct format_data fmt;
struct value *val; struct value *val;
fmt.format = last_format ? last_format : 'x'; current_printcmd_info &ci = get_current_printcmd_info ();
fmt.size = last_size;
fmt.format = ci.last_format ? ci.last_format : 'x';
fmt.size = ci.last_size;
fmt.count = 1; fmt.count = 1;
fmt.raw = 0; fmt.raw = 0;
@@ -1633,7 +1659,7 @@ x_command (char *exp, int from_tty)
{ {
const char *tmp = exp + 1; const char *tmp = exp + 1;
fmt = decode_format (&tmp, last_format, last_size); fmt = decode_format (&tmp, ci.last_format, ci.last_size);
exp = (char *) tmp; exp = (char *) tmp;
} }
@@ -1655,45 +1681,45 @@ x_command (char *exp, int from_tty)
if (/* last_format == 'i' && */ if (/* last_format == 'i' && */
TYPE_CODE (value_type (val)) == TYPE_CODE_FUNC TYPE_CODE (value_type (val)) == TYPE_CODE_FUNC
&& VALUE_LVAL (val) == lval_memory) && VALUE_LVAL (val) == lval_memory)
next_address = value_address (val); ci.next_address = value_address (val);
else else
next_address = value_as_address (val); ci.next_address = value_as_address (val);
next_gdbarch = expr->gdbarch; ci.next_gdbarch = expr->gdbarch;
} }
if (!next_gdbarch) if (!ci.next_gdbarch)
error_no_arg (_("starting display address")); error_no_arg (_("starting display address"));
do_examine (fmt, next_gdbarch, next_address); do_examine (fmt, ci.next_gdbarch, ci.next_address);
/* If the examine succeeds, we remember its size and format for next /* If the examine succeeds, we remember its size and format for next
time. Set last_size to 'b' for strings. */ time. Set last_size to 'b' for strings. */
if (fmt.format == 's') if (fmt.format == 's')
last_size = 'b'; ci.last_size = 'b';
else else
last_size = fmt.size; ci.last_size = fmt.size;
last_format = fmt.format; ci.last_format = fmt.format;
/* Set a couple of internal variables if appropriate. */ /* Set a couple of internal variables if appropriate. */
if (last_examine_value) if (ci.last_examine_value)
{ {
/* Make last address examined available to the user as $_. Use /* Make last address examined available to the user as $_. Use
the correct pointer type. */ the correct pointer type. */
struct type *pointer_type struct type *pointer_type
= lookup_pointer_type (value_type (last_examine_value)); = lookup_pointer_type (value_type (ci.last_examine_value));
set_internalvar (lookup_internalvar ("_"), set_internalvar (lookup_internalvar ("_"),
value_from_pointer (pointer_type, value_from_pointer (pointer_type,
last_examine_address)); ci.last_examine_address));
/* Make contents of last address examined available to the user /* Make contents of last address examined available to the user
as $__. If the last value has not been fetched from memory as $__. If the last value has not been fetched from memory
then don't fetch it now; instead mark it by voiding the $__ then don't fetch it now; instead mark it by voiding the $__
variable. */ variable. */
if (value_lazy (last_examine_value)) if (value_lazy (ci.last_examine_value))
clear_internalvar (lookup_internalvar ("__")); clear_internalvar (lookup_internalvar ("__"));
else else
set_internalvar (lookup_internalvar ("__"), last_examine_value); set_internalvar (lookup_internalvar ("__"), ci.last_examine_value);
} }
} }

View File

@@ -44,6 +44,7 @@
#include "readline/readline.h" #include "readline/readline.h"
#include "common/enum-flags.h" #include "common/enum-flags.h"
#include <algorithm> #include <algorithm>
#include "top.h"
#define OPEN_MODE (O_RDONLY | O_BINARY) #define OPEN_MODE (O_RDONLY | O_BINARY)
#define FDOPEN_MODE FOPEN_RB #define FDOPEN_MODE FOPEN_RB
@@ -76,15 +77,45 @@ struct substitute_path_rule
static struct substitute_path_rule *substitute_path_rules = NULL; static struct substitute_path_rule *substitute_path_rules = NULL;
/* Symtab of default file for listing lines of. */ struct current_source_info
{
/* Symtab of default file for listing lines of. */
symtab *current_source_symtab = NULL;
static struct symtab *current_source_symtab; /* Default next line to list. */
int current_source_line = 0;
/* Default next line to list. */ program_space *current_source_pspace = NULL;
static int current_source_line; /* Line number of last line printed. Default for various commands.
source_line is usually, but not always, the same as this. */
int last_line_listed;
static struct program_space *current_source_pspace; /* First line number listed by last listing command. If 0, then no
source lines have yet been listed since the last time the current
source line was changed. */
int first_line_listed;
/* Saves the name of the last source file visited and a possible
error code. Used to prevent repeating annoying "No such file or
directories" msgs. */
struct symtab *last_source_visited = NULL;
int last_source_error = 0;
};
static current_source_info &
get_current_source_info ()
{
if (current_ui->curr_source_info == NULL)
current_ui->curr_source_info = new current_source_info ();
return *current_ui->curr_source_info;
}
void
delete_current_source_info (struct ui *ui)
{
delete ui->curr_source_info;
}
/* Default number of lines to print with commands like "list". /* Default number of lines to print with commands like "list".
This is based on guessing how many long (i.e. more than chars_per_line This is based on guessing how many long (i.e. more than chars_per_line
@@ -123,23 +154,8 @@ show_filename_display_string (struct ui_file *file, int from_tty,
{ {
fprintf_filtered (file, _("Filenames are displayed as \"%s\".\n"), value); fprintf_filtered (file, _("Filenames are displayed as \"%s\".\n"), value);
} }
/* Line number of last line printed. Default for various commands.
current_source_line is usually, but not always, the same as this. */
static int last_line_listed;
/* First line number listed by last listing command. If 0, then no
source lines have yet been listed since the last time the current
source line was changed. */
static int first_line_listed;
/* Saves the name of the last source file visited and a possible error code.
Used to prevent repeating annoying "No such file or directories" msgs. */
static struct symtab *last_source_visited = NULL;
static int last_source_error = 0;
/* Return the first line listed by print_source_lines. /* Return the first line listed by print_source_lines.
Used by command interpreters to request listing from Used by command interpreters to request listing from
@@ -148,7 +164,9 @@ static int last_source_error = 0;
int int
get_first_line_listed (void) get_first_line_listed (void)
{ {
return first_line_listed; current_source_info &si = get_current_source_info ();
return si.first_line_listed;
} }
/* Clear line listed range. This makes the next "list" center the /* Clear line listed range. This makes the next "list" center the
@@ -157,8 +175,10 @@ get_first_line_listed (void)
static void static void
clear_lines_listed_range (void) clear_lines_listed_range (void)
{ {
first_line_listed = 0; current_source_info &si = get_current_source_info ();
last_line_listed = 0;
si.first_line_listed = 0;
si.last_line_listed = 0;
} }
/* Return the default number of lines to print with commands like the /* Return the default number of lines to print with commands like the
@@ -180,12 +200,14 @@ get_current_source_symtab_and_line (void)
{ {
symtab_and_line cursal; symtab_and_line cursal;
cursal.pspace = current_source_pspace; current_source_info &si = get_current_source_info ();
cursal.symtab = current_source_symtab;
cursal.line = current_source_line; cursal.pspace = si.current_source_pspace;
cursal.symtab = si.current_source_symtab;
cursal.line = si.current_source_line;
cursal.pc = 0; cursal.pc = 0;
cursal.end = 0; cursal.end = 0;
return cursal; return cursal;
} }
@@ -203,8 +225,9 @@ set_default_source_symtab_and_line (void)
if (!have_full_symbols () && !have_partial_symbols ()) if (!have_full_symbols () && !have_partial_symbols ())
error (_("No symbol table is loaded. Use the \"file\" command.")); error (_("No symbol table is loaded. Use the \"file\" command."));
current_source_info &si = get_current_source_info ();
/* Pull in a current source symtab if necessary. */ /* Pull in a current source symtab if necessary. */
if (current_source_symtab == 0) if (si.current_source_symtab == NULL)
select_source_symtab (0); select_source_symtab (0);
} }
@@ -218,15 +241,17 @@ set_current_source_symtab_and_line (const symtab_and_line &sal)
{ {
symtab_and_line cursal; symtab_and_line cursal;
cursal.pspace = current_source_pspace; current_source_info &si = get_current_source_info ();
cursal.symtab = current_source_symtab;
cursal.line = current_source_line; cursal.pspace = si.current_source_pspace;
cursal.symtab = si.current_source_symtab;
cursal.line = si.current_source_line;
cursal.pc = 0; cursal.pc = 0;
cursal.end = 0; cursal.end = 0;
current_source_pspace = sal.pspace; si.current_source_pspace = sal.pspace;
current_source_symtab = sal.symtab; si.current_source_symtab = sal.symtab;
current_source_line = sal.line; si.current_source_line = sal.line;
/* Force the next "list" to center around the current line. */ /* Force the next "list" to center around the current line. */
clear_lines_listed_range (); clear_lines_listed_range ();
@@ -239,8 +264,10 @@ set_current_source_symtab_and_line (const symtab_and_line &sal)
void void
clear_current_source_symtab_and_line (void) clear_current_source_symtab_and_line (void)
{ {
current_source_symtab = 0; current_source_info &si = get_current_source_info ();
current_source_line = 0;
si.current_source_symtab = NULL;
si.current_source_line = 0;
} }
/* Set the source file default for the "list" command to be S. /* Set the source file default for the "list" command to be S.
@@ -257,15 +284,17 @@ select_source_symtab (struct symtab *s)
struct objfile *ofp; struct objfile *ofp;
struct compunit_symtab *cu; struct compunit_symtab *cu;
current_source_info &si = get_current_source_info ();
if (s) if (s)
{ {
current_source_symtab = s; si.current_source_symtab = s;
current_source_line = 1; si.current_source_line = 1;
current_source_pspace = SYMTAB_PSPACE (s); si.current_source_pspace = SYMTAB_PSPACE (s);
return; return;
} }
if (current_source_symtab) if (si.current_source_symtab != NULL)
return; return;
/* Make the default place to list be the function `main' /* Make the default place to list be the function `main'
@@ -276,17 +305,17 @@ select_source_symtab (struct symtab *s)
= decode_line_with_current_source (main_name (), = decode_line_with_current_source (main_name (),
DECODE_LINE_FUNFIRSTLINE); DECODE_LINE_FUNFIRSTLINE);
const symtab_and_line &sal = sals[0]; const symtab_and_line &sal = sals[0];
current_source_pspace = sal.pspace; si.current_source_pspace = sal.pspace;
current_source_symtab = sal.symtab; si.current_source_symtab = sal.symtab;
current_source_line = std::max (sal.line - (lines_to_list - 1), 1); si.current_source_line = std::max (sal.line - (lines_to_list - 1), 1);
if (current_source_symtab) if (si.current_source_symtab != NULL)
return; return;
} }
/* Alright; find the last file in the symtab list (ignoring .h's /* Alright; find the last file in the symtab list (ignoring .h's
and namespace symtabs). */ and namespace symtabs). */
current_source_line = 1; si.current_source_line = 1;
ALL_FILETABS (ofp, cu, s) ALL_FILETABS (ofp, cu, s)
{ {
@@ -296,12 +325,12 @@ select_source_symtab (struct symtab *s)
if (!(len > 2 && (strcmp (&name[len - 2], ".h") == 0 if (!(len > 2 && (strcmp (&name[len - 2], ".h") == 0
|| strcmp (name, "<<C++-namespaces>>") == 0))) || strcmp (name, "<<C++-namespaces>>") == 0)))
{ {
current_source_pspace = current_program_space; si.current_source_pspace = current_program_space;
current_source_symtab = s; si.current_source_symtab = s;
} }
} }
if (current_source_symtab) if (si.current_source_symtab != NULL)
return; return;
ALL_OBJFILES (ofp) ALL_OBJFILES (ofp)
@@ -309,9 +338,9 @@ select_source_symtab (struct symtab *s)
if (ofp->sf) if (ofp->sf)
s = ofp->sf->qf->find_last_source_symtab (ofp); s = ofp->sf->qf->find_last_source_symtab (ofp);
if (s) if (s)
current_source_symtab = s; si.current_source_symtab = s;
} }
if (current_source_symtab) if (si.current_source_symtab != NULL)
return; return;
error (_("Can't find a default source file")); error (_("Can't find a default source file"));
@@ -403,7 +432,12 @@ forget_cached_source_info (void)
forget_cached_source_info_for_objfile (objfile); forget_cached_source_info_for_objfile (objfile);
} }
last_source_visited = NULL; struct ui *ui;
ALL_UIS (ui)
{
if (ui->curr_source_info != NULL)
ui->curr_source_info->last_source_visited = NULL;
}
} }
void void
@@ -645,7 +679,8 @@ add_path (char *dirname, char **which_path, int parse_separators)
static void static void
info_source_command (char *ignore, int from_tty) info_source_command (char *ignore, int from_tty)
{ {
struct symtab *s = current_source_symtab; current_source_info &si = get_current_source_info ();
struct symtab *s = si.current_source_symtab;
struct compunit_symtab *cust; struct compunit_symtab *cust;
if (!s) if (!s)
@@ -1312,8 +1347,9 @@ identify_source_line (struct symtab *s, int line, int mid_statement,
annotate_source (s->fullname, line, s->line_charpos[line - 1], annotate_source (s->fullname, line, s->line_charpos[line - 1],
mid_statement, get_objfile_arch (SYMTAB_OBJFILE (s)), pc); mid_statement, get_objfile_arch (SYMTAB_OBJFILE (s)), pc);
current_source_line = line; current_source_info &si = get_current_source_info ();
current_source_symtab = s; si.current_source_line = line;
si.current_source_symtab = s;
clear_lines_listed_range (); clear_lines_listed_range ();
return 1; return 1;
} }
@@ -1333,36 +1369,37 @@ print_source_lines_base (struct symtab *s, int line, int stopline,
struct ui_out *uiout = current_uiout; struct ui_out *uiout = current_uiout;
/* Regardless of whether we can open the file, set current_source_symtab. */ /* Regardless of whether we can open the file, set current_source_symtab. */
current_source_symtab = s; current_source_info &si = get_current_source_info ();
current_source_line = line; si.current_source_symtab = s;
first_line_listed = line; si.current_source_line = line;
si.first_line_listed = line;
/* If printing of source lines is disabled, just print file and line /* If printing of source lines is disabled, just print file and line
number. */ number. */
if (uiout->test_flags (ui_source_list)) if (uiout->test_flags (ui_source_list))
{ {
/* Only prints "No such file or directory" once. */ /* Only prints "No such file or directory" once. */
if ((s != last_source_visited) || (!last_source_error)) if ((s != si.last_source_visited) || (!si.last_source_error))
{ {
last_source_visited = s; si.last_source_visited = s;
desc = open_source_file (s); desc = open_source_file (s);
} }
else else
{ {
desc = last_source_error; desc = si.last_source_error;
flags |= PRINT_SOURCE_LINES_NOERROR; flags |= PRINT_SOURCE_LINES_NOERROR;
} }
} }
else else
{ {
desc = last_source_error; desc = si.last_source_error;
flags |= PRINT_SOURCE_LINES_NOERROR; flags |= PRINT_SOURCE_LINES_NOERROR;
noprint = 1; noprint = 1;
} }
if (desc < 0 || noprint) if (desc < 0 || noprint)
{ {
last_source_error = desc; si.last_source_error = desc;
if (!(flags & PRINT_SOURCE_LINES_NOERROR)) if (!(flags & PRINT_SOURCE_LINES_NOERROR))
{ {
@@ -1404,7 +1441,7 @@ print_source_lines_base (struct symtab *s, int line, int stopline,
return; return;
} }
last_source_error = 0; si.last_source_error = 0;
if (s->line_charpos == 0) if (s->line_charpos == 0)
find_source_lines (s, desc); find_source_lines (s, desc);
@@ -1432,13 +1469,13 @@ print_source_lines_base (struct symtab *s, int line, int stopline,
c = fgetc (stream.get ()); c = fgetc (stream.get ());
if (c == EOF) if (c == EOF)
break; break;
last_line_listed = current_source_line; si.last_line_listed = si.current_source_line;
if (flags & PRINT_SOURCE_LINES_FILENAME) if (flags & PRINT_SOURCE_LINES_FILENAME)
{ {
uiout->text (symtab_to_filename_for_display (s)); uiout->text (symtab_to_filename_for_display (s));
uiout->text (":"); uiout->text (":");
} }
xsnprintf (buf, sizeof (buf), "%d\t", current_source_line++); xsnprintf (buf, sizeof (buf), "%d\t", si.current_source_line++);
uiout->text (buf); uiout->text (buf);
do do
{ {
@@ -1492,14 +1529,16 @@ info_line_command (char *arg, int from_tty)
symtab_and_line curr_sal; symtab_and_line curr_sal;
gdb::array_view<symtab_and_line> sals; gdb::array_view<symtab_and_line> sals;
current_source_info &si = get_current_source_info ();
if (arg == 0) if (arg == 0)
{ {
curr_sal.symtab = current_source_symtab; curr_sal.symtab = si.current_source_symtab;
curr_sal.pspace = current_program_space; curr_sal.pspace = current_program_space;
if (last_line_listed != 0) if (si.last_line_listed != 0)
curr_sal.line = last_line_listed; curr_sal.line = si.last_line_listed;
else else
curr_sal.line = current_source_line; curr_sal.line = si.current_source_line;
sals = curr_sal; sals = curr_sal;
} }
@@ -1572,7 +1611,7 @@ info_line_command (char *arg, int from_tty)
set_next_address (gdbarch, start_pc); set_next_address (gdbarch, start_pc);
/* Repeating "info line" should do the following line. */ /* Repeating "info line" should do the following line. */
last_line_listed = sal.line + 1; si.last_line_listed = sal.line + 1;
/* If this is the only line, show the source code. If it could /* If this is the only line, show the source code. If it could
not find the file, don't do anything special. */ not find the file, don't do anything special. */
@@ -1599,28 +1638,30 @@ forward_search_command (char *regex, int from_tty)
char *msg; char *msg;
struct cleanup *cleanups; struct cleanup *cleanups;
line = last_line_listed + 1; current_source_info &si = get_current_source_info ();
line = si.last_line_listed + 1;
msg = (char *) re_comp (regex); msg = (char *) re_comp (regex);
if (msg) if (msg)
error (("%s"), msg); error (("%s"), msg);
if (current_source_symtab == 0) if (si.current_source_symtab == 0)
select_source_symtab (0); select_source_symtab (0);
desc = open_source_file (current_source_symtab); desc = open_source_file (si.current_source_symtab);
if (desc < 0) if (desc < 0)
perror_with_name (symtab_to_filename_for_display (current_source_symtab)); perror_with_name (symtab_to_filename_for_display (si.current_source_symtab));
cleanups = make_cleanup_close (desc); cleanups = make_cleanup_close (desc);
if (current_source_symtab->line_charpos == 0) if (si.current_source_symtab->line_charpos == 0)
find_source_lines (current_source_symtab, desc); find_source_lines (si.current_source_symtab, desc);
if (line < 1 || line > current_source_symtab->nlines) if (line < 1 || line > si.current_source_symtab->nlines)
error (_("Expression not found")); error (_("Expression not found"));
if (lseek (desc, current_source_symtab->line_charpos[line - 1], 0) < 0) if (lseek (desc, si.current_source_symtab->line_charpos[line - 1], 0) < 0)
perror_with_name (symtab_to_filename_for_display (current_source_symtab)); perror_with_name (symtab_to_filename_for_display (si.current_source_symtab));
discard_cleanups (cleanups); discard_cleanups (cleanups);
gdb_file_up stream (fdopen (desc, FDOPEN_MODE)); gdb_file_up stream (fdopen (desc, FDOPEN_MODE));
@@ -1664,9 +1705,9 @@ forward_search_command (char *regex, int from_tty)
if (re_exec (buf) > 0) if (re_exec (buf) > 0)
{ {
/* Match! */ /* Match! */
print_source_lines (current_source_symtab, line, line + 1, 0); print_source_lines (si.current_source_symtab, line, line + 1, 0);
set_internalvar_integer (lookup_internalvar ("_"), line); set_internalvar_integer (lookup_internalvar ("_"), line);
current_source_line = std::max (line - lines_to_list / 2, 1); si.current_source_line = std::max (line - lines_to_list / 2, 1);
return; return;
} }
line++; line++;
@@ -1684,28 +1725,30 @@ reverse_search_command (char *regex, int from_tty)
char *msg; char *msg;
struct cleanup *cleanups; struct cleanup *cleanups;
line = last_line_listed - 1; current_source_info &si = get_current_source_info ();
line = si.last_line_listed - 1;
msg = (char *) re_comp (regex); msg = (char *) re_comp (regex);
if (msg) if (msg)
error (("%s"), msg); error (("%s"), msg);
if (current_source_symtab == 0) if (si.current_source_symtab == 0)
select_source_symtab (0); select_source_symtab (0);
desc = open_source_file (current_source_symtab); desc = open_source_file (si.current_source_symtab);
if (desc < 0) if (desc < 0)
perror_with_name (symtab_to_filename_for_display (current_source_symtab)); perror_with_name (symtab_to_filename_for_display (si.current_source_symtab));
cleanups = make_cleanup_close (desc); cleanups = make_cleanup_close (desc);
if (current_source_symtab->line_charpos == 0) if (si.current_source_symtab->line_charpos == 0)
find_source_lines (current_source_symtab, desc); find_source_lines (si.current_source_symtab, desc);
if (line < 1 || line > current_source_symtab->nlines) if (line < 1 || line > si.current_source_symtab->nlines)
error (_("Expression not found")); error (_("Expression not found"));
if (lseek (desc, current_source_symtab->line_charpos[line - 1], 0) < 0) if (lseek (desc, si.current_source_symtab->line_charpos[line - 1], 0) < 0)
perror_with_name (symtab_to_filename_for_display (current_source_symtab)); perror_with_name (symtab_to_filename_for_display (si.current_source_symtab));
discard_cleanups (cleanups); discard_cleanups (cleanups);
gdb_file_up stream (fdopen (desc, FDOPEN_MODE)); gdb_file_up stream (fdopen (desc, FDOPEN_MODE));
@@ -1738,18 +1781,18 @@ reverse_search_command (char *regex, int from_tty)
if (re_exec (buf) > 0) if (re_exec (buf) > 0)
{ {
/* Match! */ /* Match! */
print_source_lines (current_source_symtab, line, line + 1, 0); print_source_lines (si.current_source_symtab, line, line + 1, 0);
set_internalvar_integer (lookup_internalvar ("_"), line); set_internalvar_integer (lookup_internalvar ("_"), line);
current_source_line = std::max (line - lines_to_list / 2, 1); si.current_source_line = std::max (line - lines_to_list / 2, 1);
return; return;
} }
line--; line--;
if (fseek (stream.get (), if (fseek (stream.get (),
current_source_symtab->line_charpos[line - 1], 0) < 0) si.current_source_symtab->line_charpos[line - 1], 0) < 0)
{ {
const char *filename; const char *filename;
filename = symtab_to_filename_for_display (current_source_symtab); filename = symtab_to_filename_for_display (si.current_source_symtab);
perror_with_name (filename); perror_with_name (filename);
} }
} }
@@ -1974,7 +2017,6 @@ _initialize_source (void)
{ {
struct cmd_list_element *c; struct cmd_list_element *c;
current_source_symtab = 0;
init_source_path (); init_source_path ();
/* The intention is to use POSIX Basic Regular Expressions. /* The intention is to use POSIX Basic Regular Expressions.

View File

@@ -132,10 +132,6 @@ show_confirm (struct ui_file *file, int from_tty,
char *current_directory; char *current_directory;
/* The last command line executed on the console. Used for command
repetitions. */
char *saved_command_line;
/* Nonzero if the current command is modified by "server ". This /* Nonzero if the current command is modified by "server ". This
affects things like recording into the command history, commands affects things like recording into the command history, commands
repeating on RETURN, etc. This is so a user interface (emacs, GUI, repeating on RETURN, etc. This is so a user interface (emacs, GUI,
@@ -251,6 +247,7 @@ static int highest_ui_num;
ui::ui (FILE *instream_, FILE *outstream_, FILE *errstream_) ui::ui (FILE *instream_, FILE *outstream_, FILE *errstream_)
: next (nullptr), : next (nullptr),
num (++highest_ui_num), num (++highest_ui_num),
saved_command_line (xstrdup ("")),
call_readline (nullptr), call_readline (nullptr),
input_handler (nullptr), input_handler (nullptr),
command_editing (0), command_editing (0),
@@ -301,6 +298,10 @@ ui::~ui ()
else else
ui_list = next; ui_list = next;
delete_current_printcmd_info (this);
delete_current_source_info (this);
delete_current_top_info (this);
delete m_gdb_stdin; delete m_gdb_stdin;
delete m_gdb_stdout; delete m_gdb_stdout;
delete m_gdb_stderr; delete m_gdb_stderr;
@@ -675,7 +676,10 @@ dont_repeat (void)
thing read from stdin in line and don't want to delete it. Null thing read from stdin in line and don't want to delete it. Null
lines won't repeat here in any case. */ lines won't repeat here in any case. */
if (ui->instream == ui->stdin_stream) if (ui->instream == ui->stdin_stream)
*saved_command_line = 0; {
xfree (ui->saved_command_line);
ui->saved_command_line = NULL;
}
} }
/* Prevent dont_repeat from working, and return a cleanup that /* Prevent dont_repeat from working, and return a cleanup that
@@ -1659,11 +1663,33 @@ dont_repeat_command (char *ignored, int from_tty)
{ {
/* Can't call dont_repeat here because we're not necessarily reading /* Can't call dont_repeat here because we're not necessarily reading
from stdin. */ from stdin. */
*saved_command_line = 0; xfree (current_ui->saved_command_line);
current_ui->saved_command_line = NULL;
} }
/* Functions to manipulate command line editing control variables. */ /* Functions to manipulate command line editing control variables. */
struct current_top_info
{
/* Number of the history entry which we are planning to display
next in "show commands". Relative to history_base. */
int num = 0;
};
static current_top_info &
get_current_top_info ()
{
if (current_ui->curr_top_info == NULL)
current_ui->curr_top_info = new current_top_info ();
return *current_ui->curr_top_info;
}
void
delete_current_top_info (struct ui *ui)
{
delete ui->curr_top_info;
}
/* Number of commands to print in each call to show_commands. */ /* Number of commands to print in each call to show_commands. */
#define Hist_print 10 #define Hist_print 10
void void
@@ -1672,9 +1698,7 @@ show_commands (char *args, int from_tty)
/* Index for history commands. Relative to history_base. */ /* Index for history commands. Relative to history_base. */
int offset; int offset;
/* Number of the history entry which we are planning to display next. current_top_info &ci = get_current_top_info ();
Relative to history_base. */
static int num = 0;
/* Print out some of the commands from the command history. */ /* Print out some of the commands from the command history. */
@@ -1685,28 +1709,28 @@ show_commands (char *args, int from_tty)
; ;
else else
/* "info editing <exp>" should print around command number <exp>. */ /* "info editing <exp>" should print around command number <exp>. */
num = (parse_and_eval_long (args) - history_base) - Hist_print / 2; ci.num = (parse_and_eval_long (args) - history_base) - Hist_print / 2;
} }
/* "show commands" means print the last Hist_print commands. */ /* "show commands" means print the last Hist_print commands. */
else else
{ {
num = history_length - Hist_print; ci.num = history_length - Hist_print;
} }
if (num < 0) if (ci.num < 0)
num = 0; ci.num = 0;
/* If there are at least Hist_print commands, we want to display the last /* If there are at least Hist_print commands, we want to display the last
Hist_print rather than, say, the last 6. */ Hist_print rather than, say, the last 6. */
if (history_length - num < Hist_print) if (history_length - ci.num < Hist_print)
{ {
num = history_length - Hist_print; ci.num = history_length - Hist_print;
if (num < 0) if (ci.num < 0)
num = 0; ci.num = 0;
} }
for (offset = num; for (offset = ci.num;
offset < num + Hist_print && offset < history_length; offset < ci.num + Hist_print && offset < history_length;
offset++) offset++)
{ {
printf_filtered ("%5d %s\n", history_base + offset, printf_filtered ("%5d %s\n", history_base + offset,
@@ -1715,7 +1739,7 @@ show_commands (char *args, int from_tty)
/* The next command we want to display is the next one that we haven't /* The next command we want to display is the next one that we haven't
displayed yet. */ displayed yet. */
num += Hist_print; ci.num += Hist_print;
/* If the user repeats this command with return, it should do what /* If the user repeats this command with return, it should do what
"show commands +" does. This is unnecessary if arg is null, "show commands +" does. This is unnecessary if arg is null,

View File

@@ -71,6 +71,10 @@ struct ui
input until we have a whole command line. */ input until we have a whole command line. */
struct buffer line_buffer; struct buffer line_buffer;
/* The last command line executed on the console. Used for command
repetitions. */
char *saved_command_line;
/* The callback used by the event loop whenever an event is detected /* The callback used by the event loop whenever an event is detected
on the UI's input file descriptor. This function incrementally on the UI's input file descriptor. This function incrementally
builds a buffer where it accumulates the line read up to the builds a buffer where it accumulates the line read up to the
@@ -130,6 +134,15 @@ struct ui
/* See enum prompt_state's description. */ /* See enum prompt_state's description. */
enum prompt_state prompt_state; enum prompt_state prompt_state;
/* Per-UI info for printcmd.c. Initialized on demand. */
struct current_printcmd_info *curr_printcmd_info = NULL;
/* Per-UI info for source.c. Initialized on demand. */
struct current_source_info *curr_source_info = NULL;
/* Per-UI info for top.c. Initialized on demand. */
struct current_top_info *curr_top_info = NULL;
/* The fields below that start with "m_" are "private". They're /* The fields below that start with "m_" are "private". They're
meant to be accessed through wrapper macros that make them look meant to be accessed through wrapper macros that make them look
like globals. */ like globals. */
@@ -217,7 +230,6 @@ extern void ui_register_input_event_handler (struct ui *ui);
extern void ui_unregister_input_event_handler (struct ui *ui); extern void ui_unregister_input_event_handler (struct ui *ui);
/* From top.c. */ /* From top.c. */
extern char *saved_command_line;
extern int confirm; extern int confirm;
extern int inhibit_gdbinit; extern int inhibit_gdbinit;
extern const char gdbinit[]; extern const char gdbinit[];
@@ -234,6 +246,11 @@ extern void quit_command (char *, int);
extern void quit_cover (void); extern void quit_cover (void);
extern void execute_command (char *, int); extern void execute_command (char *, int);
/* Delete the per-UI info of UI. */
extern void delete_current_printcmd_info (struct ui *ui);
extern void delete_current_source_info (struct ui *ui);
extern void delete_current_top_info (struct ui *ui);
/* If the interpreter is in sync mode (we're running a user command's /* If the interpreter is in sync mode (we're running a user command's
list, running command hooks or similars), and we just ran a list, running command hooks or similars), and we just ran a
synchronous command that started the target, wait for that command synchronous command that started the target, wait for that command