changeset 3340:585a8809fd9b

[project @ 1999-11-05 07:02:30 by jwe]
author jwe
date Fri, 05 Nov 1999 07:02:36 +0000
parents f8b4692eb51c
children 14cfc9475fe4
files src/ChangeLog src/OPERATORS/op-fil-b.cc src/OPERATORS/op-fil-bm.cc src/OPERATORS/op-fil-cm.cc src/OPERATORS/op-fil-cs.cc src/OPERATORS/op-fil-lis.cc src/OPERATORS/op-fil-m.cc src/OPERATORS/op-fil-rec.cc src/OPERATORS/op-fil-s.cc src/OPERATORS/op-fil-str.cc src/TEMPLATE-INST/Array-os.cc src/file-io.cc src/oct-fstrm.cc src/oct-fstrm.h src/oct-iostrm.cc src/oct-iostrm.h src/oct-prcstrm.cc src/oct-prcstrm.h src/oct-stdstrm.cc src/oct-stdstrm.h src/oct-stream.cc src/oct-stream.h src/oct-strstrm.cc src/oct-strstrm.h src/ov-base.cc src/ov-base.h src/ov-file.cc src/ov-file.h src/ov.cc src/ov.h src/syscalls.cc
diffstat 31 files changed, 478 insertions(+), 273 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Thu Nov 04 16:24:31 1999 +0000
+++ b/src/ChangeLog	Fri Nov 05 07:02:36 1999 +0000
@@ -1,3 +1,42 @@
+1999-11-05  John W. Eaton  <jwe@bevo.che.wisc.edu>
+
+	* ov.h (octave_value::is_stream): New predicate.
+	* ov-file.h (octave_file::is_stream): Return true.
+	* file-io.cc (Fis_stream): New function.
+
+	* ov-file.h (class octave_file): stream is now an object instead
+	of pointer.
+	* ov-file.cc (octave_file::print_raw): Handle stream as object
+	instead of pointer.  Also print stream status.
+
+	* ov-base.cc (octave_base_value::stream_value): Return object
+	instead of pointer.
+
+	* ov.cc (octave_value::stream_value): Return object instead of pointer.
+	(octave_value::octave_value (const octave_stream&)): Take const
+	reference instead of pointer arg.
+
+	* TEMPLATE-INST/Array-os.cc: Instantiate Arrays of octave_stream
+	objects, not pointers to them.
+
+	* OPERATORS/op-fil-b.cc: Cope with octave_stream class changes.
+	* OPERATORS/op-fil-bm.cc: Likewise.
+	* OPERATORS/op-fil-cm.cc: Likewise.
+	* OPERATORS/op-fil-cs.cc: Likewise.
+	* OPERATORS/op-fil-lis.cc: Likewise.
+	* OPERATORS/op-fil-m.cc: Likewise.
+	* OPERATORS/op-fil-rec.cc: Likewise.
+	* OPERATORS/op-fil-s.cc: Likewise.
+	* OPERATORS/op-fil-str.cc: Likewise.
+	* file-io.cc: Likewise.
+	* syscalls.cc (Fdup): Likewise.
+
+	* oct-fstrm.cc, oct-fstrm.h, oct-iostrm.cc, oct-iostrm.h,
+	oct-prcstrm.cc, oct-prcstrm.h, oct-stdstrm.cc, oct-stdstrm.h,
+	oct-stream.cc, oct-stream.h, oct-strstrm.cc, oct-strstrm.h:
+	Rewrite to allow octave_stream objects to be used like values
+	instead of having to use pointers.
+
 1999-11-03  John W. Eaton  <jwe@bevo.che.wisc.edu>
 
 	* oct-stream.cc (octave_base_stream::do_scanf): If it looks like
--- a/src/OPERATORS/op-fil-b.cc	Thu Nov 04 16:24:31 1999 +0000
+++ b/src/OPERATORS/op-fil-b.cc	Fri Nov 05 07:02:36 1999 +0000
@@ -46,11 +46,11 @@
 {
   CAST_BINOP_ARGS (const octave_file&, const octave_bool&);
 
-  octave_stream *oct_stream = v1.stream_value ();
+  octave_stream oct_stream = v1.stream_value ();
 
   if (oct_stream)
     {
-      ostream *osp = oct_stream->output_stream ();
+      ostream *osp = oct_stream.output_stream ();
 
       if (osp)
 	{
--- a/src/OPERATORS/op-fil-bm.cc	Thu Nov 04 16:24:31 1999 +0000
+++ b/src/OPERATORS/op-fil-bm.cc	Fri Nov 05 07:02:36 1999 +0000
@@ -46,11 +46,11 @@
 {
   CAST_BINOP_ARGS (const octave_file&, const octave_bool_matrix&);
 
-  octave_stream *oct_stream = v1.stream_value ();
+  octave_stream oct_stream = v1.stream_value ();
 
   if (oct_stream)
     {
-      ostream *osp = oct_stream->output_stream ();
+      ostream *osp = oct_stream.output_stream ();
 
       if (osp)
 	{
--- a/src/OPERATORS/op-fil-cm.cc	Thu Nov 04 16:24:31 1999 +0000
+++ b/src/OPERATORS/op-fil-cm.cc	Fri Nov 05 07:02:36 1999 +0000
@@ -46,11 +46,11 @@
 {
   CAST_BINOP_ARGS (const octave_file&, const octave_complex_matrix&);
 
-  octave_stream *oct_stream = v1.stream_value ();
+  octave_stream oct_stream = v1.stream_value ();
 
   if (oct_stream)
     {
-      ostream *osp = oct_stream->output_stream ();
+      ostream *osp = oct_stream.output_stream ();
 
       if (osp)
 	{
--- a/src/OPERATORS/op-fil-cs.cc	Thu Nov 04 16:24:31 1999 +0000
+++ b/src/OPERATORS/op-fil-cs.cc	Fri Nov 05 07:02:36 1999 +0000
@@ -46,11 +46,11 @@
 {
   CAST_BINOP_ARGS (const octave_file&, const octave_complex&);
 
-  octave_stream *oct_stream = v1.stream_value ();
+  octave_stream oct_stream = v1.stream_value ();
 
   if (oct_stream)
     {
-      ostream *osp = oct_stream->output_stream ();
+      ostream *osp = oct_stream.output_stream ();
 
       if (osp)
 	{
--- a/src/OPERATORS/op-fil-lis.cc	Thu Nov 04 16:24:31 1999 +0000
+++ b/src/OPERATORS/op-fil-lis.cc	Fri Nov 05 07:02:36 1999 +0000
@@ -46,11 +46,11 @@
 {
   CAST_BINOP_ARGS (const octave_file&, const octave_list&);
 
-  octave_stream *oct_stream = v1.stream_value ();
+  octave_stream oct_stream = v1.stream_value ();
 
   if (oct_stream)
     {
-      ostream *osp = oct_stream->output_stream ();
+      ostream *osp = oct_stream.output_stream ();
 
       if (osp)
 	{
--- a/src/OPERATORS/op-fil-m.cc	Thu Nov 04 16:24:31 1999 +0000
+++ b/src/OPERATORS/op-fil-m.cc	Fri Nov 05 07:02:36 1999 +0000
@@ -46,11 +46,11 @@
 {
   CAST_BINOP_ARGS (const octave_file&, const octave_matrix&);
 
-  octave_stream *oct_stream = v1.stream_value ();
+  octave_stream oct_stream = v1.stream_value ();
 
   if (oct_stream)
     {
-      ostream *osp = oct_stream->output_stream ();
+      ostream *osp = oct_stream.output_stream ();
 
       if (osp)
 	{
--- a/src/OPERATORS/op-fil-rec.cc	Thu Nov 04 16:24:31 1999 +0000
+++ b/src/OPERATORS/op-fil-rec.cc	Fri Nov 05 07:02:36 1999 +0000
@@ -46,11 +46,11 @@
 {
   CAST_BINOP_ARGS (const octave_file&, const octave_struct&);
 
-  octave_stream *oct_stream = v1.stream_value ();
+  octave_stream oct_stream = v1.stream_value ();
 
   if (oct_stream)
     {
-      ostream *osp = oct_stream->output_stream ();
+      ostream *osp = oct_stream.output_stream ();
 
       if (osp)
 	{
--- a/src/OPERATORS/op-fil-s.cc	Thu Nov 04 16:24:31 1999 +0000
+++ b/src/OPERATORS/op-fil-s.cc	Fri Nov 05 07:02:36 1999 +0000
@@ -46,11 +46,11 @@
 {
   CAST_BINOP_ARGS (const octave_file&, const octave_scalar&);
 
-  octave_stream *oct_stream = v1.stream_value ();
+  octave_stream oct_stream = v1.stream_value ();
 
   if (oct_stream)
     {
-      ostream *osp = oct_stream->output_stream ();
+      ostream *osp = oct_stream.output_stream ();
 
       if (osp)
 	{
--- a/src/OPERATORS/op-fil-str.cc	Thu Nov 04 16:24:31 1999 +0000
+++ b/src/OPERATORS/op-fil-str.cc	Fri Nov 05 07:02:36 1999 +0000
@@ -46,11 +46,11 @@
 {
   CAST_BINOP_ARGS (const octave_file&, const octave_char_matrix_str&);
 
-  octave_stream *oct_stream = v1.stream_value ();
+  octave_stream oct_stream = v1.stream_value ();
 
   if (oct_stream)
     {
-      ostream *osp = oct_stream->output_stream ();
+      ostream *osp = oct_stream.output_stream ();
 
       if (osp)
 	{
--- a/src/TEMPLATE-INST/Array-os.cc	Thu Nov 04 16:24:31 1999 +0000
+++ b/src/TEMPLATE-INST/Array-os.cc	Fri Nov 05 07:02:36 1999 +0000
@@ -35,7 +35,7 @@
 
 template class Array<printf_format_elt*>;
 
-template class Array<octave_stream*>;
+template class Array<octave_stream>;
 
 /*
 ;;; Local Variables: ***
--- a/src/file-io.cc	Thu Nov 04 16:24:31 1999 +0000
+++ b/src/file-io.cc	Fri Nov 05 07:02:36 1999 +0000
@@ -73,17 +73,15 @@
 void
 initialize_file_io (void)
 {
-  octave_istream *stdin_stream
-    = new octave_istream (&cin, "stdin");
+  octave_stream stdin_stream = octave_istream::create (&cin, "stdin");
 
   // This uses octave_stdout (see pager.h), not cout so that Octave's
   // standard output stream will pass through the pager.
 
-  octave_ostream *stdout_stream
-    = new octave_ostream (&octave_stdout, "stdout");
+  octave_stream stdout_stream
+    = octave_ostream::create (&octave_stdout, "stdout");
 
-  octave_ostream *stderr_stream
-    = new octave_ostream (&cerr, "stderr");
+  octave_stream stderr_stream = octave_ostream::create (&cerr, "stderr");
 
   stdin_file = octave_stream_list::insert (stdin_stream);
   stdout_file = octave_stream_list::insert (stdout_stream);
@@ -142,6 +140,19 @@
   return retval;
 }
 
+DEFUN (is_stream, args, ,
+  "is_stream (x): return nonzero if x is a stream object")
+{
+  octave_value retval;
+
+  if (args.length () == 1)
+    retval = args(0).is_stream ();
+  else
+    print_usage ("is_stream");
+
+  return retval;
+}
+
 DEFUN (fclose, args, ,
   "fclose (FILENUM): close a file")
 {
@@ -183,10 +194,10 @@
 	}
       else
 	{
-	  octave_stream *os = octave_stream_list::lookup (fid);
+	  octave_stream os = octave_stream_list::lookup (fid);
 
-	  if (os)
-	    retval = static_cast<double> (os->flush ());
+	  if (os.is_valid ())
+	    retval = static_cast<double> (os.flush ());
 	  else
 	    gripe_invalid_file_id ("fflush");
 	}
@@ -211,16 +222,16 @@
 
   if (nargin == 1 || nargin == 2)
     {
-      octave_stream *os = octave_stream_list::lookup (args(0));
+      octave_stream os = octave_stream_list::lookup (args(0));
 
-      if (os)
+      if (os.is_valid ())
 	{
 	  octave_value len_arg = (nargin == 2)
 	    ? args(1) : octave_value (static_cast<double> (INT_MAX));
 
 	  bool err = false;
 
-	  string tmp = os->getl (len_arg, err);
+	  string tmp = os.getl (len_arg, err);
 
 	  if (! err)
 	    {
@@ -251,16 +262,16 @@
 
   if (nargin == 1 || nargin == 2)
     {
-      octave_stream *os = octave_stream_list::lookup (args(0));
+      octave_stream os = octave_stream_list::lookup (args(0));
 
-      if (os)
+      if (os.is_valid ())
 	{
 	  octave_value len_arg = (nargin == 2)
 	    ? args(1) : octave_value (static_cast<double> (INT_MAX));
 
 	  bool err = false;
 
-	  string tmp = os->gets (len_arg, err);
+	  string tmp = os.gets (len_arg, err);
 
 	  if (! err)
 	    {
@@ -277,11 +288,11 @@
   return retval;
 }
 
-static octave_base_stream *
+static octave_stream
 do_stream_open (const string& name, const string& mode,
 		const string& arch, int& fid)
 {
-  octave_base_stream *retval = 0;
+  octave_stream retval;
 
   fid = -1;
 
@@ -293,17 +304,17 @@
 	oct_mach_info::string_to_float_format (arch);
 
       if (! error_state)
-	retval = new octave_fstream (name, md, flt_fmt);
+	retval = octave_fstream::create (name, md, flt_fmt);
     }
 
   return retval;
 }
 
-static octave_base_stream *
+static octave_stream
 do_stream_open (const octave_value& tc_name, const octave_value& tc_mode,
 		const octave_value& tc_arch, const char *fcn, int& fid)
 {
-  octave_base_stream *retval = 0;
+  octave_stream retval;
 
   fid = -1;
 
@@ -411,12 +422,11 @@
 
       int fid = -1;
 
-      octave_base_stream *os
-	= do_stream_open (args(0), mode, arch, "fopen", fid);
+      octave_stream os = do_stream_open (args(0), mode, arch, "fopen", fid);
 
-      if (os)
+      if (os.is_valid ())
 	{
-	  if (os->ok () && ! error_state)
+	  if (os && ! error_state)
 	    {
 	      retval(1) = "";
 	      retval(0) = octave_stream_list::insert (os);
@@ -425,12 +435,12 @@
 	    {
 	      int error_number = 0;
 
-	      retval(1) = os->error (false, error_number);
+	      retval(1) = os.error (false, error_number);
 	      retval(0) = -1.0;
 	    }
 	}
       else
-	::error ("fopen: internal error");
+	error ("fopen: internal error");
     }
   else
     print_usage ("fopen");
@@ -462,10 +472,10 @@
 
   if (nargin == 1)
     {
-      octave_stream *os = octave_stream_list::lookup (args(0));
+      octave_stream os = octave_stream_list::lookup (args(0));
 
-      if (os)
-	retval = static_cast<double> (os->rewind ());
+      if (os.is_valid ())
+	retval = static_cast<double> (os.rewind ());
       else
 	gripe_invalid_file_id ("frewind");
     }
@@ -492,14 +502,14 @@
 
   if (nargin == 2 || nargin == 3)
     {
-      octave_stream *os = octave_stream_list::lookup (args(0));
+      octave_stream os = octave_stream_list::lookup (args(0));
 
-      if (os)
+      if (os.is_valid ())
 	{
 	  octave_value origin_arg = (nargin == 3)
 	    ? args(2) : octave_value (-1.0);
 
-	  retval = static_cast<double> (os->seek (args(1), origin_arg));
+	  retval = static_cast<double> (os.seek (args(1), origin_arg));
 	}
       else
 	::error ("fseek: invalid file id");
@@ -519,10 +529,10 @@
 
   if (nargin == 1)
     {
-      octave_stream *os = octave_stream_list::lookup (args(0));
+      octave_stream os = octave_stream_list::lookup (args(0));
 
-      if (os)
-	retval = static_cast<double> (os->tell ());
+      if (os.is_valid ())
+	retval = static_cast<double> (os.tell ());
       else
 	gripe_invalid_file_id ("ftell");
     }
@@ -541,7 +551,7 @@
 
   if (nargin > 1 || (nargin > 0 && args(0).is_string ()))
     {
-      octave_stream *os	= 0;
+      octave_stream os;
       int fmt_n = 0;
 
       if (args(0).is_string ())
@@ -552,7 +562,7 @@
 	  os = octave_stream_list::lookup (args(0));
 	}
 
-      if (os)
+      if (os.is_valid ())
 	{
 	  if (args(fmt_n).is_string ())
 	    {
@@ -568,7 +578,7 @@
 		    tmp_args(i-fmt_n-1) = args(i);
 		}
 
-	      retval = os->printf (fmt, tmp_args);
+	      retval = os.printf (fmt, tmp_args);
 	    }
 	  else
 	    ::error ("fprintf: format must be a string");
@@ -591,10 +601,10 @@
 
   if (nargin == 2)
     {
-      octave_stream *os = octave_stream_list::lookup (args(0));
+      octave_stream os = octave_stream_list::lookup (args(0));
 
-      if (os)
-	retval = os->puts (args(1));
+      if (os.is_valid ())
+	retval = os.puts (args(1));
       else
 	gripe_invalid_file_id ("fputs");
     }
@@ -617,11 +627,11 @@
       retval(1) = "unknown error";
       retval(0) = "";
 
-      octave_ostrstream ostr;
+      octave_ostrstream *ostr = new octave_ostrstream ();
 
-      octave_stream os (&ostr, true);
+      octave_stream os (ostr);
 
-      if (os)
+      if (os.is_valid ())
 	{
 	  if (args(0).is_string ())
 	    {
@@ -639,9 +649,7 @@
 
 	      retval(2) = static_cast<double> (os.printf (fmt, tmp_args));
 	      retval(1) = os.error ();
-	      char *tmp = ostr.str ();
-	      retval(0) = tmp;
-	      delete [] tmp;
+	      retval(0) = ostr->str ();
 	    }
 	  else
 	    ::error ("sprintf: format must be a string");
@@ -684,15 +692,15 @@
 
   if (nargin == 3 && args(2).is_string ())
     {
-      octave_stream *os = octave_stream_list::lookup (args(0));
+      octave_stream os = octave_stream_list::lookup (args(0));
 
-      if (os)
+      if (os.is_valid ())
 	{
 	  if (args(1).is_string ())
 	    {
 	      string fmt = args(1).string_value ();
 
-	      retval = os->oscanf (fmt);
+	      retval = os.oscanf (fmt);
 	    }
 	  else
 	    ::error ("fscanf: format must be a string");
@@ -707,9 +715,9 @@
 
       if (nargin == 2 || nargin == 3)
 	{
-	  octave_stream *os = octave_stream_list::lookup (args(0));
+	  octave_stream os = octave_stream_list::lookup (args(0));
 
-	  if (os)
+	  if (os.is_valid ())
 	    {
 	      if (args(1).is_string ())
 		{
@@ -722,7 +730,7 @@
 
 		  if (! error_state)
 		    {
-		      octave_value tmp = os->scanf (fmt, size, count);
+		      octave_value tmp = os.scanf (fmt, size, count);
 
 		      retval(1) = static_cast<double> (count);
 		      retval(0) = tmp;
@@ -777,11 +785,9 @@
 	{
 	  string data = args(0).string_value ();
 
-	  octave_istrstream istr (data);
+	  octave_stream os = octave_istrstream::create (data);
 
-	  octave_stream os (&istr, true);
-
-	  if (os)
+	  if (os.is_valid ())
 	    {
 	      if (args(1).is_string ())
 		{
@@ -811,11 +817,9 @@
 	    {
 	      string data = args(0).string_value ();
 
-	      octave_istrstream istr (data);
+	      octave_stream os = octave_istrstream::create (data);
 
-	      octave_stream os (&istr, true);
-
-	      if (os)
+	      if (os.is_valid ())
 		{
 		  if (args(1).is_string ())
 		    {
@@ -979,9 +983,9 @@
       retval(1) = -1.0;
       retval(0) = Matrix ();
 
-      octave_stream *os = octave_stream_list::lookup (args(0));
+      octave_stream os = octave_stream_list::lookup (args(0));
 
-      if (os)
+      if (os.is_valid ())
 	{
 	  octave_value size = (nargin > 1)
 	    ? args(1) : octave_value (octave_Inf);
@@ -997,7 +1001,7 @@
 
 	  int count = -1;
 
-	  octave_value tmp = do_fread (*os, size, prec, skip, arch, count);
+	  octave_value tmp = do_fread (os, size, prec, skip, arch, count);
 
 	  retval(1) = static_cast<double> (count);
 	  retval(0) = tmp;
@@ -1107,9 +1111,9 @@
 
   if (nargin > 1 && nargin < 6)
     {
-      octave_stream *os = octave_stream_list::lookup (args(0));
+      octave_stream os = octave_stream_list::lookup (args(0));
 
-      if (os)
+      if (os.is_valid ())
 	{
 	  octave_value data = args(1);
 
@@ -1122,7 +1126,7 @@
 	  octave_value arch = (nargin > 4)
 	    ? args(4) : octave_value ("unknown");
 
-	  double status = do_fwrite (*os, data, prec, skip, arch);
+	  double status = do_fwrite (os, data, prec, skip, arch);
 
 	  retval = status;
 	}
@@ -1147,10 +1151,10 @@
 
   if (nargin == 1)
     {
-      octave_stream *os = octave_stream_list::lookup (args(0));
+      octave_stream os = octave_stream_list::lookup (args(0));
 
-      if (os)
-	retval = os->eof () ? 1.0 : 0.0;
+      if (os.is_valid ())
+	retval = os.eof () ? 1.0 : 0.0;
       else
 	gripe_invalid_file_id ("feof");
     }
@@ -1172,9 +1176,9 @@
 
   if (nargin == 1 || nargin == 2)
     {
-      octave_stream *os = octave_stream_list::lookup (args(0));
+      octave_stream os = octave_stream_list::lookup (args(0));
 
-      if (os)
+      if (os.is_valid ())
 	{
 	  bool clear = false;
 
@@ -1190,7 +1194,7 @@
 
 	  int error_number = 0;
 
-	  string error_message = os->error (clear, error_number);
+	  string error_message = os.error (clear, error_number);
 
 	  retval(1) = static_cast<double> (error_number);
 	  retval(0) = error_message;
@@ -1253,13 +1257,13 @@
 	    {
 	      if (mode == "r")
 		{
-		  octave_iprocstream *ips = new octave_iprocstream (name);
+		  octave_stream ips = octave_iprocstream::create (name);
 
 		  retval = octave_stream_list::insert (ips);
 		}
 	      else if (mode == "w")
 		{
-		  octave_oprocstream *ops = new octave_oprocstream (name);
+		  octave_stream ops = octave_oprocstream::create (name);
 
 		  retval = octave_stream_list::insert (ops);
 		}
--- a/src/oct-fstrm.cc	Thu Nov 04 16:24:31 1999 +0000
+++ b/src/oct-fstrm.cc	Fri Nov 05 07:02:36 1999 +0000
@@ -30,6 +30,13 @@
 #include "error.h"
 #include "oct-fstrm.h"
 
+octave_stream
+octave_fstream::create (const string& nm_arg, ios::openmode md,
+			oct_mach_info::float_format flt_fmt)
+{
+  return octave_stream (new octave_fstream (nm_arg, md, flt_fmt));
+}
+
 octave_fstream::octave_fstream (const string& nm_arg,
 				ios::openmode md = ios::in|ios::out,
 				oct_mach_info::float_format flt_fmt)
@@ -91,14 +98,6 @@
   return fs.eof ();
 }
 
-// The name of the file.
-
-string
-octave_fstream::name (void)
-{
-  return nm;
-}
-
 istream *
 octave_fstream::input_stream (void)
 {
--- a/src/oct-fstrm.h	Thu Nov 04 16:24:31 1999 +0000
+++ b/src/oct-fstrm.h	Fri Nov 05 07:02:36 1999 +0000
@@ -37,7 +37,9 @@
 		  oct_mach_info::float_format flt_fmt =
 		  oct_mach_info::native);
 
-  ~octave_fstream (void) { }
+  static octave_stream
+  create (const string& nm_arg, ios::openmode md = ios::in|ios::out,
+	  oct_mach_info::float_format flt_fmt = oct_mach_info::native);
 
   // Position a stream at OFFSET relative to ORIGIN.
 
@@ -53,12 +55,16 @@
 
   // The name of the file.
 
-  string name (void);
+  string name (void) const { return nm; }
 
   istream *input_stream (void);
 
   ostream *output_stream (void);
 
+protected:
+
+  ~octave_fstream (void) { }
+
 private:
 
   string nm;
--- a/src/oct-iostrm.cc	Thu Nov 04 16:24:31 1999 +0000
+++ b/src/oct-iostrm.cc	Fri Nov 05 07:02:36 1999 +0000
@@ -54,20 +54,24 @@
   return false;
 }
 
-// The name of the file.
-
-string
-octave_base_iostream::name (void)
-{
-  return nm;
-}
-
 void
 octave_base_iostream::invalid_operation (void) const
 {
   ::error ("%s: invalid operation", stream_type ());
 }
 
+octave_stream
+octave_istream::create (istream *arg, const string& nm)
+{
+  return octave_stream (new octave_istream (arg, nm));
+}
+
+octave_stream
+octave_ostream::create (ostream *arg, const string& nm)
+{
+  return octave_stream (new octave_ostream (arg, nm));
+}
+
 /*
 ;;; Local Variables: ***
 ;;; mode: C++ ***
--- a/src/oct-iostrm.h	Thu Nov 04 16:24:31 1999 +0000
+++ b/src/oct-iostrm.h	Fri Nov 05 07:02:36 1999 +0000
@@ -41,8 +41,6 @@
 			oct_mach_info::native)
     : octave_base_stream (md, flt_fmt), nm (n) { }
 
-  ~octave_base_iostream (void) { }
-
   // Position a stream at OFFSET relative to ORIGIN.
 
   int seek (streamoff offset, ios::seek_dir origin);
@@ -57,10 +55,12 @@
 
   // The name of the file.
 
-  string name (void);
+  string name (void) const { return nm; }
 
 protected:
 
+  ~octave_base_iostream (void) { }
+
   void invalid_operation (void) const;
 
 private:
@@ -85,12 +85,17 @@
     : octave_base_iostream (nm, ios::in, oct_mach_info::native),
       is (arg) { }
 
-  ~octave_istream (void) { }
+  static octave_stream
+  create (istream *arg = 0, const string& nm = string ());
 
   istream *input_stream (void) { return is; }
 
   ostream *output_stream (void) { return 0; }
 
+protected:
+
+  ~octave_istream (void) { }
+
 private:
 
   istream *is;
@@ -113,12 +118,17 @@
     : octave_base_iostream (nm, ios::out, oct_mach_info::native),
       os (arg) { }
 
-  ~octave_ostream (void) { }
+  static octave_stream
+  create (ostream *arg, const string& nm = string ());
 
   istream *input_stream (void) { return 0; }
 
   ostream *output_stream (void) { return os; }
 
+protected:
+
+  ~octave_ostream (void) { }
+
 private:
 
   ostream *os;
--- a/src/oct-prcstrm.cc	Thu Nov 04 16:24:31 1999 +0000
+++ b/src/oct-prcstrm.cc	Fri Nov 05 07:02:36 1999 +0000
@@ -28,6 +28,13 @@
 
 #include "oct-prcstrm.h"
 
+octave_stream
+octave_iprocstream::create (const string& n, ios::openmode arg_md,
+			    oct_mach_info::float_format flt_fmt)
+{
+  return octave_stream (new octave_iprocstream (n, arg_md, flt_fmt));
+}
+
 octave_iprocstream::octave_iprocstream (const string& n,
 					ios::openmode arg_md,
 					oct_mach_info::float_format flt_fmt)
@@ -51,6 +58,13 @@
     }
 }
 
+octave_stream
+octave_oprocstream::create (const string& n, ios::openmode arg_md,
+			    oct_mach_info::float_format flt_fmt)
+{
+  return octave_stream (new octave_oprocstream (n, arg_md, flt_fmt));
+}
+
 octave_oprocstream::octave_oprocstream (const string& n,
 					ios::openmode arg_md,
 					oct_mach_info::float_format flt_fmt)
--- a/src/oct-prcstrm.h	Thu Nov 04 16:24:31 1999 +0000
+++ b/src/oct-prcstrm.h	Fri Nov 05 07:02:36 1999 +0000
@@ -35,6 +35,12 @@
 		      oct_mach_info::float_format flt_fmt =
 		      oct_mach_info::native);
 
+  static octave_stream
+  create (const string& n, ios::openmode arg_md = ios::in,
+	  oct_mach_info::float_format flt_fmt = oct_mach_info::native);
+
+protected:
+
   ~octave_iprocstream (void);
 
 private:
@@ -56,6 +62,12 @@
 		      oct_mach_info::float_format flt_fmt =
 		      oct_mach_info::native);
 
+  static octave_stream
+  create (const string& n, ios::openmode arg_md = ios::out,
+	  oct_mach_info::float_format flt_fmt = oct_mach_info::native);
+
+protected:
+
   ~octave_oprocstream (void);
 
 private:
--- a/src/oct-stdstrm.cc	Thu Nov 04 16:24:31 1999 +0000
+++ b/src/oct-stdstrm.cc	Fri Nov 05 07:02:36 1999 +0000
@@ -83,6 +83,14 @@
   return retval;
 }
 
+octave_stream
+octave_istdiostream::create (const string& n, FILE *f,
+			     ios::openmode arg_md,
+			     oct_mach_info::float_format flt_fmt)
+{
+  return octave_stream (new octave_istdiostream (n, f, arg_md, flt_fmt));
+}
+
 octave_istdiostream::octave_istdiostream (const string& n, FILE *f,
 					  ios::openmode arg_md,
 					  oct_mach_info::float_format flt_fmt)
@@ -97,6 +105,14 @@
   delete is;
 }
 
+octave_stream
+octave_ostdiostream::create (const string& n, FILE *f,
+			     ios::openmode arg_md,
+			     oct_mach_info::float_format flt_fmt)
+{
+  return octave_stream (new octave_ostdiostream (n, f, arg_md, flt_fmt));
+}
+
 octave_ostdiostream::octave_ostdiostream (const string& n, FILE *f,
 					  ios::openmode arg_md,
 					  oct_mach_info::float_format flt_fmt)
--- a/src/oct-stdstrm.h	Thu Nov 04 16:24:31 1999 +0000
+++ b/src/oct-stdstrm.h	Fri Nov 05 07:02:36 1999 +0000
@@ -38,8 +38,6 @@
 			   oct_mach_info::native)
     : octave_base_stream (arg_md, flt_fmt), nm (n), fp (f) { }
 
-  ~octave_base_stdiostream (void);
-
   // Position a stream at OFFSET relative to ORIGIN.
 
   int seek (streamoff offset, ios::seek_dir origin);
@@ -50,7 +48,7 @@
 
   // The name of the file.
 
-  string name (void) { return nm; }
+  string name (void) const { return nm; }
 
   virtual stdiobuf *rdbuf (void) const = 0;
 
@@ -64,6 +62,8 @@
 
   FILE *fp;
 
+  ~octave_base_stdiostream (void);
+
   // No copying!
 
   octave_base_stdiostream (const octave_base_stdiostream&);
@@ -81,7 +81,9 @@
 		       oct_mach_info::float_format flt_fmt =
 		       oct_mach_info::native);
 
-  ~octave_istdiostream (void);
+  static octave_stream
+  create (const string& n, FILE *f = 0, ios::openmode arg_md = ios::in,
+	  oct_mach_info::float_format flt_fmt = oct_mach_info::native);
 
   // Return non-zero if EOF has been reached on this stream.
 
@@ -107,6 +109,8 @@
 
   istdiostream *is;
 
+  ~octave_istdiostream (void);
+
 private:
 
   // No copying!
@@ -126,7 +130,9 @@
 		       oct_mach_info::float_format flt_fmt =
 		       oct_mach_info::native);
 
-  ~octave_ostdiostream (void);
+  static octave_stream
+  create (const string& n, FILE *f = 0, ios::openmode arg_md = ios::out,
+	  oct_mach_info::float_format flt_fmt = oct_mach_info::native);
 
   // Return non-zero if EOF has been reached on this stream.
 
@@ -152,6 +158,8 @@
 
   ostdiostream *os;
 
+  ~octave_ostdiostream (void);
+
 private:
 
   // No copying!
--- a/src/oct-stream.cc	Thu Nov 04 16:24:31 1999 +0000
+++ b/src/oct-stream.cc	Fri Nov 05 07:02:36 1999 +0000
@@ -210,7 +210,7 @@
 
   for (int i = 0; i < n; i++)
     {
-      scanf_format_elt *elt = list (i);
+      scanf_format_elt *elt = list(i);
       delete elt;
     }	
 }
@@ -235,7 +235,7 @@
 	      if (num_elts == list.length ())
 		list.resize (2 * num_elts);
 
-	      list (num_elts++) = elt;
+	      list(num_elts++) = elt;
 	    }
 	  else
 	    delete [] text;
@@ -405,7 +405,7 @@
 
   for (int i = 0; i < n; i++)
     {
-      scanf_format_elt *elt = list (i);
+      scanf_format_elt *elt = list(i);
 
       cerr << elt->width << "\t"
 	   << elt->discard << "\t"
@@ -424,7 +424,7 @@
     {
       for (int i = 0; i < n; i++)
 	{
-	  scanf_format_elt *elt = list (i);
+	  scanf_format_elt *elt = list(i);
 
 	  switch (elt->type)
 	    {
@@ -452,7 +452,7 @@
     {
       for (int i = 0; i < n; i++)
 	{
-	  scanf_format_elt *elt = list (i);
+	  scanf_format_elt *elt = list(i);
 
 	  switch (elt->type)
 	    {
@@ -532,7 +532,7 @@
 
   for (int i = 0; i < n; i++)
     {
-      printf_format_elt *elt = list (i);
+      printf_format_elt *elt = list(i);
       delete elt;
     }	
 }
@@ -557,7 +557,7 @@
 	      if (num_elts == list.length ())
 		list.resize (2 * num_elts);
 
-	      list (num_elts++) = elt;
+	      list(num_elts++) = elt;
 	    }
 	  else
 	    delete [] text;
@@ -716,7 +716,7 @@
 
   for (int i = 0; i < n; i++)
     {
-      printf_format_elt *elt = list (i);
+      printf_format_elt *elt = list(i);
 
       cerr << elt->args<< "\t"
 	   << elt->type << "\t"
@@ -2178,6 +2178,43 @@
   error (msg);
 }
 
+octave_stream::octave_stream (octave_base_stream *bs = 0)
+  : rep (bs)
+{
+  if (rep)
+    rep->count = 1;
+}
+
+octave_stream::~octave_stream (void)
+{
+  if (rep && --rep->count == 0)
+    delete rep;
+}
+
+octave_stream::octave_stream (const octave_stream& s)
+  : rep (s.rep)
+{
+  if (rep)
+    rep->count++;
+}
+
+octave_stream&
+octave_stream::operator = (const octave_stream& s)
+{
+  if (rep != s.rep)
+    {
+      if (rep && --rep->count == 0)
+	delete rep;
+
+      rep = s.rep;
+
+      if (rep)
+	rep->count++;
+    }
+
+  return *this;
+}
+
 int
 octave_stream::flush (void)
 {
@@ -2343,6 +2380,24 @@
   return retval;
 }
 
+bool
+octave_stream::is_open (void) const
+{
+  bool retval = false;
+
+  if (stream_ok ("is_open"))
+    retval = rep->is_open ();
+
+  return retval;
+}
+
+void
+octave_stream::close (void)
+{
+  if (stream_ok ("close"))
+    rep->close ();
+}
+
 octave_value
 octave_stream::read (const Matrix& size,
 		     oct_data_conv::data_type dt, int skip,
@@ -2454,7 +2509,7 @@
 }
 
 string
-octave_stream::name (void)
+octave_stream::name (void) const
 {
   string retval;
 
@@ -2465,7 +2520,7 @@
 }
 
 int
-octave_stream::mode (void)
+octave_stream::mode (void) const
 {
   int retval = 0;
 
@@ -2476,7 +2531,7 @@
 }
 
 oct_mach_info::float_format
-octave_stream::float_format (void)
+octave_stream::float_format (void) const
 {
   oct_mach_info::float_format retval = oct_mach_info::unknown;
 
@@ -2577,21 +2632,21 @@
 }
 
 octave_value
-octave_stream_list::insert (octave_base_stream *obs)
+octave_stream_list::insert (const octave_stream& os)
 {
-  return (instance_ok ()) ? instance->do_insert (obs) : octave_value (-1.0);
+  return (instance_ok ()) ? instance->do_insert (os) : octave_value (-1.0);
 }
 
-octave_stream *
+octave_stream
 octave_stream_list::lookup (int fid)
 {
-  return (instance_ok ()) ? instance->do_lookup (fid) : 0;
+  return (instance_ok ()) ? instance->do_lookup (fid) : octave_stream ();
 }
 
-octave_stream *
+octave_stream
 octave_stream_list::lookup (const octave_value& fid)
 {
-  return (instance_ok ()) ? instance->do_lookup (fid) : 0;
+  return (instance_ok ()) ? instance->do_lookup (fid) : octave_stream ();
 }
 
 int
@@ -2645,64 +2700,57 @@
 }
 
 octave_value
-octave_stream_list::do_insert (octave_base_stream *obs)
+octave_stream_list::do_insert (const octave_stream& os)
 {
+  octave_value retval;
+
   int stream_number = -1;
 
-  octave_stream *os = 0;
-
-  if (obs)
+  // Insert item in first open slot, increasing size of list if
+  // necessary.
+
+  for (int i = 0; i < curr_len; i++)
     {
-      os = new octave_stream (obs);
-
-      // Insert item in first open slot, increasing size of list if
-      // necessary.
-
-      for (int i = 0; i < curr_len; i++)
+      octave_stream tmp = list(i);
+
+      if (! tmp)
 	{
-	  octave_stream *tmp = list (i);
-
-	  if (! tmp)
-	    {
-	      list (i) = os;
-	      stream_number = i;
-	      break;
-	    }
-	}
-
-      if (stream_number < 0)
-	{
-	  int total_len = list.length ();
-
-	  if (curr_len == total_len)
-	    list.resize (total_len * 2);
-
-	  list (curr_len) = os;
-	  stream_number = curr_len;
-	  curr_len++;
+	  list(i) = os;
+	  stream_number = i;
+	  break;
 	}
     }
-  else
-    ::error ("octave_stream_list: attempt to insert invalid stream");
+
+  if (stream_number < 0)
+    {
+      int total_len = list.length ();
+
+      if (curr_len == total_len)
+	list.resize (total_len * 2);
+
+      list(curr_len) = os;
+      stream_number = curr_len;
+      curr_len++;
+    }
 
   return octave_value (os, stream_number);
 }
 
-octave_stream *
+octave_stream
 octave_stream_list::do_lookup (int fid) const
 {
-  octave_stream *retval = 0;
+  octave_stream retval;
 
   if (fid >= 0 && fid < curr_len)
-    retval = list (fid);
+    retval = list(fid);
 
   return retval;
 }
 
-octave_stream *
+octave_stream
 octave_stream_list::do_lookup (const octave_value& fid) const
 {
-  octave_stream *retval = 0;
+  octave_stream retval;
 
   int i = get_file_number (fid);
 
@@ -2721,12 +2769,12 @@
 
   if (fid > 2 && fid < curr_len)
     {
-      octave_stream *os = list (fid);
+      octave_stream os = list(fid);
 
       if (os)
 	{
-	  delete os;
-	  list (fid) = 0;
+	  os.close ();
+	  list(fid) = octave_stream ();
 	  retval = 0;
 	}
     }
@@ -2752,19 +2800,13 @@
 {
   // Do flush stdout and stderr.
 
-  list (0) -> flush ();
-  list (1) -> flush ();
+  list(0) . flush ();
+  list(1) . flush ();
 
   // But don't delete them or stdin.
 
   for (int i = 3; i < curr_len; i++)
-    {
-      octave_stream *os = list (i);
-
-      delete os;
-
-      list (i) = 0;
-    }
+    list(i) = octave_stream ();
 }
 
 string_vector
@@ -2772,15 +2814,15 @@
 {
   string_vector retval;
 
-  octave_stream *os = do_lookup (fid);
+  octave_stream os = do_lookup (fid);
 
   if (os)
     {
       retval.resize (3);
 
-      retval(0) = os->name ();
-      retval(1) = octave_stream::mode_as_string (os->mode ());
-      retval(2) = oct_mach_info::float_format_as_string (os->float_format ());
+      retval(0) = os.name ();
+      retval(1) = octave_stream::mode_as_string (os.mode ());
+      retval(2) = oct_mach_info::float_format_as_string (os.float_format ());
     }
   else
     ::error ("invalid file id");
@@ -2820,16 +2862,16 @@
 
   for (int i = 0; i < curr_len; i++)
     {
-      octave_stream *os = list (i);
+      octave_stream os = list(i);
 
       if (os)
 	{
-	  string mode = octave_stream::mode_as_string (os->mode ());
+	  string mode = octave_stream::mode_as_string (os.mode ());
 
 	  string arch =
-	    oct_mach_info::float_format_as_string (os->float_format ());
-
-	  string name = os->name ();
+	    oct_mach_info::float_format_as_string (os.float_format ());
+
+	  string name = os.name ();
 
 	  buf << "  "
 	      << setiosflags (ios::right)
@@ -2863,7 +2905,7 @@
 
   for (int i = 3; i < curr_len; i++)
     {
-      if (list (i))
+      if (list(i))
 	retval (0, num_open++) = i;
     }
 
@@ -2885,9 +2927,9 @@
 
       for (int i = 3; i < curr_len; i++)
 	{
-	  octave_stream *os = list (i);
-
-	  if (os && os->name () == nm)
+	  octave_stream os = list(i);
+
+	  if (os && os.name () == nm)
 	    {
 	      retval = i;
 	      break;
--- a/src/oct-stream.h	Thu Nov 04 16:24:31 1999 +0000
+++ b/src/oct-stream.h	Fri Nov 05 07:02:36 1999 +0000
@@ -222,7 +222,8 @@
 
   octave_base_stream (ios::openmode arg_md = ios::in|ios::out,
 		      oct_mach_info::float_format ff = oct_mach_info::native)
-    : md (arg_md), flt_fmt (ff), fail (false) { }
+    : count (0), md (arg_md), flt_fmt (ff), fail (false), open_state (true)
+  { }
 
   virtual ~octave_base_stream (void) { }
 
@@ -237,13 +238,13 @@
 
   virtual long tell (void) const = 0;
 
-  // Return non-zero if EOF has been reached on this stream.
+  // Return TRUE if EOF has been reached on this stream.
 
   virtual bool eof (void) const = 0;
 
   // The name of the file.
 
-  virtual string name (void) = 0;
+  virtual string name (void) const = 0;
 
   // If the derived class provides this function and it returns a
   // pointer to a valid istream, scanf(), read(), getl(), and gets()
@@ -257,6 +258,12 @@
 
   virtual ostream *output_stream (void) { return 0; }
 
+  // Return TRUE if this stream is open.
+
+  bool is_open (void) const { return open_state; }
+
+  void close (void) { open_state = false; }
+
   int file_number (void);
 
   bool ok (void) const { return ! fail; }
@@ -267,9 +274,9 @@
 
 protected:
 
-  int mode (void) { return md; }
+  int mode (void) const { return md; }
 
-  oct_mach_info::float_format float_format (void) { return flt_fmt; }
+  oct_mach_info::float_format float_format (void) const { return flt_fmt; }
 
   // Set current error state and set fail to TRUE.
 
@@ -281,6 +288,9 @@
 
 private:
 
+  // A reference count.
+  int count;
+
   // The permission bits for the file.  Should be some combination of
   // ios::open_mode bits.
   int md;
@@ -291,6 +301,9 @@
   // TRUE if an error has occurred.
   bool fail;
 
+  // TRUE if this stream is open.
+  bool open_state;
+
   // Should contain error message if fail is TRUE.
   string errmsg;
 
@@ -362,14 +375,13 @@
 {
 public:
 
-  octave_stream (octave_base_stream *bs = 0, bool pf = false)
-    : rep (bs), preserve (pf) { }
+  octave_stream (octave_base_stream *bs = 0);
+
+  ~octave_stream (void);
 
-  ~octave_stream (void)
-    {
-      if (! preserve)
-	delete rep;
-    }
+  octave_stream (const octave_stream&);
+
+  octave_stream& operator = (const octave_stream&);
 
   int flush (void);
 
@@ -386,6 +398,10 @@
 
   int rewind (void);
 
+  bool is_open (void) const;
+
+  void close (void);
+
   octave_value read (const Matrix& size, oct_data_conv::data_type dt,
 		     int skip, oct_mach_info::float_format flt_fmt,
 		     int& count);
@@ -414,30 +430,29 @@
 
   int file_number (void) { return rep ? rep->file_number () : -1; }
 
+  bool is_valid (void) const { return (rep != 0); }
+
   bool ok (void) const { return rep && rep->ok (); }
 
   operator bool () const { return ok (); }
 
-  string name (void);
+  string name (void) const;
 
-  int mode (void);
+  int mode (void) const;
 
-  oct_mach_info::float_format float_format (void);
+  oct_mach_info::float_format float_format (void) const;
 
   static string mode_as_string (int mode);
 
-  istream *input_stream (void) { return rep->input_stream (); }
+  istream *input_stream (void) { return rep ? rep->input_stream () : 0; }
 
-  ostream *output_stream (void) { return rep->output_stream (); }
+  ostream *output_stream (void) { return rep ? rep->output_stream () : 0; }
 
 private:
 
   // The actual representation of this stream.
   octave_base_stream *rep;
 
-  // If true, do not delete rep.
-  bool preserve;
-
   void invalid_stream_error (const char *op) const;
 
   bool stream_ok (const char *op, bool clear = true) const
@@ -463,16 +478,6 @@
       if (rep)
 	rep->error (msg);
     }
-
-  // Must create named streams.
-
-  octave_stream (void);
-
-  // No copying!
-
-  octave_stream (const octave_stream&);
-
-  octave_stream& operator = (const octave_stream&);
 };
 
 class
@@ -488,10 +493,10 @@
 
   static bool instance_ok (void);
 
-  static octave_value insert (octave_base_stream *obs);
+  static octave_value insert (const octave_stream& os);
 
-  static octave_stream *lookup (int fid);
-  static octave_stream *lookup (const octave_value& fid);
+  static octave_stream lookup (int fid);
+  static octave_stream lookup (const octave_value& fid);
 
   static int remove (int fid);
   static int remove (const octave_value& fid);
@@ -509,16 +514,16 @@
 
 private:
 
-  Array<octave_stream*> list;
+  Array<octave_stream> list;
 
   int curr_len;
 
   static octave_stream_list *instance;
 
-  octave_value do_insert (octave_base_stream *obs);
+  octave_value do_insert (const octave_stream& os);
 
-  octave_stream *do_lookup (int fid) const;
-  octave_stream *do_lookup (const octave_value& fid) const;
+  octave_stream do_lookup (int fid) const;
+  octave_stream do_lookup (const octave_value& fid) const;
 
   int do_remove (int fid);
   int do_remove (const octave_value& fid);
--- a/src/oct-strstrm.cc	Thu Nov 04 16:24:31 1999 +0000
+++ b/src/oct-strstrm.cc	Fri Nov 05 07:02:36 1999 +0000
@@ -74,6 +74,27 @@
   return retval;
 }
 
+octave_stream
+octave_istrstream::create (const char *data, ios::openmode arg_md,
+			   oct_mach_info::float_format flt_fmt)
+{
+  return octave_stream (new octave_istrstream (data, arg_md, flt_fmt));
+}
+
+octave_stream
+octave_istrstream::create (const string& data, ios::openmode arg_md,
+			   oct_mach_info::float_format flt_fmt)
+{
+  return octave_stream (new octave_istrstream (data, arg_md, flt_fmt));
+}
+
+octave_stream
+octave_ostrstream::create (ios::openmode arg_md,
+			   oct_mach_info::float_format flt_fmt)
+{
+  return octave_stream (new octave_ostrstream (arg_md, flt_fmt));
+}
+
 /*
 ;;; Local Variables: ***
 ;;; mode: C++ ***
--- a/src/oct-strstrm.h	Thu Nov 04 16:24:31 1999 +0000
+++ b/src/oct-strstrm.h	Fri Nov 05 07:02:36 1999 +0000
@@ -39,8 +39,6 @@
 			 oct_mach_info::native)
     : octave_base_stream (arg_md, flt_fmt) { }
 
-  ~octave_base_strstream (void) { }
-
   // Position a stream at OFFSET relative to ORIGIN.
 
   int seek (streamoff offset, ios::seek_dir origin);
@@ -51,7 +49,7 @@
 
   // The name of the file.
 
-  string name (void) { return string (); }
+  string name (void) const { return string (); }
 
   virtual streambuf *rdbuf (void) = 0;
 
@@ -59,6 +57,10 @@
 
   virtual void clear (void) = 0;
 
+protected:
+
+  ~octave_base_strstream (void) { }
+
 private:
 
   // No copying!
@@ -85,7 +87,13 @@
 		     oct_mach_info::native)
     : octave_base_strstream (arg_md, flt_fmt), is (data.c_str ()) { }
 
-  ~octave_istrstream (void) { }
+  static octave_stream
+  create (const char *data, ios::openmode arg_md = ios::out,
+	  oct_mach_info::float_format flt_fmt = oct_mach_info::native);
+
+  static octave_stream
+  create (const string& data, ios::openmode arg_md = ios::out,
+	  oct_mach_info::float_format flt_fmt = oct_mach_info::native);
 
   // Return non-zero if EOF has been reached on this stream.
 
@@ -101,6 +109,10 @@
 
   void clear (void) { is.clear (); }
 
+protected:
+
+  ~octave_istrstream (void) { }
+
 private:
 
   istrstream is;
@@ -122,7 +134,9 @@
 		     oct_mach_info::native)
     : octave_base_strstream (arg_md, flt_fmt) { }
 
-  ~octave_ostrstream (void) { }
+  static octave_stream
+  create (ios::openmode arg_md = ios::out,
+	  oct_mach_info::float_format flt_fmt = oct_mach_info::native);
 
   // Return non-zero if EOF has been reached on this stream.
 
@@ -132,10 +146,13 @@
 
   ostream *output_stream (void) { return &os; }
 
-  char *str (void)
+  string str (void)
     {
       os << ends;
-      return os.str ();
+      char *tmp = os.str ();
+      string retval = tmp;
+      delete [] tmp;
+      return retval;
     }
 
   streambuf *rdbuf (void) { return os ? os.rdbuf () : 0; }
@@ -144,6 +161,10 @@
 
   void clear (void) { os.clear (); }
 
+protected:
+
+  ~octave_ostrstream (void) { }
+
 private:
 
   ostrstream os;
--- a/src/ov-base.cc	Thu Nov 04 16:24:31 1999 +0000
+++ b/src/ov-base.cc	Fri Nov 05 07:02:36 1999 +0000
@@ -36,6 +36,7 @@
 #include "oct-map.h"
 #include "oct-obj.h"
 #include "oct-lvalue.h"
+#include "oct-stream.h"
 #include "ops.h"
 #include "ov-base.h"
 #include "ov-scalar.h"
@@ -261,10 +262,10 @@
   return retval;
 }
 
-octave_stream *
+octave_stream
 octave_base_value::stream_value (void) const
 {
-  octave_stream *retval = 0;
+  octave_stream retval;
   gripe_wrong_type_arg ("octave_base_value::stream_value()", type_name ());
   return retval;
 }
--- a/src/ov-base.h	Thu Nov 04 16:24:31 1999 +0000
+++ b/src/ov-base.h	Fri Nov 05 07:02:36 1999 +0000
@@ -108,7 +108,7 @@
 
   bool is_map (void) const { return false; }
 
-  bool is_file (void) const { return false; }
+  bool is_stream (void) const { return false; }
 
   bool is_list (void) const { return false; }
 
@@ -179,7 +179,7 @@
 
   Octave_map map_value (void) const;
 
-  octave_stream *stream_value (void) const;
+  octave_stream stream_value (void) const;
 
   int stream_number (void) const;
 
--- a/src/ov-file.cc	Thu Nov 04 16:24:31 1999 +0000
+++ b/src/ov-file.cc	Fri Nov 05 07:02:36 1999 +0000
@@ -70,15 +70,17 @@
     {
       increment_indent_level ();
 
-      string name = stream->name ();
-      string mode = octave_stream::mode_as_string (stream->mode ());
+      string name = stream.name ();
+      string mode = octave_stream::mode_as_string (stream.mode ());
       string arch
-	= oct_mach_info::float_format_as_string (stream->float_format ());
+	= oct_mach_info::float_format_as_string (stream.float_format ());
+      string status = stream.is_open () ? "open" : "closed";
 
       indent (os); os << "id = " << number; newline (os);
       indent (os); os << "name = " << name; newline (os);
       indent (os); os << "mode = " << mode; newline (os);
       indent (os); os << "arch = " << arch; newline (os);
+      indent (os); os << "status = " << status; newline (os);
 
       decrement_indent_level ();
     }
--- a/src/ov-file.h	Thu Nov 04 16:24:31 1999 +0000
+++ b/src/ov-file.h	Fri Nov 05 07:02:36 1999 +0000
@@ -34,6 +34,7 @@
 class ostream;
 
 #include "oct-alloc.h"
+#include "oct-stream.h"
 #include "ov-base.h"
 #include "ov-typeinfo.h"
 
@@ -50,9 +51,9 @@
 public:
 
   octave_file (void)
-    : octave_base_value (), stream (0), number (-1) { }
+    : octave_base_value (), stream (), number (-1) { }
 
-  octave_file (octave_stream *s, int n)
+  octave_file (const octave_stream& s, int n)
     : octave_base_value (), stream (s), number (n) { }
 
   octave_file (const octave_file& f)
@@ -68,13 +69,13 @@
 
   double scalar_value (bool) const { return static_cast<double> (number); }
 
-  octave_stream *stream_value (void) const { return stream; }
+  octave_stream stream_value (void) const { return stream; }
 
   int stream_number (void) const { return number; }
 
   bool is_defined (void) const { return true; }
 
-  bool is_file (void) const { return true; }
+  bool is_stream (void) const { return true; }
 
   void print (ostream& os, bool pr_as_read_syntax = false) const;
 
@@ -85,7 +86,7 @@
 private:
 
   // The stream object.
-  octave_stream *stream;
+  octave_stream stream;
 
   // The number of the beast.
   int number;
--- a/src/ov.cc	Thu Nov 04 16:24:31 1999 +0000
+++ b/src/ov.cc	Fri Nov 05 07:02:36 1999 +0000
@@ -470,7 +470,7 @@
   rep->count = 1;
 }
 
-octave_value::octave_value (octave_stream *s, int n)
+octave_value::octave_value (const octave_stream& s, int n)
   : rep (new octave_file (s, n))
 {
   rep->count = 1;
@@ -715,7 +715,7 @@
   return rep->map_value ();
 }
 
-octave_stream *
+octave_stream
 octave_value::stream_value (void) const
 {
   return rep->stream_value ();
--- a/src/ov.h	Thu Nov 04 16:24:31 1999 +0000
+++ b/src/ov.h	Fri Nov 05 07:02:36 1999 +0000
@@ -171,7 +171,7 @@
   octave_value (double base, double limit, double inc);
   octave_value (const Range& r);
   octave_value (const Octave_map& m);
-  octave_value (octave_stream *s, int n);
+  octave_value (const octave_stream& s, int n);
   octave_value (octave_function *f);
   octave_value (const octave_value_list& m);
   octave_value (octave_value::magic_colon);
@@ -313,6 +313,9 @@
   virtual bool is_map (void) const
     { return rep->is_map (); }
 
+  virtual bool is_stream (void) const
+    { return rep->is_stream (); }
+
   virtual bool is_list (void) const
     { return rep->is_list (); }
 
@@ -422,7 +425,7 @@
 
   virtual Octave_map map_value (void) const;
 
-  virtual octave_stream *stream_value (void) const;
+  virtual octave_stream stream_value (void) const;
 
   virtual int stream_number (void) const;
 
--- a/src/syscalls.cc	Thu Nov 04 16:24:31 1999 +0000
+++ b/src/syscalls.cc	Fri Nov 05 07:02:36 1999 +0000
@@ -108,13 +108,13 @@
 
   if (nargin == 2)
     {
-      octave_stream *old_stream = octave_stream_list::lookup (args(0));
-      octave_stream *new_stream = octave_stream_list::lookup (args(1));
+      octave_stream old_stream = octave_stream_list::lookup (args(0));
+      octave_stream new_stream = octave_stream_list::lookup (args(1));
 
-      if (! error_state)
+      if (old_stream.is_valid () && new_stream.is_valid ())
 	{
-	  int i_old = old_stream->file_number ();
-	  int i_new = new_stream->file_number ();
+	  int i_old = old_stream.file_number ();
+	  int i_new = new_stream.file_number ();
 
 	  if (i_old >= 0 && i_new >= 0)
 	    {
@@ -598,14 +598,11 @@
 	retval(2) = msg;
       else
 	{
-	  FILE *in_file = fdopen (fid[0], "r");
-	  FILE *out_file = fdopen (fid[1], "w");
+	  FILE *ifile = fdopen (fid[0], "r");
+	  FILE *ofile = fdopen (fid[1], "w");
 
-	  octave_istdiostream *is
-	    = new octave_istdiostream (string (), in_file);
-
-	  octave_ostdiostream *os
-	    = new octave_ostdiostream (string (), out_file);
+	  octave_stream is = octave_istdiostream::create (string (), ifile);
+	  octave_stream os = octave_ostdiostream::create (string (), ofile);
 
 	  octave_value_list file_ids;