diff --git a/gdb/event-top.c b/gdb/event-top.c index 7377189..1e84fdf 100644 --- a/gdb/event-top.c +++ b/gdb/event-top.c @@ -634,8 +634,8 @@ command_line_append_input_line (struct buffer *cmd_line_buffer, char *rl) If REPEAT, handle command repetitions: - If the input command line is NOT empty, the command returned is - copied into the global 'saved_command_line' var so that it can - be repeated later. + copied into the 'ui->saved_command_line' var so that it can be + repeated later. - OTOH, if the input command line IS empty, return the previously 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 " if (startswith (cmd, SERVER_COMMAND_PREFIX)) { - /* Note that we don't set `saved_command_line'. Between this - and the check in dont_repeat, this insures that repeating - will still do the right thing. */ + /* Note that we don't set `ui->saved_command_line'. Between + this and the check in dont_repeat, this insures that + repeating will still do the right thing. */ 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++) ; if (repeat && *p1 == '\0') - return saved_command_line; + return ui->saved_command_line; /* Add command to history if appropriate. Note: lines consisting 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. */ if (repeat) { - xfree (saved_command_line); - saved_command_line = xstrdup (cmd); - return saved_command_line; + xfree (ui->saved_command_line); + ui->saved_command_line = xstrdup (cmd); + return ui->saved_command_line; } else return cmd; diff --git a/gdb/main.c b/gdb/main.c index 835ae24..8fae552 100644 --- a/gdb/main.c +++ b/gdb/main.c @@ -522,8 +522,6 @@ captured_main_1 (struct captured_main_args *context) notice_open_fds (); save_original_signals_state (); - saved_command_line = (char *) xstrdup (""); - #ifdef __MINGW32__ /* Ensure stderr is unbuffered. A Cygwin pty or pipe is implemented as a Windows pipe, and Windows buffers on pipes. */ diff --git a/gdb/printcmd.c b/gdb/printcmd.c index 017c7be..ec54658 100644 --- a/gdb/printcmd.c +++ b/gdb/printcmd.c @@ -49,37 +49,50 @@ #include "format.h" #include "source.h" #include "common/byte-vector.h" +#include "top.h" #ifdef TUI #include "tui/tui.h" /* For tui_active et al. */ #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 CORE_ADDR next_address; +static current_printcmd_info & +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. */ 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 printed as `0x1234 '. */ @@ -279,8 +292,10 @@ print_formatted (struct value *val, int size, struct type *type = check_typedef (value_type (val)); int len = TYPE_LENGTH (type); + current_printcmd_info &ci = get_current_printcmd_info (); + if (VALUE_LVAL (val) == lval_memory) - next_address = value_address (val) + len; + ci.next_address = value_address (val) + len; if (size) { @@ -290,20 +305,20 @@ print_formatted (struct value *val, int size, { struct type *elttype = value_type (val); - next_address = (value_address (val) - + val_print_string (elttype, NULL, - value_address (val), -1, - stream, options) * len); + ci.next_address = (value_address (val) + + val_print_string (elttype, NULL, + value_address (val), -1, + stream, options) * len); } return; case 'i': /* We often wrap here if there are long symbolic names. */ wrap_here (" "); - next_address = (value_address (val) - + gdb_print_insn (get_type_arch (type), - value_address (val), stream, - &branch_delay_insns)); + ci.next_address = (value_address (val) + + gdb_print_insn (get_type_arch (type), + value_address (val), stream, + &branch_delay_insns)); return; } } @@ -500,10 +515,13 @@ set_next_address (struct gdbarch *gdbarch, CORE_ADDR addr) { struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr; - next_gdbarch = gdbarch; - next_address = addr; + current_printcmd_info &ci = get_current_printcmd_info (); - /* 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 ("_"), 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; size = fmt.size; 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 regardless of the specified size. @@ -989,11 +1010,11 @@ do_examine (struct format_data fmt, struct gdbarch *gdbarch, CORE_ADDR addr) if (size == 'a') { /* Pick the appropriate size for an address. */ - if (gdbarch_ptr_bit (next_gdbarch) == 64) + if (gdbarch_ptr_bit (ci.next_gdbarch) == 64) size = 'g'; - else if (gdbarch_ptr_bit (next_gdbarch) == 32) + else if (gdbarch_ptr_bit (ci.next_gdbarch) == 32) size = 'w'; - else if (gdbarch_ptr_bit (next_gdbarch) == 16) + else if (gdbarch_ptr_bit (ci.next_gdbarch) == 16) size = 'h'; else /* 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') - val_type = builtin_type (next_gdbarch)->builtin_int8; + val_type = builtin_type (ci.next_gdbarch)->builtin_int8; 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') - val_type = builtin_type (next_gdbarch)->builtin_int32; + val_type = builtin_type (ci.next_gdbarch)->builtin_int32; else if (size == 'g') - val_type = builtin_type (next_gdbarch)->builtin_int64; + val_type = builtin_type (ci.next_gdbarch)->builtin_int64; 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 if type is not found. */ if (size == 'h') - char_type = builtin_type (next_gdbarch)->builtin_char16; + char_type = builtin_type (ci.next_gdbarch)->builtin_char16; else if (size == 'w') - char_type = builtin_type (next_gdbarch)->builtin_char32; + char_type = builtin_type (ci.next_gdbarch)->builtin_char32; if (char_type) val_type = char_type; else @@ -1028,7 +1049,7 @@ do_examine (struct format_data fmt, struct gdbarch *gdbarch, CORE_ADDR addr) warning (_("Unable to display strings with " "size '%c', using 'b' instead."), size); 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; if (format == 'i') { - next_address = find_instruction_backward (gdbarch, addr, count, - &count); + ci.next_address = find_instruction_backward (gdbarch, addr, count, + &count); } else if (format == 's') { - next_address = find_string_backward (gdbarch, addr, count, - TYPE_LENGTH (val_type), - &opts, &count); + ci.next_address = find_string_backward (gdbarch, addr, count, + TYPE_LENGTH (val_type), + &opts, &count); } 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 iteration. In backward case, we store the start address here and update next_address with it before exiting the function. */ addr_rewound = (format == 's' - ? next_address - TYPE_LENGTH (val_type) - : next_address); + ? ci.next_address - TYPE_LENGTH (val_type) + : ci.next_address); need_to_update_next_address = 1; } @@ -1081,8 +1102,8 @@ do_examine (struct format_data fmt, struct gdbarch *gdbarch, CORE_ADDR addr) { QUIT; if (format == 'i') - fputs_filtered (pc_prefix (next_address), gdb_stdout); - print_address (next_gdbarch, next_address, gdb_stdout); + fputs_filtered (pc_prefix (ci.next_address), gdb_stdout); + print_address (ci.next_gdbarch, ci.next_address, gdb_stdout); printf_filtered (":"); for (i = maxelts; i > 0 && count > 0; @@ -1091,10 +1112,10 @@ do_examine (struct format_data fmt, struct gdbarch *gdbarch, CORE_ADDR addr) printf_filtered ("\t"); /* Note that print_formatted sets next_address for the next object. */ - last_examine_address = next_address; + ci.last_examine_address = ci.next_address; - if (last_examine_value) - value_free (last_examine_value); + if (ci.last_examine_value) + value_free (ci.last_examine_value); /* The value to be displayed is not fetched greedily. 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 is left with the byte sequence from the last complete 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) - release_value (last_examine_value); + if (ci.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. */ 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) - next_address = addr_rewound; + ci.next_address = addr_rewound; } static void @@ -1149,9 +1170,12 @@ print_command_parse_format (const char **expp, const char *cmdname, if (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); - last_format = fmtp->format; + ci.last_format = fmtp->format; } else { @@ -1624,8 +1648,10 @@ x_command (char *exp, int from_tty) struct format_data fmt; struct value *val; - fmt.format = last_format ? last_format : 'x'; - fmt.size = last_size; + current_printcmd_info &ci = get_current_printcmd_info (); + + fmt.format = ci.last_format ? ci.last_format : 'x'; + fmt.size = ci.last_size; fmt.count = 1; fmt.raw = 0; @@ -1633,7 +1659,7 @@ x_command (char *exp, int from_tty) { 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; } @@ -1655,45 +1681,45 @@ x_command (char *exp, int from_tty) if (/* last_format == 'i' && */ TYPE_CODE (value_type (val)) == TYPE_CODE_FUNC && VALUE_LVAL (val) == lval_memory) - next_address = value_address (val); + ci.next_address = value_address (val); 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")); - 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 time. Set last_size to 'b' for strings. */ if (fmt.format == 's') - last_size = 'b'; + ci.last_size = 'b'; else - last_size = fmt.size; - last_format = fmt.format; + ci.last_size = fmt.size; + ci.last_format = fmt.format; /* 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 the correct 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 ("_"), value_from_pointer (pointer_type, - last_examine_address)); + ci.last_examine_address)); /* Make contents of last address examined available to the user as $__. If the last value has not been fetched from memory then don't fetch it now; instead mark it by voiding the $__ variable. */ - if (value_lazy (last_examine_value)) + if (value_lazy (ci.last_examine_value)) clear_internalvar (lookup_internalvar ("__")); else - set_internalvar (lookup_internalvar ("__"), last_examine_value); + set_internalvar (lookup_internalvar ("__"), ci.last_examine_value); } } diff --git a/gdb/source.c b/gdb/source.c index aa672fd..61a3634 100644 --- a/gdb/source.c +++ b/gdb/source.c @@ -44,6 +44,7 @@ #include "readline/readline.h" #include "common/enum-flags.h" #include +#include "top.h" #define OPEN_MODE (O_RDONLY | O_BINARY) #define FDOPEN_MODE FOPEN_RB @@ -76,15 +77,45 @@ struct substitute_path_rule 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; + + /* Default next line to list. */ + int current_source_line = 0; -static struct symtab *current_source_symtab; + program_space *current_source_pspace = NULL; -/* Default next line to list. */ + /* 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 int current_source_line; + /* 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; -static struct program_space *current_source_pspace; + /* 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". 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); } - -/* 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. Used by command interpreters to request listing from @@ -148,7 +164,9 @@ static int last_source_error = 0; int 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 @@ -157,8 +175,10 @@ get_first_line_listed (void) static void clear_lines_listed_range (void) { - first_line_listed = 0; - last_line_listed = 0; + current_source_info &si = get_current_source_info (); + + si.first_line_listed = 0; + si.last_line_listed = 0; } /* 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; - cursal.pspace = current_source_pspace; - cursal.symtab = current_source_symtab; - cursal.line = current_source_line; + current_source_info &si = get_current_source_info (); + + cursal.pspace = si.current_source_pspace; + cursal.symtab = si.current_source_symtab; + cursal.line = si.current_source_line; cursal.pc = 0; cursal.end = 0; - + return cursal; } @@ -203,8 +225,9 @@ set_default_source_symtab_and_line (void) if (!have_full_symbols () && !have_partial_symbols ()) 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. */ - if (current_source_symtab == 0) + if (si.current_source_symtab == NULL) select_source_symtab (0); } @@ -218,15 +241,17 @@ set_current_source_symtab_and_line (const symtab_and_line &sal) { symtab_and_line cursal; - cursal.pspace = current_source_pspace; - cursal.symtab = current_source_symtab; - cursal.line = current_source_line; + current_source_info &si = get_current_source_info (); + + cursal.pspace = si.current_source_pspace; + cursal.symtab = si.current_source_symtab; + cursal.line = si.current_source_line; cursal.pc = 0; cursal.end = 0; - current_source_pspace = sal.pspace; - current_source_symtab = sal.symtab; - current_source_line = sal.line; + si.current_source_pspace = sal.pspace; + si.current_source_symtab = sal.symtab; + si.current_source_line = sal.line; /* Force the next "list" to center around the current line. */ clear_lines_listed_range (); @@ -239,8 +264,10 @@ set_current_source_symtab_and_line (const symtab_and_line &sal) void clear_current_source_symtab_and_line (void) { - current_source_symtab = 0; - current_source_line = 0; + current_source_info &si = get_current_source_info (); + + si.current_source_symtab = NULL; + si.current_source_line = 0; } /* 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 compunit_symtab *cu; + current_source_info &si = get_current_source_info (); + if (s) { - current_source_symtab = s; - current_source_line = 1; - current_source_pspace = SYMTAB_PSPACE (s); + si.current_source_symtab = s; + si.current_source_line = 1; + si.current_source_pspace = SYMTAB_PSPACE (s); return; } - if (current_source_symtab) + if (si.current_source_symtab != NULL) return; /* 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_FUNFIRSTLINE); const symtab_and_line &sal = sals[0]; - current_source_pspace = sal.pspace; - current_source_symtab = sal.symtab; - current_source_line = std::max (sal.line - (lines_to_list - 1), 1); - if (current_source_symtab) + si.current_source_pspace = sal.pspace; + si.current_source_symtab = sal.symtab; + si.current_source_line = std::max (sal.line - (lines_to_list - 1), 1); + if (si.current_source_symtab != NULL) return; } /* Alright; find the last file in the symtab list (ignoring .h's and namespace symtabs). */ - current_source_line = 1; + si.current_source_line = 1; ALL_FILETABS (ofp, cu, s) { @@ -296,12 +325,12 @@ select_source_symtab (struct symtab *s) if (!(len > 2 && (strcmp (&name[len - 2], ".h") == 0 || strcmp (name, "<>") == 0))) { - current_source_pspace = current_program_space; - current_source_symtab = s; + si.current_source_pspace = current_program_space; + si.current_source_symtab = s; } } - if (current_source_symtab) + if (si.current_source_symtab != NULL) return; ALL_OBJFILES (ofp) @@ -309,9 +338,9 @@ select_source_symtab (struct symtab *s) if (ofp->sf) s = ofp->sf->qf->find_last_source_symtab (ofp); if (s) - current_source_symtab = s; + si.current_source_symtab = s; } - if (current_source_symtab) + if (si.current_source_symtab != NULL) return; error (_("Can't find a default source file")); @@ -403,7 +432,12 @@ forget_cached_source_info (void) 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 @@ -645,7 +679,8 @@ add_path (char *dirname, char **which_path, int parse_separators) static void 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; 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], mid_statement, get_objfile_arch (SYMTAB_OBJFILE (s)), pc); - current_source_line = line; - current_source_symtab = s; + current_source_info &si = get_current_source_info (); + si.current_source_line = line; + si.current_source_symtab = s; clear_lines_listed_range (); return 1; } @@ -1333,36 +1369,37 @@ print_source_lines_base (struct symtab *s, int line, int stopline, struct ui_out *uiout = current_uiout; /* Regardless of whether we can open the file, set current_source_symtab. */ - current_source_symtab = s; - current_source_line = line; - first_line_listed = line; + current_source_info &si = get_current_source_info (); + si.current_source_symtab = s; + si.current_source_line = line; + si.first_line_listed = line; /* If printing of source lines is disabled, just print file and line number. */ if (uiout->test_flags (ui_source_list)) { /* 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); } else { - desc = last_source_error; + desc = si.last_source_error; flags |= PRINT_SOURCE_LINES_NOERROR; } } else { - desc = last_source_error; + desc = si.last_source_error; flags |= PRINT_SOURCE_LINES_NOERROR; noprint = 1; } if (desc < 0 || noprint) { - last_source_error = desc; + si.last_source_error = desc; if (!(flags & PRINT_SOURCE_LINES_NOERROR)) { @@ -1404,7 +1441,7 @@ print_source_lines_base (struct symtab *s, int line, int stopline, return; } - last_source_error = 0; + si.last_source_error = 0; if (s->line_charpos == 0) find_source_lines (s, desc); @@ -1432,13 +1469,13 @@ print_source_lines_base (struct symtab *s, int line, int stopline, c = fgetc (stream.get ()); if (c == EOF) break; - last_line_listed = current_source_line; + si.last_line_listed = si.current_source_line; if (flags & PRINT_SOURCE_LINES_FILENAME) { uiout->text (symtab_to_filename_for_display (s)); uiout->text (":"); } - xsnprintf (buf, sizeof (buf), "%d\t", current_source_line++); + xsnprintf (buf, sizeof (buf), "%d\t", si.current_source_line++); uiout->text (buf); do { @@ -1492,14 +1529,16 @@ info_line_command (char *arg, int from_tty) symtab_and_line curr_sal; gdb::array_view sals; + current_source_info &si = get_current_source_info (); + if (arg == 0) { - curr_sal.symtab = current_source_symtab; + curr_sal.symtab = si.current_source_symtab; curr_sal.pspace = current_program_space; - if (last_line_listed != 0) - curr_sal.line = last_line_listed; + if (si.last_line_listed != 0) + curr_sal.line = si.last_line_listed; else - curr_sal.line = current_source_line; + curr_sal.line = si.current_source_line; sals = curr_sal; } @@ -1572,7 +1611,7 @@ info_line_command (char *arg, int from_tty) set_next_address (gdbarch, start_pc); /* 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 not find the file, don't do anything special. */ @@ -1599,28 +1638,30 @@ forward_search_command (char *regex, int from_tty) char *msg; 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); if (msg) error (("%s"), msg); - if (current_source_symtab == 0) + if (si.current_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) - 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); - if (current_source_symtab->line_charpos == 0) - find_source_lines (current_source_symtab, desc); + if (si.current_source_symtab->line_charpos == 0) + 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")); - if (lseek (desc, current_source_symtab->line_charpos[line - 1], 0) < 0) - perror_with_name (symtab_to_filename_for_display (current_source_symtab)); + if (lseek (desc, si.current_source_symtab->line_charpos[line - 1], 0) < 0) + perror_with_name (symtab_to_filename_for_display (si.current_source_symtab)); discard_cleanups (cleanups); 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) { /* 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); - current_source_line = std::max (line - lines_to_list / 2, 1); + si.current_source_line = std::max (line - lines_to_list / 2, 1); return; } line++; @@ -1684,28 +1725,30 @@ reverse_search_command (char *regex, int from_tty) char *msg; 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); if (msg) error (("%s"), msg); - if (current_source_symtab == 0) + if (si.current_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) - 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); - if (current_source_symtab->line_charpos == 0) - find_source_lines (current_source_symtab, desc); + if (si.current_source_symtab->line_charpos == 0) + 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")); - if (lseek (desc, current_source_symtab->line_charpos[line - 1], 0) < 0) - perror_with_name (symtab_to_filename_for_display (current_source_symtab)); + if (lseek (desc, si.current_source_symtab->line_charpos[line - 1], 0) < 0) + perror_with_name (symtab_to_filename_for_display (si.current_source_symtab)); discard_cleanups (cleanups); 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) { /* 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); - current_source_line = std::max (line - lines_to_list / 2, 1); + si.current_source_line = std::max (line - lines_to_list / 2, 1); return; } line--; 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; - filename = symtab_to_filename_for_display (current_source_symtab); + filename = symtab_to_filename_for_display (si.current_source_symtab); perror_with_name (filename); } } @@ -1974,7 +2017,6 @@ _initialize_source (void) { struct cmd_list_element *c; - current_source_symtab = 0; init_source_path (); /* The intention is to use POSIX Basic Regular Expressions. diff --git a/gdb/top.c b/gdb/top.c index f006c66..3919203 100644 --- a/gdb/top.c +++ b/gdb/top.c @@ -132,10 +132,6 @@ show_confirm (struct ui_file *file, int from_tty, 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 affects things like recording into the command history, commands 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_) : next (nullptr), num (++highest_ui_num), + saved_command_line (xstrdup ("")), call_readline (nullptr), input_handler (nullptr), command_editing (0), @@ -301,6 +298,10 @@ ui::~ui () else 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_stdout; 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 lines won't repeat here in any case. */ 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 @@ -1659,11 +1663,33 @@ dont_repeat_command (char *ignored, int from_tty) { /* Can't call dont_repeat here because we're not necessarily reading 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. */ +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. */ #define Hist_print 10 void @@ -1672,9 +1698,7 @@ show_commands (char *args, int from_tty) /* Index for history commands. Relative to history_base. */ int offset; - /* Number of the history entry which we are planning to display next. - Relative to history_base. */ - static int num = 0; + current_top_info &ci = get_current_top_info (); /* Print out some of the commands from the command history. */ @@ -1685,28 +1709,28 @@ show_commands (char *args, int from_tty) ; else /* "info editing " should print around command number . */ - 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. */ else { - num = history_length - Hist_print; + ci.num = history_length - Hist_print; } - if (num < 0) - num = 0; + if (ci.num < 0) + ci.num = 0; /* If there are at least Hist_print commands, we want to display the last 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; - if (num < 0) - num = 0; + ci.num = history_length - Hist_print; + if (ci.num < 0) + ci.num = 0; } - for (offset = num; - offset < num + Hist_print && offset < history_length; + for (offset = ci.num; + offset < ci.num + Hist_print && offset < history_length; 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 displayed yet. */ - num += Hist_print; + ci.num += Hist_print; /* If the user repeats this command with return, it should do what "show commands +" does. This is unnecessary if arg is null, diff --git a/gdb/top.h b/gdb/top.h index ab65ddb..94822772 100644 --- a/gdb/top.h +++ b/gdb/top.h @@ -71,6 +71,10 @@ struct ui input until we have a whole command line. */ 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 on the UI's input file descriptor. This function incrementally builds a buffer where it accumulates the line read up to the @@ -130,6 +134,15 @@ struct ui /* See enum prompt_state's description. */ 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 meant to be accessed through wrapper macros that make them look 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); /* From top.c. */ -extern char *saved_command_line; extern int confirm; extern int inhibit_gdbinit; extern const char gdbinit[]; @@ -234,6 +246,11 @@ extern void quit_command (char *, int); extern void quit_cover (void); 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 list, running command hooks or similars), and we just ran a synchronous command that started the target, wait for that command