Eliminate make_cleanup_ui_file_delete / make ui_file a class hierarchy
authorPedro Alves <palves@redhat.com>
Thu, 2 Feb 2017 11:11:47 +0000 (11:11 +0000)
committerPedro Alves <palves@redhat.com>
Thu, 2 Feb 2017 11:11:47 +0000 (11:11 +0000)
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.

81 files changed:
gdb/ChangeLog
gdb/ada-lang.c
gdb/ada-valprint.c
gdb/ada-varobj.c
gdb/aix-thread.c
gdb/arm-tdep.c
gdb/breakpoint.c
gdb/c-exp.y
gdb/cli/cli-logging.c
gdb/cli/cli-setshow.c
gdb/compile/compile-c-support.c
gdb/compile/compile-c-symbols.c
gdb/compile/compile-internal.h
gdb/compile/compile-loc2c.c
gdb/compile/compile.c
gdb/compile/compile.h
gdb/cp-support.c
gdb/disasm-selftests.c
gdb/disasm.c
gdb/dummy-frame.c
gdb/dwarf2loc.c
gdb/dwarf2loc.h
gdb/dwarf2read.c
gdb/event-top.c
gdb/gdbarch.c
gdb/gdbarch.sh
gdb/gdbtypes.c
gdb/guile/scm-breakpoint.c
gdb/guile/scm-disasm.c
gdb/guile/scm-frame.c
gdb/guile/scm-ports.c
gdb/guile/scm-type.c
gdb/guile/scm-value.c
gdb/infcmd.c
gdb/infrun.c
gdb/language.c
gdb/location.c
gdb/main.c
gdb/maint.c
gdb/mi/mi-cmd-stack.c
gdb/mi/mi-common.h
gdb/mi/mi-console.c
gdb/mi/mi-console.h
gdb/mi/mi-interp.c
gdb/mi/mi-main.c
gdb/mi/mi-out.c
gdb/mi/mi-out.h
gdb/printcmd.c
gdb/psymtab.c
gdb/python/py-arch.c
gdb/python/py-breakpoint.c
gdb/python/py-frame.c
gdb/python/py-framefilter.c
gdb/python/py-type.c
gdb/python/py-unwind.c
gdb/python/py-value.c
gdb/regcache.c
gdb/reggroups.c
gdb/remote.c
gdb/rust-lang.c
gdb/serial.c
gdb/stack.c
gdb/symmisc.c
gdb/symtab.h
gdb/top.c
gdb/tracepoint.c
gdb/tui/tui-disasm.c
gdb/tui/tui-file.c
gdb/tui/tui-file.h
gdb/tui/tui-io.c
gdb/tui/tui-regs.c
gdb/tui/tui-stack.c
gdb/typeprint.c
gdb/ui-file.c
gdb/ui-file.h
gdb/ui-out.c
gdb/ui-out.h
gdb/utils.c
gdb/utils.h
gdb/varobj.c
gdb/xtensa-tdep.c

index 723f06b21de0002e90f36236599bd360a2575004..e3bca388578491351ae123662e378b2fd10446fe 100644 (file)
@@ -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...
index 381752bab74d003f959dd390cac96f245bc2c26c..502710a462fdb80db3f613092d1a78273f5695c5 100644 (file)
@@ -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;
-
-  tmp_stream = mem_fileopen ();
-  old_chain = make_cleanup_ui_file_delete (tmp_stream);
+  string_file tmp_stream;
 
-  type_print (type, "", tmp_stream, -1);
-  std::string str = ui_file_as_string (tmp_stream);
+  type_print (type, "", &tmp_stream, -1);
 
-  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.
index 0a9e3257f0af318ec735f68e7249ef1f80f31ecf..804cf403f6f486d950850419e43eff05ea141d90 100644 (file)
@@ -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
index 52e3247c9acc6cb130cbca76fba0a8eedf4db83d..34d9c7b342635b99088847c7f7bd34eebf047c48 100644 (file)
@@ -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;
-
-  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);
+  string_file 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,
index ea6422043da9a4b66dafa83a2744e0b2b0df6f1a..cf1a46221655b3fb15fc9c1066e38d66156549eb 100644 (file)
@@ -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;
 }
index 0ae311fb104b75277e82e3a7efa90a5036ad2d47..88ed391729813dc4ef8e4dccb6698fa798e0de08 100644 (file)
@@ -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,
index 867dbb9a947d86fda1f93379b777be0215d78b5d..a76b3e427795d704a2ca137a64954f08368d2168 100644 (file)
@@ -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);
index 8a92cce0ab3fa903e7a0466f35dfe2e177405deb..2753c6ec5d17f308addc5e5753cb95be6d590719 100644 (file)
@@ -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 ());
                        }
        ;
 
index 9428624b8addf1c44fb6288ce3dfb7ca74e9a8a6..f16589604cb5ab24707ee13185541f7ccbbc2df2 100644 (file)
@@ -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
index 9298665e8f2027cc96f3986bf8e21c58b746c431..218e1f36d8fc4db11d304203f06acf4e17abc8f1 100644 (file)
@@ -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);
 }
index 877bfb726ebabc9ae68cf19168b25b65cf012f57..7ad0a872f23162430a6f26daa2a037a7b4e266cb 100644 (file)
@@ -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 ());
 }
index 60100061cc071fee9ccaca3c294d67891933a50f..9282cfc02515447f8c4ea67848c8d06b4512bbbd 100644 (file)
@@ -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)
index 4bf5bf926f8f90ea244a6dafd6b426639bf0ddf8..0c53f8c443298bd211674d034ed110a73ac34e33 100644 (file)
@@ -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);
index 81684d133c63db529a0879134807e64f90c99735..f1296e8304ec6c4a80250000964b96d7b81ee027 100644 (file)
@@ -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,
index 0ae212501fe9b7f5c022dbdf1506992a7f4eb9bb..b525f61eee880c1c7b68dcf57b4a03404581bfda 100644 (file)
@@ -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)
index a46ee6d7989ee9cabacccc15475ba0bdccf65425..743859932abf3f6214ec91f77ad8b7fe1e98c486 100644 (file)
@@ -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,
index f4498f16af20a2595d396442332cc22f6fdfa147..1b0900e489f1361b62a6d7528af9501da16da379 100644 (file)
@@ -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);
 }
 
 
index c89c5ed83b61423dbc4380fe2a1f1036641e8d45..7d0b006d3972eba5041fd4de205599c924fee8ca 100644 (file)
@@ -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)
     {
     }
index 03ff8d359e6870e6bbf8b22146553e527f7e4e02..5f0e86a057b74d0c16b28442a668798d8c1c8363 100644 (file)
@@ -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
index e81d8e9f547667f07e84ace84c71724d86b33d72..2a84b28ee7805d0c00649a56394db6d02d8b539e 100644 (file)
@@ -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);
     }
 }
 
index a592b66101d2b30e19ea34c29f78d6c1001c6570..c1e02eb315816d610b11e06a4fbfb01e8ed22b69 100644 (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)
index 24e660c8b758ade1d260d3c1073ce763d10f3aff..d6cdbd2182b474e4069ea92263a4fd8406ab51d2 100644 (file)
@@ -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,
index b5dc510a35852bde9ec49c2d353ee8e2d7267b6d..774ed7307571f2bc6b040b5b7ad03dea91576047 100644 (file)
@@ -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
index ae4f70450dab4afeb21602914e6a8c4423df42fc..5d8d077a9a44a1209d37ed26092d8f3617857241 100644 (file)
@@ -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 */
index 8bd0c19922fcadfbe06fb44bf814075b0efa9b19..266f2e9ee472fc40804ca3fa623f585bf75a88a8 100644 (file)
@@ -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 ());
 }
 
 
index 2958cabcdc7f7f9c417472d9da4eae93ba4c2874..54549b6319b8831267e49c096d44e94238198628 100755 (executable)
@@ -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
 
index 21cc00576f374393a0030ae711f3bf454498fcef..5e5db2776b16424491da44427a104239d64fea9a 100644 (file)
@@ -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;
index b2e7c96a48037856399aadd3f6e448b75daff291..71cffbb273fde3574af1cbc89f96e36e43656b1d 100644 (file)
@@ -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;
 }
 
index 25cae5a6e652a9e3c2fd567b5661a4149374e330..f8cbad6bb6cf12e6a83d3247908637d2b00a8a00 100644 (file)
@@ -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);
index 9b5159e139b5f1dcea5ad78ce909a46b1e0303e6..994f92d41c8eef80aa7795379c1f9b2b2b6c3c38 100644 (file)
@@ -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);
 
index 4a1c86435bcb65ed03a58d49707543dc61632ef9..fb3a47ba085962348181a92b302a38458c2b0212 100644 (file)
 
 /* 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)
 \f
 /* 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);
-
-  if (stream->magic != &file_port_magic)
-    internal_error (__FILE__, __LINE__,
-                   _("ioscm_file_port_delete: bad magic number"));
-  xfree (stream);
-}
-
-static void
-ioscm_file_port_rewind (struct ui_file *file)
-{
-  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);
-}
+ioscm_file_port::ioscm_file_port (SCM port)
+  : m_port (port)
+{}
 
-static void
-ioscm_file_port_put (struct ui_file *file,
-                    ui_file_put_method_ftype *write,
-                    void *dest)
+void
+ioscm_file_port::flush ()
 {
-  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)
+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_pot_file_write: bad magic number"));
-
-  scm_c_write (stream->port, buffer, length_buffer);
+  scm_c_write (m_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;
-}
 \f
 /* 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 (&current_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);
index f5de011d7e069f48eff2598405d536acfda57eab..42a8ad266611f11943c4d37d887a1571ae245b3f 100644 (file)
@@ -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)
     {
index b4f32b6b600eecf222d15f101171984d9f15853e..ebccfb6d668784e11aa4ff9e5c48b2c02b5596aa 100644 (file)
@@ -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);
 }
 \f
 /* (parse-and-eval string) -> <gdb:value>
index d761117333e2883751fc680983c10dd1241c7273..d8361624c36f6caae73ec76cf6c72810f7e2bc37 100644 (file)
@@ -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
     {
index 41f1fdd3e265cc66f97de7f5d0cc4e37951b4ebd..1e5e9f14a64593a4bef574cbf79621ff599c83f4 100644 (file)
@@ -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
index a40eb8775746bfd04ddba60bbeeff0ea75ae39d2..31c5c591ab754b3d51d40895fd8a61eac8b0e91e 100644 (file)
@@ -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,
index 37da6df509df6db1a9c32e63dac80872a5406f49..fbd09e2eba2f024c3b44e2664ae5e1d40df007c4 100644 (file)
@@ -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.  */
index f5387b6fe254773f171caf8bec25c048db6223cb..30e27c2a771320ad9df2ba9ee12704d25f26c9c6 100644 (file)
@@ -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')
index 77b56affb6cf8edc9df2ff2cbf94ad5894e9b6f6..d95f6586843f8396d86b34e4a208c0fba14988d1 100644 (file)
@@ -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);
     }
 }
 
index efaf49dfbefd3aad8ea432dd77253f95fc8515f1..acb44a28ee51cd0ec79835f7a96989c0fcd75cd9 100644 (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);
     }
 
index 0d39cb718a47b195a19d4623ad0b33f0c68f5d2a..e82b4a3dabd048c8abfec91bd16de9200ff98789 100644 (file)
@@ -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;
index afb5e94c1a9a255acae3cbb96b89463356b8c90b..7c1c2acc37bdbc2d0aec79c2f4756582ff1b4b43 100644 (file)
 
 #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)
-{
-  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"));
+mi_console_file::mi_console_file (ui_file *raw, const char *prefix, char quote)
+  : m_raw (raw),
+    m_prefix (prefix),
+    m_quote (quote)
+{}
 
-  xfree (mi_console);
-}
-
-static void
-mi_console_file_fputs (const char *buf, struct ui_file *file)
+void
+mi_console_file::write (const char *buf, long length_buf)
 {
-  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;
-
-  if (mi_console->magic != &mi_console_file_magic)
-    internal_error (__FILE__, __LINE__,
-                   _("mi_console_raw_packet: bad magic number"));
+  const std::string &str = m_buffer.string ();
 
-  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;
 }
index 64355a710d7f86b1b8673c388e9d4093ff3c6912..289013f9554f6c9d3c2171303ef9ef1df3bc3bb5 100644 (file)
 #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
index 76f4f8ceea3af70b2509b2bbe16d9e681a89254b..f167a535bcaf3faeefa1731fd7b78a896986f97f 100644 (file)
@@ -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;
 }
index 57c23ebf5d6b2d3b398aa40ebd9b3cb70c56125c..b249f2d7ccef91ead7f99aee594ca897093322e1 100644 (file)
@@ -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;
-
-      stb = mem_fileopen ();
+      string_file stb;
 
-      fputs_unfiltered ("Undefined mi command: ", stb);
-      fputstr_unfiltered (parse->command, '"', stb);
-      fputs_unfiltered (" (missing implementation)", stb);
+      stb.puts ("Undefined mi command: ");
+      stb.putstr (parse->command, '"');
+      stb.puts (" (missing implementation)");
 
-      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;
index 5a5aef95d6c48ff2a4834d3059facdbd9b6eac60..6181140c3b49d69b74ad661986e55430e0610df8 100644 (file)
@@ -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
index e82d44d2cec7805deae88156802d25ad5166df36..fea94f20ba842a87c0758f3b890fb7b29b3f1e20 100644 (file)
@@ -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;
index e4711e9fb8852d48158df0c1e8c85023ba4808f5..dab4f53b373662de170f8c52ae105673491ada3b 100644 (file)
@@ -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
index 3acc22692560e6d3799d9206146851100ccdf472..1fad8a0750b0abe093d2442c5b8db168b5d83bce 100644 (file)
@@ -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);
        }
     }
index 13cc9baf639c7456ee843adb9797e08f84ae0ac2..8d0ec3330cc332769b78d95f46d3aec2ff74a9f0 100644 (file)
@@ -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 ();
index f268b2bb44627943ff5f2f511fd3a1dea64b3118..ac649000ab8c885719e5a316b56b271d0d2d422a 100644 (file)
@@ -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.  */
index 048e7c1a88a00e48f3b84e2b424d0d6e8406f151..8f5ddd04f0bf22a58653286aa025ae7db5ad89b5 100644 (file)
@@ -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.
index bdd991158a3fb0fe4faf6b5e819d20cad8a6b02f..9dc01bad14a8f7803b2e112eddfac68193ed8d33 100644 (file)
@@ -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
index 7862829f1765c5b4c5b82e0193e5901b3d33ff1f..f6e8dd6e155bd46b7d544322dd3bbc891101b1c5 100644 (file)
@@ -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.  */
index 690412a0ecb5da908f7e74eae8c76b33825b9f39..d1b63adfbcdd21301c9c0f6f7603491d632f6f29 100644 (file)
@@ -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.
index 8f3164b53c43658689298e95020db6604ddb9f6c..8e4d06d8683fd9d45682dfb91ade7c24dc669b36 100644 (file)
@@ -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.  */
index 9d28aa2c2114e0f1c52758bb2fbe9669a329c13e..eed1bd84c8a9dd07ee77f0c3269e49e78081b127 100644 (file)
@@ -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);
     }
 }
 
index 693b378d87656019dfa033e56b0dbce351148c42..ae7d4ceeb722c29547fbcfe13d2e5a51a68b4030 100644 (file)
@@ -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);
     }
 }
 
index c4cec910c44cf91cc7f36b7f2d87cde3f46de41e..3befbd3d154ee4f0fbf65120d783b8af447b3fbe 100644 (file)
@@ -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;
-
-  stb = mem_fileopen ();
-  old_chain = make_cleanup_ui_file_delete (stb);
+  string_file 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
index 4445812e021a6ebb2d907f76e5462ceecc305a61..dd72cd9380fcaaa42e33114608402c4273ad8a28 100644 (file)
@@ -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;
 }
 
index afb70758c6022c3d2fcc424b129ac22fec5f90d7..b48b9779ed2204a6666d5c77262b3b81c59af389 100644 (file)
@@ -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;
     }
 
index f48433109a353ede57fc47d1e4149a0a97304fe8..6cd4110b7fdb8e0413c554fe77c106f5c36e212a 100644 (file)
@@ -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 ("   ");
index 811183cf0816f273bacdbd26f1c277643abce4e8..07d571acc40ca0bbadddc9aee71220dcaa09add3 100644 (file)
@@ -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)
index f4cfdf6f05f807439385cbdcc5e69ddee2e67ac7..88bdd27d60f370d06d64f3886746310917514a74 100644 (file)
@@ -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);
index f712beafb621b897308e01ba0cb6ab33b8e45ba0..6bf9d8c02165ee70a002cef37f8c61f4769b2107 100644 (file)
--- a/gdb/top.c
+++ b/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 (&current_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 ());
 }
 
 \f
@@ -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);
-
-  fprintf_filtered (stb, _("A debugging session is active.\n\n"));
-  iterate_over_inferiors (print_inferior_quit_action, stb);
-  fprintf_filtered (stb, _("\nQuit anyway? "));
+  string_file stb;
 
-  std::string str = ui_file_as_string (stb);
-
-  do_cleanups (old_chain);
+  stb.puts (_("A debugging session is active.\n\n"));
+  iterate_over_inferiors (print_inferior_quit_action, &stb);
+  stb.puts (_("\nQuit anyway? "));
 
-  return query ("%s", str.c_str ());
+  return query ("%s", stb.c_str ());
 }
 
 /* Prepare to exit GDB cleanly by undoing any changes made to the
index 18b569e30a8954c3405763f44f7d8b4422f3f0f3..2da6fdd5434d4da3b91f242e491e880aa25decc2 100644 (file)
@@ -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
index 2d1cadd9c6a90317b32bc0bf1bc75e15e2e85c85..123a9068f2c39d1fe17f2b6ef5eb1fdc532d1a95 100644 (file)
@@ -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;
 }
 
index 4dc6370d40208bc47ec5b5e6c289030881584697..2f895b7a5348cae2d04f8e79231c3aefb1c16689 100644 (file)
    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_fputs (const char *linebuffer, struct ui_file *file)
-{
-  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)
+tui_file::puts (const char *linebuffer)
 {
-  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);
+  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 ();
 }
 
-/* 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)
+tui_file::flush ()
 {
-  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 ();
 }
index 0e90cdf9b901207ebb232aa9ba60aab60cd5fba2..aceaab6baba72e6577f3aed460c0d8158eebcca6 100644 (file)
@@ -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.
 #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
index 6f00f8499063609945cd11b011a2bb195be943d5..433762bc235e7b7f487dad066e242d46988904e4 100644 (file)
@@ -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.  */
index fc7913b06ceea840300496f1e71ca098a7b130ab..7d116ee8d7003259d9c41c2ad1c64d76ab7d1941 100644 (file)
@@ -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);
 
index 945a7164620d7e2f5227030498f69c04ed4b0563..21a8bacebace1997e86915fc61de7a925acc836e 100644 (file)
@@ -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;
 }
 
index 56e993e91f24fb633a1fb9a9175166349e02edc9..a22c6fba340d5b1347c4053c9aba8858abb7adff 100644 (file)
@@ -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.
index 3dce51119bdc4331c0bbd2214471d17fdea0f6a8..60e32746eb08fae213afd230be1c99384bc744ac 100644 (file)
 #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;
-
-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;
-
-struct ui_file *
-ui_file_new (void)
-{
-  struct ui_file *file = XNEW (struct ui_file);
-
-  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;
-}
+null_file null_stream;
 
-void
-ui_file_delete (struct ui_file *file)
-{
-  file->to_delete (file);
-  xfree (file);
-}
+ui_file::ui_file ()
+{}
 
-static int
-null_file_isatty (struct ui_file *file)
-{
-  return 0;
-}
+ui_file::~ui_file ()
+{}
 
-static void
-null_file_rewind (struct ui_file *file)
+void
+ui_file::printf (const char *format, ...)
 {
-  return;
-}
+  va_list args;
 
-static void
-null_file_put (struct ui_file *file,
-              ui_file_put_method_ftype *write,
-              void *dest)
-{
-  return;
+  va_start (args, format);
+  vfprintf_unfiltered (this, format, args);
+  va_end (args);
 }
 
-static void
-null_file_flush (struct ui_file *file)
+void
+ui_file::putstr (const char *str, int quoter)
 {
-  return;
+  fputstr_unfiltered (str, quoter, this);
 }
 
-static void
-null_file_write (struct ui_file *file,
-                const char *buf,
-                long sizeof_buf)
+void
+ui_file::putstrn (const char *str, int n, int quoter)
 {
-  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;
-    }
+  fputstrn_unfiltered (str, n, quoter, this);
 }
 
-static long
-null_file_read (struct ui_file *file,
-               char *buf,
-               long sizeof_buf)
+int
+ui_file::putc (int c)
 {
-  errno = EBADF;
-  return 0;
+  return fputc_unfiltered (c, this);
 }
 
-static void
-null_file_fputs (const char *buf, struct ui_file *file)
+void
+ui_file::vprintf (const char *format, va_list args)
 {
-  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));
-    }
+  vfprintf_unfiltered (this, format, args);
 }
 
-static void
-null_file_write_async_safe (struct ui_file *file,
-                           const char *buf,
-                           long sizeof_buf)
-{
-  return;
-}
+\f
 
-static void
-null_file_delete (struct ui_file *file)
+void
+null_file::write (const char *buf, long sizeof_buf)
 {
-  return;
+  /* Discard the request.  */
 }
 
-static int
-null_file_fseek (struct ui_file *stream, long offset, int whence)
+void
+null_file::puts (const char *)
 {
-  errno = EBADF;
-
-  return -1;
+  /* Discard the request.  */
 }
 
-void *
-ui_file_data (struct ui_file *file)
+void
+null_file::write_async_safe (const char *buf, long sizeof_buf)
 {
-  if (file->magic != &ui_file_magic)
-    internal_error (__FILE__, __LINE__,
-                   _("ui_file_data: bad magic number"));
-  return file->to_data;
+  /* Discard the request.  */
 }
 
+\f
+
 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;
-}
+\f
 
-void
-set_ui_file_put (struct ui_file *file, ui_file_put_ftype *put_ptr)
-{
-  file->to_put = put_ptr;
-}
+string_file::~string_file ()
+{}
 
 void
-set_ui_file_write (struct ui_file *file,
-                   ui_file_write_ftype *write_ptr)
+string_file::write (const char *buf, long length_buf)
 {
-  file->to_write = write_ptr;
+  m_string.append (buf, length_buf);
 }
 
-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;
-}
+\f
 
-void
-set_ui_file_read (struct ui_file *file, ui_file_read_ftype *read_ptr)
+stdio_file::stdio_file (FILE *file, bool close_p)
 {
-  file->to_read = read_ptr;
+  set_stream (file);
+  m_close_p = close_p;
 }
 
-void
-set_ui_file_fputs (struct ui_file *file, ui_file_fputs_ftype *fputs_ptr)
-{
-  file->to_fputs = fputs_ptr;
-}
+stdio_file::stdio_file ()
+  : m_file (NULL),
+    m_fd (-1),
+    m_close_p (false)
+{}
 
-void
-set_ui_file_fseek (struct ui_file *file, ui_file_fseek_ftype *fseek_ptr)
+stdio_file::~stdio_file ()
 {
-  file->to_fseek = fseek_ptr;
+  if (m_close_p)
+    fclose (m_file);
 }
 
 void
-set_ui_file_data (struct ui_file *file, void *data,
-                 ui_file_delete_ftype *delete_ptr)
+stdio_file::set_stream (FILE *file)
 {
-  file->to_data = data;
-  file->to_delete = delete_ptr;
+  m_file = file;
+  m_fd = fileno (file);
 }
 
-/* ui_file utility function for converting a ``struct ui_file'' into
-   a memory buffer.  */
-
-struct accumulated_ui_file
+bool
+stdio_file::open (const char *name, const char *mode)
 {
-  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);
-}
-\f
-/* 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;
-  };
-
-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)
-{
-  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;
-}
-
-static void
-mem_file_delete (struct ui_file *file)
-{
-  struct mem_file *stream = (struct mem_file *) ui_file_data (file);
+  /* Close the previous stream, if we own it.  */
+  if (m_close_p)
+    {
+      fclose (m_file);
+      m_close_p = false;
+    }
 
-  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);
-}
+  FILE *f = gdb_fopen_cloexec (name, mode);
 
-struct ui_file *
-mem_fileopen (void)
-{
-  return mem_file_new ();
-}
+  if (f == NULL)
+    return false;
 
-static void
-mem_file_rewind (struct ui_file *file)
-{
-  struct mem_file *stream = (struct mem_file *) ui_file_data (file);
+  set_stream (f);
+  m_close_p = true;
 
-  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);
+  return true;
 }
 
 void
-mem_file_write (struct ui_file *file,
-               const char *buffer,
-               long length_buffer)
-{
-  struct mem_file *stream = (struct mem_file *) ui_file_data (file);
-
-  if (stream->magic != &mem_file_magic)
-    internal_error (__FILE__, __LINE__,
-                   _("mem_file_write: bad magic number"));
-  if (stream->buffer == NULL)
-    {
-      stream->length_buffer = length_buffer;
-      stream->sizeof_buffer = length_buffer;
-      stream->buffer = (char *) xmalloc (stream->sizeof_buffer);
-      memcpy (stream->buffer, buffer, length_buffer);
-    }
-  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;
-    }
-}
-\f
-/* ``struct ui_file'' implementation that maps directly onto
-   <stdio.h>'s FILE.  */
-
-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;
-
-static int stdio_file_magic;
-
-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;
-}
-
-static void
-stdio_file_delete (struct ui_file *file)
-{
-  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);
-}
-
-static void
-stdio_file_flush (struct ui_file *file)
+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_flush: bad magic number"));
-  fflush (stdio->file);
+  fflush (m_file);
 }
 
-static long
-stdio_file_read (struct ui_file *file, char *buf, long length_buf)
+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_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);
-}
+\f
 
-#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)
-{
-  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;
-}
-
-/* Like fdopen().  Create a ui_file from a previously opened FILE.  */
-
-struct ui_file *
-stdio_fileopen (FILE *file)
-{
-  return stdio_file_new (file, 0);
-}
+stderr_file::stderr_file (FILE *stream)
+  : stdio_file (stream)
+{}
 
-struct ui_file *
-gdb_fopen (const char *name, const char *mode)
-{
-  FILE *f = gdb_fopen_cloexec (name, mode);
-
-  if (f == NULL)
-    return NULL;
-  return stdio_file_new (f, 1);
-}
-
-/* ``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;
+\f
 
-static int tee_file_magic;
+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)
+{}
 
-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)
+tee_file::~tee_file ()
 {
-  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;
+  if (m_close_one)
+    delete m_one;
+  if (m_close_two)
+    delete m_two;
 }
 
-static void
-tee_file_delete (struct ui_file *file)
+void
+tee_file::flush ()
 {
-  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->flush ();
+  m_two->flush ();
 }
 
-static void
-tee_file_flush (struct ui_file *file)
+void
+tee_file::write (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_flush: bad magic number"));
-  tee->one->to_flush (tee->one);
-  tee->two->to_flush (tee->two);
+  m_one->write (buf, length_buf);
+  m_two->write (buf, length_buf);
 }
 
-static void
-tee_file_write (struct ui_file *file, const char *buf, long length_buf)
+void
+tee_file::write_async_safe (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);
+  m_one->write_async_safe (buf, length_buf);
+  m_two->write_async_safe (buf, length_buf);
 }
 
-static void
-tee_file_fputs (const char *linebuffer, 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_fputs: bad magic number"));
-  tee->one->to_fputs (linebuffer, tee->one);
-  tee->two->to_fputs (linebuffer, tee->two);
+  m_one->puts (linebuffer);
+  m_two->puts (linebuffer);
 }
 
-static int
-tee_file_isatty (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_isatty: bad magic number"));
-
-  return ui_file_isatty (tee->one);
+  return m_one->isatty ();
 }
index 4ad3940a986a84c4ad64ee9e2dd3e67bc86318c0..d64cdce3f6a7f7a3de5ef39d3d85c5d128f77ebe 100644 (file)
 #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.  */
+
+class ui_file
+{
+public:
+  ui_file ();
+  virtual ~ui_file () = 0;
 
-extern struct ui_file *ui_file_new (void);
+  /* Public non-virtual API.  */
 
-/* Override methods used by specific implementations of a UI_FILE
-   object.  */
+  void printf (const char *, ...) ATTRIBUTE_PRINTF (2, 3);
 
-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);
+  /* 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);
 
-/* 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);
+  void putstrn (const char *str, int n, 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);
+  int putc (int c);
 
-/* 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);
+  void vprintf (const char *, va_list) ATTRIBUTE_PRINTF (2, 0);
 
-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);
+  /* Methods below are both public, and overridable by ui_file
+     subclasses.  */
 
-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);
+  virtual void write (const char *buf, long length_buf) = 0;
 
-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);
+  /* 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_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);
+  /* 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 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);
+  virtual long read (char *buf, long length_buf)
+  { gdb_assert_not_reached ("can't read from this file type"); }
 
-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 bool isatty ()
+  { return false; }
 
-extern void *ui_file_data (struct ui_file *file);
+  virtual void flush ()
+  {}
+};
 
+typedef std::unique_ptr<ui_file> ui_file_up;
 
-extern void gdb_flush (struct ui_file *);
+/* A ui_file that writes to nowhere.  */
 
-extern void ui_file_delete (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;
+};
 
-extern void ui_file_rewind (struct ui_file *stream);
+/* 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);
+extern long ui_file_read (struct ui_file *file, char *buf, long length_buf);
+
+/* A std::string-based ui_file.  Can be used as a scratch buffer for
+   collecting output.  */
 
-/* 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);
+class string_file : public ui_file
+{
+public:
+  string_file () {}
+  ~string_file () override;
 
-/* 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);
+  /* Override ui_file methods.  */
 
-/* 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);
+  void write (const char *buf, long length_buf) override;
 
-extern long ui_file_read (struct ui_file *file, char *buf, long length_buf);
+  long read (char *buf, long length_buf) override
+  { gdb_assert_not_reached ("a string_file is not readable"); }
+
+  /* string_file-specific public API.  */
+
+  /* Accesses the std::string containing the entire output collected
+     so far.
+
+     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:
 
-extern int ui_file_fseek (struct ui_file *file, long offset, int whence);
+    1. Non-buffering hurts performance.
+    2. Non-buffering may change GDB's behavior when it is interacting
+       with a front-end, such as Emacs.
 
-/* Create/open a memory based file.  Can be used as a scratch buffer
-   for collecting output.  */
-extern struct ui_file *mem_fileopen (void);
+   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.  */
 
-/* Open/create a STDIO based UI_FILE using the already open FILE.  */
-extern struct ui_file *stdio_fileopen (FILE *file);
+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;
 
-/* Likewise, for stderr-like streams.  */
-extern struct ui_file *stderr_fileopen (FILE *file);
+  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;
 
-/* Open NAME returning an STDIO based UI_FILE.  */
-extern struct ui_file *gdb_fopen (const char *name, const char *mode);
+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
index fdcd45499d0ca91b76306aa72666ab5dca4c1266..42cffbe7f741868a61a9cc76e55fdae9bbd01cfc 100644 (file)
@@ -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.  */
index b8bea97d45f9bebe93974a6954719087ceed70cb..d54843db7bea05ab9f2ace3858c9f725cc7f50f3 100644 (file)
@@ -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);
index ab87143c755e767cfd23c69d177d0385aae4f9eb..3dc2f03d61dd0e02aa16685f77dc048e1b00ff55 100644 (file)
@@ -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.  */
index 9e71cc2792ce4b1a663aca6f752748f1ff808d98..f138702b3a430a5c5cc305ebf5d68b0e86ecc0ac 100644 (file)
@@ -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)
index bcca6c6efb8d5712beaab186ac9890221fd51c2f..3b2771f5cf54e40df788814e2367f3d5dea268e9 100644 (file)
@@ -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);
-
-  thevalue = ui_file_as_string (stb);
+    common_val_print (value, &stb, 0, &opts, current_language);
 
-  do_cleanups (old_chain);
-  return thevalue;
+  return std::move (stb.string ());
 }
 
 int
index 978b13abc57a404974fc02dfd868977b3dab0290..376f4c7340c3292273d5b0912b23ff7166382e8b 100644 (file)
@@ -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 ());
 }