Mercurial > octave
changeset 23738:8acd390d16c9
don't use singleton for stream_list object
* oct-stream.h, oct-stream.cc (stream_list): Don't use singleton
pattern. Change all uses.
(stream_list::stream_list): Initialize stdin, stdout, and stderr
streams here.
(stream_list::~stream_list): Close files here.
(stream_list::m_stdin_file, stream_list::m_stdout_file,
stream_list::m_stderr_file): New data members.
(stream_list::stdin_file, stream_list::stdout_file,
stream_list::stderr_file): New functions.
* interpreter.h, interpreter.cc (interpreter::m_stream_list):
New data member.
(interpreter::interpreter): Initialize it. Don't call
initialize_file_io.
(interpreter::~interpreter): Don't call close_files.
(interpreter::get_stream_list): New function.
* file-io.h, file-io.cc (stdin_file, stdout_file, stderr_file,
stdin_stream, stdout_stream, stderr_stream): Delete static variables.
(initialize_file_io, close_files): Delete. These actions are now
handled by the stream_list constructor and destructor.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Thu, 06 Jul 2017 13:34:31 -0400 |
parents | 7fb957d36357 |
children | 884e18e82e8f |
files | libinterp/corefcn/dlmread.cc libinterp/corefcn/file-io.cc libinterp/corefcn/file-io.h libinterp/corefcn/interpreter.cc libinterp/corefcn/interpreter.h libinterp/corefcn/oct-stream.cc libinterp/corefcn/oct-stream.h libinterp/corefcn/pr-output.cc libinterp/corefcn/syscalls.cc libinterp/dldfcn/__init_gnuplot__.cc |
diffstat | 10 files changed, 300 insertions(+), 332 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/corefcn/dlmread.cc Thu Jul 06 12:21:42 2017 -0400 +++ b/libinterp/corefcn/dlmread.cc Thu Jul 06 13:34:31 2017 -0400 @@ -36,6 +36,7 @@ #include "lo-ieee.h" #include "defun.h" +#include "interpreter.h" #include "oct-stream.h" #include "error.h" #include "ovl.h" @@ -158,8 +159,8 @@ return stat; } -DEFUN (dlmread, args, , - doc: /* -*- texinfo -*- +DEFMETHOD (dlmread, interp, args, , + doc: /* -*- texinfo -*- @deftypefn {} {@var{data} =} dlmread (@var{file}) @deftypefnx {} {@var{data} =} dlmread (@var{file}, @var{sep}) @deftypefnx {} {@var{data} =} dlmread (@var{file}, @var{sep}, @var{r0}, @var{c0}) @@ -228,7 +229,9 @@ } else if (args(0).is_scalar_type ()) { - octave::stream is = octave::stream_list::lookup (args(0), "dlmread"); + octave::stream_list& streams = interp.get_stream_list (); + + octave::stream is = streams.lookup (args(0), "dlmread"); input = is.input_stream ();
--- a/libinterp/corefcn/file-io.cc Thu Jul 06 12:21:42 2017 -0400 +++ b/libinterp/corefcn/file-io.cc Thu Jul 06 13:34:31 2017 -0400 @@ -65,6 +65,7 @@ #include "error.h" #include "errwarn.h" #include "file-io.h" +#include "interpreter.h" #include "load-path.h" #include "oct-fstrm.h" #include "oct-iostrm.h" @@ -79,37 +80,6 @@ #include "utils.h" #include "variables.h" -static octave_value stdin_file; -static octave_value stdout_file; -static octave_value stderr_file; - -static octave::stream stdin_stream; -static octave::stream stdout_stream; -static octave::stream stderr_stream; - -void -initialize_file_io (void) -{ - stdin_stream = octave_istream::create (&std::cin, "stdin"); - - // This uses octave_stdout (see pager.h), not std::cout so that Octave's - // standard output stream will pass through the pager. - - stdout_stream = octave_ostream::create (&octave_stdout, "stdout"); - - stderr_stream = octave_ostream::create (&std::cerr, "stderr"); - - stdin_file = octave::stream_list::insert (stdin_stream); - stdout_file = octave::stream_list::insert (stdout_stream); - stderr_file = octave::stream_list::insert (stderr_stream); -} - -void -close_files (void) -{ - octave::stream_list::clear (); -} - // List of files to delete when we exit or crash. // // FIXME: this should really be static, @@ -233,8 +203,8 @@ return retval; } -DEFUN (fclose, args, , - doc: /* -*- texinfo -*- +DEFMETHOD (fclose, interp, args, , + doc: /* -*- texinfo -*- @deftypefn {} {} fclose (@var{fid}) @deftypefnx {} {} fclose ("all") @deftypefnx {} {@var{status} =} fclose ("all") @@ -250,11 +220,13 @@ if (args.length () != 1) print_usage (); - return ovl (octave::stream_list::remove (args(0), "fclose")); + octave::stream_list& streams = interp.get_stream_list (); + + return ovl (streams.remove (args(0), "fclose")); } -DEFUN (fclear, args, , - doc: /* -*- texinfo -*- +DEFMETHOD (fclear, interp, args, , + doc: /* -*- texinfo -*- @deftypefn {} {} fclear (@var{fid}) Clear the stream state for the file specified by the file descriptor @var{fid}. @@ -264,17 +236,19 @@ if (args.length () != 1) print_usage (); - int fid = octave::stream_list::get_file_number (args(0)); - - octave::stream os = octave::stream_list::lookup (fid, "fclear"); + octave::stream_list& streams = interp.get_stream_list (); + + int fid = streams.get_file_number (args(0)); + + octave::stream os = streams.lookup (fid, "fclear"); os.clearerr (); return ovl (); } -DEFUN (fflush, args, , - doc: /* -*- texinfo -*- +DEFMETHOD (fflush, interp, args, , + doc: /* -*- texinfo -*- @deftypefn {} {} fflush (@var{fid}) Flush output to file descriptor @var{fid}. @@ -293,8 +267,10 @@ octave_value retval = -1; + octave::stream_list& streams = interp.get_stream_list (); + // FIXME: any way to avoid special case for stdout? - int fid = octave::stream_list::get_file_number (args(0)); + int fid = streams.get_file_number (args(0)); if (fid == 1) { @@ -304,7 +280,7 @@ } else { - octave::stream os = octave::stream_list::lookup (fid, "fflush"); + octave::stream os = streams.lookup (fid, "fflush"); retval = os.flush (); } @@ -312,8 +288,8 @@ return retval; } -DEFUN (fgetl, args, , - doc: /* -*- texinfo -*- +DEFMETHOD (fgetl, interp, args, , + doc: /* -*- texinfo -*- @deftypefn {} {@var{str} =} fgetl (@var{fid}) @deftypefnx {} {@var{str} =} fgetl (@var{fid}, @var{len}) Read characters from a file, stopping after a newline, or EOF, @@ -338,7 +314,9 @@ if (nargin < 1 || nargin > 2) print_usage (); - octave::stream os = octave::stream_list::lookup (args(0), who); + octave::stream_list& streams = interp.get_stream_list (); + + octave::stream os = streams.lookup (args(0), who); octave_value len_arg = (nargin == 2) ? args(1) : octave_value (); @@ -352,8 +330,8 @@ return ovl (-1, 0); } -DEFUN (fgets, args, , - doc: /* -*- texinfo -*- +DEFMETHOD (fgets, interp, args, , + doc: /* -*- texinfo -*- @deftypefn {} {@var{str} =} fgets (@var{fid}) @deftypefnx {} {@var{str} =} fgets (@var{fid}, @var{len}) Read characters from a file, stopping after a newline, or EOF, @@ -378,7 +356,9 @@ if (nargin < 1 || nargin > 2) print_usage (); - octave::stream os = octave::stream_list::lookup (args(0), who); + octave::stream_list& streams = interp.get_stream_list (); + + octave::stream os = streams.lookup (args(0), who); octave_value len_arg = (nargin == 2) ? args(1) : octave_value (); @@ -392,8 +372,8 @@ return ovl (-1.0, 0.0); } -DEFUN (fskipl, args, , - doc: /* -*- texinfo -*- +DEFMETHOD (fskipl, interp, args, , + doc: /* -*- texinfo -*- @deftypefn {} {@var{nlines} =} fskipl (@var{fid}) @deftypefnx {} {@var{nlines} =} fskipl (@var{fid}, @var{count}) @deftypefnx {} {@var{nlines} =} fskipl (@var{fid}, Inf) @@ -418,7 +398,9 @@ if (nargin < 1 || nargin > 2) print_usage (); - octave::stream os = octave::stream_list::lookup (args(0), who); + octave::stream_list& streams = interp.get_stream_list (); + + octave::stream os = streams.lookup (args(0), who); octave_value count_arg = (nargin == 2) ? args(1) : octave_value (); @@ -507,8 +489,8 @@ return retval; } -DEFUN (fopen, args, nargout, - doc: /* -*- texinfo -*- +DEFMETHOD (fopen, interp, args, nargout, + doc: /* -*- texinfo -*- @deftypefn {} {@var{fid} =} fopen (@var{name}) @deftypefnx {} {@var{fid} =} fopen (@var{name}, @var{mode}) @deftypefnx {} {@var{fid} =} fopen (@var{name}, @var{mode}, @var{arch}) @@ -615,6 +597,8 @@ octave_value_list retval = ovl (-1.0); + octave::stream_list& streams = interp.get_stream_list (); + if (nargin == 1) { if (args(0).is_string ()) @@ -624,11 +608,11 @@ // with MODE = "r". To open a file called "all", you have // to supply more than one argument. if (nargout < 2 && args(0).string_value () == "all") - return octave::stream_list::open_file_numbers (); + return streams.open_file_numbers (); } else { - string_vector tmp = octave::stream_list::get_info (args(0)); + string_vector tmp = streams.get_info (args(0)); retval = ovl (tmp(0), tmp(1), tmp(2)); @@ -647,7 +631,7 @@ octave::stream os = do_stream_open (args(0), mode, arch, "fopen", fid); if (os) - retval = ovl (octave::stream_list::insert (os), ""); + retval = ovl (streams.insert (os), ""); else { int error_number = 0; @@ -672,8 +656,8 @@ %! assert (arch, ""); */ -DEFUN (freport, args, , - doc: /* -*- texinfo -*- +DEFMETHOD (freport, interp, args, , + doc: /* -*- texinfo -*- @deftypefn {} {} freport () Print a list of which files have been opened, and whether they are open for reading, writing, or both. @@ -698,13 +682,15 @@ if (args.length () > 0) warning ("freport: ignoring extra arguments"); - octave_stdout << octave::stream_list::list_open_files (); + octave::stream_list& streams = interp.get_stream_list (); + + octave_stdout << streams.list_open_files (); return ovl (); } -DEFUN (frewind, args, nargout, - doc: /* -*- texinfo -*- +DEFMETHOD (frewind, interp, args, nargout, + doc: /* -*- texinfo -*- @deftypefn {} {} frewind (@var{fid}) @deftypefnx {} {@var{status} =} frewind (@var{fid}) Move the file pointer to the beginning of the file specified by file @@ -720,7 +706,9 @@ int result = -1; - octave::stream os = octave::stream_list::lookup (args(0), "frewind"); + octave::stream_list& streams = interp.get_stream_list (); + + octave::stream os = streams.lookup (args(0), "frewind"); result = os.rewind (); @@ -730,8 +718,8 @@ return ovl (); } -DEFUN (fseek, args, , - doc: /* -*- texinfo -*- +DEFMETHOD (fseek, interp, args, , + doc: /* -*- texinfo -*- @deftypefn {} {} fseek (@var{fid}, @var{offset}) @deftypefnx {} {} fseek (@var{fid}, @var{offset}, @var{origin}) @deftypefnx {} {@var{status} =} fseek (@dots{}) @@ -754,15 +742,17 @@ if (nargin < 2 || nargin > 3) print_usage (); - octave::stream os = octave::stream_list::lookup (args(0), "fseek"); + octave::stream_list& streams = interp.get_stream_list (); + + octave::stream os = streams.lookup (args(0), "fseek"); octave_value origin_arg = (nargin == 3) ? args(2) : octave_value (-1.0); return ovl (os.seek (args(1), origin_arg)); } -DEFUN (ftell, args, , - doc: /* -*- texinfo -*- +DEFMETHOD (ftell, interp, args, , + doc: /* -*- texinfo -*- @deftypefn {} {@var{pos} =} ftell (@var{fid}) Return the position of the file pointer as the number of characters from the beginning of the file specified by file descriptor @var{fid}. @@ -772,14 +762,16 @@ if (args.length () != 1) print_usage (); - octave::stream os = octave::stream_list::lookup (args(0), "ftell"); + octave::stream_list& streams = interp.get_stream_list (); + + octave::stream os = streams.lookup (args(0), "ftell"); return ovl (os.tell ()); } static octave_value_list -printf_internal (const std::string& who, const octave_value_list& args, - int nargout) +printf_internal (octave::interpreter& interp, const std::string& who, + const octave_value_list& args, int nargout) { int nargin = args.length (); @@ -791,12 +783,14 @@ octave::stream os; int fmt_n = 0; + octave::stream_list& streams = interp.get_stream_list (); + if (args(0).is_string ()) - os = octave::stream_list::lookup (1, who); + os = streams.lookup (1, who); else { fmt_n = 1; - os = octave::stream_list::lookup (args(0), who); + os = streams.lookup (args(0), who); } if (! args(fmt_n).is_string ()) @@ -820,8 +814,8 @@ return ovl (); } -DEFUN (fprintf, args, nargout, - doc: /* -*- texinfo -*- +DEFMETHOD (fprintf, interp, args, nargout, + doc: /* -*- texinfo -*- @deftypefn {} {} fprintf (@var{fid}, @var{template}, @dots{}) @deftypefnx {} {} fprintf (@var{template}, @dots{}) @deftypefnx {} {@var{numbytes} =} fprintf (@dots{}) @@ -841,11 +835,11 @@ { static std::string who = "fprintf"; - return printf_internal (who, args, nargout); + return printf_internal (interp, who, args, nargout); } -DEFUN (printf, args, nargout, - doc: /* -*- texinfo -*- +DEFMETHOD (printf, interp, args, nargout, + doc: /* -*- texinfo -*- @deftypefn {} {} printf (@var{template}, @dots{}) Print optional arguments under the control of the template string @var{template} to the stream @code{stdout} and return the number of @@ -866,22 +860,26 @@ octave_value_list tmp_args = args; - return printf_internal (who, tmp_args.prepend (octave_value (1)), nargout); + return printf_internal (interp, who, tmp_args.prepend (octave_value (1)), + nargout); } static octave_value_list -puts_internal (const std::string& who, const octave_value_list& args) +puts_internal (octave::interpreter& interp, const std::string& who, + const octave_value_list& args) { if (args.length () != 2) print_usage (); - octave::stream os = octave::stream_list::lookup (args(0), who); + octave::stream_list& streams = interp.get_stream_list (); + + octave::stream os = streams.lookup (args(0), who); return ovl (os.puts (args(1), who)); } -DEFUN (fputs, args, , - doc: /* -*- texinfo -*- +DEFMETHOD (fputs, interp, args, , + doc: /* -*- texinfo -*- @deftypefn {} {} fputs (@var{fid}, @var{string}) @deftypefnx {} {@var{status} =} fputs (@var{fid}, @var{string}) Write the string @var{string} to the file with file descriptor @var{fid}. @@ -896,11 +894,11 @@ { static std::string who = "fputs"; - return puts_internal (who, args); + return puts_internal (interp, who, args); } -DEFUN (puts, args, , - doc: /* -*- texinfo -*- +DEFMETHOD (puts, interp, args, , + doc: /* -*- texinfo -*- @deftypefn {} {} puts (@var{string}) @deftypefnx {} {@var{status} =} puts (@var{string}) Write a string to the standard output with no formatting. @@ -916,7 +914,7 @@ octave_value_list tmp_args = args; - return puts_internal (who, tmp_args.prepend (octave_value (1))); + return puts_internal (interp, who, tmp_args.prepend (octave_value (1))); } DEFUN (sprintf, args, , @@ -983,7 +981,8 @@ } static octave_value_list -scanf_internal (const std::string& who, const octave_value_list& args) +scanf_internal (octave::interpreter& interp, const std::string& who, + const octave_value_list& args) { int nargin = args.length (); @@ -992,7 +991,9 @@ octave_value_list retval; - octave::stream os = octave::stream_list::lookup (args(0), who); + octave::stream_list& streams = interp.get_stream_list (); + + octave::stream os = streams.lookup (args(0), who); if (! args(1).is_string ()) error ("%s: format TEMPLATE must be a string", who.c_str ()); @@ -1018,8 +1019,8 @@ return retval; } -DEFUN (fscanf, args, , - doc: /* -*- texinfo -*- +DEFMETHOD (fscanf, interp, args, , + doc: /* -*- texinfo -*- @deftypefn {} {[@var{val}, @var{count}, @var{errmsg}] =} fscanf (@var{fid}, @var{template}, @var{size}) @deftypefnx {} {[@var{v1}, @var{v2}, @dots{}, @var{count}, @var{errmsg}] =} fscanf (@var{fid}, @var{template}, "C") In the first form, read from @var{fid} according to @var{template}, @@ -1070,7 +1071,7 @@ { static std::string who = "fscanf"; - return scanf_internal (who, args); + return scanf_internal (interp, who, args); } static std::string @@ -1146,8 +1147,8 @@ return retval; } -DEFUN (scanf, args, , - doc: /* -*- texinfo -*- +DEFMETHOD (scanf, interp, args, , + doc: /* -*- texinfo -*- @deftypefn {} {[@var{val}, @var{count}, @var{errmsg}] =} scanf (@var{template}, @var{size}) @deftypefnx {} {[@var{v1}, @var{v2}, @dots{}, @var{count}, @var{errmsg}]] =} scanf (@var{template}, "C") This is equivalent to calling @code{fscanf} with @var{fid} = @code{stdin}. @@ -1160,11 +1161,12 @@ octave_value_list tmp_args = args; - return scanf_internal (who, tmp_args.prepend (octave_value (0))); + return scanf_internal (interp, who, tmp_args.prepend (octave_value (0))); } static octave_value_list -textscan_internal (const std::string& who, const octave_value_list& args) +textscan_internal (octave::interpreter& interp, const std::string& who, + const octave_value_list& args) { if (args.length () < 1) print_usage (who); @@ -1181,7 +1183,11 @@ error ("%s: unable to create temporary input buffer", who.c_str ()); } else - os =octave::stream_list::lookup (args(0), who); + { + octave::stream_list& streams = interp.get_stream_list (); + + os = streams.lookup (args(0), who); + } int nskip = 1; @@ -1231,8 +1237,8 @@ return ovl (result, count, errmsg); } -DEFUN (textscan, args, , - doc: /* -*- texinfo -*- +DEFMETHOD (textscan, interp, args, , + doc: /* -*- texinfo -*- @deftypefn {} {@var{C} =} textscan (@var{fid}, @var{format}) @deftypefnx {} {@var{C} =} textscan (@var{fid}, @var{format}, @var{repeat}) @deftypefnx {} {@var{C} =} textscan (@var{fid}, @var{format}, @var{param}, @var{value}, @dots{}) @@ -1498,11 +1504,11 @@ { static std::string who = "textscan"; - return textscan_internal (who, args); + return textscan_internal (interp, who, args); } -DEFUN (__textscan__, args, , - doc: /* -*- texinfo -*- +DEFMETHOD (__textscan__, interp, args, , + doc: /* -*- texinfo -*- @deftypefn {} {@var{C} =} __textscan__ (@var{who}, @dots{}) Like @code{textscan} but accept additional argument @var{who} to use as the name of the function when reporting errors. @@ -1511,7 +1517,8 @@ if (args.length () == 0) print_usage (); - return textscan_internal (args(0).string_value (), args.splice (0, 1)); + return textscan_internal (interp, args(0).string_value (), + args.splice (0, 1)); } /* @@ -2285,8 +2292,8 @@ flt_fmt, count); } -DEFUN (fread, args, , - doc: /* -*- texinfo -*- +DEFMETHOD (fread, interp, args, , + doc: /* -*- texinfo -*- @deftypefn {} {@var{val} =} fread (@var{fid}) @deftypefnx {} {@var{val} =} fread (@var{fid}, @var{size}) @deftypefnx {} {@var{val} =} fread (@var{fid}, @var{size}, @var{precision}) @@ -2461,7 +2468,9 @@ if (nargin < 1 || nargin > 5) print_usage (); - octave::stream os = octave::stream_list::lookup (args(0), "fread"); + octave::stream_list& streams = interp.get_stream_list (); + + octave::stream os = streams.lookup (args(0), "fread"); octave_value size = lo_ieee_inf_value (); octave_value prec = "uchar"; @@ -2532,8 +2541,8 @@ return os.write (data, block_size, output_type, skip, flt_fmt); } -DEFUN (fwrite, args, , - doc: /* -*- texinfo -*- +DEFMETHOD (fwrite, interp, args, , + doc: /* -*- texinfo -*- @deftypefn {} {} fwrite (@var{fid}, @var{data}) @deftypefnx {} {} fwrite (@var{fid}, @var{data}, @var{precision}) @deftypefnx {} {} fwrite (@var{fid}, @var{data}, @var{precision}, @var{skip}) @@ -2559,7 +2568,9 @@ if (nargin < 2 || nargin > 5) print_usage (); - octave::stream os = octave::stream_list::lookup (args(0), "fwrite"); + octave::stream_list& streams = interp.get_stream_list (); + + octave::stream os = streams.lookup (args(0), "fwrite"); octave_value prec = "uchar"; octave_value skip = 0; @@ -2586,8 +2597,8 @@ return ovl (do_fwrite (os, data, prec, skip, arch)); } -DEFUNX ("feof", Ffeof, args, , - doc: /* -*- texinfo -*- +DEFMETHODX ("feof", Ffeof, interp, args, , + doc: /* -*- texinfo -*- @deftypefn {} {@var{status} =} feof (@var{fid}) Return 1 if an end-of-file condition has been encountered for the file specified by file descriptor @var{fid} and 0 otherwise. @@ -2601,13 +2612,15 @@ if (args.length () != 1) print_usage (); - octave::stream os = octave::stream_list::lookup (args(0), "feof"); + octave::stream_list& streams = interp.get_stream_list (); + + octave::stream os = streams.lookup (args(0), "feof"); return ovl (os.eof () ? 1.0 : 0.0); } -DEFUNX ("ferror", Fferror, args, , - doc: /* -*- texinfo -*- +DEFMETHODX ("ferror", Fferror, interp, args, , + doc: /* -*- texinfo -*- @deftypefn {} {@var{msg} =} ferror (@var{fid}) @deftypefnx {} {[@var{msg}, @var{err}] =} ferror (@var{fid}) @deftypefnx {} {[@dots{}] =} ferror (@var{fid}, "clear") @@ -2632,7 +2645,9 @@ if (nargin < 1 || nargin > 2) print_usage (); - octave::stream os = octave::stream_list::lookup (args(0), "ferror"); + octave::stream_list& streams = interp.get_stream_list (); + + octave::stream os = streams.lookup (args(0), "ferror"); bool clear = false; @@ -2650,8 +2665,8 @@ return ovl (error_message, error_number); } -DEFUNX ("popen", Fpopen, args, , - doc: /* -*- texinfo -*- +DEFMETHODX ("popen", Fpopen, interp, args, , + doc: /* -*- texinfo -*- @deftypefn {} {@var{fid} =} popen (@var{command}, @var{mode}) Start a process and create a pipe. @@ -2696,17 +2711,19 @@ octave_value retval; + octave::stream_list& streams = interp.get_stream_list (); + if (mode == "r") { octave::stream ips = octave_iprocstream::create (name); - retval = octave::stream_list::insert (ips); + retval = streams.insert (ips); } else if (mode == "w") { octave::stream ops = octave_oprocstream::create (name); - retval = octave::stream_list::insert (ops); + retval = streams.insert (ops); } else error ("popen: invalid MODE specified"); @@ -2714,8 +2731,8 @@ return retval; } -DEFUNX ("pclose", Fpclose, args, , - doc: /* -*- texinfo -*- +DEFMETHODX ("pclose", Fpclose, interp, args, , + doc: /* -*- texinfo -*- @deftypefn {} {} pclose (@var{fid}) Close a file identifier that was opened by @code{popen}. @@ -2726,7 +2743,9 @@ if (args.length () != 1) print_usage (); - return ovl (octave::stream_list::remove (args(0), "pclose")); + octave::stream_list& streams = interp.get_stream_list (); + + return ovl (streams.remove (args(0), "pclose")); } DEFUN (tempname, args, , @@ -2822,8 +2841,8 @@ %! end_unwind_protect */ -DEFUN (tmpfile, args, , - doc: /* -*- texinfo -*- +DEFMETHOD (tmpfile, interp, args, , + doc: /* -*- texinfo -*- @deftypefn {} {[@var{fid}, @var{msg}] =} tmpfile () Return the file ID corresponding to a new temporary file with a unique name. @@ -2855,7 +2874,9 @@ if (! s) error ("tmpfile: failed to create octave_stdiostream object"); - retval = ovl (octave::stream_list::insert (s), ""); + octave::stream_list& streams = interp.get_stream_list (); + + retval = ovl (streams.insert (s), ""); } else { @@ -2865,8 +2886,8 @@ return retval; } -DEFUN (mkstemp, args, , - doc: /* -*- texinfo -*- +DEFMETHOD (mkstemp, interp, args, , + doc: /* -*- texinfo -*- @deftypefn {} {[@var{fid}, @var{name}, @var{msg}] =} mkstemp ("@var{template}") @deftypefnx {} {[@var{fid}, @var{name}, @var{msg}] =} mkstemp ("@var{template}", @var{delete}) Return the file descriptor @var{fid} corresponding to a new temporary file @@ -2930,7 +2951,9 @@ if (! s) error ("mkstemp: failed to create octave_stdiostream object"); - retval(0) = octave::stream_list::insert (s); + octave::stream_list& streams = interp.get_stream_list (); + + retval(0) = streams.insert (s); retval(1) = nm; if (nargin == 2 && args(1).is_true ()) @@ -3092,8 +3115,8 @@ return octave_value (val); } -DEFUNX ("stdin", Fstdin, args, , - doc: /* -*- texinfo -*- +DEFMETHODX ("stdin", Fstdin, interp, args, , + doc: /* -*- texinfo -*- @deftypefn {} {} stdin () Return the numeric value corresponding to the standard input stream. @@ -3102,11 +3125,13 @@ @seealso{stdout, stderr} @end deftypefn */) { - return const_value ("stdin", args, stdin_file); + octave::stream_list& streams = interp.get_stream_list (); + + return const_value ("stdin", args, streams.stdin_file ()); } -DEFUNX ("stdout", Fstdout, args, , - doc: /* -*- texinfo -*- +DEFMETHODX ("stdout", Fstdout, interp, args, , + doc: /* -*- texinfo -*- @deftypefn {} {} stdout () Return the numeric value corresponding to the standard output stream. @@ -3114,11 +3139,13 @@ @seealso{stdin, stderr} @end deftypefn */) { - return const_value ("stdout", args, stdout_file); + octave::stream_list& streams = interp.get_stream_list (); + + return const_value ("stdout", args, streams.stdout_file ()); } -DEFUNX ("stderr", Fstderr, args, , - doc: /* -*- texinfo -*- +DEFMETHODX ("stderr", Fstderr, interp, args, , + doc: /* -*- texinfo -*- @deftypefn {} {} stderr () Return the numeric value corresponding to the standard error stream. @@ -3127,5 +3154,7 @@ @seealso{stdin, stdout} @end deftypefn */) { - return const_value ("stderr", args, stderr_file); + octave::stream_list& streams = interp.get_stream_list (); + + return const_value ("stderr", args, streams.stderr_file ()); }
--- a/libinterp/corefcn/file-io.h Thu Jul 06 12:21:42 2017 -0400 +++ b/libinterp/corefcn/file-io.h Thu Jul 06 13:34:31 2017 -0400 @@ -29,10 +29,6 @@ #include <string> -extern OCTINTERP_API void initialize_file_io (void); - -extern OCTINTERP_API void close_files (void); - extern OCTINTERP_API void mark_for_deletion (const std::string&); extern OCTINTERP_API void cleanup_tmp_files (void);
--- a/libinterp/corefcn/interpreter.cc Thu Jul 06 12:21:42 2017 -0400 +++ b/libinterp/corefcn/interpreter.cc Thu Jul 06 13:34:31 2017 -0400 @@ -354,6 +354,7 @@ m_load_path (), m_symbol_table (), m_evaluator (*this), + m_stream_list (*this), m_cdef_manager (*this), m_interactive (false), m_read_site_files (true), @@ -409,8 +410,6 @@ else quit_allowed = false; - initialize_file_io (); - install_types (); install_ops (); @@ -1137,8 +1136,6 @@ OCTAVE_SAFE_CALL (gtk_manager::unload_all_toolkits, ()); - OCTAVE_SAFE_CALL (close_files, ()); - OCTAVE_SAFE_CALL (cleanup_tmp_files, ()); // FIXME: May still need something like this to ensure that @@ -1172,6 +1169,11 @@ return m_evaluator; } + stream_list& interpreter::get_stream_list (void) + { + return m_stream_list; + } + symbol_table::scope * interpreter::get_current_scope (void) {
--- a/libinterp/corefcn/interpreter.h Thu Jul 06 12:21:42 2017 -0400 +++ b/libinterp/corefcn/interpreter.h Thu Jul 06 13:34:31 2017 -0400 @@ -34,6 +34,7 @@ #include "environment.h" #include "help.h" #include "load-path.h" +#include "oct-stream.h" #include "ov-classdef.h" #include "pt-eval.h" #include "symtab.h" @@ -171,6 +172,8 @@ tree_evaluator& get_evaluator (void); + stream_list& get_stream_list (void); + cdef_manager& get_cdef_manager (void) { return m_cdef_manager; @@ -224,6 +227,8 @@ tree_evaluator m_evaluator; + stream_list m_stream_list; + cdef_manager m_cdef_manager; // TRUE means this is an interactive interpreter (forced or not).
--- a/libinterp/corefcn/oct-stream.cc Thu Jul 06 12:21:42 2017 -0400 +++ b/libinterp/corefcn/oct-stream.cc Thu Jul 06 13:34:31 2017 -0400 @@ -52,10 +52,12 @@ #include "input.h" #include "interpreter.h" #include "octave.h" +#include "oct-iostrm.h" #include "oct-stdstrm.h" #include "oct-stream.h" #include "ov.h" #include "ovl.h" +#include "pager.h" #include "utils.h" // Programming Note: There are two very different error functions used @@ -7243,97 +7245,32 @@ return retval; } - stream_list *stream_list::instance = nullptr; - - bool - stream_list::instance_ok (void) - { - bool retval = true; - - if (! instance) - { - instance = new stream_list (); - - if (instance) - singleton_cleanup_list::add (cleanup_instance); - } - - if (! instance) - ::error ("unable to create stream list object!"); - - return retval; - } - - int - stream_list::insert (stream& os) - { - return (instance_ok ()) ? instance->do_insert (os) : -1; - } - - stream - stream_list::lookup (int fid, const std::string& who) - { - return (instance_ok ()) ? instance->do_lookup (fid, who) : stream (); - } - - stream - stream_list::lookup (const octave_value& fid, const std::string& who) - { - return (instance_ok ()) ? instance->do_lookup (fid, who) : stream (); - } - - int - stream_list::remove (int fid, const std::string& who) - { - return (instance_ok ()) ? instance->do_remove (fid, who) : -1; + stream_list::stream_list (interpreter&) + : list (), lookup_cache (list.end ()), m_stdin_file (-1), + m_stdout_file (-1), m_stderr_file (-1) + { + stream stdin_stream = octave_istream::create (&std::cin, "stdin"); + + // This uses octave_stdout (see pager.h), not std::cout so that + // Octave's standard output stream will pass through the pager. + + // FIXME: we should be accessing octave_stdout from the interpreter. + + stream stdout_stream = octave_ostream::create (&octave_stdout, "stdout"); + + stream stderr_stream = octave_ostream::create (&std::cerr, "stderr"); + + m_stdin_file = insert (stdin_stream); + m_stdout_file = insert (stdout_stream); + m_stderr_file = insert (stderr_stream); } - int - stream_list::remove (const octave_value& fid, const std::string& who) - { - return (instance_ok ()) ? instance->do_remove (fid, who) : -1; - } - - void - stream_list::clear (bool flush) - { - if (instance) - instance->do_clear (flush); - } - - string_vector - stream_list::get_info (int fid) - { - return (instance_ok ()) ? instance->do_get_info (fid) : string_vector (); + stream_list::~stream_list (void) + { + clear (); } - string_vector - stream_list::get_info (const octave_value& fid) - { - return (instance_ok ()) ? instance->do_get_info (fid) : string_vector (); - } - - std::string - stream_list::list_open_files (void) - { - return (instance_ok ()) ? instance->do_list_open_files () : ""; - } - - octave_value - stream_list::open_file_numbers (void) - { - return (instance_ok ()) - ? instance->do_open_file_numbers () : octave_value (); - } - - int - stream_list::get_file_number (const octave_value& fid) - { - return (instance_ok ()) ? instance->do_get_file_number (fid) : -1; - } - - int - stream_list::do_insert (stream& os) + int stream_list::insert (stream& os) { // Insert item with key corresponding to file-descriptor. @@ -7376,8 +7313,7 @@ namespace octave { - stream - stream_list::do_lookup (int fid, const std::string& who) const + stream stream_list::lookup (int fid, const std::string& who) const { stream retval; @@ -7400,17 +7336,15 @@ return retval; } - stream - stream_list::do_lookup (const octave_value& fid, - const std::string& who) const + stream stream_list::lookup (const octave_value& fid, + const std::string& who) const { int i = get_file_number (fid); - return do_lookup (i, who); + return lookup (i, who); } - int - stream_list::do_remove (int fid, const std::string& who) + int stream_list::remove (int fid, const std::string& who) { // Can't remove stdin (std::cin), stdout (std::cout), or stderr (std::cerr). if (fid < 3) @@ -7434,14 +7368,13 @@ return 0; } - int - stream_list::do_remove (const octave_value& fid, const std::string& who) + int stream_list::remove (const octave_value& fid, const std::string& who) { int retval = -1; if (fid.is_string () && fid.string_value () == "all") { - do_clear (false); + clear (false); retval = 0; } @@ -7449,14 +7382,13 @@ { int i = get_file_number (fid); - retval = do_remove (i, who); + retval = remove (i, who); } return retval; } - void - stream_list::do_clear (bool flush) + void stream_list::clear (bool flush) { if (flush) { @@ -7497,8 +7429,7 @@ lookup_cache = list.end (); } - string_vector - stream_list::do_get_info (int fid) const + string_vector stream_list::get_info (int fid) const { string_vector retval (3); @@ -7529,8 +7460,7 @@ return retval; } - string_vector - stream_list::do_get_info (const octave_value& fid) const + string_vector stream_list::get_info (const octave_value& fid) const { int conv_err = 0; @@ -7539,11 +7469,10 @@ if (conv_err) ::error ("file id must be a file object or integer value"); - return do_get_info (int_fid); + return get_info (int_fid); } - std::string - stream_list::do_list_open_files (void) const + std::string stream_list::list_open_files (void) const { std::ostringstream buf; @@ -7575,8 +7504,7 @@ return buf.str (); } - octave_value - stream_list::do_open_file_numbers (void) const + octave_value stream_list::open_file_numbers (void) const { Matrix retval (1, list.size (), 0.0); @@ -7594,8 +7522,7 @@ return retval; } - int - stream_list::do_get_file_number (const octave_value& fid) const + int stream_list::get_file_number (const octave_value& fid) const { int retval = -1; @@ -7632,4 +7559,19 @@ return retval; } + + octave_value stream_list::stdin_file (void) const + { + return octave_value (m_stdin_file); + } + + octave_value stream_list::stdout_file (void) const + { + return octave_value (m_stdout_file); + } + + octave_value stream_list::stderr_file (void) const + { + return octave_value (m_stderr_file); + } }
--- a/libinterp/corefcn/oct-stream.h Thu Jul 06 12:21:42 2017 -0400 +++ b/libinterp/corefcn/oct-stream.h Thu Jul 06 13:34:31 2017 -0400 @@ -45,6 +45,8 @@ namespace octave { + class interpreter; + // These are only needed as arguments to private functions, so they // are also treated as private. @@ -413,35 +415,37 @@ OCTINTERP_API stream_list { - protected: - - stream_list (void) : list (), lookup_cache (list.end ()) { } - public: - ~stream_list (void) = default; + stream_list (interpreter& interp); - static bool instance_ok (void); + stream_list (const stream_list&) = delete; + stream_list& operator = (const stream_list&) = delete; + + ~stream_list (void); - static int insert (stream& os); + int insert (stream& os); - static stream lookup (int fid, const std::string& who = ""); + stream lookup (int fid, const std::string& who = "") const; + stream lookup (const octave_value& fid, const std::string& who = "") const; - static stream lookup (const octave_value& fid, const std::string& who = ""); + int remove (int fid, const std::string& who = ""); + int remove (const octave_value& fid, const std::string& who = ""); - static int remove (int fid, const std::string& who = ""); - static int remove (const octave_value& fid, const std::string& who = ""); + void clear (bool flush = true); - static void clear (bool flush = true); + string_vector get_info (int fid) const; + string_vector get_info (const octave_value& fid) const; + + std::string list_open_files (void) const; - static string_vector get_info (int fid); - static string_vector get_info (const octave_value& fid); + octave_value open_file_numbers (void) const; + + int get_file_number (const octave_value& fid) const; - static std::string list_open_files (void); - - static octave_value open_file_numbers (void); - - static int get_file_number (const octave_value& fid); + octave_value stdin_file (void) const; + octave_value stdout_file (void) const; + octave_value stderr_file (void) const; private: @@ -451,29 +455,9 @@ mutable ostrl_map::const_iterator lookup_cache; - static stream_list *instance; - - static void cleanup_instance (void) { delete instance; instance = 0; } - - int do_insert (stream& os); - - stream do_lookup (int fid, const std::string& who = "") const; - stream do_lookup (const octave_value& fid, - const std::string& who = "") const; - - int do_remove (int fid, const std::string& who = ""); - int do_remove (const octave_value& fid, const std::string& who = ""); - - void do_clear (bool flush = true); - - string_vector do_get_info (int fid) const; - string_vector do_get_info (const octave_value& fid) const; - - std::string do_list_open_files (void) const; - - octave_value do_open_file_numbers (void) const; - - int do_get_file_number (const octave_value& fid) const; + int m_stdin_file; + int m_stdout_file; + int m_stderr_file; }; }
--- a/libinterp/corefcn/pr-output.cc Thu Jul 06 12:21:42 2017 -0400 +++ b/libinterp/corefcn/pr-output.cc Thu Jul 06 13:34:31 2017 -0400 @@ -3502,8 +3502,8 @@ return retval; } -DEFUN (fdisp, args, , - classes: cell char double function_handle int8 int16 int32 int64 logical single struct uint8 uint16 uint32 uint64 +DEFMETHOD (fdisp, interp, args, , + classes: cell char double function_handle int8 int16 int32 int64 logical single struct uint8 uint16 uint32 uint64 doc: /* -*- texinfo -*- @deftypefn {} {} fdisp (@var{fid}, @var{x}) Display the value of @var{x} on the stream @var{fid}. @@ -3527,9 +3527,11 @@ if (args.length () != 2) print_usage (); - int fid = octave::stream_list::get_file_number (args(0)); - - octave::stream os = octave::stream_list::lookup (fid, "fdisp"); + octave::stream_list& streams = interp.get_stream_list (); + + int fid = streams.get_file_number (args(0)); + + octave::stream os = streams.lookup (fid, "fdisp"); std::ostream *osp = os.output_stream ();
--- a/libinterp/corefcn/syscalls.cc Thu Jul 06 12:21:42 2017 -0400 +++ b/libinterp/corefcn/syscalls.cc Thu Jul 06 13:34:31 2017 -0400 @@ -106,8 +106,8 @@ return ovl (Matrix (), -1, fs.error ()); } -DEFUNX ("dup2", Fdup2, args, , - doc: /* -*- texinfo -*- +DEFMETHODX ("dup2", Fdup2, interp, args, , + doc: /* -*- texinfo -*- @deftypefn {} {[@var{fid}, @var{msg}] =} dup2 (@var{old}, @var{new}) Duplicate a file descriptor. @@ -120,9 +120,11 @@ if (args.length () != 2) print_usage (); - octave::stream old_stream = octave::stream_list::lookup (args(0), "dup2"); + octave::stream_list& streams = interp.get_stream_list (); - octave::stream new_stream = octave::stream_list::lookup (args(1), "dup2"); + octave::stream old_stream = streams.lookup (args(0), "dup2"); + + octave::stream new_stream = streams.lookup (args(1), "dup2"); int i_old = old_stream.file_number (); int i_new = new_stream.file_number (); @@ -201,8 +203,8 @@ return ovl (status, msg); } -DEFUNX ("popen2", Fpopen2, args, , - doc: /* -*- texinfo -*- +DEFMETHODX ("popen2", Fpopen2, interp, args, , + doc: /* -*- texinfo -*- @deftypefn {} {[@var{in}, @var{out}, @var{pid}] =} popen2 (@var{command}, @var{args}) Start a subprocess with two-way communication. @@ -297,9 +299,9 @@ octave::stream os = octave_stdiostream::create (exec_file + "-out", ofile, std::ios::out); - return ovl (octave::stream_list::insert (os), - octave::stream_list::insert (is), - pid); + octave::stream_list& streams = interp.get_stream_list (); + + return ovl (streams.insert (os), streams.insert (is), pid); } /* @@ -370,8 +372,8 @@ */ -DEFUNX ("fcntl", Ffcntl, args, , - doc: /* -*- texinfo -*- +DEFMETHODX ("fcntl", Ffcntl, interp, args, , + doc: /* -*- texinfo -*- @deftypefn {} {[@var{err}, @var{msg}] =} fcntl (@var{fid}, @var{request}, @var{arg}) Change the properties of the open file @var{fid}. @@ -432,7 +434,9 @@ if (args.length () != 3) print_usage (); - octave::stream strm = octave::stream_list::lookup (args(0), "fcntl"); + octave::stream_list& streams = interp.get_stream_list (); + + octave::stream strm = streams.lookup (args(0), "fcntl"); int fid = strm.file_number (); @@ -716,8 +720,8 @@ */ -DEFUNX ("pipe", Fpipe, args, , - doc: /* -*- texinfo -*- +DEFMETHODX ("pipe", Fpipe, interp, args, , + doc: /* -*- texinfo -*- @deftypefn {} {[@var{read_fd}, @var{write_fd}, @var{err}, @var{msg}] =} pipe () Create a pipe and return the reading and writing ends of the pipe into @var{read_fd} and @var{write_fd} respectively. @@ -749,15 +753,14 @@ octave::stream os = octave_stdiostream::create ("pipe-out", ofile, std::ios::out); - return ovl (octave::stream_list::insert (is), - octave::stream_list::insert (os), - status, - msg); + octave::stream_list& streams = interp.get_stream_list (); + + return ovl (streams.insert (is), streams.insert (os), status, msg); } } -DEFUNX ("stat", Fstat, args, , - doc: /* -*- texinfo -*- +DEFMETHODX ("stat", Fstat, interp, args, , + doc: /* -*- texinfo -*- @deftypefn {} {[@var{info}, @var{err}, @var{msg}] =} stat (@var{file}) @deftypefnx {} {[@var{info}, @var{err}, @var{msg}] =} stat (@var{fid}) @deftypefnx {} {[@var{info}, @var{err}, @var{msg}] =} lstat (@var{file}) @@ -859,7 +862,9 @@ if (args(0).is_scalar_type ()) { - int fid = octave::stream_list::get_file_number (args(0)); + octave::stream_list& streams = interp.get_stream_list (); + + int fid = streams.get_file_number (args(0)); octave::sys::file_fstat fs (fid);
--- a/libinterp/dldfcn/__init_gnuplot__.cc Thu Jul 06 12:21:42 2017 -0400 +++ b/libinterp/dldfcn/__init_gnuplot__.cc Thu Jul 06 13:34:31 2017 -0400 @@ -156,14 +156,14 @@ octave_value_list args; Matrix fids = pstream.matrix_value (); - Ffputs (ovl (fids(0), "\nquit;\n")); + Ffputs (m_interpreter, ovl (fids(0), "\nquit;\n")); - Ffflush (ovl (fids(0))); - Fpclose (ovl (fids(0))); + Ffflush (m_interpreter, ovl (fids(0))); + Fpclose (m_interpreter, ovl (fids(0))); if (fids.numel () > 1) { - Fpclose (ovl (fids(1))); + Fpclose (m_interpreter, ovl (fids(1))); if (fids.numel () > 2) Fwaitpid (ovl (fids(2)));