mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-23 18:14:13 +08:00
Eliminate make_cleanup_ui_file_delete / make ui_file a class hierarchy
This patch starts from the desire to eliminate make_cleanup_ui_file_delete, but then goes beyond. It makes ui_file & friends a real C++ class hierarchy, and switches temporary ui_file-like objects to stack-based allocation. - mem_fileopen -> string_file mem_fileopen is replaced with a new string_file class that is treated as a value class created on the stack. This alone eliminates most make_cleanup_ui_file_delete calls, and, simplifies code a whole lot (diffstat shows around 1k loc dropped.) string_file's internal buffer is a std::string, thus the "string" in the name. This simplifies the implementation much, compared to mem_fileopen, which managed growing its internal buffer manually. - ui_file_as_string, ui_file_strdup, ui_file_obsavestring all gone The new string_file class has a string() method that provides direct writable access to the internal std::string buffer. This replaced ui_file_as_string, which forced a copy of the same data the stream had inside. With direct access via a writable reference, we can instead move the string out of the string_stream, avoiding deep string copying. Related, ui_file_xstrdup calls are replaced with xstrdup'ping the stream's string, and ui_file_obsavestring is replaced by obstack_copy0. With all those out of the way, getting rid of the weird ui_file_put mechanism was possible. - New ui_file::printf, ui_file::puts, etc. methods These simplify / clarify client code. I considered splitting client-code changes, like these, e.g.: - stb = mem_fileopen (); - fprintf_unfiltered (stb, "%s%s%s", - _("The valid values are:\n"), - regdesc, - _("The default is \"std\".")); + string_file stb; + stb.printf ("%s%s%s", + _("The valid values are:\n"), + regdesc, + _("The default is \"std\".")); In two steps, with the first step leaving fprintf_unfiltered (etc.) calls in place, and only afterwards do a pass to change all those to call stb.printf etc.. I didn't do that split, because (when I tried), it turned out to be pointless make-work: the first pass would have to touch the fprintf_unfiltered line anyway, to replace "stb" with "&stb". - gdb_fopen replaced with stack-based objects This avoids the need for cleanups or unique_ptr's. I.e., this: struct ui_file *file = gdb_fopen (filename, "w"); if (filename == NULL) perror_with_name (filename); cleanups = make_cleanup_ui_file_delete (file); // use file. do_cleanups (cleanups); is replaced with this: stdio_file file; if (!file.open (filename, "w")) perror_with_name (filename); // use file. - odd contorsions in null_file_write / null_file_fputs around when to call to_fputs / to_write eliminated. - Global null_stream object A few places that were allocating a ui_file in order to print to "nowhere" are adjusted to instead refer to a new 'null_stream' global stream. - TUI's tui_sfileopen eliminated. TUI's ui_file much simplified The TUI's ui_file was serving a dual purpose. It supported being used as string buffer, and supported being backed by a stdio FILE. The string buffer part is gone, replaced by using of string_file. The 'FILE *' support is now much simplified, by making the TUI's ui_file inherit from stdio_file. gdb/ChangeLog: 2017-02-02 Pedro Alves <palves@redhat.com> * ada-lang.c (type_as_string): Use string_file. * ada-valprint.c (ada_print_floating): Use string_file. * ada-varobj.c (ada_varobj_scalar_image) (ada_varobj_get_value_image): Use string_file. * aix-thread.c (aix_thread_extra_thread_info): Use string_file. * arm-tdep.c (_initialize_arm_tdep): Use string_printf. * breakpoint.c (update_inserted_breakpoint_locations) (insert_breakpoint_locations, reattach_breakpoints) (print_breakpoint_location, print_one_detail_ranged_breakpoint) (print_it_watchpoint): Use string_file. (save_breakpoints): Use stdio_file. * c-exp.y (oper): Use string_file. * cli/cli-logging.c (set_logging_redirect): Use ui_file_up and tee_file. (pop_output_files): Use delete. (handle_redirections): Use stdio_file and tee_file. * cli/cli-setshow.c (do_show_command): Use string_file. * compile/compile-c-support.c (c_compute_program): Use string_file. * compile/compile-c-symbols.c (generate_vla_size): Take a 'string_file &' instead of a 'ui_file *'. (generate_c_for_for_one_variable): Take a 'string_file &' instead of a 'ui_file *'. Use string_file. (generate_c_for_variable_locations): Take a 'string_file &' instead of a 'ui_file *'. * compile/compile-internal.h (generate_c_for_for_one_variable): Take a 'string_file &' instead of a 'ui_file *'. * compile/compile-loc2c.c (push, pushf, unary, binary) (print_label, pushf_register_address, pushf_register) (do_compile_dwarf_expr_to_c): Take a 'string_file &' instead of a 'ui_file *'. Adjust. * compile/compile.c (compile_to_object): Use string_file. * compile/compile.h (compile_dwarf_expr_to_c) (compile_dwarf_bounds_to_c): Take a 'string_file &' instead of a 'ui_file *'. * cp-support.c (inspect_type): Use string_file and obstack_copy0. (replace_typedefs_qualified_name): Use string_file and obstack_copy0. * disasm.c (gdb_pretty_print_insn): Use string_file. (gdb_disassembly): Adjust reference the null_stream global. (do_ui_file_delete): Delete. (gdb_insn_length): Use null_stream. * dummy-frame.c (maintenance_print_dummy_frames): Use stdio_file. * dwarf2loc.c (dwarf2_compile_property_to_c) (locexpr_generate_c_location, loclist_generate_c_location): Take a 'string_file &' instead of a 'ui_file *'. * dwarf2loc.h (dwarf2_compile_property_to_c): Likewise. * dwarf2read.c (do_ui_file_peek_last): Delete. (dwarf2_compute_name): Use string_file. * event-top.c (gdb_setup_readline): Use stdio_file. * gdbarch.sh (verify_gdbarch): Use string_file. * gdbtypes.c (safe_parse_type): Use null_stream. * guile/scm-breakpoint.c (gdbscm_breakpoint_commands): Use string_file. * guile/scm-disasm.c (gdbscm_print_insn_from_port): Take a 'string_file *' instead of a 'ui_file *'. (gdbscm_arch_disassemble): Use string_file. * guile/scm-frame.c (frscm_print_frame_smob): Use string_file. * guile/scm-ports.c (class ioscm_file_port): Now a class that inherits from ui_file. (ioscm_file_port_delete, ioscm_file_port_rewind) (ioscm_file_port_put): Delete. (ioscm_file_port_write): Rename to ... (ioscm_file_port::write): ... this. Remove file_port_magic checks. (ioscm_file_port_new): Delete. (ioscm_with_output_to_port_worker): Use ioscm_file_port and ui_file_up. * guile/scm-type.c (tyscm_type_name): Use string_file. * guile/scm-value.c (vlscm_print_value_smob, gdbscm_value_print): Use string_file. * infcmd.c (print_return_value_1): Use string_file. * infrun.c (print_target_wait_results): Use string_file. * language.c (add_language): Use string_file. * location.c (explicit_to_string_internal): Use string_file. * main.c (captured_main_1): Use null_file. * maint.c (maintenance_print_architecture): Use stdio_file. * mi/mi-cmd-stack.c (list_arg_or_local): Use string_file. * mi/mi-common.h (struct mi_interp) <out, err, log, targ, event_channel>: Change type to mi_console_file pointer. * mi/mi-console.c (mi_console_file_fputs, mi_console_file_flush) (mi_console_file_delete): Delete. (struct mi_console_file): Delete. (mi_console_file_magic): Delete. (mi_console_file_new): Delete. (mi_console_file::mi_console_file): New. (mi_console_file_delete): Delete. (mi_console_file_fputs): Delete. (mi_console_file::write): New. (mi_console_raw_packet): Delete. (mi_console_file::flush): New. (mi_console_file_flush): Delete. (mi_console_set_raw): Rename to ... (mi_console_file::set_raw): ... this. * mi/mi-console.h (class mi_console_file): New class. (mi_console_file_new, mi_console_set_raw): Delete. * mi/mi-interp.c (mi_interpreter_init): Use mi_console_file. (mi_set_logging): Use delete and tee_file. Adjust. * mi/mi-main.c (output_register): Use string_file. (mi_cmd_data_evaluate_expression): Use string_file. (mi_cmd_data_read_memory): Use string_file. (mi_cmd_execute, print_variable_or_computed): Use string_file. * mi/mi-out.c (mi_ui_out::main_stream): New. (mi_ui_out::rewind): Use main_stream and string_file. (mi_ui_out::put): Use main_stream and string_file. (mi_ui_out::mi_ui_out): Remove 'stream' parameter. Allocate a 'string_file' instead. (mi_out_new): Don't allocate a mem_fileopen stream here. * mi/mi-out.h (mi_ui_out::mi_ui_out): Remove 'stream' parameter. (mi_ui_out::main_stream): Declare method. * printcmd.c (eval_command): Use string_file. * psymtab.c (maintenance_print_psymbols): Use stdio_file. * python/py-arch.c (archpy_disassemble): Use string_file. * python/py-breakpoint.c (bppy_get_commands): Use string_file. * python/py-frame.c (frapy_str): Use string_file. * python/py-framefilter.c (py_print_type, py_print_single_arg): Use string_file. * python/py-type.c (typy_str): Use string_file. * python/py-unwind.c (unwind_infopy_str): Use string_file. * python/py-value.c (valpy_str): Use string_file. * record-btrace.c (btrace_insn_history): Use string_file. * regcache.c (regcache_print): Use stdio_file. * reggroups.c (maintenance_print_reggroups): Use stdio_file. * remote.c (escape_buffer): Use string_file. * rust-lang.c (rust_get_disr_info): Use string_file. * serial.c (serial_open_ops_1): Use stdio_file. (do_serial_close): Use delete. * stack.c (print_frame_arg): Use string_file. (print_frame_args): Remove local mem_fileopen stream, not used. (print_frame): Use string_file. * symmisc.c (maintenance_print_symbols): Use stdio_file. * symtab.h (struct symbol_computed_ops) <generate_c_location>: Take a 'string_file *' instead of a 'ui_file *'. * top.c (new_ui): Use stdio_file and stderr_file. (free_ui): Use delete. (execute_command_to_string): Use string_file. (quit_confirm): Use string_file. * tracepoint.c (collection_list::append_exp): Use string_file. * tui/tui-disasm.c (tui_disassemble): Use string_file. * tui/tui-file.c: Don't include "ui-file.h". (enum streamtype, struct tui_stream): Delete. (tui_file_new, tui_file_delete, tui_fileopen, tui_sfileopen) (tui_file_isatty, tui_file_rewind, tui_file_put): Delete. (tui_file::tui_file): New method. (tui_file_fputs): Delete. (tui_file_get_strbuf): Delete. (tui_file::puts): New method. (tui_file_adjust_strbuf): Delete. (tui_file_flush): Delete. (tui_file::flush): New method. * tui/tui-file.h: Tweak intro comment. Include ui-file.h. (tui_fileopen, tui_sfileopen, tui_file_get_strbuf) (tui_file_adjust_strbuf): Delete declarations. (class tui_file): New class. * tui/tui-io.c (tui_initialize_io): Use tui_file. * tui/tui-regs.c (tui_restore_gdbout): Use delete. (tui_register_format): Use string_stream. * tui/tui-stack.c (tui_make_status_line): Use string_file. (tui_get_function_from_frame): Use string_file. * typeprint.c (type_to_string): Use string_file. * ui-file.c (struct ui_file, ui_file_magic, ui_file_new): Delete. (null_stream): New global. (ui_file_delete): Delete. (ui_file::ui_file): New. (null_file_isatty): Delete. (ui_file::~ui_file): New. (null_file_rewind): Delete. (ui_file::printf): New. (null_file_put): Delete. (null_file_flush): Delete. (ui_file::putstr): New. (null_file_write): Delete. (ui_file::putstrn): New. (null_file_read): Delete. (ui_file::putc): New. (null_file_fputs): Delete. (null_file_write_async_safe): Delete. (ui_file::vprintf): New. (null_file_delete): Delete. (null_file::write): New. (null_file_fseek): Delete. (null_file::puts): New. (ui_file_data): Delete. (null_file::write_async_safe): New. (gdb_flush, ui_file_isatty): Adjust. (ui_file_put, ui_file_rewind): Delete. (ui_file_write): Adjust. (ui_file_write_for_put): Delete. (ui_file_write_async_safe, ui_file_read): Adjust. (ui_file_fseek): Delete. (fputs_unfiltered): Adjust. (set_ui_file_flush, set_ui_file_isatty, set_ui_file_rewind) (set_ui_file_put, set_ui_file_write, set_ui_file_write_async_safe) (set_ui_file_read, set_ui_file_fputs, set_ui_file_fseek) (set_ui_file_data): Delete. (string_file::~string_file, string_file::write) (struct accumulated_ui_file, do_ui_file_xstrdup, ui_file_xstrdup) (do_ui_file_as_string, ui_file_as_string): Delete. (do_ui_file_obsavestring, ui_file_obsavestring): Delete. (struct mem_file): Delete. (mem_file_new): Delete. (stdio_file::stdio_file): New. (mem_file_delete): Delete. (stdio_file::stdio_file): New. (mem_fileopen): Delete. (stdio_file::~stdio_file): New. (mem_file_rewind): Delete. (stdio_file::set_stream): New. (mem_file_put): Delete. (stdio_file::open): New. (mem_file_write): Delete. (stdio_file_magic, struct stdio_file): Delete. (stdio_file_new, stdio_file_delete, stdio_file_flush): Delete. (stdio_file::flush): New. (stdio_file_read): Rename to ... (stdio_file::read): ... this. Adjust. (stdio_file_write): Rename to ... (stdio_file::write): ... this. Adjust. (stdio_file_write_async_safe): Rename to ... (stdio_file::write_async_safe) ... this. Adjust. (stdio_file_fputs): Rename to ... (stdio_file::puts) ... this. Adjust. (stdio_file_isatty): Delete. (stdio_file_fseek): Delete. (stdio_file::isatty): New. (stderr_file_write): Rename to ... (stderr_file::write) ... this. Adjust. (stderr_file_fputs): Rename to ... (stderr_file::puts) ... this. Adjust. (stderr_fileopen, stdio_fileopen, gdb_fopen): Delete. (stderr_file::stderr_file): New. (tee_file_magic): Delete. (struct tee_file): Delete. (tee_file::tee_file): New. (tee_file_new): Delete. (tee_file::~tee_file): New. (tee_file_delete): Delete. (tee_file_flush): Rename to ... (tee_file::flush): ... this. Adjust. (tee_file_write): Rename to ... (tee_file::write): ... this. Adjust. (tee_file::write_async_safe): New. (tee_file_fputs): Rename to ... (tee_file::puts): ... this. Adjust. (tee_file_isatty): Rename to ... (tee_file::isatty): ... this. Adjust. * ui-file.h (struct obstack, struct ui_file): Don't forward-declare. (ui_file_new, ui_file_flush_ftype, set_ui_file_flush) (ui_file_write_ftype) (set_ui_file_write, ui_file_fputs_ftype, set_ui_file_fputs) (ui_file_write_async_safe_ftype, set_ui_file_write_async_safe) (ui_file_read_ftype, set_ui_file_read, ui_file_isatty_ftype) (set_ui_file_isatty, ui_file_rewind_ftype, set_ui_file_rewind) (ui_file_put_method_ftype, ui_file_put_ftype, set_ui_file_put) (ui_file_delete_ftype, set_ui_file_data, ui_file_fseek_ftype) (set_ui_file_fseek): Delete. (ui_file_data, ui_file_delete, ui_file_rewind) (struct ui_file): New. (ui_file_up): New. (class null_file): New. (null_stream): Declare. (ui_file_write_for_put, ui_file_put): Delete. (ui_file_xstrdup, ui_file_as_string, ui_file_obsavestring): Delete. (ui_file_fseek, mem_fileopen, stdio_fileopen, stderr_fileopen) (gdb_fopen, tee_file_new): Delete. (struct string_file): New. (struct stdio_file): New. (stdio_file_up): New. (struct stderr_file): New. (class tee_file): New. * ui-out.c (ui_out::field_stream): Take a 'string_file &' instead of a 'ui_file *'. Adjust. * ui-out.h (class ui_out) <field_stream>: Likewise. * utils.c (do_ui_file_delete, make_cleanup_ui_file_delete) (null_stream): Delete. (error_stream): Take a 'string_file &' instead of a 'ui_file *'. Adjust. * utils.h (struct ui_file): Delete forward declaration.. (make_cleanup_ui_file_delete, null_stream): Delete declarations. (error_stream): Take a 'string_file &' instead of a 'ui_file *'. * varobj.c (varobj_value_get_print_value): Use string_file. * xtensa-tdep.c (xtensa_verify_config): Use string_file. * gdbarch.c: Regenerate.
This commit is contained in:
parent
187808b04f
commit
d7e747318f
291
gdb/ChangeLog
291
gdb/ChangeLog
@ -1,3 +1,294 @@
|
||||
2017-02-02 Pedro Alves <palves@redhat.com>
|
||||
|
||||
* ada-lang.c (type_as_string): Use string_file.
|
||||
* ada-valprint.c (ada_print_floating): Use string_file.
|
||||
* ada-varobj.c (ada_varobj_scalar_image)
|
||||
(ada_varobj_get_value_image): Use string_file.
|
||||
* aix-thread.c (aix_thread_extra_thread_info): Use string_file.
|
||||
* arm-tdep.c (_initialize_arm_tdep): Use string_printf.
|
||||
* breakpoint.c (update_inserted_breakpoint_locations)
|
||||
(insert_breakpoint_locations, reattach_breakpoints)
|
||||
(print_breakpoint_location, print_one_detail_ranged_breakpoint)
|
||||
(print_it_watchpoint): Use string_file.
|
||||
(save_breakpoints): Use stdio_file.
|
||||
* c-exp.y (oper): Use string_file.
|
||||
* cli/cli-logging.c (set_logging_redirect): Use ui_file_up and
|
||||
tee_file.
|
||||
(pop_output_files): Use delete.
|
||||
(handle_redirections): Use stdio_file and tee_file.
|
||||
* cli/cli-setshow.c (do_show_command): Use string_file.
|
||||
* compile/compile-c-support.c (c_compute_program): Use
|
||||
string_file.
|
||||
* compile/compile-c-symbols.c (generate_vla_size): Take a
|
||||
'string_file &' instead of a 'ui_file *'.
|
||||
(generate_c_for_for_one_variable): Take a 'string_file &' instead
|
||||
of a 'ui_file *'. Use string_file.
|
||||
(generate_c_for_variable_locations): Take a 'string_file &'
|
||||
instead of a 'ui_file *'.
|
||||
* compile/compile-internal.h (generate_c_for_for_one_variable):
|
||||
Take a 'string_file &' instead of a 'ui_file *'.
|
||||
* compile/compile-loc2c.c (push, pushf, unary, binary)
|
||||
(print_label, pushf_register_address, pushf_register)
|
||||
(do_compile_dwarf_expr_to_c): Take a 'string_file &' instead of a
|
||||
'ui_file *'. Adjust.
|
||||
* compile/compile.c (compile_to_object): Use string_file.
|
||||
* compile/compile.h (compile_dwarf_expr_to_c)
|
||||
(compile_dwarf_bounds_to_c): Take a 'string_file &' instead of a
|
||||
'ui_file *'.
|
||||
* cp-support.c (inspect_type): Use string_file and obstack_copy0.
|
||||
(replace_typedefs_qualified_name): Use string_file and
|
||||
obstack_copy0.
|
||||
* disasm.c (gdb_pretty_print_insn): Use string_file.
|
||||
(gdb_disassembly): Adjust reference the null_stream global.
|
||||
(do_ui_file_delete): Delete.
|
||||
(gdb_insn_length): Use null_stream.
|
||||
* dummy-frame.c (maintenance_print_dummy_frames): Use stdio_file.
|
||||
* dwarf2loc.c (dwarf2_compile_property_to_c)
|
||||
(locexpr_generate_c_location, loclist_generate_c_location): Take a
|
||||
'string_file &' instead of a 'ui_file *'.
|
||||
* dwarf2loc.h (dwarf2_compile_property_to_c): Likewise.
|
||||
* dwarf2read.c (do_ui_file_peek_last): Delete.
|
||||
(dwarf2_compute_name): Use string_file.
|
||||
* event-top.c (gdb_setup_readline): Use stdio_file.
|
||||
* gdbarch.sh (verify_gdbarch): Use string_file.
|
||||
* gdbtypes.c (safe_parse_type): Use null_stream.
|
||||
* guile/scm-breakpoint.c (gdbscm_breakpoint_commands): Use
|
||||
string_file.
|
||||
* guile/scm-disasm.c (gdbscm_print_insn_from_port): Take a
|
||||
'string_file *' instead of a 'ui_file *'.
|
||||
(gdbscm_arch_disassemble): Use string_file.
|
||||
* guile/scm-frame.c (frscm_print_frame_smob): Use string_file.
|
||||
* guile/scm-ports.c (class ioscm_file_port): Now a class that
|
||||
inherits from ui_file.
|
||||
(ioscm_file_port_delete, ioscm_file_port_rewind)
|
||||
(ioscm_file_port_put): Delete.
|
||||
(ioscm_file_port_write): Rename to ...
|
||||
(ioscm_file_port::write): ... this. Remove file_port_magic
|
||||
checks.
|
||||
(ioscm_file_port_new): Delete.
|
||||
(ioscm_with_output_to_port_worker): Use ioscm_file_port and
|
||||
ui_file_up.
|
||||
* guile/scm-type.c (tyscm_type_name): Use string_file.
|
||||
* guile/scm-value.c (vlscm_print_value_smob, gdbscm_value_print):
|
||||
Use string_file.
|
||||
* infcmd.c (print_return_value_1): Use string_file.
|
||||
* infrun.c (print_target_wait_results): Use string_file.
|
||||
* language.c (add_language): Use string_file.
|
||||
* location.c (explicit_to_string_internal): Use string_file.
|
||||
* main.c (captured_main_1): Use null_file.
|
||||
* maint.c (maintenance_print_architecture): Use stdio_file.
|
||||
* mi/mi-cmd-stack.c (list_arg_or_local): Use string_file.
|
||||
* mi/mi-common.h (struct mi_interp) <out, err, log, targ,
|
||||
event_channel>: Change type to mi_console_file pointer.
|
||||
* mi/mi-console.c (mi_console_file_fputs, mi_console_file_flush)
|
||||
(mi_console_file_delete): Delete.
|
||||
(struct mi_console_file): Delete.
|
||||
(mi_console_file_magic): Delete.
|
||||
(mi_console_file_new): Delete.
|
||||
(mi_console_file::mi_console_file): New.
|
||||
(mi_console_file_delete): Delete.
|
||||
(mi_console_file_fputs): Delete.
|
||||
(mi_console_file::write): New.
|
||||
(mi_console_raw_packet): Delete.
|
||||
(mi_console_file::flush): New.
|
||||
(mi_console_file_flush): Delete.
|
||||
(mi_console_set_raw): Rename to ...
|
||||
(mi_console_file::set_raw): ... this.
|
||||
* mi/mi-console.h (class mi_console_file): New class.
|
||||
(mi_console_file_new, mi_console_set_raw): Delete.
|
||||
* mi/mi-interp.c (mi_interpreter_init): Use mi_console_file.
|
||||
(mi_set_logging): Use delete and tee_file. Adjust.
|
||||
* mi/mi-main.c (output_register): Use string_file.
|
||||
(mi_cmd_data_evaluate_expression): Use string_file.
|
||||
(mi_cmd_data_read_memory): Use string_file.
|
||||
(mi_cmd_execute, print_variable_or_computed): Use string_file.
|
||||
* mi/mi-out.c (mi_ui_out::main_stream): New.
|
||||
(mi_ui_out::rewind): Use main_stream and
|
||||
string_file.
|
||||
(mi_ui_out::put): Use main_stream and string_file.
|
||||
(mi_ui_out::mi_ui_out): Remove 'stream' parameter.
|
||||
Allocate a 'string_file' instead.
|
||||
(mi_out_new): Don't allocate a mem_fileopen stream here.
|
||||
* mi/mi-out.h (mi_ui_out::mi_ui_out): Remove 'stream' parameter.
|
||||
(mi_ui_out::main_stream): Declare method.
|
||||
* printcmd.c (eval_command): Use string_file.
|
||||
* psymtab.c (maintenance_print_psymbols): Use stdio_file.
|
||||
* python/py-arch.c (archpy_disassemble): Use string_file.
|
||||
* python/py-breakpoint.c (bppy_get_commands): Use string_file.
|
||||
* python/py-frame.c (frapy_str): Use string_file.
|
||||
* python/py-framefilter.c (py_print_type, py_print_single_arg):
|
||||
Use string_file.
|
||||
* python/py-type.c (typy_str): Use string_file.
|
||||
* python/py-unwind.c (unwind_infopy_str): Use string_file.
|
||||
* python/py-value.c (valpy_str): Use string_file.
|
||||
* record-btrace.c (btrace_insn_history): Use string_file.
|
||||
* regcache.c (regcache_print): Use stdio_file.
|
||||
* reggroups.c (maintenance_print_reggroups): Use stdio_file.
|
||||
* remote.c (escape_buffer): Use string_file.
|
||||
* rust-lang.c (rust_get_disr_info): Use string_file.
|
||||
* serial.c (serial_open_ops_1): Use stdio_file.
|
||||
(do_serial_close): Use delete.
|
||||
* stack.c (print_frame_arg): Use string_file.
|
||||
(print_frame_args): Remove local mem_fileopen stream, not used.
|
||||
(print_frame): Use string_file.
|
||||
* symmisc.c (maintenance_print_symbols): Use stdio_file.
|
||||
* symtab.h (struct symbol_computed_ops) <generate_c_location>:
|
||||
Take a 'string_file *' instead of a 'ui_file *'.
|
||||
* top.c (new_ui): Use stdio_file and stderr_file.
|
||||
(free_ui): Use delete.
|
||||
(execute_command_to_string): Use string_file.
|
||||
(quit_confirm): Use string_file.
|
||||
* tracepoint.c (collection_list::append_exp): Use string_file.
|
||||
* tui/tui-disasm.c (tui_disassemble): Use string_file.
|
||||
* tui/tui-file.c: Don't include "ui-file.h".
|
||||
(enum streamtype, struct tui_stream): Delete.
|
||||
(tui_file_new, tui_file_delete, tui_fileopen, tui_sfileopen)
|
||||
(tui_file_isatty, tui_file_rewind, tui_file_put): Delete.
|
||||
(tui_file::tui_file): New method.
|
||||
(tui_file_fputs): Delete.
|
||||
(tui_file_get_strbuf): Delete.
|
||||
(tui_file::puts): New method.
|
||||
(tui_file_adjust_strbuf): Delete.
|
||||
(tui_file_flush): Delete.
|
||||
(tui_file::flush): New method.
|
||||
* tui/tui-file.h: Tweak intro comment.
|
||||
Include ui-file.h.
|
||||
(tui_fileopen, tui_sfileopen, tui_file_get_strbuf)
|
||||
(tui_file_adjust_strbuf): Delete declarations.
|
||||
(class tui_file): New class.
|
||||
* tui/tui-io.c (tui_initialize_io): Use tui_file.
|
||||
* tui/tui-regs.c (tui_restore_gdbout): Use delete.
|
||||
(tui_register_format): Use string_stream.
|
||||
* tui/tui-stack.c (tui_make_status_line): Use string_file.
|
||||
(tui_get_function_from_frame): Use string_file.
|
||||
* typeprint.c (type_to_string): Use string_file.
|
||||
* ui-file.c (struct ui_file, ui_file_magic, ui_file_new): Delete.
|
||||
(null_stream): New global.
|
||||
(ui_file_delete): Delete.
|
||||
(ui_file::ui_file): New.
|
||||
(null_file_isatty): Delete.
|
||||
(ui_file::~ui_file): New.
|
||||
(null_file_rewind): Delete.
|
||||
(ui_file::printf): New.
|
||||
(null_file_put): Delete.
|
||||
(null_file_flush): Delete.
|
||||
(ui_file::putstr): New.
|
||||
(null_file_write): Delete.
|
||||
(ui_file::putstrn): New.
|
||||
(null_file_read): Delete.
|
||||
(ui_file::putc): New.
|
||||
(null_file_fputs): Delete.
|
||||
(null_file_write_async_safe): Delete.
|
||||
(ui_file::vprintf): New.
|
||||
(null_file_delete): Delete.
|
||||
(null_file::write): New.
|
||||
(null_file_fseek): Delete.
|
||||
(null_file::puts): New.
|
||||
(ui_file_data): Delete.
|
||||
(null_file::write_async_safe): New.
|
||||
(gdb_flush, ui_file_isatty): Adjust.
|
||||
(ui_file_put, ui_file_rewind): Delete.
|
||||
(ui_file_write): Adjust.
|
||||
(ui_file_write_for_put): Delete.
|
||||
(ui_file_write_async_safe, ui_file_read): Adjust.
|
||||
(ui_file_fseek): Delete.
|
||||
(fputs_unfiltered): Adjust.
|
||||
(set_ui_file_flush, set_ui_file_isatty, set_ui_file_rewind)
|
||||
(set_ui_file_put, set_ui_file_write, set_ui_file_write_async_safe)
|
||||
(set_ui_file_read, set_ui_file_fputs, set_ui_file_fseek)
|
||||
(set_ui_file_data): Delete.
|
||||
(string_file::~string_file, string_file::write)
|
||||
(struct accumulated_ui_file, do_ui_file_xstrdup, ui_file_xstrdup)
|
||||
(do_ui_file_as_string, ui_file_as_string): Delete.
|
||||
(do_ui_file_obsavestring, ui_file_obsavestring): Delete.
|
||||
(struct mem_file): Delete.
|
||||
(mem_file_new): Delete.
|
||||
(stdio_file::stdio_file): New.
|
||||
(mem_file_delete): Delete.
|
||||
(stdio_file::stdio_file): New.
|
||||
(mem_fileopen): Delete.
|
||||
(stdio_file::~stdio_file): New.
|
||||
(mem_file_rewind): Delete.
|
||||
(stdio_file::set_stream): New.
|
||||
(mem_file_put): Delete.
|
||||
(stdio_file::open): New.
|
||||
(mem_file_write): Delete.
|
||||
(stdio_file_magic, struct stdio_file): Delete.
|
||||
(stdio_file_new, stdio_file_delete, stdio_file_flush): Delete.
|
||||
(stdio_file::flush): New.
|
||||
(stdio_file_read): Rename to ...
|
||||
(stdio_file::read): ... this. Adjust.
|
||||
(stdio_file_write): Rename to ...
|
||||
(stdio_file::write): ... this. Adjust.
|
||||
(stdio_file_write_async_safe): Rename to ...
|
||||
(stdio_file::write_async_safe) ... this. Adjust.
|
||||
(stdio_file_fputs): Rename to ...
|
||||
(stdio_file::puts) ... this. Adjust.
|
||||
(stdio_file_isatty): Delete.
|
||||
(stdio_file_fseek): Delete.
|
||||
(stdio_file::isatty): New.
|
||||
(stderr_file_write): Rename to ...
|
||||
(stderr_file::write) ... this. Adjust.
|
||||
(stderr_file_fputs): Rename to ...
|
||||
(stderr_file::puts) ... this. Adjust.
|
||||
(stderr_fileopen, stdio_fileopen, gdb_fopen): Delete.
|
||||
(stderr_file::stderr_file): New.
|
||||
(tee_file_magic): Delete.
|
||||
(struct tee_file): Delete.
|
||||
(tee_file::tee_file): New.
|
||||
(tee_file_new): Delete.
|
||||
(tee_file::~tee_file): New.
|
||||
(tee_file_delete): Delete.
|
||||
(tee_file_flush): Rename to ...
|
||||
(tee_file::flush): ... this. Adjust.
|
||||
(tee_file_write): Rename to ...
|
||||
(tee_file::write): ... this. Adjust.
|
||||
(tee_file::write_async_safe): New.
|
||||
(tee_file_fputs): Rename to ...
|
||||
(tee_file::puts): ... this. Adjust.
|
||||
(tee_file_isatty): Rename to ...
|
||||
(tee_file::isatty): ... this. Adjust.
|
||||
* ui-file.h (struct obstack, struct ui_file): Don't
|
||||
forward-declare.
|
||||
(ui_file_new, ui_file_flush_ftype, set_ui_file_flush)
|
||||
(ui_file_write_ftype)
|
||||
(set_ui_file_write, ui_file_fputs_ftype, set_ui_file_fputs)
|
||||
(ui_file_write_async_safe_ftype, set_ui_file_write_async_safe)
|
||||
(ui_file_read_ftype, set_ui_file_read, ui_file_isatty_ftype)
|
||||
(set_ui_file_isatty, ui_file_rewind_ftype, set_ui_file_rewind)
|
||||
(ui_file_put_method_ftype, ui_file_put_ftype, set_ui_file_put)
|
||||
(ui_file_delete_ftype, set_ui_file_data, ui_file_fseek_ftype)
|
||||
(set_ui_file_fseek): Delete.
|
||||
(ui_file_data, ui_file_delete, ui_file_rewind)
|
||||
(struct ui_file): New.
|
||||
(ui_file_up): New.
|
||||
(class null_file): New.
|
||||
(null_stream): Declare.
|
||||
(ui_file_write_for_put, ui_file_put): Delete.
|
||||
(ui_file_xstrdup, ui_file_as_string, ui_file_obsavestring):
|
||||
Delete.
|
||||
(ui_file_fseek, mem_fileopen, stdio_fileopen, stderr_fileopen)
|
||||
(gdb_fopen, tee_file_new): Delete.
|
||||
(struct string_file): New.
|
||||
(struct stdio_file): New.
|
||||
(stdio_file_up): New.
|
||||
(struct stderr_file): New.
|
||||
(class tee_file): New.
|
||||
* ui-out.c (ui_out::field_stream): Take a 'string_file &' instead
|
||||
of a 'ui_file *'. Adjust.
|
||||
* ui-out.h (class ui_out) <field_stream>: Likewise.
|
||||
* utils.c (do_ui_file_delete, make_cleanup_ui_file_delete)
|
||||
(null_stream): Delete.
|
||||
(error_stream): Take a 'string_file &' instead of a 'ui_file *'.
|
||||
Adjust.
|
||||
* utils.h (struct ui_file): Delete forward declaration..
|
||||
(make_cleanup_ui_file_delete, null_stream): Delete declarations.
|
||||
(error_stream): Take a 'string_file &' instead of a
|
||||
'ui_file *'.
|
||||
* varobj.c (varobj_value_get_print_value): Use string_file.
|
||||
* xtensa-tdep.c (xtensa_verify_config): Use string_file.
|
||||
* gdbarch.c: Regenerate.
|
||||
|
||||
2017-02-02 Pedro Alves <palves@redhat.com>
|
||||
|
||||
* disasm.c (gdb_disassembler::pretty_print_insn): Rename to...
|
||||
|
@ -7602,17 +7602,11 @@ ada_value_struct_elt (struct value *arg, char *name, int no_err)
|
||||
static std::string
|
||||
type_as_string (struct type *type)
|
||||
{
|
||||
struct ui_file *tmp_stream = mem_fileopen ();
|
||||
struct cleanup *old_chain;
|
||||
string_file tmp_stream;
|
||||
|
||||
tmp_stream = mem_fileopen ();
|
||||
old_chain = make_cleanup_ui_file_delete (tmp_stream);
|
||||
type_print (type, "", &tmp_stream, -1);
|
||||
|
||||
type_print (type, "", tmp_stream, -1);
|
||||
std::string str = ui_file_as_string (tmp_stream);
|
||||
|
||||
do_cleanups (old_chain);
|
||||
return str;
|
||||
return std::move (tmp_stream.string ());
|
||||
}
|
||||
|
||||
/* Given a type TYPE, look up the type of the component of type named NAME.
|
||||
|
@ -298,12 +298,11 @@ static void
|
||||
ada_print_floating (const gdb_byte *valaddr, struct type *type,
|
||||
struct ui_file *stream)
|
||||
{
|
||||
struct ui_file *tmp_stream = mem_fileopen ();
|
||||
struct cleanup *cleanups = make_cleanup_ui_file_delete (tmp_stream);
|
||||
string_file tmp_stream;
|
||||
|
||||
print_floating (valaddr, type, tmp_stream);
|
||||
print_floating (valaddr, type, &tmp_stream);
|
||||
|
||||
std::string s = ui_file_as_string (tmp_stream);
|
||||
std::string &s = tmp_stream.string ();
|
||||
size_t skip_count = 0;
|
||||
|
||||
/* Modify for Ada rules. */
|
||||
@ -342,8 +341,6 @@ ada_print_floating (const gdb_byte *valaddr, struct type *type,
|
||||
}
|
||||
else
|
||||
fprintf_filtered (stream, "%s", &s[skip_count]);
|
||||
|
||||
do_cleanups (cleanups);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -79,14 +79,10 @@ ada_varobj_decode_var (struct value **value_ptr, struct type **type_ptr)
|
||||
static std::string
|
||||
ada_varobj_scalar_image (struct type *type, LONGEST val)
|
||||
{
|
||||
struct ui_file *buf = mem_fileopen ();
|
||||
struct cleanup *cleanups = make_cleanup_ui_file_delete (buf);
|
||||
string_file buf;
|
||||
|
||||
ada_print_scalar (type, val, buf);
|
||||
std::string result = ui_file_as_string (buf);
|
||||
do_cleanups (cleanups);
|
||||
|
||||
return result;
|
||||
ada_print_scalar (type, val, &buf);
|
||||
return std::move (buf.string ());
|
||||
}
|
||||
|
||||
/* Assuming that the (PARENT_VALUE, PARENT_TYPE) pair designates
|
||||
@ -808,17 +804,10 @@ static std::string
|
||||
ada_varobj_get_value_image (struct value *value,
|
||||
struct value_print_options *opts)
|
||||
{
|
||||
struct ui_file *buffer;
|
||||
struct cleanup *old_chain;
|
||||
string_file buffer;
|
||||
|
||||
buffer = mem_fileopen ();
|
||||
old_chain = make_cleanup_ui_file_delete (buffer);
|
||||
|
||||
common_val_print (value, buffer, 0, opts, current_language);
|
||||
std::string result = ui_file_as_string (buffer);
|
||||
|
||||
do_cleanups (old_chain);
|
||||
return result;
|
||||
common_val_print (value, &buffer, 0, opts, current_language);
|
||||
return std::move (buffer.string ());
|
||||
}
|
||||
|
||||
/* Assuming that the (VALUE, TYPE) pair designates an array varobj,
|
||||
|
@ -1749,7 +1749,6 @@ static char *
|
||||
aix_thread_extra_thread_info (struct target_ops *self,
|
||||
struct thread_info *thread)
|
||||
{
|
||||
struct ui_file *buf;
|
||||
int status;
|
||||
pthdb_pthread_t pdtid;
|
||||
pthdb_tid_t tid;
|
||||
@ -1762,43 +1761,42 @@ aix_thread_extra_thread_info (struct target_ops *self,
|
||||
if (!PD_TID (thread->ptid))
|
||||
return NULL;
|
||||
|
||||
buf = mem_fileopen ();
|
||||
string_file buf;
|
||||
|
||||
pdtid = thread->priv->pdtid;
|
||||
tid = thread->priv->tid;
|
||||
|
||||
if (tid != PTHDB_INVALID_TID)
|
||||
/* i18n: Like "thread-identifier %d, [state] running, suspended" */
|
||||
fprintf_unfiltered (buf, _("tid %d"), (int)tid);
|
||||
buf.printf (_("tid %d"), (int)tid);
|
||||
|
||||
status = pthdb_pthread_state (pd_session, pdtid, &state);
|
||||
if (status != PTHDB_SUCCESS)
|
||||
state = PST_NOTSUP;
|
||||
fprintf_unfiltered (buf, ", %s", state2str (state));
|
||||
buf.printf (", %s", state2str (state));
|
||||
|
||||
status = pthdb_pthread_suspendstate (pd_session, pdtid,
|
||||
&suspendstate);
|
||||
if (status == PTHDB_SUCCESS && suspendstate == PSS_SUSPENDED)
|
||||
/* i18n: Like "Thread-Id %d, [state] running, suspended" */
|
||||
fprintf_unfiltered (buf, _(", suspended"));
|
||||
buf.printf (_(", suspended"));
|
||||
|
||||
status = pthdb_pthread_detachstate (pd_session, pdtid,
|
||||
&detachstate);
|
||||
if (status == PTHDB_SUCCESS && detachstate == PDS_DETACHED)
|
||||
/* i18n: Like "Thread-Id %d, [state] running, detached" */
|
||||
fprintf_unfiltered (buf, _(", detached"));
|
||||
buf.printf (_(", detached"));
|
||||
|
||||
pthdb_pthread_cancelpend (pd_session, pdtid, &cancelpend);
|
||||
if (status == PTHDB_SUCCESS && cancelpend)
|
||||
/* i18n: Like "Thread-Id %d, [state] running, cancel pending" */
|
||||
fprintf_unfiltered (buf, _(", cancel pending"));
|
||||
buf.printf (_(", cancel pending"));
|
||||
|
||||
ui_file_write (buf, "", 1);
|
||||
buf.write ("", 1);
|
||||
|
||||
xfree (ret); /* Free old buffer. */
|
||||
|
||||
ret = ui_file_xstrdup (buf, NULL);
|
||||
ui_file_delete (buf);
|
||||
ret = xstrdup (buf.c_str ());
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -9576,13 +9576,11 @@ extern initialize_file_ftype _initialize_arm_tdep; /* -Wmissing-prototypes */
|
||||
void
|
||||
_initialize_arm_tdep (void)
|
||||
{
|
||||
struct ui_file *stb;
|
||||
long length;
|
||||
const char *setname;
|
||||
const char *setdesc;
|
||||
const char *const *regnames;
|
||||
int i;
|
||||
static std::string helptext;
|
||||
char regdesc[1024], *rdptr = regdesc;
|
||||
size_t rest = sizeof (regdesc);
|
||||
|
||||
@ -9648,13 +9646,10 @@ _initialize_arm_tdep (void)
|
||||
valid_disassembly_styles[num_disassembly_options] = NULL;
|
||||
|
||||
/* Create the help text. */
|
||||
stb = mem_fileopen ();
|
||||
fprintf_unfiltered (stb, "%s%s%s",
|
||||
_("The valid values are:\n"),
|
||||
regdesc,
|
||||
_("The default is \"std\"."));
|
||||
helptext = ui_file_as_string (stb);
|
||||
ui_file_delete (stb);
|
||||
std::string helptext = string_printf ("%s%s%s",
|
||||
_("The valid values are:\n"),
|
||||
regdesc,
|
||||
_("The default is \"std\"."));
|
||||
|
||||
add_setshow_enum_cmd("disassembler", no_class,
|
||||
valid_disassembly_styles, &disassembly_style,
|
||||
|
@ -3061,14 +3061,13 @@ update_inserted_breakpoint_locations (void)
|
||||
int hw_breakpoint_error = 0;
|
||||
int hw_bp_details_reported = 0;
|
||||
|
||||
struct ui_file *tmp_error_stream = mem_fileopen ();
|
||||
struct cleanup *cleanups = make_cleanup_ui_file_delete (tmp_error_stream);
|
||||
string_file tmp_error_stream;
|
||||
|
||||
/* Explicitly mark the warning -- this will only be printed if
|
||||
there was an error. */
|
||||
fprintf_unfiltered (tmp_error_stream, "Warning:\n");
|
||||
tmp_error_stream.puts ("Warning:\n");
|
||||
|
||||
save_current_space_and_thread ();
|
||||
struct cleanup *cleanups = save_current_space_and_thread ();
|
||||
|
||||
ALL_BP_LOCATIONS (bl, blp_tmp)
|
||||
{
|
||||
@ -3093,7 +3092,7 @@ update_inserted_breakpoint_locations (void)
|
||||
&& ptid_equal (inferior_ptid, null_ptid))
|
||||
continue;
|
||||
|
||||
val = insert_bp_location (bl, tmp_error_stream, &disabled_breaks,
|
||||
val = insert_bp_location (bl, &tmp_error_stream, &disabled_breaks,
|
||||
&hw_breakpoint_error, &hw_bp_details_reported);
|
||||
if (val)
|
||||
error_flag = val;
|
||||
@ -3121,14 +3120,13 @@ insert_breakpoint_locations (void)
|
||||
int hw_breakpoint_error = 0;
|
||||
int hw_bp_error_explained_already = 0;
|
||||
|
||||
struct ui_file *tmp_error_stream = mem_fileopen ();
|
||||
struct cleanup *cleanups = make_cleanup_ui_file_delete (tmp_error_stream);
|
||||
|
||||
string_file tmp_error_stream;
|
||||
|
||||
/* Explicitly mark the warning -- this will only be printed if
|
||||
there was an error. */
|
||||
fprintf_unfiltered (tmp_error_stream, "Warning:\n");
|
||||
tmp_error_stream.puts ("Warning:\n");
|
||||
|
||||
save_current_space_and_thread ();
|
||||
struct cleanup *cleanups = save_current_space_and_thread ();
|
||||
|
||||
ALL_BP_LOCATIONS (bl, blp_tmp)
|
||||
{
|
||||
@ -3152,7 +3150,7 @@ insert_breakpoint_locations (void)
|
||||
&& ptid_equal (inferior_ptid, null_ptid))
|
||||
continue;
|
||||
|
||||
val = insert_bp_location (bl, tmp_error_stream, &disabled_breaks,
|
||||
val = insert_bp_location (bl, &tmp_error_stream, &disabled_breaks,
|
||||
&hw_breakpoint_error, &hw_bp_error_explained_already);
|
||||
if (val)
|
||||
error_flag = val;
|
||||
@ -3187,9 +3185,9 @@ insert_breakpoint_locations (void)
|
||||
remove_breakpoint (loc);
|
||||
|
||||
hw_breakpoint_error = 1;
|
||||
fprintf_unfiltered (tmp_error_stream,
|
||||
"Could not insert hardware watchpoint %d.\n",
|
||||
bpt->number);
|
||||
tmp_error_stream.printf ("Could not insert "
|
||||
"hardware watchpoint %d.\n",
|
||||
bpt->number);
|
||||
error_flag = -1;
|
||||
}
|
||||
}
|
||||
@ -3200,8 +3198,7 @@ insert_breakpoint_locations (void)
|
||||
message about possibly exhausted resources. */
|
||||
if (hw_breakpoint_error && !hw_bp_error_explained_already)
|
||||
{
|
||||
fprintf_unfiltered (tmp_error_stream,
|
||||
"Could not insert hardware breakpoints:\n\
|
||||
tmp_error_stream.printf ("Could not insert hardware breakpoints:\n\
|
||||
You may have requested too many hardware breakpoints/watchpoints.\n");
|
||||
}
|
||||
target_terminal_ours_for_output ();
|
||||
@ -3283,7 +3280,6 @@ reattach_breakpoints (int pid)
|
||||
struct cleanup *old_chain;
|
||||
struct bp_location *bl, **blp_tmp;
|
||||
int val;
|
||||
struct ui_file *tmp_error_stream;
|
||||
int dummy1 = 0, dummy2 = 0, dummy3 = 0;
|
||||
struct inferior *inf;
|
||||
struct thread_info *tp;
|
||||
@ -3297,8 +3293,7 @@ reattach_breakpoints (int pid)
|
||||
|
||||
inferior_ptid = tp->ptid;
|
||||
|
||||
tmp_error_stream = mem_fileopen ();
|
||||
make_cleanup_ui_file_delete (tmp_error_stream);
|
||||
string_file tmp_error_stream;
|
||||
|
||||
ALL_BP_LOCATIONS (bl, blp_tmp)
|
||||
{
|
||||
@ -3308,7 +3303,7 @@ reattach_breakpoints (int pid)
|
||||
if (bl->inserted)
|
||||
{
|
||||
bl->inserted = 0;
|
||||
val = insert_bp_location (bl, tmp_error_stream, &dummy1, &dummy2, &dummy3);
|
||||
val = insert_bp_location (bl, &tmp_error_stream, &dummy1, &dummy2, &dummy3);
|
||||
if (val != 0)
|
||||
{
|
||||
do_cleanups (old_chain);
|
||||
@ -6179,14 +6174,11 @@ print_breakpoint_location (struct breakpoint *b,
|
||||
}
|
||||
else if (loc)
|
||||
{
|
||||
struct ui_file *stb = mem_fileopen ();
|
||||
struct cleanup *stb_chain = make_cleanup_ui_file_delete (stb);
|
||||
string_file stb;
|
||||
|
||||
print_address_symbolic (loc->gdbarch, loc->address, stb,
|
||||
print_address_symbolic (loc->gdbarch, loc->address, &stb,
|
||||
demangle, "");
|
||||
uiout->field_stream ("at", stb);
|
||||
|
||||
do_cleanups (stb_chain);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -10293,8 +10285,7 @@ print_one_detail_ranged_breakpoint (const struct breakpoint *b,
|
||||
{
|
||||
CORE_ADDR address_start, address_end;
|
||||
struct bp_location *bl = b->loc;
|
||||
struct ui_file *stb = mem_fileopen ();
|
||||
struct cleanup *cleanup = make_cleanup_ui_file_delete (stb);
|
||||
string_file stb;
|
||||
|
||||
gdb_assert (bl);
|
||||
|
||||
@ -10302,13 +10293,11 @@ print_one_detail_ranged_breakpoint (const struct breakpoint *b,
|
||||
address_end = address_start + bl->length - 1;
|
||||
|
||||
uiout->text ("\taddress range: ");
|
||||
fprintf_unfiltered (stb, "[%s, %s]",
|
||||
print_core_address (bl->gdbarch, address_start),
|
||||
print_core_address (bl->gdbarch, address_end));
|
||||
stb.printf ("[%s, %s]",
|
||||
print_core_address (bl->gdbarch, address_start),
|
||||
print_core_address (bl->gdbarch, address_end));
|
||||
uiout->field_stream ("addr", stb);
|
||||
uiout->text ("\n");
|
||||
|
||||
do_cleanups (cleanup);
|
||||
}
|
||||
|
||||
/* Implement the "print_mention" breakpoint_ops method for
|
||||
@ -10740,7 +10729,6 @@ print_it_watchpoint (bpstat bs)
|
||||
{
|
||||
struct cleanup *old_chain;
|
||||
struct breakpoint *b;
|
||||
struct ui_file *stb;
|
||||
enum print_stop_action result;
|
||||
struct watchpoint *w;
|
||||
struct ui_out *uiout = current_uiout;
|
||||
@ -10750,12 +10738,13 @@ print_it_watchpoint (bpstat bs)
|
||||
b = bs->breakpoint_at;
|
||||
w = (struct watchpoint *) b;
|
||||
|
||||
stb = mem_fileopen ();
|
||||
old_chain = make_cleanup_ui_file_delete (stb);
|
||||
old_chain = make_cleanup (null_cleanup, NULL);
|
||||
|
||||
annotate_watchpoint (b->number);
|
||||
maybe_print_thread_hit_breakpoint (uiout);
|
||||
|
||||
string_file stb;
|
||||
|
||||
switch (b->type)
|
||||
{
|
||||
case bp_watchpoint:
|
||||
@ -10766,10 +10755,10 @@ print_it_watchpoint (bpstat bs)
|
||||
mention (b);
|
||||
make_cleanup_ui_out_tuple_begin_end (uiout, "value");
|
||||
uiout->text ("\nOld value = ");
|
||||
watchpoint_value_print (bs->old_val, stb);
|
||||
watchpoint_value_print (bs->old_val, &stb);
|
||||
uiout->field_stream ("old", stb);
|
||||
uiout->text ("\nNew value = ");
|
||||
watchpoint_value_print (w->val, stb);
|
||||
watchpoint_value_print (w->val, &stb);
|
||||
uiout->field_stream ("new", stb);
|
||||
uiout->text ("\n");
|
||||
/* More than one watchpoint may have been triggered. */
|
||||
@ -10783,7 +10772,7 @@ print_it_watchpoint (bpstat bs)
|
||||
mention (b);
|
||||
make_cleanup_ui_out_tuple_begin_end (uiout, "value");
|
||||
uiout->text ("\nValue = ");
|
||||
watchpoint_value_print (w->val, stb);
|
||||
watchpoint_value_print (w->val, &stb);
|
||||
uiout->field_stream ("value", stb);
|
||||
uiout->text ("\n");
|
||||
result = PRINT_UNKNOWN;
|
||||
@ -10799,7 +10788,7 @@ print_it_watchpoint (bpstat bs)
|
||||
mention (b);
|
||||
make_cleanup_ui_out_tuple_begin_end (uiout, "value");
|
||||
uiout->text ("\nOld value = ");
|
||||
watchpoint_value_print (bs->old_val, stb);
|
||||
watchpoint_value_print (bs->old_val, &stb);
|
||||
uiout->field_stream ("old", stb);
|
||||
uiout->text ("\nNew value = ");
|
||||
}
|
||||
@ -10813,7 +10802,7 @@ print_it_watchpoint (bpstat bs)
|
||||
make_cleanup_ui_out_tuple_begin_end (uiout, "value");
|
||||
uiout->text ("\nValue = ");
|
||||
}
|
||||
watchpoint_value_print (w->val, stb);
|
||||
watchpoint_value_print (w->val, &stb);
|
||||
uiout->field_stream ("new", stb);
|
||||
uiout->text ("\n");
|
||||
result = PRINT_UNKNOWN;
|
||||
@ -15669,7 +15658,6 @@ save_breakpoints (char *filename, int from_tty,
|
||||
struct breakpoint *tp;
|
||||
int any = 0;
|
||||
struct cleanup *cleanup;
|
||||
struct ui_file *fp;
|
||||
int extra_trace_bits = 0;
|
||||
|
||||
if (filename == 0 || *filename == 0)
|
||||
@ -15705,14 +15693,15 @@ save_breakpoints (char *filename, int from_tty,
|
||||
|
||||
filename = tilde_expand (filename);
|
||||
cleanup = make_cleanup (xfree, filename);
|
||||
fp = gdb_fopen (filename, "w");
|
||||
if (!fp)
|
||||
|
||||
stdio_file fp;
|
||||
|
||||
if (!fp.open (filename, "w"))
|
||||
error (_("Unable to open file '%s' for saving (%s)"),
|
||||
filename, safe_strerror (errno));
|
||||
make_cleanup_ui_file_delete (fp);
|
||||
|
||||
if (extra_trace_bits)
|
||||
save_trace_state_variables (fp);
|
||||
save_trace_state_variables (&fp);
|
||||
|
||||
ALL_BREAKPOINTS (tp)
|
||||
{
|
||||
@ -15724,23 +15713,23 @@ save_breakpoints (char *filename, int from_tty,
|
||||
if (filter && !filter (tp))
|
||||
continue;
|
||||
|
||||
tp->ops->print_recreate (tp, fp);
|
||||
tp->ops->print_recreate (tp, &fp);
|
||||
|
||||
/* Note, we can't rely on tp->number for anything, as we can't
|
||||
assume the recreated breakpoint numbers will match. Use $bpnum
|
||||
instead. */
|
||||
|
||||
if (tp->cond_string)
|
||||
fprintf_unfiltered (fp, " condition $bpnum %s\n", tp->cond_string);
|
||||
fp.printf (" condition $bpnum %s\n", tp->cond_string);
|
||||
|
||||
if (tp->ignore_count)
|
||||
fprintf_unfiltered (fp, " ignore $bpnum %d\n", tp->ignore_count);
|
||||
fp.printf (" ignore $bpnum %d\n", tp->ignore_count);
|
||||
|
||||
if (tp->type != bp_dprintf && tp->commands)
|
||||
{
|
||||
fprintf_unfiltered (fp, " commands\n");
|
||||
fp.puts (" commands\n");
|
||||
|
||||
current_uiout->redirect (fp);
|
||||
current_uiout->redirect (&fp);
|
||||
TRY
|
||||
{
|
||||
print_command_lines (current_uiout, tp->commands->commands, 2);
|
||||
@ -15753,11 +15742,11 @@ save_breakpoints (char *filename, int from_tty,
|
||||
END_CATCH
|
||||
|
||||
current_uiout->redirect (NULL);
|
||||
fprintf_unfiltered (fp, " end\n");
|
||||
fp.puts (" end\n");
|
||||
}
|
||||
|
||||
if (tp->enable_state == bp_disabled)
|
||||
fprintf_unfiltered (fp, "disable $bpnum\n");
|
||||
fp.puts ("disable $bpnum\n");
|
||||
|
||||
/* If this is a multi-location breakpoint, check if the locations
|
||||
should be individually disabled. Watchpoint locations are
|
||||
@ -15769,12 +15758,12 @@ save_breakpoints (char *filename, int from_tty,
|
||||
|
||||
for (loc = tp->loc; loc != NULL; loc = loc->next, n++)
|
||||
if (!loc->enabled)
|
||||
fprintf_unfiltered (fp, "disable $bpnum.%d\n", n);
|
||||
fp.printf ("disable $bpnum.%d\n", n);
|
||||
}
|
||||
}
|
||||
|
||||
if (extra_trace_bits && *default_collect)
|
||||
fprintf_unfiltered (fp, "set default-collect %s\n", default_collect);
|
||||
fp.printf ("set default-collect %s\n", default_collect);
|
||||
|
||||
if (from_tty)
|
||||
printf_filtered (_("Saved to file '%s'.\n"), filename);
|
||||
|
@ -1555,13 +1555,11 @@ oper: OPERATOR NEW
|
||||
| OPERATOR OBJC_LBRAC ']'
|
||||
{ $$ = operator_stoken ("[]"); }
|
||||
| OPERATOR conversion_type_id
|
||||
{ struct ui_file *buf = mem_fileopen ();
|
||||
{ string_file buf;
|
||||
|
||||
c_print_type ($2, NULL, buf, -1, 0,
|
||||
c_print_type ($2, NULL, &buf, -1, 0,
|
||||
&type_print_raw_options);
|
||||
std::string name = ui_file_as_string (buf);
|
||||
ui_file_delete (buf);
|
||||
$$ = operator_stoken (name.c_str ());
|
||||
$$ = operator_stoken (buf.c_str ());
|
||||
}
|
||||
;
|
||||
|
||||
|
@ -76,7 +76,7 @@ static struct ui_file *logging_no_redirect_file;
|
||||
static void
|
||||
set_logging_redirect (char *args, int from_tty, struct cmd_list_element *c)
|
||||
{
|
||||
struct cleanup *cleanups;
|
||||
ui_file_up destroy_old_stdout;
|
||||
struct ui_file *output, *new_logging_no_redirect_file;
|
||||
struct ui_out *uiout = current_uiout;
|
||||
|
||||
@ -85,15 +85,13 @@ set_logging_redirect (char *args, int from_tty, struct cmd_list_element *c)
|
||||
|| (logging_redirect == 0 && logging_no_redirect_file != NULL))
|
||||
return;
|
||||
|
||||
cleanups = make_cleanup (null_cleanup, NULL);
|
||||
|
||||
if (logging_redirect != 0)
|
||||
{
|
||||
gdb_assert (logging_no_redirect_file != NULL);
|
||||
|
||||
/* ui_out_redirect still has not been called for next
|
||||
gdb_stdout. */
|
||||
make_cleanup_ui_file_delete (gdb_stdout);
|
||||
destroy_old_stdout.reset (gdb_stdout);
|
||||
|
||||
output = logging_no_redirect_file;
|
||||
new_logging_no_redirect_file = NULL;
|
||||
@ -105,9 +103,7 @@ set_logging_redirect (char *args, int from_tty, struct cmd_list_element *c)
|
||||
else
|
||||
{
|
||||
gdb_assert (logging_no_redirect_file == NULL);
|
||||
output = tee_file_new (saved_output.out, 0, gdb_stdout, 0);
|
||||
if (output == NULL)
|
||||
perror_with_name (_("set logging"));
|
||||
output = new tee_file (saved_output.out, 0, gdb_stdout, 0);
|
||||
new_logging_no_redirect_file = gdb_stdout;
|
||||
|
||||
if (from_tty)
|
||||
@ -135,8 +131,6 @@ set_logging_redirect (char *args, int from_tty, struct cmd_list_element *c)
|
||||
|
||||
uiout->redirect (NULL);
|
||||
uiout->redirect (output);
|
||||
|
||||
do_cleanups (cleanups);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -152,7 +146,7 @@ pop_output_files (void)
|
||||
{
|
||||
if (logging_no_redirect_file)
|
||||
{
|
||||
ui_file_delete (logging_no_redirect_file);
|
||||
delete logging_no_redirect_file;
|
||||
logging_no_redirect_file = NULL;
|
||||
}
|
||||
|
||||
@ -160,7 +154,7 @@ pop_output_files (void)
|
||||
{
|
||||
/* Only delete one of the files -- they are all set to the same
|
||||
value. */
|
||||
ui_file_delete (gdb_stdout);
|
||||
delete gdb_stdout;
|
||||
|
||||
gdb_stdout = saved_output.out;
|
||||
gdb_stderr = saved_output.err;
|
||||
@ -184,9 +178,8 @@ pop_output_files (void)
|
||||
static void
|
||||
handle_redirections (int from_tty)
|
||||
{
|
||||
struct cleanup *cleanups;
|
||||
struct ui_file *output;
|
||||
struct ui_file *no_redirect_file = NULL;
|
||||
ui_file_up output;
|
||||
ui_file_up no_redirect_file;
|
||||
|
||||
if (saved_filename != NULL)
|
||||
{
|
||||
@ -195,36 +188,30 @@ handle_redirections (int from_tty)
|
||||
return;
|
||||
}
|
||||
|
||||
output = gdb_fopen (logging_filename, logging_overwrite ? "w" : "a");
|
||||
if (output == NULL)
|
||||
stdio_file_up log (new stdio_file ());
|
||||
if (!log->open (logging_filename, logging_overwrite ? "w" : "a"))
|
||||
perror_with_name (_("set logging"));
|
||||
cleanups = make_cleanup_ui_file_delete (output);
|
||||
|
||||
/* Redirects everything to gdb_stdout while this is running. */
|
||||
if (!logging_redirect)
|
||||
{
|
||||
no_redirect_file = output;
|
||||
no_redirect_file = std::move (log);
|
||||
output.reset (new tee_file (gdb_stdout, 0, no_redirect_file.get (), 0));
|
||||
|
||||
output = tee_file_new (gdb_stdout, 0, no_redirect_file, 0);
|
||||
if (output == NULL)
|
||||
perror_with_name (_("set logging"));
|
||||
make_cleanup_ui_file_delete (output);
|
||||
if (from_tty)
|
||||
fprintf_unfiltered (gdb_stdout, "Copying output to %s.\n",
|
||||
logging_filename);
|
||||
logging_no_redirect_file = no_redirect_file;
|
||||
}
|
||||
else
|
||||
{
|
||||
gdb_assert (logging_no_redirect_file == NULL);
|
||||
output = std::move (log);
|
||||
|
||||
if (from_tty)
|
||||
fprintf_unfiltered (gdb_stdout, "Redirecting output to %s.\n",
|
||||
logging_filename);
|
||||
}
|
||||
|
||||
discard_cleanups (cleanups);
|
||||
|
||||
saved_filename = xstrdup (logging_filename);
|
||||
saved_output.out = gdb_stdout;
|
||||
saved_output.err = gdb_stderr;
|
||||
@ -233,18 +220,22 @@ handle_redirections (int from_tty)
|
||||
saved_output.targerr = gdb_stdtargerr;
|
||||
|
||||
/* Let the interpreter do anything it needs. */
|
||||
if (current_interp_set_logging (1, output, no_redirect_file) == 0)
|
||||
if (current_interp_set_logging (1, output.get (),
|
||||
no_redirect_file.get ()) == 0)
|
||||
{
|
||||
gdb_stdout = output;
|
||||
gdb_stdlog = output;
|
||||
gdb_stderr = output;
|
||||
gdb_stdtarg = output;
|
||||
gdb_stdtargerr = output;
|
||||
gdb_stdout = output.get ();
|
||||
gdb_stdlog = output.get ();
|
||||
gdb_stderr = output.get ();
|
||||
gdb_stdtarg = output.get ();
|
||||
gdb_stdtargerr = output.get ();
|
||||
}
|
||||
|
||||
output.release ();
|
||||
logging_no_redirect_file = no_redirect_file.release ();
|
||||
|
||||
/* Don't do the redirect for MI, it confuses MI's ui-out scheme. */
|
||||
if (!current_uiout->is_mi_like_p ())
|
||||
current_uiout->redirect (output);
|
||||
current_uiout->redirect (gdb_stdout);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -568,13 +568,10 @@ void
|
||||
do_show_command (const char *arg, int from_tty, struct cmd_list_element *c)
|
||||
{
|
||||
struct ui_out *uiout = current_uiout;
|
||||
struct cleanup *old_chain;
|
||||
struct ui_file *stb;
|
||||
|
||||
gdb_assert (c->type == show_cmd);
|
||||
|
||||
stb = mem_fileopen ();
|
||||
old_chain = make_cleanup_ui_file_delete (stb);
|
||||
string_file stb;
|
||||
|
||||
/* Possibly call the pre hook. */
|
||||
if (c->pre_show_hook)
|
||||
@ -584,29 +581,29 @@ do_show_command (const char *arg, int from_tty, struct cmd_list_element *c)
|
||||
{
|
||||
case var_string:
|
||||
if (*(char **) c->var)
|
||||
fputstr_filtered (*(char **) c->var, '"', stb);
|
||||
stb.putstr (*(char **) c->var, '"');
|
||||
break;
|
||||
case var_string_noescape:
|
||||
case var_optional_filename:
|
||||
case var_filename:
|
||||
case var_enum:
|
||||
if (*(char **) c->var)
|
||||
fputs_filtered (*(char **) c->var, stb);
|
||||
stb.puts (*(char **) c->var);
|
||||
break;
|
||||
case var_boolean:
|
||||
fputs_filtered (*(int *) c->var ? "on" : "off", stb);
|
||||
stb.puts (*(int *) c->var ? "on" : "off");
|
||||
break;
|
||||
case var_auto_boolean:
|
||||
switch (*(enum auto_boolean*) c->var)
|
||||
{
|
||||
case AUTO_BOOLEAN_TRUE:
|
||||
fputs_filtered ("on", stb);
|
||||
stb.puts ("on");
|
||||
break;
|
||||
case AUTO_BOOLEAN_FALSE:
|
||||
fputs_filtered ("off", stb);
|
||||
stb.puts ("off");
|
||||
break;
|
||||
case AUTO_BOOLEAN_AUTO:
|
||||
fputs_filtered ("auto", stb);
|
||||
stb.puts ("auto");
|
||||
break;
|
||||
default:
|
||||
internal_error (__FILE__, __LINE__,
|
||||
@ -619,24 +616,24 @@ do_show_command (const char *arg, int from_tty, struct cmd_list_element *c)
|
||||
case var_zuinteger:
|
||||
if (c->var_type == var_uinteger
|
||||
&& *(unsigned int *) c->var == UINT_MAX)
|
||||
fputs_filtered ("unlimited", stb);
|
||||
stb.puts ("unlimited");
|
||||
else
|
||||
fprintf_filtered (stb, "%u", *(unsigned int *) c->var);
|
||||
stb.printf ("%u", *(unsigned int *) c->var);
|
||||
break;
|
||||
case var_integer:
|
||||
case var_zinteger:
|
||||
if (c->var_type == var_integer
|
||||
&& *(int *) c->var == INT_MAX)
|
||||
fputs_filtered ("unlimited", stb);
|
||||
stb.puts ("unlimited");
|
||||
else
|
||||
fprintf_filtered (stb, "%d", *(int *) c->var);
|
||||
stb.printf ("%d", *(int *) c->var);
|
||||
break;
|
||||
case var_zuinteger_unlimited:
|
||||
{
|
||||
if (*(int *) c->var == -1)
|
||||
fputs_filtered ("unlimited", stb);
|
||||
stb.puts ("unlimited");
|
||||
else
|
||||
fprintf_filtered (stb, "%d", *(int *) c->var);
|
||||
stb.printf ("%d", *(int *) c->var);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -653,14 +650,11 @@ do_show_command (const char *arg, int from_tty, struct cmd_list_element *c)
|
||||
uiout->field_stream ("value", stb);
|
||||
else
|
||||
{
|
||||
std::string value = ui_file_as_string (stb);
|
||||
|
||||
if (c->show_value_func != NULL)
|
||||
c->show_value_func (gdb_stdout, from_tty, c, value.c_str ());
|
||||
c->show_value_func (gdb_stdout, from_tty, c, stb.c_str ());
|
||||
else
|
||||
deprecated_show_value_hack (gdb_stdout, from_tty, c, value.c_str ());
|
||||
deprecated_show_value_hack (gdb_stdout, from_tty, c, stb.c_str ());
|
||||
}
|
||||
do_cleanups (old_chain);
|
||||
|
||||
c->func (c, NULL, from_tty);
|
||||
}
|
||||
|
@ -333,15 +333,12 @@ c_compute_program (struct compile_instance *inst,
|
||||
const struct block *expr_block,
|
||||
CORE_ADDR expr_pc)
|
||||
{
|
||||
struct ui_file *buf, *var_stream = NULL;
|
||||
std::string code;
|
||||
struct cleanup *cleanup;
|
||||
struct compile_c_instance *context = (struct compile_c_instance *) inst;
|
||||
|
||||
buf = mem_fileopen ();
|
||||
cleanup = make_cleanup_ui_file_delete (buf);
|
||||
string_file buf;
|
||||
string_file var_stream;
|
||||
|
||||
write_macro_definitions (expr_block, expr_pc, buf);
|
||||
write_macro_definitions (expr_block, expr_pc, &buf);
|
||||
|
||||
/* Do not generate local variable information for "raw"
|
||||
compilations. In this case we aren't emitting our own function
|
||||
@ -355,21 +352,17 @@ c_compute_program (struct compile_instance *inst,
|
||||
before generating the function header, so we can define the
|
||||
register struct before the function body. This requires a
|
||||
temporary stream. */
|
||||
var_stream = mem_fileopen ();
|
||||
make_cleanup_ui_file_delete (var_stream);
|
||||
registers_used = generate_c_for_variable_locations (context,
|
||||
var_stream, gdbarch,
|
||||
expr_block, expr_pc);
|
||||
make_cleanup (xfree, registers_used);
|
||||
|
||||
fputs_unfiltered ("typedef unsigned int"
|
||||
" __attribute__ ((__mode__(__pointer__)))"
|
||||
" __gdb_uintptr;\n",
|
||||
buf);
|
||||
fputs_unfiltered ("typedef int"
|
||||
" __attribute__ ((__mode__(__pointer__)))"
|
||||
" __gdb_intptr;\n",
|
||||
buf);
|
||||
buf.puts ("typedef unsigned int"
|
||||
" __attribute__ ((__mode__(__pointer__)))"
|
||||
" __gdb_uintptr;\n");
|
||||
buf.puts ("typedef int"
|
||||
" __attribute__ ((__mode__(__pointer__)))"
|
||||
" __gdb_intptr;\n");
|
||||
|
||||
/* Iterate all log2 sizes in bytes supported by c_get_mode_for_size. */
|
||||
for (i = 0; i < 4; ++i)
|
||||
@ -377,24 +370,23 @@ c_compute_program (struct compile_instance *inst,
|
||||
const char *mode = c_get_mode_for_size (1 << i);
|
||||
|
||||
gdb_assert (mode != NULL);
|
||||
fprintf_unfiltered (buf,
|
||||
"typedef int"
|
||||
" __attribute__ ((__mode__(__%s__)))"
|
||||
" __gdb_int_%s;\n",
|
||||
mode, mode);
|
||||
buf.printf ("typedef int"
|
||||
" __attribute__ ((__mode__(__%s__)))"
|
||||
" __gdb_int_%s;\n",
|
||||
mode, mode);
|
||||
}
|
||||
|
||||
generate_register_struct (buf, gdbarch, registers_used);
|
||||
generate_register_struct (&buf, gdbarch, registers_used);
|
||||
}
|
||||
|
||||
add_code_header (inst->scope, buf);
|
||||
add_code_header (inst->scope, &buf);
|
||||
|
||||
if (inst->scope == COMPILE_I_SIMPLE_SCOPE
|
||||
|| inst->scope == COMPILE_I_PRINT_ADDRESS_SCOPE
|
||||
|| inst->scope == COMPILE_I_PRINT_VALUE_SCOPE)
|
||||
{
|
||||
ui_file_put (var_stream, ui_file_write_for_put, buf);
|
||||
fputs_unfiltered ("#pragma GCC user_expression\n", buf);
|
||||
buf.write (var_stream.c_str (), var_stream.size ());
|
||||
buf.puts ("#pragma GCC user_expression\n");
|
||||
}
|
||||
|
||||
/* The user expression has to be in its own scope, so that "extern"
|
||||
@ -402,15 +394,15 @@ c_compute_program (struct compile_instance *inst,
|
||||
declaration is in the same scope as the declaration provided by
|
||||
gdb. */
|
||||
if (inst->scope != COMPILE_I_RAW_SCOPE)
|
||||
fputs_unfiltered ("{\n", buf);
|
||||
buf.puts ("{\n");
|
||||
|
||||
fputs_unfiltered ("#line 1 \"gdb command line\"\n", buf);
|
||||
buf.puts ("#line 1 \"gdb command line\"\n");
|
||||
|
||||
switch (inst->scope)
|
||||
{
|
||||
case COMPILE_I_PRINT_ADDRESS_SCOPE:
|
||||
case COMPILE_I_PRINT_VALUE_SCOPE:
|
||||
fprintf_unfiltered (buf,
|
||||
buf.printf (
|
||||
"__auto_type " COMPILE_I_EXPR_VAL " = %s;\n"
|
||||
"typeof (%s) *" COMPILE_I_EXPR_PTR_TYPE ";\n"
|
||||
"memcpy (" COMPILE_I_PRINT_OUT_ARG ", %s" COMPILE_I_EXPR_VAL ",\n"
|
||||
@ -420,22 +412,20 @@ c_compute_program (struct compile_instance *inst,
|
||||
? "&" : ""));
|
||||
break;
|
||||
default:
|
||||
fputs_unfiltered (input, buf);
|
||||
buf.puts (input);
|
||||
break;
|
||||
}
|
||||
|
||||
fputs_unfiltered ("\n", buf);
|
||||
buf.puts ("\n");
|
||||
|
||||
/* For larger user expressions the automatic semicolons may be
|
||||
confusing. */
|
||||
if (strchr (input, '\n') == NULL)
|
||||
fputs_unfiltered (";\n", buf);
|
||||
buf.puts (";\n");
|
||||
|
||||
if (inst->scope != COMPILE_I_RAW_SCOPE)
|
||||
fputs_unfiltered ("}\n", buf);
|
||||
buf.puts ("}\n");
|
||||
|
||||
add_code_footer (inst->scope, buf);
|
||||
code = ui_file_as_string (buf);
|
||||
do_cleanups (cleanup);
|
||||
return code;
|
||||
add_code_footer (inst->scope, &buf);
|
||||
return std::move (buf.string ());
|
||||
}
|
||||
|
@ -584,7 +584,7 @@ symbol_seen (htab_t hashtab, struct symbol *sym)
|
||||
|
||||
static void
|
||||
generate_vla_size (struct compile_c_instance *compiler,
|
||||
struct ui_file *stream,
|
||||
string_file &stream,
|
||||
struct gdbarch *gdbarch,
|
||||
unsigned char *registers_used,
|
||||
CORE_ADDR pc,
|
||||
@ -640,7 +640,7 @@ generate_vla_size (struct compile_c_instance *compiler,
|
||||
|
||||
static void
|
||||
generate_c_for_for_one_variable (struct compile_c_instance *compiler,
|
||||
struct ui_file *stream,
|
||||
string_file &stream,
|
||||
struct gdbarch *gdbarch,
|
||||
unsigned char *registers_used,
|
||||
CORE_ADDR pc,
|
||||
@ -651,14 +651,14 @@ generate_c_for_for_one_variable (struct compile_c_instance *compiler,
|
||||
{
|
||||
if (is_dynamic_type (SYMBOL_TYPE (sym)))
|
||||
{
|
||||
struct ui_file *size_file = mem_fileopen ();
|
||||
struct cleanup *cleanup = make_cleanup_ui_file_delete (size_file);
|
||||
/* We need to emit to a temporary buffer in case an error
|
||||
occurs in the middle. */
|
||||
string_file local_file;
|
||||
|
||||
generate_vla_size (compiler, size_file, gdbarch, registers_used, pc,
|
||||
generate_vla_size (compiler, local_file, gdbarch, registers_used, pc,
|
||||
SYMBOL_TYPE (sym), sym);
|
||||
ui_file_put (size_file, ui_file_write_for_put, stream);
|
||||
|
||||
do_cleanups (cleanup);
|
||||
stream.write (local_file.c_str (), local_file.size ());
|
||||
}
|
||||
|
||||
if (SYMBOL_COMPUTED_OPS (sym) != NULL)
|
||||
@ -667,14 +667,13 @@ generate_c_for_for_one_variable (struct compile_c_instance *compiler,
|
||||
struct cleanup *cleanup = make_cleanup (xfree, generated_name);
|
||||
/* We need to emit to a temporary buffer in case an error
|
||||
occurs in the middle. */
|
||||
struct ui_file *local_file = mem_fileopen ();
|
||||
string_file local_file;
|
||||
|
||||
make_cleanup_ui_file_delete (local_file);
|
||||
SYMBOL_COMPUTED_OPS (sym)->generate_c_location (sym, local_file,
|
||||
gdbarch,
|
||||
registers_used,
|
||||
pc, generated_name);
|
||||
ui_file_put (local_file, ui_file_write_for_put, stream);
|
||||
stream.write (local_file.c_str (), local_file.size ());
|
||||
|
||||
do_cleanups (cleanup);
|
||||
}
|
||||
@ -719,7 +718,7 @@ generate_c_for_for_one_variable (struct compile_c_instance *compiler,
|
||||
|
||||
unsigned char *
|
||||
generate_c_for_variable_locations (struct compile_c_instance *compiler,
|
||||
struct ui_file *stream,
|
||||
string_file &stream,
|
||||
struct gdbarch *gdbarch,
|
||||
const struct block *block,
|
||||
CORE_ADDR pc)
|
||||
|
@ -135,7 +135,7 @@ extern struct compile_instance *new_compile_instance (struct gcc_c_context *fe);
|
||||
|
||||
extern unsigned char *generate_c_for_variable_locations
|
||||
(struct compile_c_instance *compiler,
|
||||
struct ui_file *stream,
|
||||
string_file &stream,
|
||||
struct gdbarch *gdbarch,
|
||||
const struct block *block,
|
||||
CORE_ADDR pc);
|
||||
|
@ -435,9 +435,9 @@ compute_stack_depth (enum bfd_endian byte_order, unsigned int addr_size,
|
||||
/* Emit code to push a constant. */
|
||||
|
||||
static void
|
||||
push (int indent, struct ui_file *stream, ULONGEST l)
|
||||
push (int indent, string_file &stream, ULONGEST l)
|
||||
{
|
||||
fprintfi_filtered (indent, stream,
|
||||
fprintfi_filtered (indent, &stream,
|
||||
"__gdb_stack[++__gdb_tos] = (" GCC_UINTPTR ") %s;\n",
|
||||
hex_string (l));
|
||||
}
|
||||
@ -445,57 +445,57 @@ push (int indent, struct ui_file *stream, ULONGEST l)
|
||||
/* Emit code to push an arbitrary expression. This works like
|
||||
printf. */
|
||||
|
||||
static void pushf (int indent, struct ui_file *stream, const char *format, ...)
|
||||
static void pushf (int indent, string_file &stream, const char *format, ...)
|
||||
ATTRIBUTE_PRINTF (3, 4);
|
||||
|
||||
static void
|
||||
pushf (int indent, struct ui_file *stream, const char *format, ...)
|
||||
pushf (int indent, string_file &stream, const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
fprintfi_filtered (indent, stream, "__gdb_stack[__gdb_tos + 1] = ");
|
||||
fprintfi_filtered (indent, &stream, "__gdb_stack[__gdb_tos + 1] = ");
|
||||
va_start (args, format);
|
||||
vfprintf_filtered (stream, format, args);
|
||||
stream.vprintf (format, args);
|
||||
va_end (args);
|
||||
fprintf_filtered (stream, ";\n");
|
||||
stream.puts (";\n");
|
||||
|
||||
fprintfi_filtered (indent, stream, "++__gdb_tos;\n");
|
||||
fprintfi_filtered (indent, &stream, "++__gdb_tos;\n");
|
||||
}
|
||||
|
||||
/* Emit code for a unary expression -- one which operates in-place on
|
||||
the top-of-stack. This works like printf. */
|
||||
|
||||
static void unary (int indent, struct ui_file *stream, const char *format, ...)
|
||||
static void unary (int indent, string_file &stream, const char *format, ...)
|
||||
ATTRIBUTE_PRINTF (3, 4);
|
||||
|
||||
static void
|
||||
unary (int indent, struct ui_file *stream, const char *format, ...)
|
||||
unary (int indent, string_file &stream, const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
fprintfi_filtered (indent, stream, "__gdb_stack[__gdb_tos] = ");
|
||||
fprintfi_filtered (indent, &stream, "__gdb_stack[__gdb_tos] = ");
|
||||
va_start (args, format);
|
||||
vfprintf_filtered (stream, format, args);
|
||||
stream.vprintf (format, args);
|
||||
va_end (args);
|
||||
fprintf_filtered (stream, ";\n");
|
||||
stream.puts (";\n");
|
||||
}
|
||||
|
||||
/* Emit code for a unary expression -- one which uses the top two
|
||||
stack items, popping the topmost one. This works like printf. */
|
||||
static void binary (int indent, struct ui_file *stream, const char *format, ...)
|
||||
static void binary (int indent, string_file &stream, const char *format, ...)
|
||||
ATTRIBUTE_PRINTF (3, 4);
|
||||
|
||||
static void
|
||||
binary (int indent, struct ui_file *stream, const char *format, ...)
|
||||
binary (int indent, string_file &stream, const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
fprintfi_filtered (indent, stream, "__gdb_stack[__gdb_tos - 1] = ");
|
||||
fprintfi_filtered (indent, &stream, "__gdb_stack[__gdb_tos - 1] = ");
|
||||
va_start (args, format);
|
||||
vfprintf_filtered (stream, format, args);
|
||||
stream.vprintf (format, args);
|
||||
va_end (args);
|
||||
fprintf_filtered (stream, ";\n");
|
||||
fprintfi_filtered (indent, stream, "--__gdb_tos;\n");
|
||||
stream.puts (";\n");
|
||||
fprintfi_filtered (indent, &stream, "--__gdb_tos;\n");
|
||||
}
|
||||
|
||||
/* Print the name of a label given its "SCOPE", an arbitrary integer
|
||||
@ -503,10 +503,9 @@ binary (int indent, struct ui_file *stream, const char *format, ...)
|
||||
corresponding to the label's point of definition. */
|
||||
|
||||
static void
|
||||
print_label (struct ui_file *stream, unsigned int scope, int target)
|
||||
print_label (string_file &stream, unsigned int scope, int target)
|
||||
{
|
||||
fprintf_filtered (stream, "__label_%u_%s",
|
||||
scope, pulongest (target));
|
||||
stream.printf ("__label_%u_%s", scope, pulongest (target));
|
||||
}
|
||||
|
||||
/* Emit code that pushes a register's address on the stack.
|
||||
@ -514,7 +513,7 @@ print_label (struct ui_file *stream, unsigned int scope, int target)
|
||||
register was needed by this expression. */
|
||||
|
||||
static void
|
||||
pushf_register_address (int indent, struct ui_file *stream,
|
||||
pushf_register_address (int indent, string_file &stream,
|
||||
unsigned char *registers_used,
|
||||
struct gdbarch *gdbarch, int regnum)
|
||||
{
|
||||
@ -535,7 +534,7 @@ pushf_register_address (int indent, struct ui_file *stream,
|
||||
register's value before it is pushed. */
|
||||
|
||||
static void
|
||||
pushf_register (int indent, struct ui_file *stream,
|
||||
pushf_register (int indent, string_file &stream,
|
||||
unsigned char *registers_used,
|
||||
struct gdbarch *gdbarch, int regnum, uint64_t offset)
|
||||
{
|
||||
@ -584,7 +583,7 @@ pushf_register (int indent, struct ui_file *stream,
|
||||
things. */
|
||||
|
||||
static void
|
||||
do_compile_dwarf_expr_to_c (int indent, struct ui_file *stream,
|
||||
do_compile_dwarf_expr_to_c (int indent, string_file &stream,
|
||||
const char *type_name,
|
||||
const char *result_name,
|
||||
struct symbol *sym, CORE_ADDR pc,
|
||||
@ -609,9 +608,9 @@ do_compile_dwarf_expr_to_c (int indent, struct ui_file *stream,
|
||||
|
||||
++scope;
|
||||
|
||||
fprintfi_filtered (indent, stream, "__attribute__ ((unused)) %s %s;\n",
|
||||
fprintfi_filtered (indent, &stream, "__attribute__ ((unused)) %s %s;\n",
|
||||
type_name, result_name);
|
||||
fprintfi_filtered (indent, stream, "{\n");
|
||||
fprintfi_filtered (indent, &stream, "{\n");
|
||||
indent += 2;
|
||||
|
||||
stack_depth = compute_stack_depth (byte_order, addr_size,
|
||||
@ -648,20 +647,20 @@ do_compile_dwarf_expr_to_c (int indent, struct ui_file *stream,
|
||||
"compiled code."),
|
||||
SYMBOL_PRINT_NAME (sym));
|
||||
|
||||
fprintfi_filtered (indent, stream, "%s = %s;\n",
|
||||
fprintfi_filtered (indent, &stream, "%s = %s;\n",
|
||||
result_name,
|
||||
core_addr_to_string (value_address (val)));
|
||||
fprintfi_filtered (indent - 2, stream, "}\n");
|
||||
fprintfi_filtered (indent - 2, &stream, "}\n");
|
||||
do_cleanups (cleanup);
|
||||
return;
|
||||
}
|
||||
|
||||
fprintfi_filtered (indent, stream, GCC_UINTPTR " __gdb_stack[%d];\n",
|
||||
fprintfi_filtered (indent, &stream, GCC_UINTPTR " __gdb_stack[%d];\n",
|
||||
stack_depth);
|
||||
|
||||
if (need_tempvar)
|
||||
fprintfi_filtered (indent, stream, GCC_UINTPTR " __gdb_tmp;\n");
|
||||
fprintfi_filtered (indent, stream, "int __gdb_tos = -1;\n");
|
||||
fprintfi_filtered (indent, &stream, GCC_UINTPTR " __gdb_tmp;\n");
|
||||
fprintfi_filtered (indent, &stream, "int __gdb_tos = -1;\n");
|
||||
|
||||
if (initial != NULL)
|
||||
pushf (indent, stream, "%s", core_addr_to_string (*initial));
|
||||
@ -672,13 +671,13 @@ do_compile_dwarf_expr_to_c (int indent, struct ui_file *stream,
|
||||
uint64_t uoffset, reg;
|
||||
int64_t offset;
|
||||
|
||||
print_spaces (indent - 2, stream);
|
||||
print_spaces (indent - 2, &stream);
|
||||
if (info[op_ptr - base].label)
|
||||
{
|
||||
print_label (stream, scope, op_ptr - base);
|
||||
fprintf_filtered (stream, ":;");
|
||||
stream.puts (":;");
|
||||
}
|
||||
fprintf_filtered (stream, "/* %s */\n", get_DW_OP_name (op));
|
||||
stream.printf ("/* %s */\n", get_DW_OP_name (op));
|
||||
|
||||
/* This is handy for debugging the generated code:
|
||||
fprintf_filtered (stream, "if (__gdb_tos != %d) abort ();\n",
|
||||
@ -919,7 +918,7 @@ do_compile_dwarf_expr_to_c (int indent, struct ui_file *stream,
|
||||
break;
|
||||
|
||||
case DW_OP_drop:
|
||||
fprintfi_filtered (indent, stream, "--__gdb_tos;\n");
|
||||
fprintfi_filtered (indent, &stream, "--__gdb_tos;\n");
|
||||
break;
|
||||
|
||||
case DW_OP_pick:
|
||||
@ -929,13 +928,13 @@ do_compile_dwarf_expr_to_c (int indent, struct ui_file *stream,
|
||||
break;
|
||||
|
||||
case DW_OP_swap:
|
||||
fprintfi_filtered (indent, stream,
|
||||
fprintfi_filtered (indent, &stream,
|
||||
"__gdb_tmp = __gdb_stack[__gdb_tos - 1];\n");
|
||||
fprintfi_filtered (indent, stream,
|
||||
fprintfi_filtered (indent, &stream,
|
||||
"__gdb_stack[__gdb_tos - 1] = "
|
||||
"__gdb_stack[__gdb_tos];\n");
|
||||
fprintfi_filtered (indent, stream, ("__gdb_stack[__gdb_tos] = "
|
||||
"__gdb_tmp;\n"));
|
||||
fprintfi_filtered (indent, &stream, ("__gdb_stack[__gdb_tos] = "
|
||||
"__gdb_tmp;\n"));
|
||||
break;
|
||||
|
||||
case DW_OP_over:
|
||||
@ -943,15 +942,15 @@ do_compile_dwarf_expr_to_c (int indent, struct ui_file *stream,
|
||||
break;
|
||||
|
||||
case DW_OP_rot:
|
||||
fprintfi_filtered (indent, stream, ("__gdb_tmp = "
|
||||
"__gdb_stack[__gdb_tos];\n"));
|
||||
fprintfi_filtered (indent, stream,
|
||||
fprintfi_filtered (indent, &stream, ("__gdb_tmp = "
|
||||
"__gdb_stack[__gdb_tos];\n"));
|
||||
fprintfi_filtered (indent, &stream,
|
||||
"__gdb_stack[__gdb_tos] = "
|
||||
"__gdb_stack[__gdb_tos - 1];\n");
|
||||
fprintfi_filtered (indent, stream,
|
||||
fprintfi_filtered (indent, &stream,
|
||||
"__gdb_stack[__gdb_tos - 1] = "
|
||||
"__gdb_stack[__gdb_tos -2];\n");
|
||||
fprintfi_filtered (indent, stream, "__gdb_stack[__gdb_tos - 2] = "
|
||||
fprintfi_filtered (indent, &stream, "__gdb_stack[__gdb_tos - 2] = "
|
||||
"__gdb_tmp;\n");
|
||||
break;
|
||||
|
||||
@ -973,7 +972,7 @@ do_compile_dwarf_expr_to_c (int indent, struct ui_file *stream,
|
||||
|
||||
/* Cast to a pointer of the desired type, then
|
||||
dereference. */
|
||||
fprintfi_filtered (indent, stream,
|
||||
fprintfi_filtered (indent, &stream,
|
||||
"__gdb_stack[__gdb_tos] = "
|
||||
"*((__gdb_int_%s *) "
|
||||
"__gdb_stack[__gdb_tos]);\n",
|
||||
@ -1099,19 +1098,19 @@ do_compile_dwarf_expr_to_c (int indent, struct ui_file *stream,
|
||||
case DW_OP_skip:
|
||||
offset = extract_signed_integer (op_ptr, 2, byte_order);
|
||||
op_ptr += 2;
|
||||
fprintfi_filtered (indent, stream, "goto ");
|
||||
fprintfi_filtered (indent, &stream, "goto ");
|
||||
print_label (stream, scope, op_ptr + offset - base);
|
||||
fprintf_filtered (stream, ";\n");
|
||||
stream.puts (";\n");
|
||||
break;
|
||||
|
||||
case DW_OP_bra:
|
||||
offset = extract_signed_integer (op_ptr, 2, byte_order);
|
||||
op_ptr += 2;
|
||||
fprintfi_filtered (indent, stream,
|
||||
fprintfi_filtered (indent, &stream,
|
||||
"if ((( " GCC_INTPTR
|
||||
") __gdb_stack[__gdb_tos--]) != 0) goto ");
|
||||
print_label (stream, scope, op_ptr + offset - base);
|
||||
fprintf_filtered (stream, ";\n");
|
||||
stream.puts (";\n");
|
||||
break;
|
||||
|
||||
case DW_OP_nop:
|
||||
@ -1122,9 +1121,9 @@ do_compile_dwarf_expr_to_c (int indent, struct ui_file *stream,
|
||||
}
|
||||
}
|
||||
|
||||
fprintfi_filtered (indent, stream, "%s = __gdb_stack[__gdb_tos];\n",
|
||||
fprintfi_filtered (indent, &stream, "%s = __gdb_stack[__gdb_tos];\n",
|
||||
result_name);
|
||||
fprintfi_filtered (indent - 2, stream, "}\n");
|
||||
fprintfi_filtered (indent - 2, &stream, "}\n");
|
||||
|
||||
do_cleanups (cleanup);
|
||||
}
|
||||
@ -1132,7 +1131,7 @@ do_compile_dwarf_expr_to_c (int indent, struct ui_file *stream,
|
||||
/* See compile.h. */
|
||||
|
||||
void
|
||||
compile_dwarf_expr_to_c (struct ui_file *stream, const char *result_name,
|
||||
compile_dwarf_expr_to_c (string_file &stream, const char *result_name,
|
||||
struct symbol *sym, CORE_ADDR pc,
|
||||
struct gdbarch *arch, unsigned char *registers_used,
|
||||
unsigned int addr_size,
|
||||
@ -1147,7 +1146,7 @@ compile_dwarf_expr_to_c (struct ui_file *stream, const char *result_name,
|
||||
/* See compile.h. */
|
||||
|
||||
void
|
||||
compile_dwarf_bounds_to_c (struct ui_file *stream,
|
||||
compile_dwarf_bounds_to_c (string_file &stream,
|
||||
const char *result_name,
|
||||
const struct dynamic_prop *prop,
|
||||
struct symbol *sym, CORE_ADDR pc,
|
||||
|
@ -494,22 +494,19 @@ compile_to_object (struct command_line *cmd, const char *cmd_string,
|
||||
/* From the provided expression, build a scope to pass to the
|
||||
compiler. */
|
||||
|
||||
std::string input_buf;
|
||||
string_file input_buf;
|
||||
const char *input;
|
||||
|
||||
if (cmd != NULL)
|
||||
{
|
||||
struct ui_file *stream = mem_fileopen ();
|
||||
struct command_line *iter;
|
||||
|
||||
make_cleanup_ui_file_delete (stream);
|
||||
for (iter = cmd->body_list[0]; iter; iter = iter->next)
|
||||
{
|
||||
fputs_unfiltered (iter->line, stream);
|
||||
fputs_unfiltered ("\n", stream);
|
||||
input_buf.puts (iter->line);
|
||||
input_buf.puts ("\n");
|
||||
}
|
||||
|
||||
input_buf = ui_file_as_string (stream);
|
||||
input = input_buf.c_str ();
|
||||
}
|
||||
else if (cmd_string != NULL)
|
||||
|
@ -55,7 +55,7 @@ extern void eval_compile_command (struct command_line *cmd,
|
||||
PER_CU is the per-CU object used for looking up various other
|
||||
things. */
|
||||
|
||||
extern void compile_dwarf_expr_to_c (struct ui_file *stream,
|
||||
extern void compile_dwarf_expr_to_c (string_file &stream,
|
||||
const char *result_name,
|
||||
struct symbol *sym,
|
||||
CORE_ADDR pc,
|
||||
@ -90,7 +90,7 @@ extern void compile_dwarf_expr_to_c (struct ui_file *stream,
|
||||
PER_CU is the per-CU object used for looking up various other
|
||||
things. */
|
||||
|
||||
extern void compile_dwarf_bounds_to_c (struct ui_file *stream,
|
||||
extern void compile_dwarf_bounds_to_c (string_file &stream,
|
||||
const char *result_name,
|
||||
const struct dynamic_prop *prop,
|
||||
struct symbol *sym, CORE_ADDR pc,
|
||||
|
@ -192,7 +192,6 @@ inspect_type (struct demangle_parse_info *info,
|
||||
int is_anon;
|
||||
struct type *type;
|
||||
std::unique_ptr<demangle_parse_info> i;
|
||||
struct ui_file *buf;
|
||||
|
||||
/* Get the real type of the typedef. */
|
||||
type = check_typedef (otype);
|
||||
@ -228,23 +227,21 @@ inspect_type (struct demangle_parse_info *info,
|
||||
type = last;
|
||||
}
|
||||
|
||||
buf = mem_fileopen ();
|
||||
string_file buf;
|
||||
TRY
|
||||
{
|
||||
type_print (type, "", buf, -1);
|
||||
}
|
||||
|
||||
{
|
||||
type_print (type, "", &buf, -1);
|
||||
}
|
||||
/* If type_print threw an exception, there is little point
|
||||
in continuing, so just bow out gracefully. */
|
||||
CATCH (except, RETURN_MASK_ERROR)
|
||||
{
|
||||
ui_file_delete (buf);
|
||||
return 0;
|
||||
}
|
||||
END_CATCH
|
||||
|
||||
name = ui_file_obsavestring (buf, &info->obstack, &len);
|
||||
ui_file_delete (buf);
|
||||
len = buf.size ();
|
||||
name = (char *) obstack_copy0 (&info->obstack, buf.c_str (), len);
|
||||
|
||||
/* Turn the result into a new tree. Note that this
|
||||
tree will contain pointers into NAME, so NAME cannot
|
||||
@ -301,7 +298,7 @@ replace_typedefs_qualified_name (struct demangle_parse_info *info,
|
||||
{
|
||||
long len;
|
||||
char *name;
|
||||
struct ui_file *buf = mem_fileopen ();
|
||||
string_file buf;
|
||||
struct demangle_component *comp = ret_comp;
|
||||
|
||||
/* Walk each node of the qualified name, reconstructing the name of
|
||||
@ -315,9 +312,9 @@ replace_typedefs_qualified_name (struct demangle_parse_info *info,
|
||||
{
|
||||
struct demangle_component newobj;
|
||||
|
||||
ui_file_write (buf, d_left (comp)->u.s_name.s,
|
||||
d_left (comp)->u.s_name.len);
|
||||
name = ui_file_obsavestring (buf, &info->obstack, &len);
|
||||
buf.write (d_left (comp)->u.s_name.s, d_left (comp)->u.s_name.len);
|
||||
len = buf.size ();
|
||||
name = (char *) obstack_copy0 (&info->obstack, buf.c_str (), len);
|
||||
newobj.type = DEMANGLE_COMPONENT_NAME;
|
||||
newobj.u.s_name.s = name;
|
||||
newobj.u.s_name.len = len;
|
||||
@ -330,12 +327,11 @@ replace_typedefs_qualified_name (struct demangle_parse_info *info,
|
||||
string and replace the top DEMANGLE_COMPONENT_QUAL_NAME
|
||||
node. */
|
||||
|
||||
ui_file_rewind (buf);
|
||||
buf.clear ();
|
||||
n = cp_comp_to_string (&newobj, 100);
|
||||
if (n == NULL)
|
||||
{
|
||||
/* If something went astray, abort typedef substitutions. */
|
||||
ui_file_delete (buf);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -360,14 +356,13 @@ replace_typedefs_qualified_name (struct demangle_parse_info *info,
|
||||
if (name == NULL)
|
||||
{
|
||||
/* If something went astray, abort typedef substitutions. */
|
||||
ui_file_delete (buf);
|
||||
return;
|
||||
}
|
||||
fputs_unfiltered (name, buf);
|
||||
buf.puts (name);
|
||||
xfree (name);
|
||||
}
|
||||
|
||||
ui_file_write (buf, "::", 2);
|
||||
buf.write ("::", 2);
|
||||
comp = d_right (comp);
|
||||
}
|
||||
|
||||
@ -377,8 +372,9 @@ replace_typedefs_qualified_name (struct demangle_parse_info *info,
|
||||
|
||||
if (comp->type == DEMANGLE_COMPONENT_NAME)
|
||||
{
|
||||
ui_file_write (buf, comp->u.s_name.s, comp->u.s_name.len);
|
||||
name = ui_file_obsavestring (buf, &info->obstack, &len);
|
||||
buf.write (comp->u.s_name.s, comp->u.s_name.len);
|
||||
len = buf.size ();
|
||||
name = (char *) obstack_copy0 (&info->obstack, buf.c_str (), len);
|
||||
|
||||
/* Replace the top (DEMANGLE_COMPONENT_QUAL_NAME) node
|
||||
with a DEMANGLE_COMPONENT_NAME node containing the whole
|
||||
@ -390,8 +386,6 @@ replace_typedefs_qualified_name (struct demangle_parse_info *info,
|
||||
}
|
||||
else
|
||||
replace_typedefs (info, comp, finder, data);
|
||||
|
||||
ui_file_delete (buf);
|
||||
}
|
||||
|
||||
|
||||
|
@ -113,7 +113,7 @@ print_one_insn_test (struct gdbarch *gdbarch)
|
||||
const gdb_byte *insn,
|
||||
size_t len)
|
||||
: gdb_disassembler (gdbarch,
|
||||
(verbose ? gdb_stdout : null_stream ()),
|
||||
(verbose ? gdb_stdout : &null_stream),
|
||||
gdb_disassembler_test::read_memory),
|
||||
m_insn (insn), m_len (len)
|
||||
{
|
||||
@ -173,7 +173,7 @@ memory_error_test (struct gdbarch *gdbarch)
|
||||
{
|
||||
public:
|
||||
gdb_disassembler_test (struct gdbarch *gdbarch)
|
||||
: gdb_disassembler (gdbarch, null_stream (),
|
||||
: gdb_disassembler (gdbarch, &null_stream,
|
||||
gdb_disassembler_test::read_memory)
|
||||
{
|
||||
}
|
||||
|
18
gdb/disasm.c
18
gdb/disasm.c
@ -248,8 +248,7 @@ gdb_pretty_print_insn (struct gdbarch *gdbarch, struct ui_out *uiout,
|
||||
if (name != NULL)
|
||||
xfree (name);
|
||||
|
||||
struct ui_file *stb = mem_fileopen ();
|
||||
make_cleanup_ui_file_delete (stb);
|
||||
string_file stb;
|
||||
|
||||
if (flags & DISASSEMBLY_RAW_INSN)
|
||||
{
|
||||
@ -260,28 +259,23 @@ gdb_pretty_print_insn (struct gdbarch *gdbarch, struct ui_out *uiout,
|
||||
|
||||
/* Build the opcodes using a temporary stream so we can
|
||||
write them out in a single go for the MI. */
|
||||
struct ui_file *opcode_stream = mem_fileopen ();
|
||||
struct cleanup *cleanups =
|
||||
make_cleanup_ui_file_delete (opcode_stream);
|
||||
string_file opcode_stream;
|
||||
|
||||
size = gdb_print_insn (gdbarch, pc, stb, NULL);
|
||||
size = gdb_print_insn (gdbarch, pc, &stb, NULL);
|
||||
end_pc = pc + size;
|
||||
|
||||
for (;pc < end_pc; ++pc)
|
||||
{
|
||||
read_code (pc, &data, 1);
|
||||
fprintf_filtered (opcode_stream, "%s%02x",
|
||||
spacer, (unsigned) data);
|
||||
opcode_stream.printf ("%s%02x", spacer, (unsigned) data);
|
||||
spacer = " ";
|
||||
}
|
||||
|
||||
uiout->field_stream ("opcodes", opcode_stream);
|
||||
uiout->text ("\t");
|
||||
|
||||
do_cleanups (cleanups);
|
||||
}
|
||||
else
|
||||
size = gdb_print_insn (gdbarch, pc, stb, NULL);
|
||||
size = gdb_print_insn (gdbarch, pc, &stb, NULL);
|
||||
|
||||
uiout->field_stream ("inst", stb);
|
||||
do_cleanups (ui_out_chain);
|
||||
@ -856,7 +850,7 @@ gdb_print_insn (struct gdbarch *gdbarch, CORE_ADDR memaddr,
|
||||
int
|
||||
gdb_insn_length (struct gdbarch *gdbarch, CORE_ADDR addr)
|
||||
{
|
||||
return gdb_print_insn (gdbarch, addr, null_stream (), NULL);
|
||||
return gdb_print_insn (gdbarch, addr, &null_stream, NULL);
|
||||
}
|
||||
|
||||
/* fprintf-function for gdb_buffered_insn_length. This function is a
|
||||
|
@ -409,14 +409,11 @@ maintenance_print_dummy_frames (char *args, int from_tty)
|
||||
fprint_dummy_frames (gdb_stdout);
|
||||
else
|
||||
{
|
||||
struct cleanup *cleanups;
|
||||
struct ui_file *file = gdb_fopen (args, "w");
|
||||
stdio_file file;
|
||||
|
||||
if (file == NULL)
|
||||
if (!file.open (args, "w"))
|
||||
perror_with_name (_("maintenance print dummy-frames"));
|
||||
cleanups = make_cleanup_ui_file_delete (file);
|
||||
fprint_dummy_frames (file);
|
||||
do_cleanups (cleanups);
|
||||
fprint_dummy_frames (&file);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2632,7 +2632,7 @@ dwarf2_evaluate_property (const struct dynamic_prop *prop,
|
||||
/* See dwarf2loc.h. */
|
||||
|
||||
void
|
||||
dwarf2_compile_property_to_c (struct ui_file *stream,
|
||||
dwarf2_compile_property_to_c (string_file &stream,
|
||||
const char *result_name,
|
||||
struct gdbarch *gdbarch,
|
||||
unsigned char *registers_used,
|
||||
@ -4348,7 +4348,7 @@ locexpr_tracepoint_var_ref (struct symbol *symbol, struct gdbarch *gdbarch,
|
||||
/* symbol_computed_ops 'generate_c_location' method. */
|
||||
|
||||
static void
|
||||
locexpr_generate_c_location (struct symbol *sym, struct ui_file *stream,
|
||||
locexpr_generate_c_location (struct symbol *sym, string_file &stream,
|
||||
struct gdbarch *gdbarch,
|
||||
unsigned char *registers_used,
|
||||
CORE_ADDR pc, const char *result_name)
|
||||
@ -4558,7 +4558,7 @@ loclist_tracepoint_var_ref (struct symbol *symbol, struct gdbarch *gdbarch,
|
||||
/* symbol_computed_ops 'generate_c_location' method. */
|
||||
|
||||
static void
|
||||
loclist_generate_c_location (struct symbol *sym, struct ui_file *stream,
|
||||
loclist_generate_c_location (struct symbol *sym, string_file &stream,
|
||||
struct gdbarch *gdbarch,
|
||||
unsigned char *registers_used,
|
||||
CORE_ADDR pc, const char *result_name)
|
||||
|
@ -151,7 +151,7 @@ int dwarf2_evaluate_property (const struct dynamic_prop *prop,
|
||||
evaluated.
|
||||
SYM the originating symbol, used for error reporting. */
|
||||
|
||||
void dwarf2_compile_property_to_c (struct ui_file *stream,
|
||||
void dwarf2_compile_property_to_c (string_file &stream,
|
||||
const char *result_name,
|
||||
struct gdbarch *gdbarch,
|
||||
unsigned char *registers_used,
|
||||
|
@ -8409,17 +8409,6 @@ die_needs_namespace (struct die_info *die, struct dwarf2_cu *cu)
|
||||
}
|
||||
}
|
||||
|
||||
/* Retrieve the last character from a mem_file. */
|
||||
|
||||
static void
|
||||
do_ui_file_peek_last (void *object, const char *buffer, long length)
|
||||
{
|
||||
char *last_char_p = (char *) object;
|
||||
|
||||
if (length > 0)
|
||||
*last_char_p = buffer[length - 1];
|
||||
}
|
||||
|
||||
/* Compute the fully qualified name of DIE in CU. If PHYSNAME is nonzero,
|
||||
compute the physname for the object, which include a method's:
|
||||
- formal parameters (C++),
|
||||
@ -8478,21 +8467,21 @@ dwarf2_compute_name (const char *name,
|
||||
{
|
||||
long length;
|
||||
const char *prefix;
|
||||
struct ui_file *buf;
|
||||
const char *canonical_name = NULL;
|
||||
|
||||
string_file buf;
|
||||
|
||||
prefix = determine_prefix (die, cu);
|
||||
buf = mem_fileopen ();
|
||||
if (*prefix != '\0')
|
||||
{
|
||||
char *prefixed_name = typename_concat (NULL, prefix, name,
|
||||
physname, cu);
|
||||
|
||||
fputs_unfiltered (prefixed_name, buf);
|
||||
buf.puts (prefixed_name);
|
||||
xfree (prefixed_name);
|
||||
}
|
||||
else
|
||||
fputs_unfiltered (name, buf);
|
||||
buf.puts (name);
|
||||
|
||||
/* Template parameters may be specified in the DIE's DW_AT_name, or
|
||||
as children with DW_TAG_template_type_param or
|
||||
@ -8537,25 +8526,25 @@ dwarf2_compute_name (const char *name,
|
||||
|
||||
if (first)
|
||||
{
|
||||
fputs_unfiltered ("<", buf);
|
||||
buf.puts ("<");
|
||||
first = 0;
|
||||
}
|
||||
else
|
||||
fputs_unfiltered (", ", buf);
|
||||
buf.puts (", ");
|
||||
|
||||
attr = dwarf2_attr (child, DW_AT_type, cu);
|
||||
if (attr == NULL)
|
||||
{
|
||||
complaint (&symfile_complaints,
|
||||
_("template parameter missing DW_AT_type"));
|
||||
fputs_unfiltered ("UNKNOWN_TYPE", buf);
|
||||
buf.puts ("UNKNOWN_TYPE");
|
||||
continue;
|
||||
}
|
||||
type = die_type (child, cu);
|
||||
|
||||
if (child->tag == DW_TAG_template_type_param)
|
||||
{
|
||||
c_print_type (type, "", buf, -1, 0, &type_print_raw_options);
|
||||
c_print_type (type, "", &buf, -1, 0, &type_print_raw_options);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -8565,7 +8554,7 @@ dwarf2_compute_name (const char *name,
|
||||
complaint (&symfile_complaints,
|
||||
_("template parameter missing "
|
||||
"DW_AT_const_value"));
|
||||
fputs_unfiltered ("UNKNOWN_VALUE", buf);
|
||||
buf.puts ("UNKNOWN_VALUE");
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -8576,7 +8565,7 @@ dwarf2_compute_name (const char *name,
|
||||
if (TYPE_NOSIGN (type))
|
||||
/* GDB prints characters as NUMBER 'CHAR'. If that's
|
||||
changed, this can use value_print instead. */
|
||||
c_printchar (value, type, buf);
|
||||
c_printchar (value, type, &buf);
|
||||
else
|
||||
{
|
||||
struct value_print_options opts;
|
||||
@ -8599,7 +8588,7 @@ dwarf2_compute_name (const char *name,
|
||||
the radix. */
|
||||
get_formatted_print_options (&opts, 'd');
|
||||
opts.raw = 1;
|
||||
value_print (v, buf, &opts);
|
||||
value_print (v, &buf, &opts);
|
||||
release_value (v);
|
||||
value_free (v);
|
||||
}
|
||||
@ -8611,12 +8600,10 @@ dwarf2_compute_name (const char *name,
|
||||
{
|
||||
/* Close the argument list, with a space if necessary
|
||||
(nested templates). */
|
||||
char last_char = '\0';
|
||||
ui_file_put (buf, do_ui_file_peek_last, &last_char);
|
||||
if (last_char == '>')
|
||||
fputs_unfiltered (" >", buf);
|
||||
if (!buf.empty () && buf.string ().back () == '>')
|
||||
buf.puts (" >");
|
||||
else
|
||||
fputs_unfiltered (">", buf);
|
||||
buf.puts (">");
|
||||
}
|
||||
}
|
||||
|
||||
@ -8628,7 +8615,7 @@ dwarf2_compute_name (const char *name,
|
||||
{
|
||||
struct type *type = read_type_die (die, cu);
|
||||
|
||||
c_type_print_args (type, buf, 1, cu->language,
|
||||
c_type_print_args (type, &buf, 1, cu->language,
|
||||
&type_print_raw_options);
|
||||
|
||||
if (cu->language == language_cplus)
|
||||
@ -8643,12 +8630,11 @@ dwarf2_compute_name (const char *name,
|
||||
&& TYPE_CODE (TYPE_FIELD_TYPE (type, 0)) == TYPE_CODE_PTR
|
||||
&& TYPE_CONST (TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (type,
|
||||
0))))
|
||||
fputs_unfiltered (" const", buf);
|
||||
buf.puts (" const");
|
||||
}
|
||||
}
|
||||
|
||||
std::string intermediate_name = ui_file_as_string (buf);
|
||||
ui_file_delete (buf);
|
||||
const std::string &intermediate_name = buf.string ();
|
||||
|
||||
if (cu->language == language_cplus)
|
||||
canonical_name
|
||||
|
@ -1237,8 +1237,8 @@ gdb_setup_readline (int editing)
|
||||
mess it up here. The sync stuff should really go away over
|
||||
time. */
|
||||
if (!batch_silent)
|
||||
gdb_stdout = stdio_fileopen (ui->outstream);
|
||||
gdb_stderr = stderr_fileopen (ui->errstream);
|
||||
gdb_stdout = new stdio_file (ui->outstream);
|
||||
gdb_stderr = new stderr_file (ui->errstream);
|
||||
gdb_stdlog = gdb_stderr; /* for moment */
|
||||
gdb_stdtarg = gdb_stderr; /* for moment */
|
||||
gdb_stdtargerr = gdb_stderr; /* for moment */
|
||||
|
@ -497,17 +497,13 @@ gdbarch_free (struct gdbarch *arch)
|
||||
static void
|
||||
verify_gdbarch (struct gdbarch *gdbarch)
|
||||
{
|
||||
struct ui_file *log;
|
||||
struct cleanup *cleanups;
|
||||
long length;
|
||||
string_file log;
|
||||
|
||||
log = mem_fileopen ();
|
||||
cleanups = make_cleanup_ui_file_delete (log);
|
||||
/* fundamental */
|
||||
if (gdbarch->byte_order == BFD_ENDIAN_UNKNOWN)
|
||||
fprintf_unfiltered (log, "\n\tbyte-order");
|
||||
log.puts ("\n\tbyte-order");
|
||||
if (gdbarch->bfd_arch_info == NULL)
|
||||
fprintf_unfiltered (log, "\n\tbfd_arch_info");
|
||||
log.puts ("\n\tbfd_arch_info");
|
||||
/* Check those that need to be defined for the given multi-arch level. */
|
||||
/* Skip verify of bits_big_endian, invalid_p == 0 */
|
||||
/* Skip verify of short_bit, invalid_p == 0 */
|
||||
@ -542,7 +538,7 @@ verify_gdbarch (struct gdbarch *gdbarch)
|
||||
/* Skip verify of pseudo_register_read_value, has predicate. */
|
||||
/* Skip verify of pseudo_register_write, has predicate. */
|
||||
if (gdbarch->num_regs == -1)
|
||||
fprintf_unfiltered (log, "\n\tnum_regs");
|
||||
log.puts ("\n\tnum_regs");
|
||||
/* Skip verify of num_pseudo_regs, invalid_p == 0 */
|
||||
/* Skip verify of ax_pseudo_register_collect, has predicate. */
|
||||
/* Skip verify of ax_pseudo_register_push_stack, has predicate. */
|
||||
@ -556,7 +552,7 @@ verify_gdbarch (struct gdbarch *gdbarch)
|
||||
/* Skip verify of sdb_reg_to_regnum, invalid_p == 0 */
|
||||
/* Skip verify of dwarf2_reg_to_regnum, invalid_p == 0 */
|
||||
if (gdbarch->register_name == 0)
|
||||
fprintf_unfiltered (log, "\n\tregister_name");
|
||||
log.puts ("\n\tregister_name");
|
||||
/* Skip verify of register_type, has predicate. */
|
||||
/* Skip verify of dummy_id, has predicate. */
|
||||
/* Skip verify of deprecated_fp_regnum, invalid_p == 0 */
|
||||
@ -579,14 +575,14 @@ verify_gdbarch (struct gdbarch *gdbarch)
|
||||
/* Skip verify of return_value, has predicate. */
|
||||
/* Skip verify of return_in_first_hidden_param_p, invalid_p == 0 */
|
||||
if (gdbarch->skip_prologue == 0)
|
||||
fprintf_unfiltered (log, "\n\tskip_prologue");
|
||||
log.puts ("\n\tskip_prologue");
|
||||
/* Skip verify of skip_main_prologue, has predicate. */
|
||||
/* Skip verify of skip_entrypoint, has predicate. */
|
||||
if (gdbarch->inner_than == 0)
|
||||
fprintf_unfiltered (log, "\n\tinner_than");
|
||||
log.puts ("\n\tinner_than");
|
||||
/* Skip verify of breakpoint_from_pc, invalid_p == 0 */
|
||||
if (gdbarch->breakpoint_kind_from_pc == 0)
|
||||
fprintf_unfiltered (log, "\n\tbreakpoint_kind_from_pc");
|
||||
log.puts ("\n\tbreakpoint_kind_from_pc");
|
||||
/* Skip verify of sw_breakpoint_from_kind, invalid_p == 0 */
|
||||
/* Skip verify of breakpoint_kind_from_current_state, invalid_p == 0 */
|
||||
/* Skip verify of adjust_breakpoint_address, has predicate. */
|
||||
@ -607,7 +603,7 @@ verify_gdbarch (struct gdbarch *gdbarch)
|
||||
/* Skip verify of software_single_step, has predicate. */
|
||||
/* Skip verify of single_step_through_delay, has predicate. */
|
||||
if (gdbarch->print_insn == 0)
|
||||
fprintf_unfiltered (log, "\n\tprint_insn");
|
||||
log.puts ("\n\tprint_insn");
|
||||
/* Skip verify of skip_trampoline_code, invalid_p == 0 */
|
||||
/* Skip verify of skip_solib_resolver, invalid_p == 0 */
|
||||
/* Skip verify of in_solib_return_trampoline, invalid_p == 0 */
|
||||
@ -641,9 +637,9 @@ verify_gdbarch (struct gdbarch *gdbarch)
|
||||
/* Skip verify of displaced_step_hw_singlestep, invalid_p == 0 */
|
||||
/* Skip verify of displaced_step_fixup, has predicate. */
|
||||
if ((! gdbarch->displaced_step_free_closure) != (! gdbarch->displaced_step_copy_insn))
|
||||
fprintf_unfiltered (log, "\n\tdisplaced_step_free_closure");
|
||||
log.puts ("\n\tdisplaced_step_free_closure");
|
||||
if ((! gdbarch->displaced_step_location) != (! gdbarch->displaced_step_copy_insn))
|
||||
fprintf_unfiltered (log, "\n\tdisplaced_step_location");
|
||||
log.puts ("\n\tdisplaced_step_location");
|
||||
/* Skip verify of relocate_instruction, has predicate. */
|
||||
/* Skip verify of overlay_update, has predicate. */
|
||||
/* Skip verify of core_read_description, has predicate. */
|
||||
@ -696,12 +692,10 @@ verify_gdbarch (struct gdbarch *gdbarch)
|
||||
/* Skip verify of gcc_target_options, invalid_p == 0 */
|
||||
/* Skip verify of gnu_triplet_regexp, invalid_p == 0 */
|
||||
/* Skip verify of addressable_memory_unit_size, invalid_p == 0 */
|
||||
std::string buf = ui_file_as_string (log);
|
||||
if (!buf.empty ())
|
||||
if (!log.empty ())
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("verify_gdbarch: the following are invalid ...%s"),
|
||||
buf.c_str ());
|
||||
do_cleanups (cleanups);
|
||||
log.c_str ());
|
||||
}
|
||||
|
||||
|
||||
|
@ -1875,17 +1875,13 @@ cat <<EOF
|
||||
static void
|
||||
verify_gdbarch (struct gdbarch *gdbarch)
|
||||
{
|
||||
struct ui_file *log;
|
||||
struct cleanup *cleanups;
|
||||
long length;
|
||||
string_file log;
|
||||
|
||||
log = mem_fileopen ();
|
||||
cleanups = make_cleanup_ui_file_delete (log);
|
||||
/* fundamental */
|
||||
if (gdbarch->byte_order == BFD_ENDIAN_UNKNOWN)
|
||||
fprintf_unfiltered (log, "\n\tbyte-order");
|
||||
log.puts ("\n\tbyte-order");
|
||||
if (gdbarch->bfd_arch_info == NULL)
|
||||
fprintf_unfiltered (log, "\n\tbfd_arch_info");
|
||||
log.puts ("\n\tbfd_arch_info");
|
||||
/* Check those that need to be defined for the given multi-arch level. */
|
||||
EOF
|
||||
function_list | while do_read
|
||||
@ -1914,21 +1910,19 @@ do
|
||||
elif [ -n "${invalid_p}" ]
|
||||
then
|
||||
printf " if (${invalid_p})\n"
|
||||
printf " fprintf_unfiltered (log, \"\\\\n\\\\t${function}\");\n"
|
||||
printf " log.puts (\"\\\\n\\\\t${function}\");\n"
|
||||
elif [ -n "${predefault}" ]
|
||||
then
|
||||
printf " if (gdbarch->${function} == ${predefault})\n"
|
||||
printf " fprintf_unfiltered (log, \"\\\\n\\\\t${function}\");\n"
|
||||
printf " log.puts (\"\\\\n\\\\t${function}\");\n"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
cat <<EOF
|
||||
std::string buf = ui_file_as_string (log);
|
||||
if (!buf.empty ())
|
||||
if (!log.empty ())
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("verify_gdbarch: the following are invalid ...%s"),
|
||||
buf.c_str ());
|
||||
do_cleanups (cleanups);
|
||||
log.c_str ());
|
||||
}
|
||||
EOF
|
||||
|
||||
|
@ -2459,7 +2459,7 @@ safe_parse_type (struct gdbarch *gdbarch, char *p, int length)
|
||||
|
||||
/* Suppress error messages. */
|
||||
saved_gdb_stderr = gdb_stderr;
|
||||
gdb_stderr = ui_file_new ();
|
||||
gdb_stderr = &null_stream;
|
||||
|
||||
/* Call parse_and_eval_type() without fear of longjmp()s. */
|
||||
TRY
|
||||
@ -2473,7 +2473,6 @@ safe_parse_type (struct gdbarch *gdbarch, char *p, int length)
|
||||
END_CATCH
|
||||
|
||||
/* Stop suppressing error messages. */
|
||||
ui_file_delete (gdb_stderr);
|
||||
gdb_stderr = saved_gdb_stderr;
|
||||
|
||||
return type;
|
||||
|
@ -978,8 +978,6 @@ gdbscm_breakpoint_commands (SCM self)
|
||||
= bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
|
||||
struct breakpoint *bp;
|
||||
long length;
|
||||
struct ui_file *string_file;
|
||||
struct cleanup *chain;
|
||||
SCM result;
|
||||
|
||||
bp = bp_smob->bp;
|
||||
@ -987,10 +985,9 @@ gdbscm_breakpoint_commands (SCM self)
|
||||
if (bp->commands == NULL)
|
||||
return SCM_BOOL_F;
|
||||
|
||||
string_file = mem_fileopen ();
|
||||
chain = make_cleanup_ui_file_delete (string_file);
|
||||
string_file buf;
|
||||
|
||||
current_uiout->redirect (string_file);
|
||||
current_uiout->redirect (&buf);
|
||||
TRY
|
||||
{
|
||||
print_command_lines (current_uiout, breakpoint_commands (bp), 0);
|
||||
@ -998,15 +995,12 @@ gdbscm_breakpoint_commands (SCM self)
|
||||
current_uiout->redirect (NULL);
|
||||
CATCH (except, RETURN_MASK_ALL)
|
||||
{
|
||||
do_cleanups (chain);
|
||||
gdbscm_throw_gdb_exception (except);
|
||||
}
|
||||
END_CATCH
|
||||
|
||||
std::string cmdstr = ui_file_as_string (string_file);
|
||||
result = gdbscm_scm_from_c_string (cmdstr.c_str ());
|
||||
result = gdbscm_scm_from_c_string (buf.c_str ());
|
||||
|
||||
do_cleanups (chain);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -146,7 +146,7 @@ gdbscm_disassembler::gdbscm_disassembler (struct gdbarch *gdbarch,
|
||||
static int
|
||||
gdbscm_print_insn_from_port (struct gdbarch *gdbarch,
|
||||
SCM port, ULONGEST offset, CORE_ADDR memaddr,
|
||||
struct ui_file *stream, int *branch_delay_insns)
|
||||
string_file *stream, int *branch_delay_insns)
|
||||
{
|
||||
gdbscm_disassembler di (gdbarch, stream, port, offset);
|
||||
|
||||
@ -245,33 +245,29 @@ gdbscm_arch_disassemble (SCM self, SCM start_scm, SCM rest)
|
||||
for (pc = start, i = 0; pc <= end && i < count; )
|
||||
{
|
||||
int insn_len = 0;
|
||||
struct ui_file *memfile = mem_fileopen ();
|
||||
struct cleanup *cleanups = make_cleanup_ui_file_delete (memfile);
|
||||
string_file buf;
|
||||
|
||||
TRY
|
||||
{
|
||||
if (using_port)
|
||||
{
|
||||
insn_len = gdbscm_print_insn_from_port (gdbarch, port, offset,
|
||||
pc, memfile, NULL);
|
||||
pc, &buf, NULL);
|
||||
}
|
||||
else
|
||||
insn_len = gdb_print_insn (gdbarch, pc, memfile, NULL);
|
||||
insn_len = gdb_print_insn (gdbarch, pc, &buf, NULL);
|
||||
}
|
||||
CATCH (except, RETURN_MASK_ALL)
|
||||
{
|
||||
GDBSCM_HANDLE_GDB_EXCEPTION_WITH_CLEANUPS (except, cleanups);
|
||||
GDBSCM_HANDLE_GDB_EXCEPTION (except);
|
||||
}
|
||||
END_CATCH
|
||||
|
||||
std::string as = ui_file_as_string (memfile);
|
||||
|
||||
result = scm_cons (dascm_make_insn (pc, as.c_str (), insn_len),
|
||||
result = scm_cons (dascm_make_insn (pc, buf.c_str (), insn_len),
|
||||
result);
|
||||
|
||||
pc += insn_len;
|
||||
i++;
|
||||
do_cleanups (cleanups);
|
||||
}
|
||||
|
||||
return scm_reverse_x (result, SCM_EOL);
|
||||
|
@ -156,15 +156,12 @@ static int
|
||||
frscm_print_frame_smob (SCM self, SCM port, scm_print_state *pstate)
|
||||
{
|
||||
frame_smob *f_smob = (frame_smob *) SCM_SMOB_DATA (self);
|
||||
struct ui_file *strfile;
|
||||
|
||||
gdbscm_printf (port, "#<%s ", frame_smob_name);
|
||||
|
||||
strfile = mem_fileopen ();
|
||||
fprint_frame_id (strfile, f_smob->frame_id);
|
||||
std::string s = ui_file_as_string (strfile);
|
||||
gdbscm_printf (port, "%s", s.c_str ());
|
||||
ui_file_delete (strfile);
|
||||
string_file strfile;
|
||||
fprint_frame_id (&strfile, f_smob->frame_id);
|
||||
gdbscm_printf (port, "%s", strfile.c_str ());
|
||||
|
||||
scm_puts (">", port);
|
||||
|
||||
|
@ -37,11 +37,18 @@
|
||||
|
||||
/* A ui-file for sending output to Guile. */
|
||||
|
||||
typedef struct
|
||||
class ioscm_file_port : public ui_file
|
||||
{
|
||||
int *magic;
|
||||
SCM port;
|
||||
} ioscm_file_port;
|
||||
public:
|
||||
/* Return a ui_file that writes to PORT. */
|
||||
explicit ioscm_file_port (SCM port);
|
||||
|
||||
void flush () override;
|
||||
void write (const char *buf, long length_buf) override;
|
||||
|
||||
private:
|
||||
SCM m_port;
|
||||
};
|
||||
|
||||
/* Data for a memory port. */
|
||||
|
||||
@ -431,74 +438,21 @@ gdbscm_error_port (void)
|
||||
|
||||
/* Support for sending GDB I/O to Guile ports. */
|
||||
|
||||
static void
|
||||
ioscm_file_port_delete (struct ui_file *file)
|
||||
{
|
||||
ioscm_file_port *stream = (ioscm_file_port *) ui_file_data (file);
|
||||
ioscm_file_port::ioscm_file_port (SCM port)
|
||||
: m_port (port)
|
||||
{}
|
||||
|
||||
if (stream->magic != &file_port_magic)
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("ioscm_file_port_delete: bad magic number"));
|
||||
xfree (stream);
|
||||
void
|
||||
ioscm_file_port::flush ()
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
ioscm_file_port_rewind (struct ui_file *file)
|
||||
void
|
||||
ioscm_file_port::write (const char *buffer, long length_buffer)
|
||||
{
|
||||
ioscm_file_port *stream = (ioscm_file_port *) ui_file_data (file);
|
||||
|
||||
if (stream->magic != &file_port_magic)
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("ioscm_file_port_rewind: bad magic number"));
|
||||
|
||||
scm_truncate_file (stream->port, 0);
|
||||
scm_c_write (m_port, buffer, length_buffer);
|
||||
}
|
||||
|
||||
static void
|
||||
ioscm_file_port_put (struct ui_file *file,
|
||||
ui_file_put_method_ftype *write,
|
||||
void *dest)
|
||||
{
|
||||
ioscm_file_port *stream = (ioscm_file_port *) ui_file_data (file);
|
||||
|
||||
if (stream->magic != &file_port_magic)
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("ioscm_file_port_put: bad magic number"));
|
||||
|
||||
/* This function doesn't meld with ports very well. */
|
||||
}
|
||||
|
||||
static void
|
||||
ioscm_file_port_write (struct ui_file *file,
|
||||
const char *buffer,
|
||||
long length_buffer)
|
||||
{
|
||||
ioscm_file_port *stream = (ioscm_file_port *) ui_file_data (file);
|
||||
|
||||
if (stream->magic != &file_port_magic)
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("ioscm_pot_file_write: bad magic number"));
|
||||
|
||||
scm_c_write (stream->port, buffer, length_buffer);
|
||||
}
|
||||
|
||||
/* Return a ui_file that writes to PORT. */
|
||||
|
||||
static struct ui_file *
|
||||
ioscm_file_port_new (SCM port)
|
||||
{
|
||||
ioscm_file_port *stream = XCNEW (ioscm_file_port);
|
||||
struct ui_file *file = ui_file_new ();
|
||||
|
||||
set_ui_file_data (file, stream, ioscm_file_port_delete);
|
||||
set_ui_file_rewind (file, ioscm_file_port_rewind);
|
||||
set_ui_file_put (file, ioscm_file_port_put);
|
||||
set_ui_file_write (file, ioscm_file_port_write);
|
||||
stream->magic = &file_port_magic;
|
||||
stream->port = port;
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
/* Helper routine for with-{output,error}-to-port. */
|
||||
|
||||
@ -506,7 +460,6 @@ static SCM
|
||||
ioscm_with_output_to_port_worker (SCM port, SCM thunk, enum oport oport,
|
||||
const char *func_name)
|
||||
{
|
||||
struct ui_file *port_file;
|
||||
struct cleanup *cleanups;
|
||||
SCM result;
|
||||
|
||||
@ -520,21 +473,19 @@ ioscm_with_output_to_port_worker (SCM port, SCM thunk, enum oport oport,
|
||||
make_cleanup_restore_integer (¤t_ui->async);
|
||||
current_ui->async = 0;
|
||||
|
||||
port_file = ioscm_file_port_new (port);
|
||||
|
||||
make_cleanup_ui_file_delete (port_file);
|
||||
ui_file_up port_file (new ioscm_file_port (port));
|
||||
|
||||
scoped_restore save_file = make_scoped_restore (oport == GDB_STDERR
|
||||
? &gdb_stderr : &gdb_stdout);
|
||||
|
||||
if (oport == GDB_STDERR)
|
||||
gdb_stderr = port_file;
|
||||
gdb_stderr = port_file.get ();
|
||||
else
|
||||
{
|
||||
current_uiout->redirect (port_file);
|
||||
current_uiout->redirect (port_file.get ());
|
||||
make_cleanup_ui_out_redirect_pop (current_uiout);
|
||||
|
||||
gdb_stdout = port_file;
|
||||
gdb_stdout = port_file.get ();
|
||||
}
|
||||
|
||||
result = gdbscm_safe_call_0 (thunk, NULL);
|
||||
|
@ -107,18 +107,10 @@ tyscm_type_name (struct type *type)
|
||||
{
|
||||
TRY
|
||||
{
|
||||
struct cleanup *old_chain;
|
||||
struct ui_file *stb;
|
||||
string_file stb;
|
||||
|
||||
stb = mem_fileopen ();
|
||||
old_chain = make_cleanup_ui_file_delete (stb);
|
||||
|
||||
LA_PRINT_TYPE (type, "", stb, -1, 0, &type_print_raw_options);
|
||||
|
||||
std::string name = ui_file_as_string (stb);
|
||||
do_cleanups (old_chain);
|
||||
|
||||
return name;
|
||||
LA_PRINT_TYPE (type, "", &stb, -1, 0, &type_print_raw_options);
|
||||
return std::move (stb.string ());
|
||||
}
|
||||
CATCH (except, RETURN_MASK_ALL)
|
||||
{
|
||||
|
@ -157,15 +157,10 @@ vlscm_print_value_smob (SCM self, SCM port, scm_print_state *pstate)
|
||||
|
||||
TRY
|
||||
{
|
||||
struct ui_file *stb = mem_fileopen ();
|
||||
struct cleanup *old_chain = make_cleanup_ui_file_delete (stb);
|
||||
string_file stb;
|
||||
|
||||
common_val_print (v_smob->value, stb, 0, &opts, current_language);
|
||||
|
||||
std::string s = ui_file_as_string (stb);
|
||||
scm_puts (s.c_str (), port);
|
||||
|
||||
do_cleanups (old_chain);
|
||||
common_val_print (v_smob->value, &stb, 0, &opts, current_language);
|
||||
scm_puts (stb.c_str (), port);
|
||||
}
|
||||
CATCH (except, RETURN_MASK_ALL)
|
||||
{
|
||||
@ -1277,21 +1272,15 @@ gdbscm_value_print (SCM self)
|
||||
= vlscm_get_value_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
|
||||
struct value *value = v_smob->value;
|
||||
struct value_print_options opts;
|
||||
std::string s;
|
||||
SCM result;
|
||||
|
||||
get_user_print_options (&opts);
|
||||
opts.deref_ref = 0;
|
||||
|
||||
string_file stb;
|
||||
|
||||
TRY
|
||||
{
|
||||
struct ui_file *stb = mem_fileopen ();
|
||||
struct cleanup *old_chain = make_cleanup_ui_file_delete (stb);
|
||||
|
||||
common_val_print (value, stb, 0, &opts, current_language);
|
||||
s = ui_file_as_string (stb);
|
||||
|
||||
do_cleanups (old_chain);
|
||||
common_val_print (value, &stb, 0, &opts, current_language);
|
||||
}
|
||||
CATCH (except, RETURN_MASK_ALL)
|
||||
{
|
||||
@ -1304,10 +1293,8 @@ gdbscm_value_print (SCM self)
|
||||
IWBN to use scm_take_locale_string here, but we'd have to temporarily
|
||||
override the default port conversion handler because contrary to
|
||||
documentation it doesn't necessarily free the input string. */
|
||||
result = scm_from_stringn (s.c_str (), s.size (), host_charset (),
|
||||
SCM_FAILED_CONVERSION_QUESTION_MARK);
|
||||
|
||||
return result;
|
||||
return scm_from_stringn (stb.c_str (), stb.size (), host_charset (),
|
||||
SCM_FAILED_CONVERSION_QUESTION_MARK);
|
||||
}
|
||||
|
||||
/* (parse-and-eval string) -> <gdb:value>
|
||||
|
12
gdb/infcmd.c
12
gdb/infcmd.c
@ -1670,21 +1670,19 @@ print_return_value_1 (struct ui_out *uiout, struct return_value_info *rv)
|
||||
if (rv->value != NULL)
|
||||
{
|
||||
struct value_print_options opts;
|
||||
struct ui_file *stb;
|
||||
struct cleanup *old_chain;
|
||||
|
||||
/* Print it. */
|
||||
stb = mem_fileopen ();
|
||||
old_chain = make_cleanup_ui_file_delete (stb);
|
||||
uiout->text ("Value returned is ");
|
||||
uiout->field_fmt ("gdb-result-var", "$%d",
|
||||
rv->value_history_index);
|
||||
rv->value_history_index);
|
||||
uiout->text (" = ");
|
||||
get_no_prettyformat_print_options (&opts);
|
||||
value_print (rv->value, stb, &opts);
|
||||
|
||||
string_file stb;
|
||||
|
||||
value_print (rv->value, &stb, &opts);
|
||||
uiout->field_stream ("return-value", stb);
|
||||
uiout->text ("\n");
|
||||
do_cleanups (old_chain);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
36
gdb/infrun.c
36
gdb/infrun.c
@ -3438,40 +3438,32 @@ print_target_wait_results (ptid_t waiton_ptid, ptid_t result_ptid,
|
||||
const struct target_waitstatus *ws)
|
||||
{
|
||||
char *status_string = target_waitstatus_to_string (ws);
|
||||
struct ui_file *tmp_stream = mem_fileopen ();
|
||||
string_file stb;
|
||||
|
||||
/* The text is split over several lines because it was getting too long.
|
||||
Call fprintf_unfiltered (gdb_stdlog) once so that the text is still
|
||||
output as a unit; we want only one timestamp printed if debug_timestamp
|
||||
is set. */
|
||||
|
||||
fprintf_unfiltered (tmp_stream,
|
||||
"infrun: target_wait (%d.%ld.%ld",
|
||||
ptid_get_pid (waiton_ptid),
|
||||
ptid_get_lwp (waiton_ptid),
|
||||
ptid_get_tid (waiton_ptid));
|
||||
stb.printf ("infrun: target_wait (%d.%ld.%ld",
|
||||
ptid_get_pid (waiton_ptid),
|
||||
ptid_get_lwp (waiton_ptid),
|
||||
ptid_get_tid (waiton_ptid));
|
||||
if (ptid_get_pid (waiton_ptid) != -1)
|
||||
fprintf_unfiltered (tmp_stream,
|
||||
" [%s]", target_pid_to_str (waiton_ptid));
|
||||
fprintf_unfiltered (tmp_stream, ", status) =\n");
|
||||
fprintf_unfiltered (tmp_stream,
|
||||
"infrun: %d.%ld.%ld [%s],\n",
|
||||
ptid_get_pid (result_ptid),
|
||||
ptid_get_lwp (result_ptid),
|
||||
ptid_get_tid (result_ptid),
|
||||
target_pid_to_str (result_ptid));
|
||||
fprintf_unfiltered (tmp_stream,
|
||||
"infrun: %s\n",
|
||||
status_string);
|
||||
|
||||
std::string text = ui_file_as_string (tmp_stream);
|
||||
stb.printf (" [%s]", target_pid_to_str (waiton_ptid));
|
||||
stb.printf (", status) =\n");
|
||||
stb.printf ("infrun: %d.%ld.%ld [%s],\n",
|
||||
ptid_get_pid (result_ptid),
|
||||
ptid_get_lwp (result_ptid),
|
||||
ptid_get_tid (result_ptid),
|
||||
target_pid_to_str (result_ptid));
|
||||
stb.printf ("infrun: %s\n", status_string);
|
||||
|
||||
/* This uses %s in part to handle %'s in the text, but also to avoid
|
||||
a gcc error: the format attribute requires a string literal. */
|
||||
fprintf_unfiltered (gdb_stdlog, "%s", text.c_str ());
|
||||
fprintf_unfiltered (gdb_stdlog, "%s", stb.c_str ());
|
||||
|
||||
xfree (status_string);
|
||||
ui_file_delete (tmp_stream);
|
||||
}
|
||||
|
||||
/* Select a thread at random, out of those which are resumed and have
|
||||
|
@ -539,9 +539,6 @@ add_language (const struct language_defn *lang)
|
||||
static const char **language_names = NULL;
|
||||
/* For the "help set language" command. */
|
||||
|
||||
int i;
|
||||
struct ui_file *tmp_stream;
|
||||
|
||||
if (lang->la_magic != LANG_MAGIC)
|
||||
{
|
||||
fprintf_unfiltered (gdb_stderr,
|
||||
@ -569,9 +566,9 @@ add_language (const struct language_defn *lang)
|
||||
language_names = XRESIZEVEC (const char *, language_names,
|
||||
languages_size + 1);
|
||||
|
||||
for (i = 0; i < languages_size; ++i)
|
||||
for (int i = 0; i < languages_size; ++i)
|
||||
language_names[i] = languages[i]->la_name;
|
||||
language_names[i] = NULL;
|
||||
language_names[languages_size] = NULL;
|
||||
|
||||
/* Add the filename extensions. */
|
||||
if (lang->la_filename_extensions != NULL)
|
||||
@ -584,37 +581,32 @@ add_language (const struct language_defn *lang)
|
||||
}
|
||||
|
||||
/* Build the "help set language" docs. */
|
||||
tmp_stream = mem_fileopen ();
|
||||
string_file doc;
|
||||
|
||||
fprintf_unfiltered (tmp_stream,
|
||||
_("Set the current source language.\n"
|
||||
"The currently understood settings are:\n\nlocal or "
|
||||
"auto Automatic setting based on source file\n"));
|
||||
doc.printf (_("Set the current source language.\n"
|
||||
"The currently understood settings are:\n\nlocal or "
|
||||
"auto Automatic setting based on source file\n"));
|
||||
|
||||
for (i = 0; i < languages_size; ++i)
|
||||
for (int i = 0; i < languages_size; ++i)
|
||||
{
|
||||
/* Already dealt with these above. */
|
||||
if (languages[i]->la_language == language_unknown
|
||||
|| languages[i]->la_language == language_auto)
|
||||
continue;
|
||||
|
||||
/* FIXME: i18n: for now assume that the human-readable name
|
||||
is just a capitalization of the internal name. */
|
||||
fprintf_unfiltered (tmp_stream, "%-16s Use the %c%s language\n",
|
||||
languages[i]->la_name,
|
||||
/* Capitalize first letter of language
|
||||
name. */
|
||||
toupper (languages[i]->la_name[0]),
|
||||
languages[i]->la_name + 1);
|
||||
/* FIXME: i18n: for now assume that the human-readable name is
|
||||
just a capitalization of the internal name. */
|
||||
doc.printf ("%-16s Use the %c%s language\n",
|
||||
languages[i]->la_name,
|
||||
/* Capitalize first letter of language name. */
|
||||
toupper (languages[i]->la_name[0]),
|
||||
languages[i]->la_name + 1);
|
||||
}
|
||||
|
||||
std::string language_set_doc = ui_file_as_string (tmp_stream);
|
||||
ui_file_delete (tmp_stream);
|
||||
|
||||
add_setshow_enum_cmd ("language", class_support,
|
||||
(const char **) language_names,
|
||||
&language,
|
||||
language_set_doc.c_str (),
|
||||
doc.c_str (),
|
||||
_("Show the current source language."),
|
||||
NULL, set_language_command,
|
||||
show_language_command,
|
||||
|
@ -227,59 +227,52 @@ static char *
|
||||
explicit_to_string_internal (int as_linespec,
|
||||
const struct explicit_location *explicit_loc)
|
||||
{
|
||||
struct ui_file *buf;
|
||||
char space, *result;
|
||||
int need_space = 0;
|
||||
struct cleanup *cleanup;
|
||||
|
||||
space = as_linespec ? ':' : ' ';
|
||||
buf = mem_fileopen ();
|
||||
cleanup = make_cleanup_ui_file_delete (buf);
|
||||
char space = as_linespec ? ':' : ' ';
|
||||
string_file buf;
|
||||
|
||||
if (explicit_loc->source_filename != NULL)
|
||||
{
|
||||
if (!as_linespec)
|
||||
fputs_unfiltered ("-source ", buf);
|
||||
fputs_unfiltered (explicit_loc->source_filename, buf);
|
||||
buf.puts ("-source ");
|
||||
buf.puts (explicit_loc->source_filename);
|
||||
need_space = 1;
|
||||
}
|
||||
|
||||
if (explicit_loc->function_name != NULL)
|
||||
{
|
||||
if (need_space)
|
||||
fputc_unfiltered (space, buf);
|
||||
buf.putc (space);
|
||||
if (!as_linespec)
|
||||
fputs_unfiltered ("-function ", buf);
|
||||
fputs_unfiltered (explicit_loc->function_name, buf);
|
||||
buf.puts ("-function ");
|
||||
buf.puts (explicit_loc->function_name);
|
||||
need_space = 1;
|
||||
}
|
||||
|
||||
if (explicit_loc->label_name != NULL)
|
||||
{
|
||||
if (need_space)
|
||||
fputc_unfiltered (space, buf);
|
||||
buf.putc (space);
|
||||
if (!as_linespec)
|
||||
fputs_unfiltered ("-label ", buf);
|
||||
fputs_unfiltered (explicit_loc->label_name, buf);
|
||||
buf.puts ("-label ");
|
||||
buf.puts (explicit_loc->label_name);
|
||||
need_space = 1;
|
||||
}
|
||||
|
||||
if (explicit_loc->line_offset.sign != LINE_OFFSET_UNKNOWN)
|
||||
{
|
||||
if (need_space)
|
||||
fputc_unfiltered (space, buf);
|
||||
buf.putc (space);
|
||||
if (!as_linespec)
|
||||
fputs_unfiltered ("-line ", buf);
|
||||
fprintf_filtered (buf, "%s%d",
|
||||
(explicit_loc->line_offset.sign == LINE_OFFSET_NONE ? ""
|
||||
: (explicit_loc->line_offset.sign
|
||||
== LINE_OFFSET_PLUS ? "+" : "-")),
|
||||
explicit_loc->line_offset.offset);
|
||||
buf.puts ("-line ");
|
||||
buf.printf ("%s%d",
|
||||
(explicit_loc->line_offset.sign == LINE_OFFSET_NONE ? ""
|
||||
: (explicit_loc->line_offset.sign
|
||||
== LINE_OFFSET_PLUS ? "+" : "-")),
|
||||
explicit_loc->line_offset.offset);
|
||||
}
|
||||
|
||||
result = ui_file_xstrdup (buf, NULL);
|
||||
do_cleanups (cleanup);
|
||||
return result;
|
||||
return xstrdup (buf.c_str ());
|
||||
}
|
||||
|
||||
/* See description in location.h. */
|
||||
|
@ -763,7 +763,7 @@ captured_main_1 (struct captured_main_args *context)
|
||||
break;
|
||||
case 'B':
|
||||
batch_flag = batch_silent = 1;
|
||||
gdb_stdout = ui_file_new();
|
||||
gdb_stdout = new null_file ();
|
||||
break;
|
||||
case 'D':
|
||||
if (optarg[0] == '\0')
|
||||
|
@ -403,14 +403,11 @@ maintenance_print_architecture (char *args, int from_tty)
|
||||
gdbarch_dump (gdbarch, gdb_stdout);
|
||||
else
|
||||
{
|
||||
struct cleanup *cleanups;
|
||||
struct ui_file *file = gdb_fopen (args, "w");
|
||||
stdio_file file;
|
||||
|
||||
if (file == NULL)
|
||||
if (!file.open (args, "w"))
|
||||
perror_with_name (_("maintenance print architecture"));
|
||||
cleanups = make_cleanup_ui_file_delete (file);
|
||||
gdbarch_dump (gdbarch, file);
|
||||
do_cleanups (cleanups);
|
||||
gdbarch_dump (gdbarch, &file);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -488,7 +488,6 @@ list_arg_or_local (const struct frame_arg *arg, enum what_to_list what,
|
||||
{
|
||||
struct cleanup *old_chain;
|
||||
struct ui_out *uiout = current_uiout;
|
||||
struct ui_file *stb;
|
||||
|
||||
gdb_assert (!arg->val || !arg->error);
|
||||
gdb_assert ((values == PRINT_NO_VALUES && arg->val == NULL
|
||||
@ -511,15 +510,16 @@ list_arg_or_local (const struct frame_arg *arg, enum what_to_list what,
|
||||
TYPE_LENGTH (value_type (arg->val))))))
|
||||
return;
|
||||
|
||||
stb = mem_fileopen ();
|
||||
old_chain = make_cleanup_ui_file_delete (stb);
|
||||
old_chain = make_cleanup (null_cleanup, NULL);
|
||||
|
||||
if (values != PRINT_NO_VALUES || what == all)
|
||||
make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
|
||||
|
||||
fputs_filtered (SYMBOL_PRINT_NAME (arg->sym), stb);
|
||||
string_file stb;
|
||||
|
||||
stb.puts (SYMBOL_PRINT_NAME (arg->sym));
|
||||
if (arg->entry_kind == print_entry_values_only)
|
||||
fputs_filtered ("@entry", stb);
|
||||
stb.puts ("@entry");
|
||||
uiout->field_stream ("name", stb);
|
||||
|
||||
if (what == all && SYMBOL_IS_ARGUMENT (arg->sym))
|
||||
@ -528,7 +528,7 @@ list_arg_or_local (const struct frame_arg *arg, enum what_to_list what,
|
||||
if (values == PRINT_SIMPLE_VALUES)
|
||||
{
|
||||
check_typedef (arg->sym->type);
|
||||
type_print (arg->sym->type, "", stb, -1);
|
||||
type_print (arg->sym->type, "", &stb, -1);
|
||||
uiout->field_stream ("type", stb);
|
||||
}
|
||||
|
||||
@ -546,7 +546,7 @@ list_arg_or_local (const struct frame_arg *arg, enum what_to_list what,
|
||||
|
||||
get_no_prettyformat_print_options (&opts);
|
||||
opts.deref_ref = 1;
|
||||
common_val_print (arg->val, stb, 0, &opts,
|
||||
common_val_print (arg->val, &stb, 0, &opts,
|
||||
language_def (SYMBOL_LANGUAGE (arg->sym)));
|
||||
}
|
||||
CATCH (except, RETURN_MASK_ERROR)
|
||||
@ -556,8 +556,7 @@ list_arg_or_local (const struct frame_arg *arg, enum what_to_list what,
|
||||
END_CATCH
|
||||
}
|
||||
if (error_message != NULL)
|
||||
fprintf_filtered (stb, _("<error reading variable: %s>"),
|
||||
error_message);
|
||||
stb.printf (_("<error reading variable: %s>"), error_message);
|
||||
uiout->field_stream ("value", stb);
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,8 @@
|
||||
#ifndef MI_COMMON_H
|
||||
#define MI_COMMON_H
|
||||
|
||||
struct mi_console_file;
|
||||
|
||||
/* Represents the reason why GDB is sending an asynchronous command to
|
||||
the front end. NOTE: When modifing this, don't forget to update
|
||||
gdb.texinfo! */
|
||||
@ -51,11 +53,11 @@ const char *async_reason_lookup (enum async_reply_reason reason);
|
||||
struct mi_interp
|
||||
{
|
||||
/* MI's output channels */
|
||||
struct ui_file *out;
|
||||
struct ui_file *err;
|
||||
struct ui_file *log;
|
||||
struct ui_file *targ;
|
||||
struct ui_file *event_channel;
|
||||
mi_console_file *out;
|
||||
mi_console_file *err;
|
||||
mi_console_file *log;
|
||||
mi_console_file *targ;
|
||||
mi_console_file *event_channel;
|
||||
|
||||
/* Raw console output. */
|
||||
struct ui_file *raw_stdout;
|
||||
|
@ -26,118 +26,56 @@
|
||||
|
||||
#include "defs.h"
|
||||
#include "mi-console.h"
|
||||
static ui_file_fputs_ftype mi_console_file_fputs;
|
||||
static ui_file_flush_ftype mi_console_file_flush;
|
||||
static ui_file_delete_ftype mi_console_file_delete;
|
||||
|
||||
struct mi_console_file
|
||||
{
|
||||
int *magic;
|
||||
struct ui_file *raw;
|
||||
struct ui_file *buffer;
|
||||
const char *prefix;
|
||||
char quote;
|
||||
};
|
||||
|
||||
/* Use the address of this otherwise-unused global as a magic number
|
||||
identifying this class of ui_file objects. */
|
||||
static int mi_console_file_magic;
|
||||
|
||||
/* Create a console that wraps the given output stream RAW with the
|
||||
string PREFIX and quoting it with QUOTE. */
|
||||
|
||||
struct ui_file *
|
||||
mi_console_file_new (struct ui_file *raw, const char *prefix, char quote)
|
||||
mi_console_file::mi_console_file (ui_file *raw, const char *prefix, char quote)
|
||||
: m_raw (raw),
|
||||
m_prefix (prefix),
|
||||
m_quote (quote)
|
||||
{}
|
||||
|
||||
void
|
||||
mi_console_file::write (const char *buf, long length_buf)
|
||||
{
|
||||
struct ui_file *ui_file = ui_file_new ();
|
||||
struct mi_console_file *mi_console = XNEW (struct mi_console_file);
|
||||
|
||||
mi_console->magic = &mi_console_file_magic;
|
||||
mi_console->raw = raw;
|
||||
mi_console->buffer = mem_fileopen ();
|
||||
mi_console->prefix = prefix;
|
||||
mi_console->quote = quote;
|
||||
set_ui_file_fputs (ui_file, mi_console_file_fputs);
|
||||
set_ui_file_flush (ui_file, mi_console_file_flush);
|
||||
set_ui_file_data (ui_file, mi_console, mi_console_file_delete);
|
||||
|
||||
return ui_file;
|
||||
}
|
||||
|
||||
static void
|
||||
mi_console_file_delete (struct ui_file *file)
|
||||
{
|
||||
struct mi_console_file *mi_console
|
||||
= (struct mi_console_file *) ui_file_data (file);
|
||||
|
||||
if (mi_console->magic != &mi_console_file_magic)
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("mi_console_file_delete: bad magic number"));
|
||||
|
||||
xfree (mi_console);
|
||||
}
|
||||
|
||||
static void
|
||||
mi_console_file_fputs (const char *buf, struct ui_file *file)
|
||||
{
|
||||
struct mi_console_file *mi_console
|
||||
= (struct mi_console_file *) ui_file_data (file);
|
||||
|
||||
if (mi_console->magic != &mi_console_file_magic)
|
||||
internal_error (__FILE__, __LINE__,
|
||||
"mi_console_file_fputs: bad magic number");
|
||||
|
||||
size_t prev_size = m_buffer.size ();
|
||||
/* Append the text to our internal buffer. */
|
||||
fputs_unfiltered (buf, mi_console->buffer);
|
||||
/* Flush when an embedded newline is present anywhere in the buffer. */
|
||||
if (strchr (buf, '\n') != NULL)
|
||||
gdb_flush (file);
|
||||
m_buffer.write (buf, length_buf);
|
||||
/* Flush when an embedded newline is present anywhere in the
|
||||
buffer. */
|
||||
if (strchr (m_buffer.c_str () + prev_size, '\n') != NULL)
|
||||
this->flush ();
|
||||
}
|
||||
|
||||
/* Transform a byte sequence into a console output packet. */
|
||||
|
||||
static void
|
||||
mi_console_raw_packet (void *data, const char *buf, long length_buf)
|
||||
void
|
||||
mi_console_file::flush ()
|
||||
{
|
||||
struct mi_console_file *mi_console = (struct mi_console_file *) data;
|
||||
const std::string &str = m_buffer.string ();
|
||||
|
||||
if (mi_console->magic != &mi_console_file_magic)
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("mi_console_raw_packet: bad magic number"));
|
||||
|
||||
if (length_buf > 0)
|
||||
/* Transform a byte sequence into a console output packet. */
|
||||
if (!str.empty ())
|
||||
{
|
||||
fputs_unfiltered (mi_console->prefix, mi_console->raw);
|
||||
if (mi_console->quote)
|
||||
size_t length_buf = str.size ();
|
||||
const char *buf = str.data ();
|
||||
|
||||
fputs_unfiltered (m_prefix, m_raw);
|
||||
if (m_quote)
|
||||
{
|
||||
fputc_unfiltered (mi_console->quote, mi_console->raw);
|
||||
fputstrn_unfiltered (buf, length_buf,
|
||||
mi_console->quote, mi_console->raw);
|
||||
fputc_unfiltered (mi_console->quote, mi_console->raw);
|
||||
fputc_unfiltered ('\n', mi_console->raw);
|
||||
fputc_unfiltered (m_quote, m_raw);
|
||||
fputstrn_unfiltered (buf, length_buf, m_quote, m_raw);
|
||||
fputc_unfiltered (m_quote, m_raw);
|
||||
fputc_unfiltered ('\n', m_raw);
|
||||
}
|
||||
else
|
||||
{
|
||||
fputstrn_unfiltered (buf, length_buf, 0, mi_console->raw);
|
||||
fputc_unfiltered ('\n', mi_console->raw);
|
||||
fputstrn_unfiltered (buf, length_buf, 0, m_raw);
|
||||
fputc_unfiltered ('\n', m_raw);
|
||||
}
|
||||
gdb_flush (mi_console->raw);
|
||||
gdb_flush (m_raw);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
mi_console_file_flush (struct ui_file *file)
|
||||
{
|
||||
struct mi_console_file *mi_console
|
||||
= (struct mi_console_file *) ui_file_data (file);
|
||||
|
||||
if (mi_console->magic != &mi_console_file_magic)
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("mi_console_file_flush: bad magic number"));
|
||||
|
||||
ui_file_put (mi_console->buffer, mi_console_raw_packet, mi_console);
|
||||
ui_file_rewind (mi_console->buffer);
|
||||
|
||||
m_buffer.clear ();
|
||||
}
|
||||
|
||||
/* Change the underlying stream of the console directly; this is
|
||||
@ -145,14 +83,7 @@ mi_console_file_flush (struct ui_file *file)
|
||||
logging enable/disable. */
|
||||
|
||||
void
|
||||
mi_console_set_raw (struct ui_file *file, struct ui_file *raw)
|
||||
mi_console_file::set_raw (ui_file *raw)
|
||||
{
|
||||
struct mi_console_file *mi_console
|
||||
= (struct mi_console_file *) ui_file_data (file);
|
||||
|
||||
if (mi_console->magic != &mi_console_file_magic)
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("mi_console_file_set_raw: bad magic number"));
|
||||
|
||||
mi_console->raw = raw;
|
||||
m_raw = raw;
|
||||
}
|
||||
|
@ -20,11 +20,37 @@
|
||||
#ifndef MI_CONSOLE_H
|
||||
#define MI_CONSOLE_H
|
||||
|
||||
extern struct ui_file *mi_console_file_new (struct ui_file *raw,
|
||||
const char *prefix,
|
||||
char quote);
|
||||
/* An output stream for MI. Wraps a given output stream with a prefix
|
||||
and handles quoting. This stream is locally buffered. */
|
||||
|
||||
extern void mi_console_set_raw (struct ui_file *console,
|
||||
struct ui_file *raw);
|
||||
class mi_console_file : public ui_file
|
||||
{
|
||||
public:
|
||||
/* Create a console that wraps the given output stream RAW with the
|
||||
string PREFIX and quoting it with QUOTE. */
|
||||
mi_console_file (ui_file *raw, const char *prefix, char quote);
|
||||
|
||||
/* MI-specific API. */
|
||||
void set_raw (ui_file *raw);
|
||||
|
||||
/* ui_file-specific methods. */
|
||||
|
||||
void flush () override;
|
||||
|
||||
void write (const char *buf, long length_buf) override;
|
||||
|
||||
private:
|
||||
/* The wrapped raw output stream. */
|
||||
ui_file *m_raw;
|
||||
|
||||
/* The local buffer. */
|
||||
string_file m_buffer;
|
||||
|
||||
/* The prefix. */
|
||||
const char *m_prefix;
|
||||
|
||||
/* The quote char. */
|
||||
char m_quote;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -126,11 +126,11 @@ mi_interpreter_init (struct interp *interp, int top_level)
|
||||
|
||||
/* Create MI console channels, each with a different prefix so they
|
||||
can be distinguished. */
|
||||
mi->out = mi_console_file_new (mi->raw_stdout, "~", '"');
|
||||
mi->err = mi_console_file_new (mi->raw_stdout, "&", '"');
|
||||
mi->out = new mi_console_file (mi->raw_stdout, "~", '"');
|
||||
mi->err = new mi_console_file (mi->raw_stdout, "&", '"');
|
||||
mi->log = mi->err;
|
||||
mi->targ = mi_console_file_new (mi->raw_stdout, "@", '"');
|
||||
mi->event_channel = mi_console_file_new (mi->raw_stdout, "=", 0);
|
||||
mi->targ = new mi_console_file (mi->raw_stdout, "@", '"');
|
||||
mi->event_channel = new mi_console_file (mi->raw_stdout, "=", 0);
|
||||
|
||||
name = interp_name (interp);
|
||||
/* INTERP_MI selects the most recent released version. "mi2" was
|
||||
@ -1391,8 +1391,8 @@ mi_set_logging (struct interp *interp, int start_log,
|
||||
it), and create one based on raw_stdout instead. */
|
||||
if (logfile)
|
||||
{
|
||||
ui_file_delete (out);
|
||||
out = tee_file_new (mi->raw_stdout, 0, logfile, 0);
|
||||
delete out;
|
||||
out = new tee_file (mi->raw_stdout, false, logfile, false);
|
||||
}
|
||||
|
||||
mi->saved_raw_stdout = mi->raw_stdout;
|
||||
@ -1404,11 +1404,11 @@ mi_set_logging (struct interp *interp, int start_log,
|
||||
mi->saved_raw_stdout = NULL;
|
||||
}
|
||||
|
||||
mi_console_set_raw (mi->out, mi->raw_stdout);
|
||||
mi_console_set_raw (mi->err, mi->raw_stdout);
|
||||
mi_console_set_raw (mi->log, mi->raw_stdout);
|
||||
mi_console_set_raw (mi->targ, mi->raw_stdout);
|
||||
mi_console_set_raw (mi->event_channel, mi->raw_stdout);
|
||||
mi->out->set_raw (mi->raw_stdout);
|
||||
mi->err->set_raw (mi->raw_stdout);
|
||||
mi->log->set_raw (mi->raw_stdout);
|
||||
mi->targ->set_raw (mi->raw_stdout);
|
||||
mi->event_channel->set_raw (mi->raw_stdout);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -1267,7 +1267,6 @@ output_register (struct frame_info *frame, int regnum, int format,
|
||||
struct value *val = value_of_register (regnum, frame);
|
||||
struct cleanup *tuple_cleanup;
|
||||
struct value_print_options opts;
|
||||
struct ui_file *stb;
|
||||
|
||||
if (skip_unavailable && !value_entirely_available (val))
|
||||
return;
|
||||
@ -1281,14 +1280,13 @@ output_register (struct frame_info *frame, int regnum, int format,
|
||||
if (format == 'r')
|
||||
format = 'z';
|
||||
|
||||
stb = mem_fileopen ();
|
||||
make_cleanup_ui_file_delete (stb);
|
||||
string_file stb;
|
||||
|
||||
get_formatted_print_options (&opts, format);
|
||||
opts.deref_ref = 1;
|
||||
val_print (value_type (val),
|
||||
value_embedded_offset (val), 0,
|
||||
stb, 0, val, &opts, current_language);
|
||||
&stb, 0, val, &opts, current_language);
|
||||
uiout->field_stream ("value", stb);
|
||||
|
||||
do_cleanups (tuple_cleanup);
|
||||
@ -1358,15 +1356,10 @@ mi_cmd_data_write_register_values (char *command, char **argv, int argc)
|
||||
void
|
||||
mi_cmd_data_evaluate_expression (char *command, char **argv, int argc)
|
||||
{
|
||||
struct cleanup *old_chain;
|
||||
struct value *val;
|
||||
struct ui_file *stb;
|
||||
struct value_print_options opts;
|
||||
struct ui_out *uiout = current_uiout;
|
||||
|
||||
stb = mem_fileopen ();
|
||||
old_chain = make_cleanup_ui_file_delete (stb);
|
||||
|
||||
if (argc != 1)
|
||||
error (_("-data-evaluate-expression: "
|
||||
"Usage: -data-evaluate-expression expression"));
|
||||
@ -1375,14 +1368,14 @@ mi_cmd_data_evaluate_expression (char *command, char **argv, int argc)
|
||||
|
||||
val = evaluate_expression (expr.get ());
|
||||
|
||||
string_file stb;
|
||||
|
||||
/* Print the result of the expression evaluation. */
|
||||
get_user_print_options (&opts);
|
||||
opts.deref_ref = 0;
|
||||
common_val_print (val, stb, 0, &opts, current_language);
|
||||
common_val_print (val, &stb, 0, &opts, current_language);
|
||||
|
||||
uiout->field_stream ("value", stb);
|
||||
|
||||
do_cleanups (old_chain);
|
||||
}
|
||||
|
||||
/* This is the -data-read-memory command.
|
||||
@ -1522,15 +1515,13 @@ mi_cmd_data_read_memory (char *command, char **argv, int argc)
|
||||
|
||||
/* Build the result as a two dimentional table. */
|
||||
{
|
||||
struct ui_file *stream;
|
||||
struct cleanup *cleanup_stream;
|
||||
int row;
|
||||
int row_byte;
|
||||
struct cleanup *cleanup_list;
|
||||
|
||||
stream = mem_fileopen ();
|
||||
cleanup_stream = make_cleanup_ui_file_delete (stream);
|
||||
string_file stream;
|
||||
|
||||
make_cleanup_ui_out_list_begin_end (uiout, "memory");
|
||||
cleanup_list = make_cleanup_ui_out_list_begin_end (uiout, "memory");
|
||||
for (row = 0, row_byte = 0;
|
||||
row < nr_rows;
|
||||
row++, row_byte += nr_cols * word_size)
|
||||
@ -1557,9 +1548,9 @@ mi_cmd_data_read_memory (char *command, char **argv, int argc)
|
||||
}
|
||||
else
|
||||
{
|
||||
ui_file_rewind (stream);
|
||||
stream.clear ();
|
||||
print_scalar_formatted (&mbuf[col_byte], word_type, &opts,
|
||||
word_asize, stream);
|
||||
word_asize, &stream);
|
||||
uiout->field_stream (NULL, stream);
|
||||
}
|
||||
}
|
||||
@ -1568,22 +1559,22 @@ mi_cmd_data_read_memory (char *command, char **argv, int argc)
|
||||
{
|
||||
int byte;
|
||||
|
||||
ui_file_rewind (stream);
|
||||
stream.clear ();
|
||||
for (byte = row_byte;
|
||||
byte < row_byte + word_size * nr_cols; byte++)
|
||||
{
|
||||
if (byte >= nr_bytes)
|
||||
fputc_unfiltered ('X', stream);
|
||||
stream.putc ('X');
|
||||
else if (mbuf[byte] < 32 || mbuf[byte] > 126)
|
||||
fputc_unfiltered (aschar, stream);
|
||||
stream.putc (aschar);
|
||||
else
|
||||
fputc_unfiltered (mbuf[byte], stream);
|
||||
stream.putc (mbuf[byte]);
|
||||
}
|
||||
uiout->field_stream ("ascii", stream);
|
||||
}
|
||||
do_cleanups (cleanup_tuple);
|
||||
}
|
||||
do_cleanups (cleanup_stream);
|
||||
do_cleanups (cleanup_list);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2317,15 +2308,12 @@ mi_cmd_execute (struct mi_parse *parse)
|
||||
else
|
||||
{
|
||||
/* FIXME: DELETE THIS. */
|
||||
struct ui_file *stb;
|
||||
string_file stb;
|
||||
|
||||
stb = mem_fileopen ();
|
||||
stb.puts ("Undefined mi command: ");
|
||||
stb.putstr (parse->command, '"');
|
||||
stb.puts (" (missing implementation)");
|
||||
|
||||
fputs_unfiltered ("Undefined mi command: ", stb);
|
||||
fputstr_unfiltered (parse->command, '"', stb);
|
||||
fputs_unfiltered (" (missing implementation)", stb);
|
||||
|
||||
make_cleanup_ui_file_delete (stb);
|
||||
error_stream (stb);
|
||||
}
|
||||
do_cleanups (cleanup);
|
||||
@ -2705,12 +2693,10 @@ print_variable_or_computed (const char *expression, enum print_values values)
|
||||
{
|
||||
struct cleanup *old_chain;
|
||||
struct value *val;
|
||||
struct ui_file *stb;
|
||||
struct type *type;
|
||||
struct ui_out *uiout = current_uiout;
|
||||
|
||||
stb = mem_fileopen ();
|
||||
old_chain = make_cleanup_ui_file_delete (stb);
|
||||
string_file stb;
|
||||
|
||||
expression_up expr = parse_expression (expression);
|
||||
|
||||
@ -2719,6 +2705,7 @@ print_variable_or_computed (const char *expression, enum print_values values)
|
||||
else
|
||||
val = evaluate_expression (expr.get ());
|
||||
|
||||
old_chain = make_cleanup (null_cleanup, NULL);
|
||||
if (values != PRINT_NO_VALUES)
|
||||
make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
|
||||
uiout->field_string ("name", expression);
|
||||
@ -2727,7 +2714,7 @@ print_variable_or_computed (const char *expression, enum print_values values)
|
||||
{
|
||||
case PRINT_SIMPLE_VALUES:
|
||||
type = check_typedef (value_type (val));
|
||||
type_print (value_type (val), "", stb, -1);
|
||||
type_print (value_type (val), "", &stb, -1);
|
||||
uiout->field_stream ("type", stb);
|
||||
if (TYPE_CODE (type) != TYPE_CODE_ARRAY
|
||||
&& TYPE_CODE (type) != TYPE_CODE_STRUCT
|
||||
@ -2737,7 +2724,7 @@ print_variable_or_computed (const char *expression, enum print_values values)
|
||||
|
||||
get_no_prettyformat_print_options (&opts);
|
||||
opts.deref_ref = 1;
|
||||
common_val_print (val, stb, 0, &opts, current_language);
|
||||
common_val_print (val, &stb, 0, &opts, current_language);
|
||||
uiout->field_stream ("value", stb);
|
||||
}
|
||||
break;
|
||||
@ -2747,7 +2734,7 @@ print_variable_or_computed (const char *expression, enum print_values values)
|
||||
|
||||
get_no_prettyformat_print_options (&opts);
|
||||
opts.deref_ref = 1;
|
||||
common_val_print (val, stb, 0, &opts, current_language);
|
||||
common_val_print (val, &stb, 0, &opts, current_language);
|
||||
uiout->field_stream ("value", stb);
|
||||
}
|
||||
break;
|
||||
|
@ -236,23 +236,31 @@ mi_ui_out::close (ui_out_type type)
|
||||
m_suppress_field_separator = false;
|
||||
}
|
||||
|
||||
string_file *
|
||||
mi_ui_out::main_stream ()
|
||||
{
|
||||
gdb_assert (m_streams.size () == 1);
|
||||
|
||||
return (string_file *) m_streams.back ();
|
||||
}
|
||||
|
||||
/* Clear the buffer. */
|
||||
|
||||
void
|
||||
mi_ui_out::rewind ()
|
||||
{
|
||||
ui_file_rewind (m_streams.back ());
|
||||
main_stream ()->clear ();
|
||||
}
|
||||
|
||||
/* Dump the buffer onto the specified stream. */
|
||||
|
||||
void
|
||||
mi_ui_out::put (ui_file *stream)
|
||||
mi_ui_out::put (ui_file *where)
|
||||
{
|
||||
ui_file *outstream = m_streams.back ();
|
||||
string_file *mi_stream = main_stream ();
|
||||
|
||||
ui_file_put (outstream, ui_file_write_for_put, stream);
|
||||
ui_file_rewind (outstream);
|
||||
where->write (mi_stream->data (), mi_stream->size ());
|
||||
mi_stream->clear ();
|
||||
}
|
||||
|
||||
/* Return the current MI version. */
|
||||
@ -265,13 +273,12 @@ mi_ui_out::version ()
|
||||
|
||||
/* Constructor for an `mi_out_data' object. */
|
||||
|
||||
mi_ui_out::mi_ui_out (int mi_version, ui_file *stream)
|
||||
mi_ui_out::mi_ui_out (int mi_version)
|
||||
: m_suppress_field_separator (false),
|
||||
m_suppress_output (false),
|
||||
m_mi_version (mi_version)
|
||||
{
|
||||
gdb_assert (stream != NULL);
|
||||
|
||||
string_file *stream = new string_file ();
|
||||
m_streams.push_back (stream);
|
||||
}
|
||||
|
||||
@ -284,9 +291,7 @@ mi_ui_out::~mi_ui_out ()
|
||||
mi_ui_out *
|
||||
mi_out_new (int mi_version)
|
||||
{
|
||||
ui_file *stream = mem_fileopen ();
|
||||
|
||||
return new mi_ui_out (mi_version, stream);
|
||||
return new mi_ui_out (mi_version);
|
||||
}
|
||||
|
||||
/* Helper function to return the given UIOUT as an mi_ui_out. It is an error
|
||||
|
@ -30,7 +30,7 @@ class mi_ui_out : public ui_out
|
||||
{
|
||||
public:
|
||||
|
||||
explicit mi_ui_out (int mi_version, ui_file *stream);
|
||||
explicit mi_ui_out (int mi_version);
|
||||
virtual ~mi_ui_out ();
|
||||
|
||||
/* MI-specific */
|
||||
@ -78,6 +78,11 @@ private:
|
||||
void open (const char *name, ui_out_type type);
|
||||
void close (ui_out_type type);
|
||||
|
||||
/* Convenience method that returns the MI out's string stream cast
|
||||
to its appropriate type. Assumes/asserts that output was not
|
||||
redirected. */
|
||||
string_file *main_stream ();
|
||||
|
||||
bool m_suppress_field_separator;
|
||||
bool m_suppress_output;
|
||||
int m_mi_version;
|
||||
|
@ -2717,18 +2717,13 @@ printf_command (char *arg, int from_tty)
|
||||
static void
|
||||
eval_command (char *arg, int from_tty)
|
||||
{
|
||||
struct ui_file *ui_out = mem_fileopen ();
|
||||
struct cleanup *cleanups = make_cleanup_ui_file_delete (ui_out);
|
||||
string_file stb;
|
||||
|
||||
ui_printf (arg, ui_out);
|
||||
ui_printf (arg, &stb);
|
||||
|
||||
std::string expanded = ui_file_as_string (ui_out);
|
||||
|
||||
expanded = insert_user_defined_cmd_args (expanded.c_str ());
|
||||
std::string expanded = insert_user_defined_cmd_args (stb.c_str ());
|
||||
|
||||
execute_command (&expanded[0], from_tty);
|
||||
|
||||
do_cleanups (cleanups);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1965,6 +1965,8 @@ maintenance_print_psymbols (char *args, int from_tty)
|
||||
if (address_arg != NULL && source_arg != NULL)
|
||||
error (_("Must specify at most one of -pc and -source"));
|
||||
|
||||
stdio_file arg_outfile;
|
||||
|
||||
if (argv[outfile_idx] != NULL)
|
||||
{
|
||||
char *outfile_name;
|
||||
@ -1973,10 +1975,9 @@ maintenance_print_psymbols (char *args, int from_tty)
|
||||
error (_("Junk at end of command"));
|
||||
outfile_name = tilde_expand (argv[outfile_idx]);
|
||||
make_cleanup (xfree, outfile_name);
|
||||
outfile = gdb_fopen (outfile_name, FOPEN_WT);
|
||||
if (outfile == NULL)
|
||||
if (!arg_outfile.open (outfile_name, FOPEN_WT))
|
||||
perror_with_name (outfile_name);
|
||||
make_cleanup_ui_file_delete (outfile);
|
||||
outfile = &arg_outfile;
|
||||
}
|
||||
|
||||
if (address_arg != NULL)
|
||||
@ -2011,9 +2012,8 @@ maintenance_print_psymbols (char *args, int from_tty)
|
||||
{
|
||||
if (!printed_objfile_header)
|
||||
{
|
||||
fprintf_filtered (outfile,
|
||||
"\nPartial symtabs for objfile %s\n",
|
||||
objfile_name (objfile));
|
||||
outfile->printf ("\nPartial symtabs for objfile %s\n",
|
||||
objfile_name (objfile));
|
||||
printed_objfile_header = 1;
|
||||
}
|
||||
dump_psymtab (objfile, ps, outfile);
|
||||
@ -2039,9 +2039,8 @@ maintenance_print_psymbols (char *args, int from_tty)
|
||||
{
|
||||
if (!printed_objfile_header)
|
||||
{
|
||||
fprintf_filtered (outfile,
|
||||
"\nPartial symtabs for objfile %s\n",
|
||||
objfile_name (objfile));
|
||||
outfile->printf ("\nPartial symtabs for objfile %s\n",
|
||||
objfile_name (objfile));
|
||||
printed_objfile_header = 1;
|
||||
}
|
||||
dump_psymtab (objfile, ps, outfile);
|
||||
@ -2056,7 +2055,7 @@ maintenance_print_psymbols (char *args, int from_tty)
|
||||
&& source_arg == NULL
|
||||
&& objfile->psymtabs_addrmap != NULL)
|
||||
{
|
||||
fprintf_filtered (outfile, "\n");
|
||||
outfile->puts ("\n");
|
||||
dump_psymtab_addrmap (objfile, NULL, outfile);
|
||||
}
|
||||
}
|
||||
|
@ -193,54 +193,38 @@ archpy_disassemble (PyObject *self, PyObject *args, PyObject *kw)
|
||||
|| (end_obj == NULL && count_obj == NULL && pc == start);)
|
||||
{
|
||||
int insn_len = 0;
|
||||
struct ui_file *memfile = mem_fileopen ();
|
||||
gdbpy_ref insn_dict (PyDict_New ());
|
||||
|
||||
if (insn_dict == NULL)
|
||||
{
|
||||
ui_file_delete (memfile);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
return NULL;
|
||||
if (PyList_Append (result_list.get (), insn_dict.get ()))
|
||||
{
|
||||
ui_file_delete (memfile);
|
||||
return NULL; /* PyList_Append Sets the exception. */
|
||||
|
||||
return NULL; /* PyList_Append Sets the exception. */
|
||||
}
|
||||
string_file stb;
|
||||
|
||||
TRY
|
||||
{
|
||||
insn_len = gdb_print_insn (gdbarch, pc, memfile, NULL);
|
||||
insn_len = gdb_print_insn (gdbarch, pc, &stb, NULL);
|
||||
}
|
||||
CATCH (except, RETURN_MASK_ALL)
|
||||
{
|
||||
ui_file_delete (memfile);
|
||||
|
||||
gdbpy_convert_exception (except);
|
||||
return NULL;
|
||||
}
|
||||
END_CATCH
|
||||
|
||||
std::string as = ui_file_as_string (memfile);
|
||||
|
||||
if (PyDict_SetItemString (insn_dict.get (), "addr",
|
||||
gdb_py_long_from_ulongest (pc))
|
||||
|| PyDict_SetItemString (insn_dict.get (), "asm",
|
||||
PyString_FromString (!as.empty ()
|
||||
? as.c_str ()
|
||||
PyString_FromString (!stb.empty ()
|
||||
? stb.c_str ()
|
||||
: "<unknown>"))
|
||||
|| PyDict_SetItemString (insn_dict.get (), "length",
|
||||
PyInt_FromLong (insn_len)))
|
||||
{
|
||||
ui_file_delete (memfile);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
return NULL;
|
||||
|
||||
pc += insn_len;
|
||||
i++;
|
||||
ui_file_delete (memfile);
|
||||
}
|
||||
|
||||
return result_list.release ();
|
||||
|
@ -485,19 +485,16 @@ bppy_get_commands (PyObject *self, void *closure)
|
||||
gdbpy_breakpoint_object *self_bp = (gdbpy_breakpoint_object *) self;
|
||||
struct breakpoint *bp = self_bp->bp;
|
||||
long length;
|
||||
struct ui_file *string_file;
|
||||
PyObject *result;
|
||||
struct cleanup *chain;
|
||||
|
||||
BPPY_REQUIRE_VALID (self_bp);
|
||||
|
||||
if (! self_bp->bp->commands)
|
||||
Py_RETURN_NONE;
|
||||
|
||||
string_file = mem_fileopen ();
|
||||
chain = make_cleanup_ui_file_delete (string_file);
|
||||
string_file stb;
|
||||
|
||||
current_uiout->redirect (string_file);
|
||||
current_uiout->redirect (&stb);
|
||||
TRY
|
||||
{
|
||||
print_command_lines (current_uiout, breakpoint_commands (bp), 0);
|
||||
@ -505,17 +502,13 @@ bppy_get_commands (PyObject *self, void *closure)
|
||||
CATCH (except, RETURN_MASK_ALL)
|
||||
{
|
||||
current_uiout->redirect (NULL);
|
||||
do_cleanups (chain);
|
||||
gdbpy_convert_exception (except);
|
||||
return NULL;
|
||||
}
|
||||
END_CATCH
|
||||
|
||||
current_uiout->redirect (NULL);
|
||||
std::string cmdstr = ui_file_as_string (string_file);
|
||||
result = host_string_to_python_string (cmdstr.c_str ());
|
||||
do_cleanups (chain);
|
||||
return result;
|
||||
return host_string_to_python_string (stb.c_str ());
|
||||
}
|
||||
|
||||
/* Python function to get the breakpoint type. */
|
||||
|
@ -80,13 +80,10 @@ frame_object_to_frame_info (PyObject *obj)
|
||||
static PyObject *
|
||||
frapy_str (PyObject *self)
|
||||
{
|
||||
PyObject *result;
|
||||
struct ui_file *strfile;
|
||||
string_file strfile;
|
||||
|
||||
strfile = mem_fileopen ();
|
||||
fprint_frame_id (strfile, ((frame_object *) self)->frame_id);
|
||||
std::string s = ui_file_as_string (strfile);
|
||||
return PyString_FromString (s.c_str ());
|
||||
fprint_frame_id (&strfile, ((frame_object *) self)->frame_id);
|
||||
return PyString_FromString (strfile.c_str ());
|
||||
}
|
||||
|
||||
/* Implementation of gdb.Frame.is_valid (self) -> Boolean.
|
||||
|
@ -208,15 +208,11 @@ py_print_type (struct ui_out *out, struct value *val)
|
||||
|
||||
TRY
|
||||
{
|
||||
struct ui_file *stb;
|
||||
struct cleanup *cleanup;
|
||||
|
||||
stb = mem_fileopen ();
|
||||
cleanup = make_cleanup_ui_file_delete (stb);
|
||||
check_typedef (value_type (val));
|
||||
type_print (value_type (val), "", stb, -1);
|
||||
|
||||
string_file stb;
|
||||
type_print (value_type (val), "", &stb, -1);
|
||||
out->field_stream ("type", stb);
|
||||
do_cleanups (cleanup);
|
||||
}
|
||||
CATCH (except, RETURN_MASK_ALL)
|
||||
{
|
||||
@ -280,14 +276,10 @@ py_print_value (struct ui_out *out, struct value *val,
|
||||
{
|
||||
TRY
|
||||
{
|
||||
struct ui_file *stb;
|
||||
struct cleanup *cleanup;
|
||||
string_file stb;
|
||||
|
||||
stb = mem_fileopen ();
|
||||
cleanup = make_cleanup_ui_file_delete (stb);
|
||||
common_val_print (val, stb, indent, opts, language);
|
||||
common_val_print (val, &stb, indent, opts, language);
|
||||
out->field_stream ("value", stb);
|
||||
do_cleanups (cleanup);
|
||||
}
|
||||
CATCH (except, RETURN_MASK_ALL)
|
||||
{
|
||||
@ -393,26 +385,22 @@ py_print_single_arg (struct ui_out *out,
|
||||
entry value options. */
|
||||
if (fa != NULL)
|
||||
{
|
||||
struct ui_file *stb;
|
||||
string_file stb;
|
||||
|
||||
stb = mem_fileopen ();
|
||||
make_cleanup_ui_file_delete (stb);
|
||||
fprintf_symbol_filtered (stb, SYMBOL_PRINT_NAME (fa->sym),
|
||||
fprintf_symbol_filtered (&stb, SYMBOL_PRINT_NAME (fa->sym),
|
||||
SYMBOL_LANGUAGE (fa->sym),
|
||||
DMGL_PARAMS | DMGL_ANSI);
|
||||
if (fa->entry_kind == print_entry_values_compact)
|
||||
{
|
||||
fputs_filtered ("=", stb);
|
||||
stb.puts ("=");
|
||||
|
||||
fprintf_symbol_filtered (stb, SYMBOL_PRINT_NAME (fa->sym),
|
||||
fprintf_symbol_filtered (&stb, SYMBOL_PRINT_NAME (fa->sym),
|
||||
SYMBOL_LANGUAGE (fa->sym),
|
||||
DMGL_PARAMS | DMGL_ANSI);
|
||||
}
|
||||
if (fa->entry_kind == print_entry_values_only
|
||||
|| fa->entry_kind == print_entry_values_compact)
|
||||
{
|
||||
fputs_filtered ("@entry", stb);
|
||||
}
|
||||
stb.puts ("@entry");
|
||||
out->field_stream ("name", stb);
|
||||
}
|
||||
else
|
||||
|
@ -967,22 +967,13 @@ typy_template_argument (PyObject *self, PyObject *args)
|
||||
static PyObject *
|
||||
typy_str (PyObject *self)
|
||||
{
|
||||
std::string thetype;
|
||||
string_file thetype;
|
||||
PyObject *result;
|
||||
|
||||
TRY
|
||||
{
|
||||
struct cleanup *old_chain;
|
||||
struct ui_file *stb;
|
||||
|
||||
stb = mem_fileopen ();
|
||||
old_chain = make_cleanup_ui_file_delete (stb);
|
||||
|
||||
LA_PRINT_TYPE (type_object_to_type (self), "", stb, -1, 0,
|
||||
LA_PRINT_TYPE (type_object_to_type (self), "", &thetype, -1, 0,
|
||||
&type_print_raw_options);
|
||||
|
||||
thetype = ui_file_as_string (stb);
|
||||
do_cleanups (old_chain);
|
||||
}
|
||||
CATCH (except, RETURN_MASK_ALL)
|
||||
{
|
||||
@ -990,10 +981,8 @@ typy_str (PyObject *self)
|
||||
}
|
||||
END_CATCH
|
||||
|
||||
result = PyUnicode_Decode (thetype.c_str (), thetype.length (),
|
||||
host_charset (), NULL);
|
||||
|
||||
return result;
|
||||
return PyUnicode_Decode (thetype.c_str (), thetype.size (),
|
||||
host_charset (), NULL);
|
||||
}
|
||||
|
||||
/* Implement the richcompare method. */
|
||||
|
@ -198,12 +198,11 @@ pyuw_object_attribute_to_pointer (PyObject *pyo, const char *attr_name,
|
||||
static PyObject *
|
||||
unwind_infopy_str (PyObject *self)
|
||||
{
|
||||
struct ui_file *strfile = mem_fileopen ();
|
||||
unwind_info_object *unwind_info = (unwind_info_object *) self;
|
||||
PyObject *result;
|
||||
string_file stb;
|
||||
|
||||
fprintf_unfiltered (strfile, "Frame ID: ");
|
||||
fprint_frame_id (strfile, unwind_info->frame_id);
|
||||
stb.puts ("Frame ID: ");
|
||||
fprint_frame_id (&stb, unwind_info->frame_id);
|
||||
{
|
||||
char *sep = "";
|
||||
int i;
|
||||
@ -211,18 +210,18 @@ unwind_infopy_str (PyObject *self)
|
||||
saved_reg *reg;
|
||||
|
||||
get_user_print_options (&opts);
|
||||
fprintf_unfiltered (strfile, "\nSaved registers: (");
|
||||
stb.printf ("\nSaved registers: (");
|
||||
for (i = 0; VEC_iterate (saved_reg, unwind_info->saved_regs, i, reg); i++)
|
||||
{
|
||||
struct value *value = value_object_to_value (reg->value);
|
||||
|
||||
fprintf_unfiltered (strfile, "%s(%d, ", sep, reg->number);
|
||||
stb.printf ("%s(%d, ", sep, reg->number);
|
||||
if (value != NULL)
|
||||
{
|
||||
TRY
|
||||
{
|
||||
value_print (value, strfile, &opts);
|
||||
fprintf_unfiltered (strfile, ")");
|
||||
value_print (value, &stb, &opts);
|
||||
stb.puts (")");
|
||||
}
|
||||
CATCH (except, RETURN_MASK_ALL)
|
||||
{
|
||||
@ -231,16 +230,13 @@ unwind_infopy_str (PyObject *self)
|
||||
END_CATCH
|
||||
}
|
||||
else
|
||||
fprintf_unfiltered (strfile, "<BAD>)");
|
||||
stb.puts ("<BAD>)");
|
||||
sep = ", ";
|
||||
}
|
||||
fprintf_unfiltered (strfile, ")");
|
||||
stb.puts (")");
|
||||
}
|
||||
|
||||
std::string s = ui_file_as_string (strfile);
|
||||
result = PyString_FromString (s.c_str ());
|
||||
ui_file_delete (strfile);
|
||||
return result;
|
||||
return PyString_FromString (stb.c_str ());
|
||||
}
|
||||
|
||||
/* Create UnwindInfo instance for given PendingFrame and frame ID.
|
||||
|
@ -867,23 +867,17 @@ valpy_call (PyObject *self, PyObject *args, PyObject *keywords)
|
||||
static PyObject *
|
||||
valpy_str (PyObject *self)
|
||||
{
|
||||
std::string s;
|
||||
PyObject *result;
|
||||
struct value_print_options opts;
|
||||
|
||||
get_user_print_options (&opts);
|
||||
opts.deref_ref = 0;
|
||||
|
||||
string_file stb;
|
||||
|
||||
TRY
|
||||
{
|
||||
struct ui_file *stb = mem_fileopen ();
|
||||
struct cleanup *old_chain = make_cleanup_ui_file_delete (stb);
|
||||
|
||||
common_val_print (((value_object *) self)->value, stb, 0,
|
||||
common_val_print (((value_object *) self)->value, &stb, 0,
|
||||
&opts, python_language);
|
||||
s = ui_file_as_string (stb);
|
||||
|
||||
do_cleanups (old_chain);
|
||||
}
|
||||
CATCH (except, RETURN_MASK_ALL)
|
||||
{
|
||||
@ -891,9 +885,7 @@ valpy_str (PyObject *self)
|
||||
}
|
||||
END_CATCH
|
||||
|
||||
result = PyUnicode_Decode (s.c_str (), s.length (), host_charset (), NULL);
|
||||
|
||||
return result;
|
||||
return PyUnicode_Decode (stb.c_str (), stb.size (), host_charset (), NULL);
|
||||
}
|
||||
|
||||
/* Implements gdb.Value.is_optimized_out. */
|
||||
|
@ -1498,14 +1498,11 @@ regcache_print (char *args, enum regcache_dump_what what_to_dump)
|
||||
regcache_dump (get_current_regcache (), gdb_stdout, what_to_dump);
|
||||
else
|
||||
{
|
||||
struct cleanup *cleanups;
|
||||
struct ui_file *file = gdb_fopen (args, "w");
|
||||
stdio_file file;
|
||||
|
||||
if (file == NULL)
|
||||
if (!file.open (args, "w"))
|
||||
perror_with_name (_("maintenance print architecture"));
|
||||
cleanups = make_cleanup_ui_file_delete (file);
|
||||
regcache_dump (get_current_regcache (), file, what_to_dump);
|
||||
do_cleanups (cleanups);
|
||||
regcache_dump (get_current_regcache (), &file, what_to_dump);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -270,14 +270,11 @@ maintenance_print_reggroups (char *args, int from_tty)
|
||||
reggroups_dump (gdbarch, gdb_stdout);
|
||||
else
|
||||
{
|
||||
struct cleanup *cleanups;
|
||||
struct ui_file *file = gdb_fopen (args, "w");
|
||||
stdio_file file;
|
||||
|
||||
if (file == NULL)
|
||||
if (!file.open (args, "w"))
|
||||
perror_with_name (_("maintenance print reggroups"));
|
||||
cleanups = make_cleanup_ui_file_delete (file);
|
||||
reggroups_dump (gdbarch, file);
|
||||
do_cleanups (cleanups);
|
||||
reggroups_dump (gdbarch, &file);
|
||||
}
|
||||
}
|
||||
|
||||
|
12
gdb/remote.c
12
gdb/remote.c
@ -8674,16 +8674,10 @@ remote_send (char **buf,
|
||||
static std::string
|
||||
escape_buffer (const char *buf, int n)
|
||||
{
|
||||
struct cleanup *old_chain;
|
||||
struct ui_file *stb;
|
||||
string_file stb;
|
||||
|
||||
stb = mem_fileopen ();
|
||||
old_chain = make_cleanup_ui_file_delete (stb);
|
||||
|
||||
fputstrn_unfiltered (buf, n, '\\', stb);
|
||||
std::string str = ui_file_as_string (stb);
|
||||
do_cleanups (old_chain);
|
||||
return str;
|
||||
stb.putstrn (buf, n, '\\');
|
||||
return std::move (stb.string ());
|
||||
}
|
||||
|
||||
/* Display a null-terminated packet on stdout, for debugging, using C
|
||||
|
@ -125,7 +125,6 @@ rust_get_disr_info (struct type *type, const gdb_byte *valaddr,
|
||||
int i;
|
||||
struct disr_info ret;
|
||||
struct type *disr_type;
|
||||
struct ui_file *temp_file;
|
||||
struct value_print_options opts;
|
||||
struct cleanup *cleanup;
|
||||
const char *name_segment;
|
||||
@ -229,17 +228,16 @@ rust_get_disr_info (struct type *type, const gdb_byte *valaddr,
|
||||
if (strcmp (TYPE_FIELD_NAME (disr_type, 0), "RUST$ENUM$DISR") != 0)
|
||||
error (_("Rust debug format has changed"));
|
||||
|
||||
temp_file = mem_fileopen ();
|
||||
cleanup = make_cleanup_ui_file_delete (temp_file);
|
||||
string_file temp_file;
|
||||
/* The first value of the first field (or any field)
|
||||
is the discriminant value. */
|
||||
c_val_print (TYPE_FIELD_TYPE (disr_type, 0),
|
||||
(embedded_offset + TYPE_FIELD_BITPOS (type, 0) / 8
|
||||
+ TYPE_FIELD_BITPOS (disr_type, 0) / 8),
|
||||
address, temp_file,
|
||||
address, &temp_file,
|
||||
0, val, &opts);
|
||||
|
||||
ret.name = ui_file_as_string (temp_file);
|
||||
ret.name = std::move (temp_file.string ());
|
||||
name_segment = rust_last_path_segment (ret.name.c_str ());
|
||||
if (name_segment != NULL)
|
||||
{
|
||||
@ -271,7 +269,6 @@ rust_get_disr_info (struct type *type, const gdb_byte *valaddr,
|
||||
TYPE_TAG_NAME (type), ret.name.c_str ());
|
||||
}
|
||||
|
||||
do_cleanups (cleanup);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -251,9 +251,12 @@ serial_open_ops_1 (const struct serial_ops *ops, const char *open_name)
|
||||
|
||||
if (serial_logfile != NULL)
|
||||
{
|
||||
serial_logfp = gdb_fopen (serial_logfile, "w");
|
||||
if (serial_logfp == NULL)
|
||||
stdio_file_up file (new stdio_file ());
|
||||
|
||||
if (!file->open (serial_logfile, "w"))
|
||||
perror_with_name (serial_logfile);
|
||||
|
||||
serial_logfp = file.release ();
|
||||
}
|
||||
|
||||
return scb;
|
||||
@ -315,7 +318,7 @@ do_serial_close (struct serial *scb, int really_close)
|
||||
serial_current_type = 0;
|
||||
|
||||
/* XXX - What if serial_logfp == gdb_stdout or gdb_stderr? */
|
||||
ui_file_delete (serial_logfp);
|
||||
delete serial_logfp;
|
||||
serial_logfp = NULL;
|
||||
}
|
||||
|
||||
|
28
gdb/stack.c
28
gdb/stack.c
@ -225,11 +225,9 @@ print_frame_arg (const struct frame_arg *arg)
|
||||
{
|
||||
struct ui_out *uiout = current_uiout;
|
||||
struct cleanup *old_chain;
|
||||
struct ui_file *stb;
|
||||
const char *error_message = NULL;
|
||||
|
||||
stb = mem_fileopen ();
|
||||
old_chain = make_cleanup_ui_file_delete (stb);
|
||||
string_file stb;
|
||||
|
||||
gdb_assert (!arg->val || !arg->error);
|
||||
gdb_assert (arg->entry_kind == print_entry_values_no
|
||||
@ -239,22 +237,22 @@ print_frame_arg (const struct frame_arg *arg)
|
||||
|
||||
annotate_arg_begin ();
|
||||
|
||||
make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
|
||||
fprintf_symbol_filtered (stb, SYMBOL_PRINT_NAME (arg->sym),
|
||||
old_chain = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
|
||||
fprintf_symbol_filtered (&stb, SYMBOL_PRINT_NAME (arg->sym),
|
||||
SYMBOL_LANGUAGE (arg->sym), DMGL_PARAMS | DMGL_ANSI);
|
||||
if (arg->entry_kind == print_entry_values_compact)
|
||||
{
|
||||
/* It is OK to provide invalid MI-like stream as with
|
||||
PRINT_ENTRY_VALUE_COMPACT we never use MI. */
|
||||
fputs_filtered ("=", stb);
|
||||
stb.puts ("=");
|
||||
|
||||
fprintf_symbol_filtered (stb, SYMBOL_PRINT_NAME (arg->sym),
|
||||
fprintf_symbol_filtered (&stb, SYMBOL_PRINT_NAME (arg->sym),
|
||||
SYMBOL_LANGUAGE (arg->sym),
|
||||
DMGL_PARAMS | DMGL_ANSI);
|
||||
}
|
||||
if (arg->entry_kind == print_entry_values_only
|
||||
|| arg->entry_kind == print_entry_values_compact)
|
||||
fputs_filtered ("@entry", stb);
|
||||
stb.puts ("@entry");
|
||||
uiout->field_stream ("name", stb);
|
||||
annotate_arg_name_end ();
|
||||
uiout->text ("=");
|
||||
@ -294,7 +292,7 @@ print_frame_arg (const struct frame_arg *arg)
|
||||
/* True in "summary" mode, false otherwise. */
|
||||
opts.summary = !strcmp (print_frame_arguments, "scalars");
|
||||
|
||||
common_val_print (arg->val, stb, 2, &opts, language);
|
||||
common_val_print (arg->val, &stb, 2, &opts, language);
|
||||
}
|
||||
CATCH (except, RETURN_MASK_ERROR)
|
||||
{
|
||||
@ -303,8 +301,7 @@ print_frame_arg (const struct frame_arg *arg)
|
||||
END_CATCH
|
||||
}
|
||||
if (error_message != NULL)
|
||||
fprintf_filtered (stb, _("<error reading variable: %s>"),
|
||||
error_message);
|
||||
stb.printf (_("<error reading variable: %s>"), error_message);
|
||||
}
|
||||
|
||||
uiout->field_stream ("value", stb);
|
||||
@ -1158,7 +1155,6 @@ print_frame (struct frame_info *frame, int print_level,
|
||||
struct ui_out *uiout = current_uiout;
|
||||
char *funname = NULL;
|
||||
enum language funlang = language_unknown;
|
||||
struct ui_file *stb;
|
||||
struct cleanup *old_chain, *list_chain;
|
||||
struct value_print_options opts;
|
||||
struct symbol *func;
|
||||
@ -1167,11 +1163,9 @@ print_frame (struct frame_info *frame, int print_level,
|
||||
|
||||
pc_p = get_frame_pc_if_available (frame, &pc);
|
||||
|
||||
stb = mem_fileopen ();
|
||||
old_chain = make_cleanup_ui_file_delete (stb);
|
||||
|
||||
find_frame_funname (frame, &funname, &funlang, &func);
|
||||
make_cleanup (xfree, funname);
|
||||
old_chain = make_cleanup (xfree, funname);
|
||||
|
||||
annotate_frame_begin (print_level ? frame_relative_level (frame) : 0,
|
||||
gdbarch, pc);
|
||||
@ -1199,7 +1193,9 @@ print_frame (struct frame_info *frame, int print_level,
|
||||
uiout->text (" in ");
|
||||
}
|
||||
annotate_frame_function_name ();
|
||||
fprintf_symbol_filtered (stb, funname ? funname : "??",
|
||||
|
||||
string_file stb;
|
||||
fprintf_symbol_filtered (&stb, funname ? funname : "??",
|
||||
funlang, DMGL_ANSI);
|
||||
uiout->field_stream ("func", stb);
|
||||
uiout->wrap_hint (" ");
|
||||
|
@ -457,6 +457,8 @@ maintenance_print_symbols (char *args, int from_tty)
|
||||
if (address_arg != NULL && source_arg != NULL)
|
||||
error (_("Must specify at most one of -pc and -source"));
|
||||
|
||||
stdio_file arg_outfile;
|
||||
|
||||
if (argv[outfile_idx] != NULL)
|
||||
{
|
||||
char *outfile_name;
|
||||
@ -465,10 +467,9 @@ maintenance_print_symbols (char *args, int from_tty)
|
||||
error (_("Junk at end of command"));
|
||||
outfile_name = tilde_expand (argv[outfile_idx]);
|
||||
make_cleanup (xfree, outfile_name);
|
||||
outfile = gdb_fopen (outfile_name, FOPEN_WT);
|
||||
if (outfile == NULL)
|
||||
if (!arg_outfile.open (outfile_name, FOPEN_WT))
|
||||
perror_with_name (outfile_name);
|
||||
make_cleanup_ui_file_delete (outfile);
|
||||
outfile = &arg_outfile;
|
||||
}
|
||||
|
||||
if (address_arg != NULL)
|
||||
@ -744,6 +745,8 @@ maintenance_print_msymbols (char *args, int from_tty)
|
||||
}
|
||||
outfile_idx = i;
|
||||
|
||||
stdio_file arg_outfile;
|
||||
|
||||
if (argv[outfile_idx] != NULL)
|
||||
{
|
||||
char *outfile_name;
|
||||
@ -752,10 +755,9 @@ maintenance_print_msymbols (char *args, int from_tty)
|
||||
error (_("Junk at end of command"));
|
||||
outfile_name = tilde_expand (argv[outfile_idx]);
|
||||
make_cleanup (xfree, outfile_name);
|
||||
outfile = gdb_fopen (outfile_name, FOPEN_WT);
|
||||
if (outfile == NULL)
|
||||
if (!arg_outfile.open (outfile_name, FOPEN_WT))
|
||||
perror_with_name (outfile_name);
|
||||
make_cleanup_ui_file_delete (outfile);
|
||||
outfile = &arg_outfile;
|
||||
}
|
||||
|
||||
ALL_OBJFILES (objfile)
|
||||
|
@ -674,7 +674,7 @@ struct symbol_computed_ops
|
||||
The generated C code must assign the location to a local
|
||||
variable; this variable's name is RESULT_NAME. */
|
||||
|
||||
void (*generate_c_location) (struct symbol *symbol, struct ui_file *stream,
|
||||
void (*generate_c_location) (struct symbol *symbol, string_file &stream,
|
||||
struct gdbarch *gdbarch,
|
||||
unsigned char *registers_used,
|
||||
CORE_ADDR pc, const char *result_name);
|
||||
|
51
gdb/top.c
51
gdb/top.c
@ -272,9 +272,9 @@ new_ui (FILE *instream, FILE *outstream, FILE *errstream)
|
||||
|
||||
ui->input_interactive_p = ISATTY (ui->instream);
|
||||
|
||||
ui->m_gdb_stdin = stdio_fileopen (ui->instream);
|
||||
ui->m_gdb_stdout = stdio_fileopen (ui->outstream);
|
||||
ui->m_gdb_stderr = stderr_fileopen (ui->errstream);
|
||||
ui->m_gdb_stdin = new stdio_file (ui->instream);
|
||||
ui->m_gdb_stdout = new stdio_file (ui->outstream);
|
||||
ui->m_gdb_stderr = new stderr_file (ui->errstream);
|
||||
ui->m_gdb_stdlog = ui->m_gdb_stderr;
|
||||
|
||||
ui->prompt_state = PROMPT_NEEDED;
|
||||
@ -296,9 +296,9 @@ new_ui (FILE *instream, FILE *outstream, FILE *errstream)
|
||||
static void
|
||||
free_ui (struct ui *ui)
|
||||
{
|
||||
ui_file_delete (ui->m_gdb_stdin);
|
||||
ui_file_delete (ui->m_gdb_stdout);
|
||||
ui_file_delete (ui->m_gdb_stderr);
|
||||
delete ui->m_gdb_stdin;
|
||||
delete ui->m_gdb_stdout;
|
||||
delete ui->m_gdb_stderr;
|
||||
|
||||
xfree (ui);
|
||||
}
|
||||
@ -693,7 +693,6 @@ execute_command (char *p, int from_tty)
|
||||
std::string
|
||||
execute_command_to_string (char *p, int from_tty)
|
||||
{
|
||||
struct ui_file *str_file;
|
||||
struct cleanup *cleanup;
|
||||
|
||||
/* GDB_STDOUT should be better already restored during these
|
||||
@ -702,31 +701,27 @@ execute_command_to_string (char *p, int from_tty)
|
||||
|
||||
scoped_restore save_async = make_scoped_restore (¤t_ui->async, 0);
|
||||
|
||||
str_file = mem_fileopen ();
|
||||
string_file str_file;
|
||||
|
||||
make_cleanup_ui_file_delete (str_file);
|
||||
|
||||
current_uiout->redirect (str_file);
|
||||
current_uiout->redirect (&str_file);
|
||||
make_cleanup_ui_out_redirect_pop (current_uiout);
|
||||
|
||||
scoped_restore save_stdout
|
||||
= make_scoped_restore (&gdb_stdout, str_file);
|
||||
= make_scoped_restore (&gdb_stdout, &str_file);
|
||||
scoped_restore save_stderr
|
||||
= make_scoped_restore (&gdb_stderr, str_file);
|
||||
= make_scoped_restore (&gdb_stderr, &str_file);
|
||||
scoped_restore save_stdlog
|
||||
= make_scoped_restore (&gdb_stdlog, str_file);
|
||||
= make_scoped_restore (&gdb_stdlog, &str_file);
|
||||
scoped_restore save_stdtarg
|
||||
= make_scoped_restore (&gdb_stdtarg, str_file);
|
||||
= make_scoped_restore (&gdb_stdtarg, &str_file);
|
||||
scoped_restore save_stdtargerr
|
||||
= make_scoped_restore (&gdb_stdtargerr, str_file);
|
||||
= make_scoped_restore (&gdb_stdtargerr, &str_file);
|
||||
|
||||
execute_command (p, from_tty);
|
||||
|
||||
std::string retval = ui_file_as_string (str_file);
|
||||
|
||||
do_cleanups (cleanup);
|
||||
|
||||
return retval;
|
||||
return std::move (str_file.string ());
|
||||
}
|
||||
|
||||
|
||||
@ -1569,26 +1564,18 @@ print_inferior_quit_action (struct inferior *inf, void *arg)
|
||||
int
|
||||
quit_confirm (void)
|
||||
{
|
||||
struct ui_file *stb;
|
||||
struct cleanup *old_chain;
|
||||
|
||||
/* Don't even ask if we're only debugging a core file inferior. */
|
||||
if (!have_live_inferiors ())
|
||||
return 1;
|
||||
|
||||
/* Build the query string as a single string. */
|
||||
stb = mem_fileopen ();
|
||||
old_chain = make_cleanup_ui_file_delete (stb);
|
||||
string_file stb;
|
||||
|
||||
fprintf_filtered (stb, _("A debugging session is active.\n\n"));
|
||||
iterate_over_inferiors (print_inferior_quit_action, stb);
|
||||
fprintf_filtered (stb, _("\nQuit anyway? "));
|
||||
stb.puts (_("A debugging session is active.\n\n"));
|
||||
iterate_over_inferiors (print_inferior_quit_action, &stb);
|
||||
stb.puts (_("\nQuit anyway? "));
|
||||
|
||||
std::string str = ui_file_as_string (stb);
|
||||
|
||||
do_cleanups (old_chain);
|
||||
|
||||
return query ("%s", str.c_str ());
|
||||
return query ("%s", stb.c_str ());
|
||||
}
|
||||
|
||||
/* Prepare to exit GDB cleanly by undoing any changes made to the
|
||||
|
@ -1304,12 +1304,11 @@ collection_list::stringify ()
|
||||
void
|
||||
collection_list::append_exp (struct expression *exp)
|
||||
{
|
||||
struct ui_file *tmp_stream = mem_fileopen ();
|
||||
string_file tmp_stream;
|
||||
|
||||
print_expression (exp, tmp_stream);
|
||||
print_expression (exp, &tmp_stream);
|
||||
|
||||
m_computed.push_back (ui_file_as_string (tmp_stream));
|
||||
ui_file_delete (tmp_stream);
|
||||
m_computed.push_back (std::move (tmp_stream.string ()));
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -54,10 +54,7 @@ static CORE_ADDR
|
||||
tui_disassemble (struct gdbarch *gdbarch, struct tui_asm_line *asm_lines,
|
||||
CORE_ADDR pc, int count)
|
||||
{
|
||||
struct ui_file *gdb_dis_out;
|
||||
|
||||
/* Now init the ui_file structure. */
|
||||
gdb_dis_out = tui_sfileopen (256);
|
||||
string_file gdb_dis_out;
|
||||
|
||||
/* Now construct each line. */
|
||||
for (; count > 0; count--, asm_lines++)
|
||||
@ -67,20 +64,19 @@ tui_disassemble (struct gdbarch *gdbarch, struct tui_asm_line *asm_lines,
|
||||
if (asm_lines->insn)
|
||||
xfree (asm_lines->insn);
|
||||
|
||||
print_address (gdbarch, pc, gdb_dis_out);
|
||||
print_address (gdbarch, pc, &gdb_dis_out);
|
||||
asm_lines->addr = pc;
|
||||
asm_lines->addr_string = xstrdup (tui_file_get_strbuf (gdb_dis_out));
|
||||
asm_lines->addr_string = xstrdup (gdb_dis_out.c_str ());
|
||||
|
||||
ui_file_rewind (gdb_dis_out);
|
||||
gdb_dis_out.clear ();
|
||||
|
||||
pc = pc + gdb_print_insn (gdbarch, pc, gdb_dis_out, NULL);
|
||||
pc = pc + gdb_print_insn (gdbarch, pc, &gdb_dis_out, NULL);
|
||||
|
||||
asm_lines->insn = xstrdup (tui_file_get_strbuf (gdb_dis_out));
|
||||
asm_lines->insn = xstrdup (gdb_dis_out.c_str ());
|
||||
|
||||
/* Reset the buffer to empty. */
|
||||
ui_file_rewind (gdb_dis_out);
|
||||
gdb_dis_out.clear ();
|
||||
}
|
||||
ui_file_delete (gdb_dis_out);
|
||||
return pc;
|
||||
}
|
||||
|
||||
|
@ -17,145 +17,14 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "ui-file.h"
|
||||
#include "tui/tui-file.h"
|
||||
#include "tui/tui-io.h"
|
||||
#include "tui/tui-command.h"
|
||||
#include "tui.h"
|
||||
|
||||
/* A ``struct ui_file'' that is compatible with all the legacy
|
||||
code. */
|
||||
|
||||
/* new */
|
||||
enum streamtype
|
||||
{
|
||||
afile,
|
||||
astring
|
||||
};
|
||||
|
||||
/* new */
|
||||
struct tui_stream
|
||||
{
|
||||
int *ts_magic;
|
||||
enum streamtype ts_streamtype;
|
||||
FILE *ts_filestream;
|
||||
char *ts_strbuf;
|
||||
int ts_buflen;
|
||||
};
|
||||
|
||||
static ui_file_flush_ftype tui_file_flush;
|
||||
extern ui_file_fputs_ftype tui_file_fputs;
|
||||
static ui_file_isatty_ftype tui_file_isatty;
|
||||
static ui_file_rewind_ftype tui_file_rewind;
|
||||
static ui_file_put_ftype tui_file_put;
|
||||
static ui_file_delete_ftype tui_file_delete;
|
||||
static struct ui_file *tui_file_new (void);
|
||||
static int tui_file_magic;
|
||||
|
||||
static struct ui_file *
|
||||
tui_file_new (void)
|
||||
{
|
||||
struct tui_stream *tui = XNEW (struct tui_stream);
|
||||
struct ui_file *file = ui_file_new ();
|
||||
|
||||
set_ui_file_data (file, tui, tui_file_delete);
|
||||
set_ui_file_flush (file, tui_file_flush);
|
||||
set_ui_file_fputs (file, tui_file_fputs);
|
||||
set_ui_file_isatty (file, tui_file_isatty);
|
||||
set_ui_file_rewind (file, tui_file_rewind);
|
||||
set_ui_file_put (file, tui_file_put);
|
||||
tui->ts_magic = &tui_file_magic;
|
||||
return file;
|
||||
}
|
||||
|
||||
static void
|
||||
tui_file_delete (struct ui_file *file)
|
||||
{
|
||||
struct tui_stream *tmpstream = (struct tui_stream *) ui_file_data (file);
|
||||
|
||||
if (tmpstream->ts_magic != &tui_file_magic)
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("tui_file_delete: bad magic number"));
|
||||
if ((tmpstream->ts_streamtype == astring)
|
||||
&& (tmpstream->ts_strbuf != NULL))
|
||||
{
|
||||
xfree (tmpstream->ts_strbuf);
|
||||
}
|
||||
xfree (tmpstream);
|
||||
}
|
||||
|
||||
struct ui_file *
|
||||
tui_fileopen (FILE *stream)
|
||||
{
|
||||
struct ui_file *file = tui_file_new ();
|
||||
struct tui_stream *tmpstream = (struct tui_stream *) ui_file_data (file);
|
||||
|
||||
tmpstream->ts_streamtype = afile;
|
||||
tmpstream->ts_filestream = stream;
|
||||
tmpstream->ts_strbuf = NULL;
|
||||
tmpstream->ts_buflen = 0;
|
||||
return file;
|
||||
}
|
||||
|
||||
struct ui_file *
|
||||
tui_sfileopen (int n)
|
||||
{
|
||||
struct ui_file *file = tui_file_new ();
|
||||
struct tui_stream *tmpstream = (struct tui_stream *) ui_file_data (file);
|
||||
|
||||
tmpstream->ts_streamtype = astring;
|
||||
tmpstream->ts_filestream = NULL;
|
||||
if (n > 0)
|
||||
{
|
||||
tmpstream->ts_strbuf = XNEWVEC (char, n + 1);
|
||||
tmpstream->ts_strbuf[0] = '\0';
|
||||
}
|
||||
else
|
||||
/* Do not allocate the buffer now. The first time something is
|
||||
printed one will be allocated by tui_file_adjust_strbuf(). */
|
||||
tmpstream->ts_strbuf = NULL;
|
||||
tmpstream->ts_buflen = n;
|
||||
return file;
|
||||
}
|
||||
|
||||
static int
|
||||
tui_file_isatty (struct ui_file *file)
|
||||
{
|
||||
struct tui_stream *stream = (struct tui_stream *) ui_file_data (file);
|
||||
|
||||
if (stream->ts_magic != &tui_file_magic)
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("tui_file_isatty: bad magic number"));
|
||||
if (stream->ts_streamtype == afile)
|
||||
return (isatty (fileno (stream->ts_filestream)));
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
tui_file_rewind (struct ui_file *file)
|
||||
{
|
||||
struct tui_stream *stream = (struct tui_stream *) ui_file_data (file);
|
||||
|
||||
if (stream->ts_magic != &tui_file_magic)
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("tui_file_rewind: bad magic number"));
|
||||
stream->ts_strbuf[0] = '\0';
|
||||
}
|
||||
|
||||
static void
|
||||
tui_file_put (struct ui_file *file,
|
||||
ui_file_put_method_ftype *write,
|
||||
void *dest)
|
||||
{
|
||||
struct tui_stream *stream = (struct tui_stream *) ui_file_data (file);
|
||||
|
||||
if (stream->ts_magic != &tui_file_magic)
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("tui_file_put: bad magic number"));
|
||||
if (stream->ts_streamtype == astring)
|
||||
write (dest, stream->ts_strbuf, strlen (stream->ts_strbuf));
|
||||
}
|
||||
tui_file::tui_file (FILE *stream)
|
||||
: stdio_file (stream)
|
||||
{}
|
||||
|
||||
/* All TUI I/O sent to the *_filtered and *_unfiltered functions
|
||||
eventually ends up here. The fputs_unfiltered_hook is primarily
|
||||
@ -164,91 +33,22 @@ tui_file_put (struct ui_file *file,
|
||||
gdb_stderr are sent to the hook. Everything else is sent on to
|
||||
fputs to allow file I/O to be handled appropriately. */
|
||||
|
||||
/* FIXME: Should be broken up and moved to a TUI specific file. */
|
||||
void
|
||||
tui_file::puts (const char *linebuffer)
|
||||
{
|
||||
tui_puts (linebuffer);
|
||||
/* gdb_stdout is buffered, and the caller must gdb_flush it at
|
||||
appropriate times. Other streams are not so buffered. */
|
||||
if (this != gdb_stdout)
|
||||
tui_refresh_cmd_win ();
|
||||
}
|
||||
|
||||
void
|
||||
tui_file_fputs (const char *linebuffer, struct ui_file *file)
|
||||
tui_file::flush ()
|
||||
{
|
||||
struct tui_stream *stream = (struct tui_stream *) ui_file_data (file);
|
||||
|
||||
if (stream->ts_streamtype == astring)
|
||||
{
|
||||
tui_file_adjust_strbuf (strlen (linebuffer), file);
|
||||
strcat (stream->ts_strbuf, linebuffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
tui_puts (linebuffer);
|
||||
/* gdb_stdout is buffered, and the caller must gdb_flush it at
|
||||
appropriate times. Other streams are not so buffered. */
|
||||
if (file != gdb_stdout)
|
||||
tui_refresh_cmd_win ();
|
||||
}
|
||||
}
|
||||
|
||||
char *
|
||||
tui_file_get_strbuf (struct ui_file *file)
|
||||
{
|
||||
struct tui_stream *stream = (struct tui_stream *) ui_file_data (file);
|
||||
|
||||
if (stream->ts_magic != &tui_file_magic)
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("tui_file_get_strbuf: bad magic number"));
|
||||
return (stream->ts_strbuf);
|
||||
}
|
||||
|
||||
/* Adjust the length of the buffer by the amount necessary to
|
||||
accomodate appending a string of length N to the buffer
|
||||
contents. */
|
||||
void
|
||||
tui_file_adjust_strbuf (int n, struct ui_file *file)
|
||||
{
|
||||
struct tui_stream *stream = (struct tui_stream *) ui_file_data (file);
|
||||
int non_null_chars;
|
||||
|
||||
if (stream->ts_magic != &tui_file_magic)
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("tui_file_adjust_strbuf: bad magic number"));
|
||||
|
||||
if (stream->ts_streamtype != astring)
|
||||
return;
|
||||
|
||||
if (stream->ts_strbuf)
|
||||
{
|
||||
/* There is already a buffer allocated. */
|
||||
non_null_chars = strlen (stream->ts_strbuf);
|
||||
|
||||
if (n > (stream->ts_buflen - non_null_chars - 1))
|
||||
{
|
||||
stream->ts_buflen = n + non_null_chars + 1;
|
||||
stream->ts_strbuf
|
||||
= XRESIZEVEC (char, stream->ts_strbuf, stream->ts_buflen);
|
||||
}
|
||||
}
|
||||
else
|
||||
/* No buffer yet, so allocate one of the desired size. */
|
||||
stream->ts_strbuf = XNEWVEC (char, n + 1);
|
||||
}
|
||||
|
||||
static void
|
||||
tui_file_flush (struct ui_file *file)
|
||||
{
|
||||
struct tui_stream *stream = (struct tui_stream *) ui_file_data (file);
|
||||
|
||||
if (stream->ts_magic != &tui_file_magic)
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("tui_file_flush: bad magic number"));
|
||||
|
||||
switch (stream->ts_streamtype)
|
||||
{
|
||||
case astring:
|
||||
break;
|
||||
case afile:
|
||||
/* gdb_stdout is buffered. Other files are always flushed on
|
||||
every write. */
|
||||
if (file == gdb_stdout)
|
||||
tui_refresh_cmd_win ();
|
||||
fflush (stream->ts_filestream);
|
||||
break;
|
||||
}
|
||||
/* gdb_stdout is buffered. Other files are always flushed on
|
||||
every write. */
|
||||
if (this == gdb_stdout)
|
||||
tui_refresh_cmd_win ();
|
||||
stdio_file::flush ();
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* UI_FILE - a generic STDIO like output stream.
|
||||
/* TUI_FILE - a STDIO-like output stream for the TUI.
|
||||
Copyright (C) 1999-2017 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
@ -19,9 +19,17 @@
|
||||
#ifndef TUI_FILE_H
|
||||
#define TUI_FILE_H
|
||||
|
||||
extern struct ui_file *tui_fileopen (FILE *);
|
||||
extern struct ui_file *tui_sfileopen (int);
|
||||
extern char *tui_file_get_strbuf (struct ui_file *);
|
||||
extern void tui_file_adjust_strbuf (int, struct ui_file *);
|
||||
#include "ui-file.h"
|
||||
|
||||
/* A STDIO-like output stream for the TUI. */
|
||||
|
||||
class tui_file : public stdio_file
|
||||
{
|
||||
public:
|
||||
explicit tui_file (FILE *stream);
|
||||
|
||||
void flush () override;
|
||||
void puts (const char *) override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -528,8 +528,8 @@ tui_initialize_io (void)
|
||||
#endif
|
||||
|
||||
/* Create tui output streams. */
|
||||
tui_stdout = tui_fileopen (stdout);
|
||||
tui_stderr = tui_fileopen (stderr);
|
||||
tui_stdout = new tui_file (stdout);
|
||||
tui_stderr = new tui_file (stderr);
|
||||
tui_out = tui_out_new (tui_stdout);
|
||||
|
||||
/* Create the default UI. */
|
||||
|
@ -711,7 +711,7 @@ TUI command to control the register window."), tuicmd);
|
||||
static void
|
||||
tui_restore_gdbout (void *ui)
|
||||
{
|
||||
ui_file_delete (gdb_stdout);
|
||||
delete gdb_stdout;
|
||||
gdb_stdout = (struct ui_file*) ui;
|
||||
pagination_enabled = 1;
|
||||
}
|
||||
@ -723,29 +723,26 @@ static char *
|
||||
tui_register_format (struct frame_info *frame, int regnum)
|
||||
{
|
||||
struct gdbarch *gdbarch = get_frame_arch (frame);
|
||||
struct ui_file *stream;
|
||||
struct ui_file *old_stdout;
|
||||
struct cleanup *cleanups;
|
||||
char *p, *s;
|
||||
char *ret;
|
||||
|
||||
string_file stream;
|
||||
|
||||
pagination_enabled = 0;
|
||||
old_stdout = gdb_stdout;
|
||||
stream = tui_sfileopen (256);
|
||||
gdb_stdout = stream;
|
||||
gdb_stdout = &stream;
|
||||
cleanups = make_cleanup (tui_restore_gdbout, (void*) old_stdout);
|
||||
gdbarch_print_registers_info (gdbarch, stream, frame, regnum, 1);
|
||||
|
||||
/* Save formatted output in the buffer. */
|
||||
p = tui_file_get_strbuf (stream);
|
||||
gdbarch_print_registers_info (gdbarch, &stream, frame, regnum, 1);
|
||||
|
||||
/* Remove the possible \n. */
|
||||
s = strrchr (p, '\n');
|
||||
if (s && s[1] == 0)
|
||||
*s = 0;
|
||||
std::string &str = stream.string ();
|
||||
if (!str.empty () && str.back () == '\n')
|
||||
str.resize (str.size () - 1);
|
||||
|
||||
/* Expand tabs into spaces, since ncurses on MS-Windows doesn't. */
|
||||
ret = tui_expand_tabs (p, 0);
|
||||
ret = tui_expand_tabs (str.c_str (), 0);
|
||||
|
||||
do_cleanups (cleanups);
|
||||
|
||||
|
@ -68,12 +68,9 @@ tui_make_status_line (struct tui_locator_element *loc)
|
||||
int status_size;
|
||||
int i, proc_width;
|
||||
const char *pid_name;
|
||||
const char *pc_buf;
|
||||
int target_width;
|
||||
int pid_width;
|
||||
int line_width;
|
||||
int pc_width;
|
||||
struct ui_file *pc_out;
|
||||
|
||||
if (ptid_equal (inferior_ptid, null_ptid))
|
||||
pid_name = "No process";
|
||||
@ -102,12 +99,14 @@ tui_make_status_line (struct tui_locator_element *loc)
|
||||
line_width = MIN_LINE_WIDTH;
|
||||
|
||||
/* Translate PC address. */
|
||||
pc_out = tui_sfileopen (128);
|
||||
string_file pc_out;
|
||||
|
||||
fputs_filtered (loc->gdbarch? paddress (loc->gdbarch, loc->addr) : "??",
|
||||
pc_out);
|
||||
pc_buf = tui_file_get_strbuf (pc_out);
|
||||
pc_width = strlen (pc_buf);
|
||||
|
||||
&pc_out);
|
||||
|
||||
const char *pc_buf = pc_out.c_str ();
|
||||
int pc_width = pc_out.size ();
|
||||
|
||||
/* First determine the amount of proc name width we have available.
|
||||
The +1 are for a space separator between fields.
|
||||
The -1 are to take into account the \0 counted by sizeof. */
|
||||
@ -204,7 +203,6 @@ tui_make_status_line (struct tui_locator_element *loc)
|
||||
string[i] = ' ';
|
||||
string[status_size] = (char) 0;
|
||||
|
||||
ui_file_delete (pc_out);
|
||||
return string;
|
||||
}
|
||||
|
||||
@ -215,21 +213,21 @@ static char*
|
||||
tui_get_function_from_frame (struct frame_info *fi)
|
||||
{
|
||||
static char name[256];
|
||||
struct ui_file *stream = tui_sfileopen (256);
|
||||
char *p;
|
||||
string_file stream;
|
||||
|
||||
print_address_symbolic (get_frame_arch (fi), get_frame_pc (fi),
|
||||
stream, demangle, "");
|
||||
p = tui_file_get_strbuf (stream);
|
||||
&stream, demangle, "");
|
||||
|
||||
/* Use simple heuristics to isolate the function name. The symbol
|
||||
can be demangled and we can have function parameters. Remove
|
||||
them because the status line is too short to display them. */
|
||||
if (*p == '<')
|
||||
p++;
|
||||
strncpy (name, p, sizeof (name) - 1);
|
||||
const char *d = stream.c_str ();
|
||||
if (*d == '<')
|
||||
d++;
|
||||
strncpy (name, d, sizeof (name) - 1);
|
||||
name[sizeof (name) - 1] = 0;
|
||||
p = strchr (name, '(');
|
||||
|
||||
char *p = strchr (name, '(');
|
||||
if (!p)
|
||||
p = strchr (name, '>');
|
||||
if (p)
|
||||
@ -237,7 +235,6 @@ tui_get_function_from_frame (struct frame_info *fi)
|
||||
p = strchr (name, '+');
|
||||
if (p)
|
||||
*p = 0;
|
||||
ui_file_delete (stream);
|
||||
return name;
|
||||
}
|
||||
|
||||
|
@ -371,26 +371,19 @@ type_print (struct type *type, const char *varstring, struct ui_file *stream,
|
||||
std::string
|
||||
type_to_string (struct type *type)
|
||||
{
|
||||
std::string s;
|
||||
struct ui_file *stb;
|
||||
struct cleanup *old_chain;
|
||||
|
||||
stb = mem_fileopen ();
|
||||
old_chain = make_cleanup_ui_file_delete (stb);
|
||||
|
||||
TRY
|
||||
{
|
||||
type_print (type, "", stb, -1);
|
||||
s = ui_file_as_string (stb);
|
||||
string_file stb;
|
||||
|
||||
type_print (type, "", &stb, -1);
|
||||
return std::move (stb.string ());
|
||||
}
|
||||
CATCH (except, RETURN_MASK_ALL)
|
||||
{
|
||||
}
|
||||
END_CATCH
|
||||
|
||||
do_cleanups (old_chain);
|
||||
|
||||
return s;
|
||||
return {};
|
||||
}
|
||||
|
||||
/* Print type of EXP, or last thing in value history if EXP == NULL.
|
||||
|
814
gdb/ui-file.c
814
gdb/ui-file.c
@ -25,193 +25,80 @@
|
||||
#include "gdb_select.h"
|
||||
#include "filestuff.h"
|
||||
|
||||
static ui_file_isatty_ftype null_file_isatty;
|
||||
static ui_file_write_ftype null_file_write;
|
||||
static ui_file_write_ftype null_file_write_async_safe;
|
||||
static ui_file_fputs_ftype null_file_fputs;
|
||||
static ui_file_read_ftype null_file_read;
|
||||
static ui_file_flush_ftype null_file_flush;
|
||||
static ui_file_delete_ftype null_file_delete;
|
||||
static ui_file_rewind_ftype null_file_rewind;
|
||||
static ui_file_put_ftype null_file_put;
|
||||
static ui_file_fseek_ftype null_file_fseek;
|
||||
null_file null_stream;
|
||||
|
||||
struct ui_file
|
||||
{
|
||||
int *magic;
|
||||
ui_file_flush_ftype *to_flush;
|
||||
ui_file_write_ftype *to_write;
|
||||
ui_file_write_async_safe_ftype *to_write_async_safe;
|
||||
ui_file_fputs_ftype *to_fputs;
|
||||
ui_file_read_ftype *to_read;
|
||||
ui_file_delete_ftype *to_delete;
|
||||
ui_file_isatty_ftype *to_isatty;
|
||||
ui_file_rewind_ftype *to_rewind;
|
||||
ui_file_put_ftype *to_put;
|
||||
ui_file_fseek_ftype *to_fseek;
|
||||
void *to_data;
|
||||
};
|
||||
int ui_file_magic;
|
||||
ui_file::ui_file ()
|
||||
{}
|
||||
|
||||
struct ui_file *
|
||||
ui_file_new (void)
|
||||
ui_file::~ui_file ()
|
||||
{}
|
||||
|
||||
void
|
||||
ui_file::printf (const char *format, ...)
|
||||
{
|
||||
struct ui_file *file = XNEW (struct ui_file);
|
||||
va_list args;
|
||||
|
||||
file->magic = &ui_file_magic;
|
||||
set_ui_file_data (file, NULL, null_file_delete);
|
||||
set_ui_file_flush (file, null_file_flush);
|
||||
set_ui_file_write (file, null_file_write);
|
||||
set_ui_file_write_async_safe (file, null_file_write_async_safe);
|
||||
set_ui_file_fputs (file, null_file_fputs);
|
||||
set_ui_file_read (file, null_file_read);
|
||||
set_ui_file_isatty (file, null_file_isatty);
|
||||
set_ui_file_rewind (file, null_file_rewind);
|
||||
set_ui_file_put (file, null_file_put);
|
||||
set_ui_file_fseek (file, null_file_fseek);
|
||||
return file;
|
||||
va_start (args, format);
|
||||
vfprintf_unfiltered (this, format, args);
|
||||
va_end (args);
|
||||
}
|
||||
|
||||
void
|
||||
ui_file_delete (struct ui_file *file)
|
||||
ui_file::putstr (const char *str, int quoter)
|
||||
{
|
||||
file->to_delete (file);
|
||||
xfree (file);
|
||||
fputstr_unfiltered (str, quoter, this);
|
||||
}
|
||||
|
||||
static int
|
||||
null_file_isatty (struct ui_file *file)
|
||||
void
|
||||
ui_file::putstrn (const char *str, int n, int quoter)
|
||||
{
|
||||
return 0;
|
||||
fputstrn_unfiltered (str, n, quoter, this);
|
||||
}
|
||||
|
||||
static void
|
||||
null_file_rewind (struct ui_file *file)
|
||||
int
|
||||
ui_file::putc (int c)
|
||||
{
|
||||
return;
|
||||
return fputc_unfiltered (c, this);
|
||||
}
|
||||
|
||||
static void
|
||||
null_file_put (struct ui_file *file,
|
||||
ui_file_put_method_ftype *write,
|
||||
void *dest)
|
||||
void
|
||||
ui_file::vprintf (const char *format, va_list args)
|
||||
{
|
||||
return;
|
||||
vfprintf_unfiltered (this, format, args);
|
||||
}
|
||||
|
||||
static void
|
||||
null_file_flush (struct ui_file *file)
|
||||
|
||||
|
||||
void
|
||||
null_file::write (const char *buf, long sizeof_buf)
|
||||
{
|
||||
return;
|
||||
/* Discard the request. */
|
||||
}
|
||||
|
||||
static void
|
||||
null_file_write (struct ui_file *file,
|
||||
const char *buf,
|
||||
long sizeof_buf)
|
||||
void
|
||||
null_file::puts (const char *)
|
||||
{
|
||||
if (file->to_fputs == null_file_fputs)
|
||||
/* Both the write and fputs methods are null. Discard the
|
||||
request. */
|
||||
return;
|
||||
else
|
||||
{
|
||||
/* The fputs method isn't null, slowly pass the write request
|
||||
onto that. FYI, this isn't as bad as it may look - the
|
||||
current (as of 1999-11-07) printf_* function calls fputc and
|
||||
fputc does exactly the below. By having a write function it
|
||||
is possible to clean up that code. */
|
||||
int i;
|
||||
char b[2];
|
||||
|
||||
b[1] = '\0';
|
||||
for (i = 0; i < sizeof_buf; i++)
|
||||
{
|
||||
b[0] = buf[i];
|
||||
file->to_fputs (b, file);
|
||||
}
|
||||
return;
|
||||
}
|
||||
/* Discard the request. */
|
||||
}
|
||||
|
||||
static long
|
||||
null_file_read (struct ui_file *file,
|
||||
char *buf,
|
||||
long sizeof_buf)
|
||||
void
|
||||
null_file::write_async_safe (const char *buf, long sizeof_buf)
|
||||
{
|
||||
errno = EBADF;
|
||||
return 0;
|
||||
/* Discard the request. */
|
||||
}
|
||||
|
||||
static void
|
||||
null_file_fputs (const char *buf, struct ui_file *file)
|
||||
{
|
||||
if (file->to_write == null_file_write)
|
||||
/* Both the write and fputs methods are null. Discard the
|
||||
request. */
|
||||
return;
|
||||
else
|
||||
{
|
||||
/* The write method was implemented, use that. */
|
||||
file->to_write (file, buf, strlen (buf));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
null_file_write_async_safe (struct ui_file *file,
|
||||
const char *buf,
|
||||
long sizeof_buf)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
null_file_delete (struct ui_file *file)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static int
|
||||
null_file_fseek (struct ui_file *stream, long offset, int whence)
|
||||
{
|
||||
errno = EBADF;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void *
|
||||
ui_file_data (struct ui_file *file)
|
||||
{
|
||||
if (file->magic != &ui_file_magic)
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("ui_file_data: bad magic number"));
|
||||
return file->to_data;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
gdb_flush (struct ui_file *file)
|
||||
{
|
||||
file->to_flush (file);
|
||||
file->flush ();
|
||||
}
|
||||
|
||||
int
|
||||
ui_file_isatty (struct ui_file *file)
|
||||
{
|
||||
return file->to_isatty (file);
|
||||
}
|
||||
|
||||
void
|
||||
ui_file_rewind (struct ui_file *file)
|
||||
{
|
||||
file->to_rewind (file);
|
||||
}
|
||||
|
||||
void
|
||||
ui_file_put (struct ui_file *file,
|
||||
ui_file_put_method_ftype *write,
|
||||
void *dest)
|
||||
{
|
||||
file->to_put (file, write, dest);
|
||||
return file->isatty ();
|
||||
}
|
||||
|
||||
void
|
||||
@ -219,13 +106,7 @@ ui_file_write (struct ui_file *file,
|
||||
const char *buf,
|
||||
long length_buf)
|
||||
{
|
||||
file->to_write (file, buf, length_buf);
|
||||
}
|
||||
|
||||
void
|
||||
ui_file_write_for_put (void *data, const char *buffer, long length_buffer)
|
||||
{
|
||||
ui_file_write ((struct ui_file *) data, buffer, length_buffer);
|
||||
file->write (buf, length_buf);
|
||||
}
|
||||
|
||||
void
|
||||
@ -233,622 +114,215 @@ ui_file_write_async_safe (struct ui_file *file,
|
||||
const char *buf,
|
||||
long length_buf)
|
||||
{
|
||||
file->to_write_async_safe (file, buf, length_buf);
|
||||
file->write_async_safe (buf, length_buf);
|
||||
}
|
||||
|
||||
long
|
||||
ui_file_read (struct ui_file *file, char *buf, long length_buf)
|
||||
{
|
||||
return file->to_read (file, buf, length_buf);
|
||||
}
|
||||
|
||||
int
|
||||
ui_file_fseek (struct ui_file *file, long offset, int whence)
|
||||
{
|
||||
return file->to_fseek (file, offset, whence);
|
||||
return file->read (buf, length_buf);
|
||||
}
|
||||
|
||||
void
|
||||
fputs_unfiltered (const char *buf, struct ui_file *file)
|
||||
{
|
||||
file->to_fputs (buf, file);
|
||||
file->puts (buf);
|
||||
}
|
||||
|
||||
void
|
||||
set_ui_file_flush (struct ui_file *file, ui_file_flush_ftype *flush_ptr)
|
||||
{
|
||||
file->to_flush = flush_ptr;
|
||||
}
|
||||
|
||||
void
|
||||
set_ui_file_isatty (struct ui_file *file, ui_file_isatty_ftype *isatty_ptr)
|
||||
{
|
||||
file->to_isatty = isatty_ptr;
|
||||
}
|
||||
|
||||
void
|
||||
set_ui_file_rewind (struct ui_file *file, ui_file_rewind_ftype *rewind_ptr)
|
||||
{
|
||||
file->to_rewind = rewind_ptr;
|
||||
}
|
||||
|
||||
void
|
||||
set_ui_file_put (struct ui_file *file, ui_file_put_ftype *put_ptr)
|
||||
{
|
||||
file->to_put = put_ptr;
|
||||
}
|
||||
|
||||
void
|
||||
set_ui_file_write (struct ui_file *file,
|
||||
ui_file_write_ftype *write_ptr)
|
||||
{
|
||||
file->to_write = write_ptr;
|
||||
}
|
||||
|
||||
void
|
||||
set_ui_file_write_async_safe (struct ui_file *file,
|
||||
ui_file_write_async_safe_ftype *write_async_safe_ptr)
|
||||
{
|
||||
file->to_write_async_safe = write_async_safe_ptr;
|
||||
}
|
||||
|
||||
void
|
||||
set_ui_file_read (struct ui_file *file, ui_file_read_ftype *read_ptr)
|
||||
{
|
||||
file->to_read = read_ptr;
|
||||
}
|
||||
|
||||
void
|
||||
set_ui_file_fputs (struct ui_file *file, ui_file_fputs_ftype *fputs_ptr)
|
||||
{
|
||||
file->to_fputs = fputs_ptr;
|
||||
}
|
||||
|
||||
void
|
||||
set_ui_file_fseek (struct ui_file *file, ui_file_fseek_ftype *fseek_ptr)
|
||||
{
|
||||
file->to_fseek = fseek_ptr;
|
||||
}
|
||||
|
||||
void
|
||||
set_ui_file_data (struct ui_file *file, void *data,
|
||||
ui_file_delete_ftype *delete_ptr)
|
||||
{
|
||||
file->to_data = data;
|
||||
file->to_delete = delete_ptr;
|
||||
}
|
||||
|
||||
/* ui_file utility function for converting a ``struct ui_file'' into
|
||||
a memory buffer. */
|
||||
|
||||
struct accumulated_ui_file
|
||||
{
|
||||
char *buffer;
|
||||
long length;
|
||||
};
|
||||
|
||||
static void
|
||||
do_ui_file_xstrdup (void *context, const char *buffer, long length)
|
||||
{
|
||||
struct accumulated_ui_file *acc = (struct accumulated_ui_file *) context;
|
||||
|
||||
if (acc->buffer == NULL)
|
||||
acc->buffer = (char *) xmalloc (length + 1);
|
||||
else
|
||||
acc->buffer = (char *) xrealloc (acc->buffer, acc->length + length + 1);
|
||||
memcpy (acc->buffer + acc->length, buffer, length);
|
||||
acc->length += length;
|
||||
acc->buffer[acc->length] = '\0';
|
||||
}
|
||||
|
||||
char *
|
||||
ui_file_xstrdup (struct ui_file *file, long *length)
|
||||
{
|
||||
struct accumulated_ui_file acc;
|
||||
|
||||
acc.buffer = NULL;
|
||||
acc.length = 0;
|
||||
ui_file_put (file, do_ui_file_xstrdup, &acc);
|
||||
if (acc.buffer == NULL)
|
||||
acc.buffer = xstrdup ("");
|
||||
if (length != NULL)
|
||||
*length = acc.length;
|
||||
return acc.buffer;
|
||||
}
|
||||
|
||||
/* ui_file utility function for converting a ``struct ui_file'' into a
|
||||
std:string. */
|
||||
|
||||
static void
|
||||
do_ui_file_as_string (void *context, const char *buffer, long length)
|
||||
{
|
||||
std::string *str = (std::string *) context;
|
||||
|
||||
*str = std::string (buffer, length);
|
||||
}
|
||||
|
||||
/* See ui-file.h. */
|
||||
|
||||
std::string
|
||||
ui_file_as_string (struct ui_file *file)
|
||||
{
|
||||
std::string str;
|
||||
|
||||
ui_file_put (file, do_ui_file_as_string, &str);
|
||||
return str;
|
||||
}
|
||||
|
||||
static void
|
||||
do_ui_file_obsavestring (void *context, const char *buffer, long length)
|
||||
{
|
||||
struct obstack *obstack = (struct obstack *) context;
|
||||
|
||||
obstack_grow (obstack, buffer, length);
|
||||
}
|
||||
|
||||
char *
|
||||
ui_file_obsavestring (struct ui_file *file, struct obstack *obstack,
|
||||
long *length)
|
||||
{
|
||||
ui_file_put (file, do_ui_file_obsavestring, obstack);
|
||||
*length = obstack_object_size (obstack);
|
||||
obstack_1grow (obstack, '\0');
|
||||
return (char *) obstack_finish (obstack);
|
||||
}
|
||||
|
||||
/* A pure memory based ``struct ui_file'' that can be used an output
|
||||
buffer. The buffers accumulated contents are available via
|
||||
ui_file_put(). */
|
||||
|
||||
struct mem_file
|
||||
{
|
||||
int *magic;
|
||||
char *buffer;
|
||||
int sizeof_buffer;
|
||||
int length_buffer;
|
||||
};
|
||||
string_file::~string_file ()
|
||||
{}
|
||||
|
||||
static ui_file_rewind_ftype mem_file_rewind;
|
||||
static ui_file_put_ftype mem_file_put;
|
||||
static ui_file_write_ftype mem_file_write;
|
||||
static ui_file_delete_ftype mem_file_delete;
|
||||
static struct ui_file *mem_file_new (void);
|
||||
static int mem_file_magic;
|
||||
|
||||
static struct ui_file *
|
||||
mem_file_new (void)
|
||||
void
|
||||
string_file::write (const char *buf, long length_buf)
|
||||
{
|
||||
struct mem_file *stream = XNEW (struct mem_file);
|
||||
struct ui_file *file = ui_file_new ();
|
||||
|
||||
set_ui_file_data (file, stream, mem_file_delete);
|
||||
set_ui_file_rewind (file, mem_file_rewind);
|
||||
set_ui_file_put (file, mem_file_put);
|
||||
set_ui_file_write (file, mem_file_write);
|
||||
stream->magic = &mem_file_magic;
|
||||
stream->buffer = NULL;
|
||||
stream->sizeof_buffer = 0;
|
||||
stream->length_buffer = 0;
|
||||
return file;
|
||||
m_string.append (buf, length_buf);
|
||||
}
|
||||
|
||||
static void
|
||||
mem_file_delete (struct ui_file *file)
|
||||
{
|
||||
struct mem_file *stream = (struct mem_file *) ui_file_data (file);
|
||||
|
||||
|
||||
if (stream->magic != &mem_file_magic)
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("mem_file_delete: bad magic number"));
|
||||
if (stream->buffer != NULL)
|
||||
xfree (stream->buffer);
|
||||
xfree (stream);
|
||||
stdio_file::stdio_file (FILE *file, bool close_p)
|
||||
{
|
||||
set_stream (file);
|
||||
m_close_p = close_p;
|
||||
}
|
||||
|
||||
struct ui_file *
|
||||
mem_fileopen (void)
|
||||
stdio_file::stdio_file ()
|
||||
: m_file (NULL),
|
||||
m_fd (-1),
|
||||
m_close_p (false)
|
||||
{}
|
||||
|
||||
stdio_file::~stdio_file ()
|
||||
{
|
||||
return mem_file_new ();
|
||||
}
|
||||
|
||||
static void
|
||||
mem_file_rewind (struct ui_file *file)
|
||||
{
|
||||
struct mem_file *stream = (struct mem_file *) ui_file_data (file);
|
||||
|
||||
if (stream->magic != &mem_file_magic)
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("mem_file_rewind: bad magic number"));
|
||||
stream->length_buffer = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
mem_file_put (struct ui_file *file,
|
||||
ui_file_put_method_ftype *write,
|
||||
void *dest)
|
||||
{
|
||||
struct mem_file *stream = (struct mem_file *) ui_file_data (file);
|
||||
|
||||
if (stream->magic != &mem_file_magic)
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("mem_file_put: bad magic number"));
|
||||
if (stream->length_buffer > 0)
|
||||
write (dest, stream->buffer, stream->length_buffer);
|
||||
if (m_close_p)
|
||||
fclose (m_file);
|
||||
}
|
||||
|
||||
void
|
||||
mem_file_write (struct ui_file *file,
|
||||
const char *buffer,
|
||||
long length_buffer)
|
||||
stdio_file::set_stream (FILE *file)
|
||||
{
|
||||
struct mem_file *stream = (struct mem_file *) ui_file_data (file);
|
||||
m_file = file;
|
||||
m_fd = fileno (file);
|
||||
}
|
||||
|
||||
if (stream->magic != &mem_file_magic)
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("mem_file_write: bad magic number"));
|
||||
if (stream->buffer == NULL)
|
||||
bool
|
||||
stdio_file::open (const char *name, const char *mode)
|
||||
{
|
||||
/* Close the previous stream, if we own it. */
|
||||
if (m_close_p)
|
||||
{
|
||||
stream->length_buffer = length_buffer;
|
||||
stream->sizeof_buffer = length_buffer;
|
||||
stream->buffer = (char *) xmalloc (stream->sizeof_buffer);
|
||||
memcpy (stream->buffer, buffer, length_buffer);
|
||||
fclose (m_file);
|
||||
m_close_p = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
int new_length = stream->length_buffer + length_buffer;
|
||||
|
||||
if (new_length >= stream->sizeof_buffer)
|
||||
{
|
||||
stream->sizeof_buffer = new_length;
|
||||
stream->buffer
|
||||
= (char *) xrealloc (stream->buffer, stream->sizeof_buffer);
|
||||
}
|
||||
memcpy (stream->buffer + stream->length_buffer, buffer, length_buffer);
|
||||
stream->length_buffer = new_length;
|
||||
}
|
||||
}
|
||||
|
||||
/* ``struct ui_file'' implementation that maps directly onto
|
||||
<stdio.h>'s FILE. */
|
||||
FILE *f = gdb_fopen_cloexec (name, mode);
|
||||
|
||||
static ui_file_write_ftype stdio_file_write;
|
||||
static ui_file_write_async_safe_ftype stdio_file_write_async_safe;
|
||||
static ui_file_fputs_ftype stdio_file_fputs;
|
||||
static ui_file_read_ftype stdio_file_read;
|
||||
static ui_file_isatty_ftype stdio_file_isatty;
|
||||
static ui_file_delete_ftype stdio_file_delete;
|
||||
static struct ui_file *stdio_file_new (FILE *file, int close_p);
|
||||
static ui_file_flush_ftype stdio_file_flush;
|
||||
static ui_file_fseek_ftype stdio_file_fseek;
|
||||
if (f == NULL)
|
||||
return false;
|
||||
|
||||
static int stdio_file_magic;
|
||||
set_stream (f);
|
||||
m_close_p = true;
|
||||
|
||||
struct stdio_file
|
||||
{
|
||||
int *magic;
|
||||
FILE *file;
|
||||
/* The associated file descriptor is extracted ahead of time for
|
||||
stdio_file_write_async_safe's benefit, in case fileno isn't async-safe. */
|
||||
int fd;
|
||||
int close_p;
|
||||
};
|
||||
|
||||
static struct ui_file *
|
||||
stdio_file_new (FILE *file, int close_p)
|
||||
{
|
||||
struct ui_file *ui_file = ui_file_new ();
|
||||
struct stdio_file *stdio = XNEW (struct stdio_file);
|
||||
|
||||
stdio->magic = &stdio_file_magic;
|
||||
stdio->file = file;
|
||||
stdio->fd = fileno (file);
|
||||
stdio->close_p = close_p;
|
||||
set_ui_file_data (ui_file, stdio, stdio_file_delete);
|
||||
set_ui_file_flush (ui_file, stdio_file_flush);
|
||||
set_ui_file_write (ui_file, stdio_file_write);
|
||||
set_ui_file_write_async_safe (ui_file, stdio_file_write_async_safe);
|
||||
set_ui_file_fputs (ui_file, stdio_file_fputs);
|
||||
set_ui_file_read (ui_file, stdio_file_read);
|
||||
set_ui_file_isatty (ui_file, stdio_file_isatty);
|
||||
set_ui_file_fseek (ui_file, stdio_file_fseek);
|
||||
return ui_file;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
stdio_file_delete (struct ui_file *file)
|
||||
void
|
||||
stdio_file::flush ()
|
||||
{
|
||||
struct stdio_file *stdio = (struct stdio_file *) ui_file_data (file);
|
||||
|
||||
if (stdio->magic != &stdio_file_magic)
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("stdio_file_delete: bad magic number"));
|
||||
if (stdio->close_p)
|
||||
{
|
||||
fclose (stdio->file);
|
||||
}
|
||||
xfree (stdio);
|
||||
fflush (m_file);
|
||||
}
|
||||
|
||||
static void
|
||||
stdio_file_flush (struct ui_file *file)
|
||||
long
|
||||
stdio_file::read (char *buf, long length_buf)
|
||||
{
|
||||
struct stdio_file *stdio = (struct stdio_file *) ui_file_data (file);
|
||||
|
||||
if (stdio->magic != &stdio_file_magic)
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("stdio_file_flush: bad magic number"));
|
||||
fflush (stdio->file);
|
||||
}
|
||||
|
||||
static long
|
||||
stdio_file_read (struct ui_file *file, char *buf, long length_buf)
|
||||
{
|
||||
struct stdio_file *stdio = (struct stdio_file *) ui_file_data (file);
|
||||
|
||||
if (stdio->magic != &stdio_file_magic)
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("stdio_file_read: bad magic number"));
|
||||
|
||||
/* Wait until at least one byte of data is available, or we get
|
||||
interrupted with Control-C. */
|
||||
{
|
||||
fd_set readfds;
|
||||
|
||||
FD_ZERO (&readfds);
|
||||
FD_SET (stdio->fd, &readfds);
|
||||
if (interruptible_select (stdio->fd + 1, &readfds, NULL, NULL, NULL) == -1)
|
||||
FD_SET (m_fd, &readfds);
|
||||
if (interruptible_select (m_fd + 1, &readfds, NULL, NULL, NULL) == -1)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return read (stdio->fd, buf, length_buf);
|
||||
return ::read (m_fd, buf, length_buf);
|
||||
}
|
||||
|
||||
static void
|
||||
stdio_file_write (struct ui_file *file, const char *buf, long length_buf)
|
||||
void
|
||||
stdio_file::write (const char *buf, long length_buf)
|
||||
{
|
||||
struct stdio_file *stdio = (struct stdio_file *) ui_file_data (file);
|
||||
|
||||
if (stdio->magic != &stdio_file_magic)
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("stdio_file_write: bad magic number"));
|
||||
/* Calling error crashes when we are called from the exception framework. */
|
||||
if (fwrite (buf, length_buf, 1, stdio->file))
|
||||
if (fwrite (buf, length_buf, 1, m_file))
|
||||
{
|
||||
/* Nothing. */
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
stdio_file_write_async_safe (struct ui_file *file,
|
||||
const char *buf, long length_buf)
|
||||
void
|
||||
stdio_file::write_async_safe (const char *buf, long length_buf)
|
||||
{
|
||||
struct stdio_file *stdio = (struct stdio_file *) ui_file_data (file);
|
||||
|
||||
if (stdio->magic != &stdio_file_magic)
|
||||
{
|
||||
/* gettext isn't necessarily async safe, so we can't use _("error message") here.
|
||||
We could extract the correct translation ahead of time, but this is an extremely
|
||||
rare event, and one of the other stdio_file_* routines will presumably catch
|
||||
the problem anyway. For now keep it simple and ignore the error here. */
|
||||
return;
|
||||
}
|
||||
|
||||
/* This is written the way it is to avoid a warning from gcc about not using the
|
||||
result of write (since it can be declared with attribute warn_unused_result).
|
||||
Alas casting to void doesn't work for this. */
|
||||
if (write (stdio->fd, buf, length_buf))
|
||||
if (::write (m_fd, buf, length_buf))
|
||||
{
|
||||
/* Nothing. */
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
stdio_file_fputs (const char *linebuffer, struct ui_file *file)
|
||||
void
|
||||
stdio_file::puts (const char *linebuffer)
|
||||
{
|
||||
struct stdio_file *stdio = (struct stdio_file *) ui_file_data (file);
|
||||
|
||||
if (stdio->magic != &stdio_file_magic)
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("stdio_file_fputs: bad magic number"));
|
||||
/* Calling error crashes when we are called from the exception framework. */
|
||||
if (fputs (linebuffer, stdio->file))
|
||||
if (fputs (linebuffer, m_file))
|
||||
{
|
||||
/* Nothing. */
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
stdio_file_isatty (struct ui_file *file)
|
||||
bool
|
||||
stdio_file::isatty ()
|
||||
{
|
||||
struct stdio_file *stdio = (struct stdio_file *) ui_file_data (file);
|
||||
|
||||
if (stdio->magic != &stdio_file_magic)
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("stdio_file_isatty: bad magic number"));
|
||||
return (isatty (stdio->fd));
|
||||
return ::isatty (m_fd);
|
||||
}
|
||||
|
||||
static int
|
||||
stdio_file_fseek (struct ui_file *file, long offset, int whence)
|
||||
{
|
||||
struct stdio_file *stdio = (struct stdio_file *) ui_file_data (file);
|
||||
|
||||
|
||||
if (stdio->magic != &stdio_file_magic)
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("stdio_file_fseek: bad magic number"));
|
||||
|
||||
return fseek (stdio->file, offset, whence);
|
||||
}
|
||||
|
||||
#ifdef __MINGW32__
|
||||
/* This is the implementation of ui_file method to_write for stderr.
|
||||
/* This is the implementation of ui_file method 'write' for stderr.
|
||||
gdb_stdout is flushed before writing to gdb_stderr. */
|
||||
|
||||
static void
|
||||
stderr_file_write (struct ui_file *file, const char *buf, long length_buf)
|
||||
void
|
||||
stderr_file::write (const char *buf, long length_buf)
|
||||
{
|
||||
gdb_flush (gdb_stdout);
|
||||
stdio_file_write (file, buf, length_buf);
|
||||
stdio_file::write (buf, length_buf);
|
||||
}
|
||||
|
||||
/* This is the implementation of ui_file method to_fputs for stderr.
|
||||
/* This is the implementation of ui_file method 'puts' for stderr.
|
||||
gdb_stdout is flushed before writing to gdb_stderr. */
|
||||
|
||||
static void
|
||||
stderr_file_fputs (const char *linebuffer, struct ui_file *file)
|
||||
void
|
||||
stderr_file::puts (const char *linebuffer)
|
||||
{
|
||||
gdb_flush (gdb_stdout);
|
||||
stdio_file_fputs (linebuffer, file);
|
||||
stdio_file::puts (linebuffer);
|
||||
}
|
||||
#endif
|
||||
|
||||
struct ui_file *
|
||||
stderr_fileopen (FILE *stream)
|
||||
stderr_file::stderr_file (FILE *stream)
|
||||
: stdio_file (stream)
|
||||
{}
|
||||
|
||||
|
||||
|
||||
tee_file::tee_file (ui_file *one, bool close_one,
|
||||
ui_file *two, bool close_two)
|
||||
: m_one (one),
|
||||
m_two (two),
|
||||
m_close_one (close_one),
|
||||
m_close_two (close_two)
|
||||
{}
|
||||
|
||||
tee_file::~tee_file ()
|
||||
{
|
||||
struct ui_file *ui_file = stdio_fileopen (stream);
|
||||
|
||||
#ifdef __MINGW32__
|
||||
/* There is no real line-buffering on Windows, see
|
||||
http://msdn.microsoft.com/en-us/library/86cebhfs%28v=vs.71%29.aspx
|
||||
so the stdout is either fully-buffered or non-buffered. We can't
|
||||
make stdout non-buffered, because of two concerns,
|
||||
1. non-buffering hurts performance,
|
||||
2. non-buffering may change GDB's behavior when it is interacting
|
||||
with front-end, such as Emacs.
|
||||
|
||||
We decided to leave stdout as fully buffered, but flush it first
|
||||
when something is written to stderr. */
|
||||
|
||||
/* Method 'to_write_async_safe' is not overwritten, because there's
|
||||
no way to flush a stream in an async-safe manner. Fortunately,
|
||||
it doesn't really matter, because:
|
||||
- that method is only used for printing internal debug output
|
||||
from signal handlers.
|
||||
- Windows hosts don't have a concept of async-safeness. Signal
|
||||
handlers run in a separate thread, so they can call
|
||||
the regular non-async-safe output routines freely. */
|
||||
set_ui_file_write (ui_file, stderr_file_write);
|
||||
set_ui_file_fputs (ui_file, stderr_file_fputs);
|
||||
#endif
|
||||
|
||||
return ui_file;
|
||||
if (m_close_one)
|
||||
delete m_one;
|
||||
if (m_close_two)
|
||||
delete m_two;
|
||||
}
|
||||
|
||||
/* Like fdopen(). Create a ui_file from a previously opened FILE. */
|
||||
|
||||
struct ui_file *
|
||||
stdio_fileopen (FILE *file)
|
||||
void
|
||||
tee_file::flush ()
|
||||
{
|
||||
return stdio_file_new (file, 0);
|
||||
m_one->flush ();
|
||||
m_two->flush ();
|
||||
}
|
||||
|
||||
struct ui_file *
|
||||
gdb_fopen (const char *name, const char *mode)
|
||||
void
|
||||
tee_file::write (const char *buf, long length_buf)
|
||||
{
|
||||
FILE *f = gdb_fopen_cloexec (name, mode);
|
||||
|
||||
if (f == NULL)
|
||||
return NULL;
|
||||
return stdio_file_new (f, 1);
|
||||
m_one->write (buf, length_buf);
|
||||
m_two->write (buf, length_buf);
|
||||
}
|
||||
|
||||
/* ``struct ui_file'' implementation that maps onto two ui-file objects. */
|
||||
|
||||
static ui_file_write_ftype tee_file_write;
|
||||
static ui_file_fputs_ftype tee_file_fputs;
|
||||
static ui_file_isatty_ftype tee_file_isatty;
|
||||
static ui_file_delete_ftype tee_file_delete;
|
||||
static ui_file_flush_ftype tee_file_flush;
|
||||
|
||||
static int tee_file_magic;
|
||||
|
||||
struct tee_file
|
||||
{
|
||||
int *magic;
|
||||
struct ui_file *one, *two;
|
||||
int close_one, close_two;
|
||||
};
|
||||
|
||||
struct ui_file *
|
||||
tee_file_new (struct ui_file *one, int close_one,
|
||||
struct ui_file *two, int close_two)
|
||||
void
|
||||
tee_file::write_async_safe (const char *buf, long length_buf)
|
||||
{
|
||||
struct ui_file *ui_file = ui_file_new ();
|
||||
struct tee_file *tee = XNEW (struct tee_file);
|
||||
|
||||
tee->magic = &tee_file_magic;
|
||||
tee->one = one;
|
||||
tee->two = two;
|
||||
tee->close_one = close_one;
|
||||
tee->close_two = close_two;
|
||||
set_ui_file_data (ui_file, tee, tee_file_delete);
|
||||
set_ui_file_flush (ui_file, tee_file_flush);
|
||||
set_ui_file_write (ui_file, tee_file_write);
|
||||
set_ui_file_fputs (ui_file, tee_file_fputs);
|
||||
set_ui_file_isatty (ui_file, tee_file_isatty);
|
||||
return ui_file;
|
||||
m_one->write_async_safe (buf, length_buf);
|
||||
m_two->write_async_safe (buf, length_buf);
|
||||
}
|
||||
|
||||
static void
|
||||
tee_file_delete (struct ui_file *file)
|
||||
void
|
||||
tee_file::puts (const char *linebuffer)
|
||||
{
|
||||
struct tee_file *tee = (struct tee_file *) ui_file_data (file);
|
||||
|
||||
if (tee->magic != &tee_file_magic)
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("tee_file_delete: bad magic number"));
|
||||
if (tee->close_one)
|
||||
ui_file_delete (tee->one);
|
||||
if (tee->close_two)
|
||||
ui_file_delete (tee->two);
|
||||
|
||||
xfree (tee);
|
||||
m_one->puts (linebuffer);
|
||||
m_two->puts (linebuffer);
|
||||
}
|
||||
|
||||
static void
|
||||
tee_file_flush (struct ui_file *file)
|
||||
bool
|
||||
tee_file::isatty ()
|
||||
{
|
||||
struct tee_file *tee = (struct tee_file *) ui_file_data (file);
|
||||
|
||||
if (tee->magic != &tee_file_magic)
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("tee_file_flush: bad magic number"));
|
||||
tee->one->to_flush (tee->one);
|
||||
tee->two->to_flush (tee->two);
|
||||
}
|
||||
|
||||
static void
|
||||
tee_file_write (struct ui_file *file, const char *buf, long length_buf)
|
||||
{
|
||||
struct tee_file *tee = (struct tee_file *) ui_file_data (file);
|
||||
|
||||
if (tee->magic != &tee_file_magic)
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("tee_file_write: bad magic number"));
|
||||
ui_file_write (tee->one, buf, length_buf);
|
||||
ui_file_write (tee->two, buf, length_buf);
|
||||
}
|
||||
|
||||
static void
|
||||
tee_file_fputs (const char *linebuffer, struct ui_file *file)
|
||||
{
|
||||
struct tee_file *tee = (struct tee_file *) ui_file_data (file);
|
||||
|
||||
if (tee->magic != &tee_file_magic)
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("tee_file_fputs: bad magic number"));
|
||||
tee->one->to_fputs (linebuffer, tee->one);
|
||||
tee->two->to_fputs (linebuffer, tee->two);
|
||||
}
|
||||
|
||||
static int
|
||||
tee_file_isatty (struct ui_file *file)
|
||||
{
|
||||
struct tee_file *tee = (struct tee_file *) ui_file_data (file);
|
||||
|
||||
if (tee->magic != &tee_file_magic)
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("tee_file_isatty: bad magic number"));
|
||||
|
||||
return ui_file_isatty (tee->one);
|
||||
return m_one->isatty ();
|
||||
}
|
||||
|
302
gdb/ui-file.h
302
gdb/ui-file.h
@ -19,140 +19,246 @@
|
||||
#ifndef UI_FILE_H
|
||||
#define UI_FILE_H
|
||||
|
||||
struct obstack;
|
||||
struct ui_file;
|
||||
|
||||
#include <string>
|
||||
|
||||
/* Create a generic ui_file object with null methods. */
|
||||
/* The abstract ui_file base class. */
|
||||
|
||||
extern struct ui_file *ui_file_new (void);
|
||||
class ui_file
|
||||
{
|
||||
public:
|
||||
ui_file ();
|
||||
virtual ~ui_file () = 0;
|
||||
|
||||
/* Override methods used by specific implementations of a UI_FILE
|
||||
object. */
|
||||
/* Public non-virtual API. */
|
||||
|
||||
typedef void (ui_file_flush_ftype) (struct ui_file *stream);
|
||||
extern void set_ui_file_flush (struct ui_file *stream,
|
||||
ui_file_flush_ftype *flush);
|
||||
void printf (const char *, ...) ATTRIBUTE_PRINTF (2, 3);
|
||||
|
||||
/* NOTE: Both fputs and write methods are available. Default
|
||||
implementations that mapping one onto the other are included. */
|
||||
typedef void (ui_file_write_ftype) (struct ui_file *stream,
|
||||
const char *buf, long length_buf);
|
||||
extern void set_ui_file_write (struct ui_file *stream,
|
||||
ui_file_write_ftype *fputs);
|
||||
/* Print a string whose delimiter is QUOTER. Note that these
|
||||
routines should only be called for printing things which are
|
||||
independent of the language of the program being debugged. */
|
||||
void putstr (const char *str, int quoter);
|
||||
|
||||
typedef void (ui_file_fputs_ftype) (const char *, struct ui_file *stream);
|
||||
extern void set_ui_file_fputs (struct ui_file *stream,
|
||||
ui_file_fputs_ftype *fputs);
|
||||
void putstrn (const char *str, int n, int quoter);
|
||||
|
||||
/* This version of "write" is safe for use in signal handlers.
|
||||
It's not guaranteed that all existing output will have been
|
||||
flushed first.
|
||||
Implementations are also free to ignore some or all of the request.
|
||||
fputs_async is not provided as the async versions are rarely used,
|
||||
no point in having both for a rarely used interface. */
|
||||
typedef void (ui_file_write_async_safe_ftype)
|
||||
(struct ui_file *stream, const char *buf, long length_buf);
|
||||
extern void set_ui_file_write_async_safe
|
||||
(struct ui_file *stream, ui_file_write_async_safe_ftype *write_async_safe);
|
||||
int putc (int c);
|
||||
|
||||
typedef long (ui_file_read_ftype) (struct ui_file *stream,
|
||||
char *buf, long length_buf);
|
||||
extern void set_ui_file_read (struct ui_file *stream,
|
||||
ui_file_read_ftype *fread);
|
||||
void vprintf (const char *, va_list) ATTRIBUTE_PRINTF (2, 0);
|
||||
|
||||
typedef int (ui_file_isatty_ftype) (struct ui_file *stream);
|
||||
extern void set_ui_file_isatty (struct ui_file *stream,
|
||||
ui_file_isatty_ftype *isatty);
|
||||
/* Methods below are both public, and overridable by ui_file
|
||||
subclasses. */
|
||||
|
||||
typedef void (ui_file_rewind_ftype) (struct ui_file *stream);
|
||||
extern void set_ui_file_rewind (struct ui_file *stream,
|
||||
ui_file_rewind_ftype *rewind);
|
||||
virtual void write (const char *buf, long length_buf) = 0;
|
||||
|
||||
typedef void (ui_file_put_method_ftype) (void *object, const char *buffer,
|
||||
long length_buffer);
|
||||
typedef void (ui_file_put_ftype) (struct ui_file *stream,
|
||||
ui_file_put_method_ftype *method,
|
||||
void *context);
|
||||
extern void set_ui_file_put (struct ui_file *stream, ui_file_put_ftype *put);
|
||||
/* This version of "write" is safe for use in signal handlers. It's
|
||||
not guaranteed that all existing output will have been flushed
|
||||
first. Implementations are also free to ignore some or all of
|
||||
the request. puts_async is not provided as the async versions
|
||||
are rarely used, no point in having both for a rarely used
|
||||
interface. */
|
||||
virtual void write_async_safe (const char *buf, long length_buf)
|
||||
{ gdb_assert_not_reached ("write_async_safe"); }
|
||||
|
||||
typedef void (ui_file_delete_ftype) (struct ui_file * stream);
|
||||
extern void set_ui_file_data (struct ui_file *stream, void *data,
|
||||
ui_file_delete_ftype *to_delete);
|
||||
/* Some ui_files override this to provide a efficient implementation
|
||||
that avoids a strlen. */
|
||||
virtual void puts (const char *str)
|
||||
{ this->write (str, strlen (str)); }
|
||||
|
||||
typedef int (ui_file_fseek_ftype) (struct ui_file *stream, long offset,
|
||||
int whence);
|
||||
extern void set_ui_file_fseek (struct ui_file *stream,
|
||||
ui_file_fseek_ftype *fseek_ptr);
|
||||
virtual long read (char *buf, long length_buf)
|
||||
{ gdb_assert_not_reached ("can't read from this file type"); }
|
||||
|
||||
extern void *ui_file_data (struct ui_file *file);
|
||||
virtual bool isatty ()
|
||||
{ return false; }
|
||||
|
||||
virtual void flush ()
|
||||
{}
|
||||
};
|
||||
|
||||
extern void gdb_flush (struct ui_file *);
|
||||
typedef std::unique_ptr<ui_file> ui_file_up;
|
||||
|
||||
extern void ui_file_delete (struct ui_file *stream);
|
||||
/* A ui_file that writes to nowhere. */
|
||||
|
||||
extern void ui_file_rewind (struct ui_file *stream);
|
||||
class null_file : public ui_file
|
||||
{
|
||||
public:
|
||||
void write (const char *buf, long length_buf) override;
|
||||
void write_async_safe (const char *buf, long sizeof_buf) override;
|
||||
void puts (const char *str) override;
|
||||
};
|
||||
|
||||
/* A preallocated null_file stream. */
|
||||
extern null_file null_stream;
|
||||
|
||||
extern void gdb_flush (ui_file *);
|
||||
|
||||
extern int ui_file_isatty (struct ui_file *);
|
||||
|
||||
extern void ui_file_write (struct ui_file *file, const char *buf,
|
||||
long length_buf);
|
||||
|
||||
/* A wrapper for ui_file_write that is suitable for use by
|
||||
ui_file_put. */
|
||||
|
||||
extern void ui_file_write_for_put (void *data, const char *buffer,
|
||||
long length_buffer);
|
||||
|
||||
extern void ui_file_write_async_safe (struct ui_file *file, const char *buf,
|
||||
long length_buf);
|
||||
|
||||
/* NOTE: copies left to right. */
|
||||
extern void ui_file_put (struct ui_file *src,
|
||||
ui_file_put_method_ftype *write, void *dest);
|
||||
|
||||
/* Returns a freshly allocated buffer containing the entire contents
|
||||
of FILE (as determined by ui_file_put()) with a NUL character
|
||||
appended. LENGTH, if not NULL, is set to the size of the buffer
|
||||
minus that appended NUL. */
|
||||
extern char *ui_file_xstrdup (struct ui_file *file, long *length);
|
||||
|
||||
/* Returns a std::string containing the entire contents of FILE (as
|
||||
determined by ui_file_put()). */
|
||||
extern std::string ui_file_as_string (struct ui_file *file);
|
||||
|
||||
/* Similar to ui_file_xstrdup, but return a new string allocated on
|
||||
OBSTACK. */
|
||||
extern char *ui_file_obsavestring (struct ui_file *file,
|
||||
struct obstack *obstack, long *length);
|
||||
|
||||
extern long ui_file_read (struct ui_file *file, char *buf, long length_buf);
|
||||
|
||||
extern int ui_file_fseek (struct ui_file *file, long offset, int whence);
|
||||
/* A std::string-based ui_file. Can be used as a scratch buffer for
|
||||
collecting output. */
|
||||
|
||||
/* Create/open a memory based file. Can be used as a scratch buffer
|
||||
for collecting output. */
|
||||
extern struct ui_file *mem_fileopen (void);
|
||||
class string_file : public ui_file
|
||||
{
|
||||
public:
|
||||
string_file () {}
|
||||
~string_file () override;
|
||||
|
||||
/* Override ui_file methods. */
|
||||
|
||||
void write (const char *buf, long length_buf) override;
|
||||
|
||||
/* Open/create a STDIO based UI_FILE using the already open FILE. */
|
||||
extern struct ui_file *stdio_fileopen (FILE *file);
|
||||
long read (char *buf, long length_buf) override
|
||||
{ gdb_assert_not_reached ("a string_file is not readable"); }
|
||||
|
||||
/* Likewise, for stderr-like streams. */
|
||||
extern struct ui_file *stderr_fileopen (FILE *file);
|
||||
/* string_file-specific public API. */
|
||||
|
||||
/* Accesses the std::string containing the entire output collected
|
||||
so far.
|
||||
|
||||
/* Open NAME returning an STDIO based UI_FILE. */
|
||||
extern struct ui_file *gdb_fopen (const char *name, const char *mode);
|
||||
Returns a non-const reference so that it's easy to move the
|
||||
string contents out of the string_file. E.g.:
|
||||
|
||||
string_file buf;
|
||||
buf.printf (....);
|
||||
buf.printf (....);
|
||||
return std::move (buf.string ());
|
||||
*/
|
||||
std::string &string () { return m_string; }
|
||||
|
||||
/* Provide a few convenience methods with the same API as the
|
||||
underlying std::string. */
|
||||
const char *data () const { return m_string.data (); }
|
||||
const char *c_str () const { return m_string.c_str (); }
|
||||
size_t size () const { return m_string.size (); }
|
||||
bool empty () const { return m_string.empty (); }
|
||||
void clear () { return m_string.clear (); }
|
||||
|
||||
private:
|
||||
/* The internal buffer. */
|
||||
std::string m_string;
|
||||
};
|
||||
|
||||
/* A ui_file implementation that maps directly onto <stdio.h>'s FILE.
|
||||
A stdio_file can either own its underlying file, or not. If it
|
||||
owns the file, then destroying the stdio_file closes the underlying
|
||||
file, otherwise it is left open. */
|
||||
|
||||
class stdio_file : public ui_file
|
||||
{
|
||||
public:
|
||||
/* Create a ui_file from a previously opened FILE. CLOSE_P
|
||||
indicates whether the underlying file should be closed when the
|
||||
stdio_file is destroyed. */
|
||||
explicit stdio_file (FILE *file, bool close_p = false);
|
||||
|
||||
/* Create an stdio_file that is not managing any file yet. Call
|
||||
open to actually open something. */
|
||||
stdio_file ();
|
||||
|
||||
~stdio_file () override;
|
||||
|
||||
/* Open NAME in mode MODE, and own the resulting file. Returns true
|
||||
on success, false otherwise. If the stdio_file previously owned
|
||||
a file, it is closed. */
|
||||
bool open (const char *name, const char *mode);
|
||||
|
||||
void flush () override;
|
||||
|
||||
void write (const char *buf, long length_buf) override;
|
||||
|
||||
void write_async_safe (const char *buf, long length_buf) override;
|
||||
|
||||
void puts (const char *) override;
|
||||
|
||||
long read (char *buf, long length_buf) override;
|
||||
|
||||
bool isatty () override;
|
||||
|
||||
private:
|
||||
/* Sets the internal stream to FILE, and saves the FILE's file
|
||||
descriptor in M_FD. */
|
||||
void set_stream (FILE *file);
|
||||
|
||||
/* The file. */
|
||||
FILE *m_file;
|
||||
|
||||
/* The associated file descriptor is extracted ahead of time for
|
||||
stdio_file::write_async_safe's benefit, in case fileno isn't
|
||||
async-safe. */
|
||||
int m_fd;
|
||||
|
||||
/* If true, M_FILE is closed on destruction. */
|
||||
bool m_close_p;
|
||||
};
|
||||
|
||||
typedef std::unique_ptr<stdio_file> stdio_file_up;
|
||||
|
||||
/* Like stdio_file, but specifically for stderr.
|
||||
|
||||
This exists because there is no real line-buffering on Windows, see
|
||||
<http://msdn.microsoft.com/en-us/library/86cebhfs%28v=vs.71%29.aspx>
|
||||
so the stdout is either fully-buffered or non-buffered. We can't
|
||||
make stdout non-buffered, because of two concerns:
|
||||
|
||||
1. Non-buffering hurts performance.
|
||||
2. Non-buffering may change GDB's behavior when it is interacting
|
||||
with a front-end, such as Emacs.
|
||||
|
||||
We leave stdout as fully buffered, but flush it first when
|
||||
something is written to stderr.
|
||||
|
||||
Note that the 'write_async_safe' method is not overridden, because
|
||||
there's no way to flush a stream in an async-safe manner.
|
||||
Fortunately, it doesn't really matter, because:
|
||||
|
||||
1. That method is only used for printing internal debug output
|
||||
from signal handlers.
|
||||
|
||||
2. Windows hosts don't have a concept of async-safeness. Signal
|
||||
handlers run in a separate thread, so they can call the regular
|
||||
non-async-safe output routines freely.
|
||||
*/
|
||||
class stderr_file : public stdio_file
|
||||
{
|
||||
public:
|
||||
explicit stderr_file (FILE *stream);
|
||||
|
||||
/* Override the output routines to flush gdb_stdout before deferring
|
||||
to stdio_file for the actual outputting. */
|
||||
void write (const char *buf, long length_buf) override;
|
||||
void puts (const char *linebuffer) override;
|
||||
};
|
||||
|
||||
/* A ui_file implementation that maps onto two ui-file objects. */
|
||||
|
||||
class tee_file : public ui_file
|
||||
{
|
||||
public:
|
||||
/* Create a file which writes to both ONE and TWO. CLOSE_ONE and
|
||||
CLOSE_TWO indicate whether the original files should be closed
|
||||
when the new file is closed. */
|
||||
tee_file (ui_file *one, bool close_one,
|
||||
ui_file *two, bool close_two);
|
||||
~tee_file () override;
|
||||
|
||||
void write (const char *buf, long length_buf) override;
|
||||
void write_async_safe (const char *buf, long length_buf) override;
|
||||
void puts (const char *) override;
|
||||
|
||||
bool isatty () override;
|
||||
void flush () override;
|
||||
|
||||
private:
|
||||
/* The two underlying ui_files, and whether they should each be
|
||||
closed on destruction. */
|
||||
ui_file *m_one, *m_two;
|
||||
bool m_close_one, m_close_two;
|
||||
};
|
||||
|
||||
/* Create a file which writes to both ONE and TWO. CLOSE_ONE
|
||||
and CLOSE_TWO indicate whether the original files should be
|
||||
closed when the new file is closed. */
|
||||
extern struct ui_file *tee_file_new (struct ui_file *one,
|
||||
int close_one,
|
||||
struct ui_file *two,
|
||||
int close_two);
|
||||
#endif
|
||||
|
10
gdb/ui-out.c
10
gdb/ui-out.c
@ -529,15 +529,13 @@ ui_out::field_core_addr (const char *fldname, struct gdbarch *gdbarch,
|
||||
}
|
||||
|
||||
void
|
||||
ui_out::field_stream (const char *fldname, ui_file *stream)
|
||||
ui_out::field_stream (const char *fldname, string_file &stream)
|
||||
{
|
||||
std::string buffer = ui_file_as_string (stream);
|
||||
|
||||
if (!buffer.empty ())
|
||||
field_string (fldname, buffer.c_str ());
|
||||
if (!stream.empty ())
|
||||
field_string (fldname, stream.c_str ());
|
||||
else
|
||||
field_skip (fldname);
|
||||
ui_file_rewind (stream);
|
||||
stream.clear ();
|
||||
}
|
||||
|
||||
/* Used to omit a field. */
|
||||
|
@ -108,7 +108,7 @@ class ui_out
|
||||
void field_core_addr (const char *fldname, struct gdbarch *gdbarch,
|
||||
CORE_ADDR address);
|
||||
void field_string (const char *fldname, const char *string);
|
||||
void field_stream (const char *fldname, ui_file *stream);
|
||||
void field_stream (const char *fldname, string_file &stream);
|
||||
void field_skip (const char *fldname);
|
||||
void field_fmt (const char *fldname, const char *format, ...)
|
||||
ATTRIBUTE_PRINTF (3, 4);
|
||||
|
33
gdb/utils.c
33
gdb/utils.c
@ -187,33 +187,6 @@ make_cleanup_obstack_free (struct obstack *obstack)
|
||||
return make_cleanup (do_obstack_free, obstack);
|
||||
}
|
||||
|
||||
static void
|
||||
do_ui_file_delete (void *arg)
|
||||
{
|
||||
ui_file_delete ((struct ui_file *) arg);
|
||||
}
|
||||
|
||||
struct cleanup *
|
||||
make_cleanup_ui_file_delete (struct ui_file *arg)
|
||||
{
|
||||
return make_cleanup (do_ui_file_delete, arg);
|
||||
}
|
||||
|
||||
struct ui_file *
|
||||
null_stream (void)
|
||||
{
|
||||
/* A simple implementation of singleton pattern. */
|
||||
static struct ui_file *stream = NULL;
|
||||
|
||||
if (stream == NULL)
|
||||
{
|
||||
stream = ui_file_new ();
|
||||
/* Delete it on gdb exit. */
|
||||
make_final_cleanup (do_ui_file_delete, stream);
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
/* Helper function for make_cleanup_ui_out_redirect_pop. */
|
||||
|
||||
static void
|
||||
@ -460,11 +433,9 @@ verror (const char *string, va_list args)
|
||||
}
|
||||
|
||||
void
|
||||
error_stream (struct ui_file *stream)
|
||||
error_stream (const string_file &stream)
|
||||
{
|
||||
std::string message = ui_file_as_string (stream);
|
||||
|
||||
error (("%s"), message.c_str ());
|
||||
error (("%s"), stream.c_str ());
|
||||
}
|
||||
|
||||
/* Emit a message and abort. */
|
||||
|
@ -66,9 +66,6 @@ char **gdb_buildargv (const char *);
|
||||
|
||||
extern struct cleanup *make_cleanup_freeargv (char **);
|
||||
|
||||
struct ui_file;
|
||||
extern struct cleanup *make_cleanup_ui_file_delete (struct ui_file *);
|
||||
|
||||
struct ui_out;
|
||||
extern struct cleanup *
|
||||
make_cleanup_ui_out_redirect_pop (struct ui_out *uiout);
|
||||
@ -189,9 +186,6 @@ extern struct ui_file *gdb_stdtarg;
|
||||
extern struct ui_file *gdb_stdtargerr;
|
||||
extern struct ui_file *gdb_stdtargin;
|
||||
|
||||
/* Return a null stream. */
|
||||
extern struct ui_file *null_stream (void);
|
||||
|
||||
/* Set the screen dimensions to WIDTH and HEIGHT. */
|
||||
|
||||
extern void set_screen_width_and_height (int width, int height);
|
||||
@ -306,7 +300,7 @@ extern void (*deprecated_error_begin_hook) (void);
|
||||
|
||||
extern char *warning_pre_print;
|
||||
|
||||
extern void error_stream (struct ui_file *) ATTRIBUTE_NORETURN;
|
||||
extern void error_stream (const string_file &) ATTRIBUTE_NORETURN;
|
||||
|
||||
extern void demangler_vwarning (const char *file, int line,
|
||||
const char *, va_list ap)
|
||||
|
29
gdb/varobj.c
29
gdb/varobj.c
@ -2400,8 +2400,6 @@ varobj_value_get_print_value (struct value *value,
|
||||
enum varobj_display_formats format,
|
||||
const struct varobj *var)
|
||||
{
|
||||
struct ui_file *stb;
|
||||
struct cleanup *old_chain;
|
||||
struct value_print_options opts;
|
||||
struct type *type = NULL;
|
||||
long len = 0;
|
||||
@ -2413,9 +2411,7 @@ varobj_value_get_print_value (struct value *value,
|
||||
if (value == NULL)
|
||||
return std::string ();
|
||||
|
||||
stb = mem_fileopen ();
|
||||
old_chain = make_cleanup_ui_file_delete (stb);
|
||||
|
||||
string_file stb;
|
||||
std::string thevalue;
|
||||
|
||||
#if HAVE_PYTHON
|
||||
@ -2430,10 +2426,7 @@ varobj_value_get_print_value (struct value *value,
|
||||
/* First check to see if we have any children at all. If so,
|
||||
we simply return {...}. */
|
||||
if (dynamic_varobj_has_child_method (var))
|
||||
{
|
||||
do_cleanups (old_chain);
|
||||
return "{...}";
|
||||
}
|
||||
return "{...}";
|
||||
|
||||
if (PyObject_HasAttr (value_formatter, gdbpy_to_string_cst))
|
||||
{
|
||||
@ -2441,7 +2434,7 @@ varobj_value_get_print_value (struct value *value,
|
||||
|
||||
gdbpy_ref output (apply_varobj_pretty_printer (value_formatter,
|
||||
&replacement,
|
||||
stb));
|
||||
&stb));
|
||||
|
||||
/* If we have string like output ... */
|
||||
if (output != NULL)
|
||||
@ -2484,10 +2477,7 @@ varobj_value_get_print_value (struct value *value,
|
||||
type = builtin_type (gdbarch)->builtin_char;
|
||||
|
||||
if (!string_print)
|
||||
{
|
||||
do_cleanups (old_chain);
|
||||
return thevalue;
|
||||
}
|
||||
return thevalue;
|
||||
}
|
||||
else
|
||||
gdbpy_print_stack ();
|
||||
@ -2507,20 +2497,17 @@ varobj_value_get_print_value (struct value *value,
|
||||
|
||||
/* If the THEVALUE has contents, it is a regular string. */
|
||||
if (!thevalue.empty ())
|
||||
LA_PRINT_STRING (stb, type, (gdb_byte *) thevalue.c_str (),
|
||||
LA_PRINT_STRING (&stb, type, (gdb_byte *) thevalue.c_str (),
|
||||
len, encoding.get (), 0, &opts);
|
||||
else if (string_print)
|
||||
/* Otherwise, if string_print is set, and it is not a regular
|
||||
string, it is a lazy string. */
|
||||
val_print_string (type, encoding.get (), str_addr, len, stb, &opts);
|
||||
val_print_string (type, encoding.get (), str_addr, len, &stb, &opts);
|
||||
else
|
||||
/* All other cases. */
|
||||
common_val_print (value, stb, 0, &opts, current_language);
|
||||
common_val_print (value, &stb, 0, &opts, current_language);
|
||||
|
||||
thevalue = ui_file_as_string (stb);
|
||||
|
||||
do_cleanups (old_chain);
|
||||
return thevalue;
|
||||
return std::move (stb.string ());
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -3063,45 +3063,38 @@ xtensa_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc)
|
||||
static void
|
||||
xtensa_verify_config (struct gdbarch *gdbarch)
|
||||
{
|
||||
struct ui_file *log;
|
||||
struct cleanup *cleanups;
|
||||
struct gdbarch_tdep *tdep;
|
||||
|
||||
tdep = gdbarch_tdep (gdbarch);
|
||||
log = mem_fileopen ();
|
||||
cleanups = make_cleanup_ui_file_delete (log);
|
||||
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
||||
string_file log;
|
||||
|
||||
/* Verify that we got a reasonable number of AREGS. */
|
||||
if ((tdep->num_aregs & -tdep->num_aregs) != tdep->num_aregs)
|
||||
fprintf_unfiltered (log, _("\
|
||||
log.printf (_("\
|
||||
\n\tnum_aregs: Number of AR registers (%d) is not a power of two!"),
|
||||
tdep->num_aregs);
|
||||
tdep->num_aregs);
|
||||
|
||||
/* Verify that certain registers exist. */
|
||||
|
||||
if (tdep->pc_regnum == -1)
|
||||
fprintf_unfiltered (log, _("\n\tpc_regnum: No PC register"));
|
||||
log.printf (_("\n\tpc_regnum: No PC register"));
|
||||
if (tdep->isa_use_exceptions && tdep->ps_regnum == -1)
|
||||
fprintf_unfiltered (log, _("\n\tps_regnum: No PS register"));
|
||||
log.printf (_("\n\tps_regnum: No PS register"));
|
||||
|
||||
if (tdep->isa_use_windowed_registers)
|
||||
{
|
||||
if (tdep->wb_regnum == -1)
|
||||
fprintf_unfiltered (log, _("\n\twb_regnum: No WB register"));
|
||||
log.printf (_("\n\twb_regnum: No WB register"));
|
||||
if (tdep->ws_regnum == -1)
|
||||
fprintf_unfiltered (log, _("\n\tws_regnum: No WS register"));
|
||||
log.printf (_("\n\tws_regnum: No WS register"));
|
||||
if (tdep->ar_base == -1)
|
||||
fprintf_unfiltered (log, _("\n\tar_base: No AR registers"));
|
||||
log.printf (_("\n\tar_base: No AR registers"));
|
||||
}
|
||||
|
||||
if (tdep->a0_base == -1)
|
||||
fprintf_unfiltered (log, _("\n\ta0_base: No Ax registers"));
|
||||
log.printf (_("\n\ta0_base: No Ax registers"));
|
||||
|
||||
std::string buf = ui_file_as_string (log);
|
||||
if (!buf.empty ())
|
||||
if (!log.empty ())
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("the following are invalid: %s"), buf.c_str ());
|
||||
do_cleanups (cleanups);
|
||||
_("the following are invalid: %s"), log.c_str ());
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user