changeset 4326:1cae4472c624

[project @ 2003-02-15 23:14:47 by jwe]
author jwe
date Sat, 15 Feb 2003 23:14:47 +0000
parents f30803e587ac
children c29c382a5b4b
files src/ChangeLog src/c-file-ptr-stream.cc src/c-file-ptr-stream.h src/file-io.cc src/oct-prcstrm.cc src/oct-stdstrm.cc src/oct-stdstrm.h src/oct-stream.cc src/ov-file.cc
diffstat 9 files changed, 327 insertions(+), 74 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Sat Feb 15 04:54:57 2003 +0000
+++ b/src/ChangeLog	Sat Feb 15 23:14:47 2003 +0000
@@ -1,3 +1,16 @@
+2003-02-15  John W. Eaton  <jwe@bevo.che.wisc.edu>
+
+	* file-io.cc (Ftmpfile, Fmkstemp): New functions.
+	* oct-stdstrm.h (octave_iostdiostream): New class.
+	(octave_istdiostream::octave_istdiostream,
+	octave_istdiostream::create,
+	octave_ostdiostream::octave_ostdiostream, octave_ostdiostream::create, 
+	octave_iostdiostream::octave_iostdiostream,
+	octave_iostdiostream::create): Make close function the last arg.
+	Change all uses.
+
+	* c-file-ptr-stream.h (iostream): New class.
+
 2003-02-14  John W. Eaton  <jwe@bevo.che.wisc.edu>
 
 	* octave.cc (maximum_braindamage): Set boolean built-in variables
--- a/src/c-file-ptr-stream.cc	Sat Feb 15 04:54:57 2003 +0000
+++ b/src/c-file-ptr-stream.cc	Sat Feb 15 23:14:47 2003 +0000
@@ -189,20 +189,6 @@
   return retval;
 }
 
-void
-i_c_file_ptr_stream::close (void)
-{
-  if (buf)
-    buf->close ();
-}
-
-void
-o_c_file_ptr_stream::close (void)
-{
-  if (buf)
-    buf->close ();
-}
-
 /*
 ;;; Local Variables: ***
 ;;; mode: C++ ***
--- a/src/c-file-ptr-stream.h	Sat Feb 15 04:54:57 2003 +0000
+++ b/src/c-file-ptr-stream.h	Sat Feb 15 23:14:47 2003 +0000
@@ -103,7 +103,7 @@
 
   c_file_ptr_buf *rdbuf (void) { return buf; }
 
-  void close (void);
+  void close (void) { if (buf) buf->close (); }
 
 private:
 
@@ -123,7 +123,27 @@
 
   c_file_ptr_buf *rdbuf (void) { return buf; }
 
-  void close (void);
+  void close (void) { if (buf) buf->close (); }
+
+private:
+
+  c_file_ptr_buf *buf;
+};
+
+class
+io_c_file_ptr_stream : public std::iostream
+{
+public:
+
+  io_c_file_ptr_stream (FILE* f,
+			c_file_ptr_buf::close_fcn cf = c_file_ptr_buf::fclose)
+    : std::iostream (0), buf (new c_file_ptr_buf (f, cf)) { init (buf); }
+
+  ~io_c_file_ptr_stream (void) { delete buf; buf = 0; }
+
+  c_file_ptr_buf *rdbuf (void) { return buf; }
+
+  void close (void) { if (buf) buf->close (); }
 
 private:
 
--- a/src/file-io.cc	Sat Feb 15 04:54:57 2003 +0000
+++ b/src/file-io.cc	Sat Feb 15 23:14:47 2003 +0000
@@ -62,6 +62,7 @@
 #include "oct-stream.h"
 #include "oct-strstrm.h"
 #include "pager.h"
+#include "pt-plot.h"
 #include "sysdep.h"
 #include "utils.h"
 #include "variables.h"
@@ -1384,7 +1385,7 @@
 
 DEFUN (popen, args, ,
   "-*- texinfo -*-\n\
-@deftypefn {Built-in Function} {fid =} popen (@var{command}, @var{mode})\n\
+@deftypefn {Built-in Function} {@var{fid} =} popen (@var{command}, @var{mode})\n\
 Start a process and create a pipe.  The name of the command to run is\n\
 given by @var{command}.  The file identifier corresponding to the input\n\
 or output stream of the process is returned in @var{fid}.  The argument\n\
@@ -1486,7 +1487,8 @@
 directory for temporary files is used.  Since the named file is not\n\
 opened, by @code{tmpnam}, it is possible (though relatively unlikely)\n\
 that it will not be available by the time your program attempts to open it.\n\
-@end deftypefn")
+@end deftypefn\n\
+@seealso{tmpfile, mkstemp, and P_tmpdir}")
 {
   octave_value retval;
 
@@ -1517,6 +1519,156 @@
 
 DEFALIAS (octave_tmp_file_name, tmpnam);
 
+DEFUN (tmpfile, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn {Built-in Function} {[@var{fid}, @var{msg}] =} tmpfile ()\n\
+Return the file ID corresponding to a new temporary file with a unique\n\
+name.  The file is opened in binary read/write (@code{\"w+b\"}) mode.\n\
+The file will be deleted automatically when it is closed or when Octave\n\
+exits.\n\
+\n\
+If successful, @var{fid} is a valid file ID and @var{msg} is an empty\n\
+string.  Otherwise, @var{fid} is -1 and @var{msg} contains a\n\
+system-dependent error message.\n\
+@end deftypefn\n\
+@seealso{tmpnam, mkstemp, and P_tmpdir}")
+{
+  octave_value_list retval;
+
+  retval(1) = std::string ();
+  retval(0) = -1;
+
+  int nargin = args.length ();
+
+  if (nargin == 0)
+    {
+      FILE *fid = tmpfile ();
+
+      if (fid)
+	{
+	  std::string nm;
+
+	  std::ios::openmode md = fopen_mode_to_ios_mode ("w+b");
+
+	  octave_stream s = octave_iostdiostream::create (nm, fid, md);
+
+	  if (s)
+	    retval(0) = octave_stream_list::insert (s);
+	  else
+	    error ("tmpfile: failed to create octave_iostdiostream object");
+
+	}
+      else
+	{
+	  using namespace std;
+	  retval(1) = ::strerror (errno);
+	  retval(0) = -1;
+	}
+    }
+  else
+    print_usage ("tmpfile");
+
+  return retval;
+}
+
+#define HAVE_MKSTEMP 1
+
+
+DEFUN (mkstemp, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn {Built-in Function} {[@var{fid}, @var{name}, @var{msg}] =} tmpfile (@var{template}, @var{delete})\n\
+Return the file ID corresponding to a new temporary file with a unique\n\
+name created from @var{template}.  The last six characters of @var{template}\n\
+must be @code{XXXXXX} and tehse are replaced with a string that makes the\n\
+filename unique.  The file is then created with mode read/write and\n\
+permissions that are system dependent (on GNU/Linux systems, the permissions\n\
+will be 0600 for versions of glibc 2.0.7 and later).  The file is opened\n\
+with the @code{O_EXCL} flag.\n\
+\n\
+If the optional argument @var{delete} is supplied and is true,\n\
+the file will be deleted automatically when Octave exits, or when\n\
+the function @code{purge_tmp_files} is called.\n\
+\n\
+If successful, @var{fid} is a valid file ID, @var{name} is the name of\n\
+the file, and and @var{msg} is an empty string.  Otherwise, @var{fid}\n\
+is -1, @var{name} is empty, and @var{msg} contains a system-dependent\n\
+error message.\n\
+@end deftypefn\n\
+@seealso{tmpfile, tmpnam, and P_tmpdir}")
+{
+  octave_value_list retval;
+
+  retval(2) = std::string ();
+  retval(1) = std::string ();
+  retval(0) = -1;
+
+#if defined (HAVE_MKSTEMP)
+
+  int nargin = args.length ();
+
+  if (nargin == 1 || nargin == 2)
+    {
+      std::string tmpl8 = args(0).string_value ();
+
+      if (! error_state)
+	{
+	  std::auto_ptr<char> tmp_auto_ptr (strsave (tmpl8.c_str ()));
+	  char *tmp = tmp_auto_ptr.get ();
+
+	  int fd = mkstemp (tmp);
+
+	  if (fd < 0)
+	    {
+	      using namespace std;
+	      retval(1) = ::strerror (errno);
+	      retval(0) = fd;
+	    }
+	  else
+	    {
+	      const char *fopen_mode = "w+";
+
+	      FILE *fid = fdopen (fd, fopen_mode);
+
+	      if (fid)
+		{
+		  std::string nm = tmp;
+
+		  std::ios::openmode md = fopen_mode_to_ios_mode (fopen_mode);
+
+		  octave_stream s = octave_iostdiostream::create (nm, fid, md);
+
+		  if (s)
+		    {
+		      retval(1) = nm;
+		      retval(0) = octave_stream_list::insert (s);
+
+		      if (nargin == 2)
+			mark_for_deletion (nm);
+		    }
+		  else
+		    error ("mkstemp: failed to create octave_iostdiostream object");
+		}
+	      else
+		{
+		  using namespace std;
+		  retval(1) = ::strerror (errno);
+		  retval(0) = -1;
+		}
+	    }
+	}
+      else
+	error ("mkstemp: expecting string as first argument");
+    }
+  else
+    print_usage ("mkstemp");
+
+#else
+  retval(2) = "mkstemp: not supported on this sytem";
+#endif
+
+  return retval;
+}
+
 static int
 convert (int x, int ibase, int obase)
 {
--- a/src/oct-prcstrm.cc	Sat Feb 15 04:54:57 2003 +0000
+++ b/src/oct-prcstrm.cc	Sat Feb 15 23:14:47 2003 +0000
@@ -44,8 +44,8 @@
 octave_iprocstream::octave_iprocstream (const std::string& n,
 					std::ios::openmode arg_md,
 					oct_mach_info::float_format flt_fmt)
-  : octave_istdiostream (n, ::popen (n.c_str (), "r"), cxx_pclose,
-			 arg_md, flt_fmt)
+  : octave_istdiostream (n, ::popen (n.c_str (), "r"),
+			 arg_md, flt_fmt, cxx_pclose)
 {
 }
 
@@ -64,8 +64,8 @@
 octave_oprocstream::octave_oprocstream (const std::string& n,
 					std::ios::openmode arg_md,
 					oct_mach_info::float_format flt_fmt)
-  : octave_ostdiostream (n, ::popen (n.c_str (), "w"), cxx_pclose,
-			 arg_md, flt_fmt)
+  : octave_ostdiostream (n, ::popen (n.c_str (), "w"),
+			 arg_md, flt_fmt, cxx_pclose)
 {
 }
 
--- a/src/oct-stdstrm.cc	Sat Feb 15 04:54:57 2003 +0000
+++ b/src/oct-stdstrm.cc	Sat Feb 15 23:14:47 2003 +0000
@@ -76,17 +76,17 @@
 
 octave_stream
 octave_istdiostream::create (const std::string& n, FILE *f,
-			     c_file_ptr_buf::close_fcn cf,
 			     std::ios::openmode arg_md,
-			     oct_mach_info::float_format flt_fmt)
+			     oct_mach_info::float_format flt_fmt,
+			     c_file_ptr_buf::close_fcn cf)
 {
-  return octave_stream (new octave_istdiostream (n, f, cf, arg_md, flt_fmt));
+  return octave_stream (new octave_istdiostream (n, f, arg_md, flt_fmt, cf));
 }
 
 octave_istdiostream::octave_istdiostream (const std::string& n, FILE *f,
-					  c_file_ptr_buf::close_fcn cf,
 					  std::ios::openmode arg_md,
-					  oct_mach_info::float_format flt_fmt)
+					  oct_mach_info::float_format flt_fmt,
+					  c_file_ptr_buf::close_fcn cf)
   : octave_base_stdiostream (n, arg_md, flt_fmt), is (0)
 {
   if (f)
@@ -107,17 +107,17 @@
 
 octave_stream
 octave_ostdiostream::create (const std::string& n, FILE *f,
-			     c_file_ptr_buf::close_fcn cf,
 			     std::ios::openmode arg_md,
-			     oct_mach_info::float_format flt_fmt)
+			     oct_mach_info::float_format flt_fmt,
+			     c_file_ptr_buf::close_fcn cf)
 {
-  return octave_stream (new octave_ostdiostream (n, f, cf, arg_md, flt_fmt));
+  return octave_stream (new octave_ostdiostream (n, f, arg_md, flt_fmt, cf));
 }
 
 octave_ostdiostream::octave_ostdiostream (const std::string& n, FILE *f,
-					  c_file_ptr_buf::close_fcn cf,
 					  std::ios::openmode arg_md,
-					  oct_mach_info::float_format flt_fmt)
+					  oct_mach_info::float_format flt_fmt,
+					  c_file_ptr_buf::close_fcn cf)
   : octave_base_stdiostream (n, arg_md, flt_fmt), os (0)
 {
   if (f)
@@ -136,6 +136,37 @@
     os->close ();
 }
 
+octave_stream
+octave_iostdiostream::create (const std::string& n, FILE *f,
+			      std::ios::openmode arg_md,
+			      oct_mach_info::float_format flt_fmt,
+			      c_file_ptr_buf::close_fcn cf)
+{
+  return octave_stream (new octave_iostdiostream (n, f, arg_md, flt_fmt, cf));
+}
+
+octave_iostdiostream::octave_iostdiostream (const std::string& n, FILE *f,
+					    std::ios::openmode arg_md,
+					    oct_mach_info::float_format flt_fmt,
+					    c_file_ptr_buf::close_fcn cf)
+  : octave_base_stdiostream (n, arg_md, flt_fmt), s (0)
+{
+  if (f)
+    s = new io_c_file_ptr_stream (f, cf);
+}
+
+octave_iostdiostream::~octave_iostdiostream (void)
+{
+  delete s;
+}
+
+void
+octave_iostdiostream::do_close (void)
+{
+  if (s)
+    s->close ();
+}
+
 /*
 ;;; Local Variables: ***
 ;;; mode: C++ ***
--- a/src/oct-stdstrm.h	Sat Feb 15 04:54:57 2003 +0000
+++ b/src/oct-stdstrm.h	Sat Feb 15 23:14:47 2003 +0000
@@ -74,16 +74,15 @@
 public:
 
   octave_istdiostream (const std::string& n, FILE *f = 0,
-		       c_file_ptr_buf::close_fcn cf = c_file_ptr_buf::fclose,
 		       std::ios::openmode arg_md = std::ios::in,
-		       oct_mach_info::float_format flt_fmt =
-		       oct_mach_info::native);
+		       oct_mach_info::float_format flt_fmt = oct_mach_info::native,
+		       c_file_ptr_buf::close_fcn cf = c_file_ptr_buf::fclose);
 
   static octave_stream
   create (const std::string& n, FILE *f = 0,
-	  c_file_ptr_buf::close_fcn cf = c_file_ptr_buf::fclose,
 	  std::ios::openmode arg_md = std::ios::in,
-	  oct_mach_info::float_format flt_fmt = oct_mach_info::native);
+	  oct_mach_info::float_format flt_fmt = oct_mach_info::native,
+	  c_file_ptr_buf::close_fcn cf = c_file_ptr_buf::fclose);
 
   // Return non-zero if EOF has been reached on this stream.
 
@@ -128,16 +127,15 @@
 public:
 
   octave_ostdiostream (const std::string& n, FILE *f = 0,
-		       c_file_ptr_buf::close_fcn cf = c_file_ptr_buf::fclose,
 		       std::ios::openmode arg_md = std::ios::out,
-		       oct_mach_info::float_format flt_fmt =
-		       oct_mach_info::native);
+		       oct_mach_info::float_format flt_fmt = oct_mach_info::native,
+		       c_file_ptr_buf::close_fcn cf = c_file_ptr_buf::fclose);
 
   static octave_stream
   create (const std::string& n, FILE *f = 0,
-	  c_file_ptr_buf::close_fcn cf = c_file_ptr_buf::fclose,
 	  std::ios::openmode arg_md = std::ios::out,
-	  oct_mach_info::float_format flt_fmt = oct_mach_info::native);
+	  oct_mach_info::float_format flt_fmt = oct_mach_info::native,
+	  c_file_ptr_buf::close_fcn cf = c_file_ptr_buf::fclose);
 
   // Return non-zero if EOF has been reached on this stream.
 
@@ -176,6 +174,59 @@
   octave_ostdiostream& operator = (const octave_ostdiostream&);
 };
 
+class
+octave_iostdiostream : public octave_base_stdiostream
+{
+public:
+
+  octave_iostdiostream (const std::string& n, FILE *f = 0,
+			std::ios::openmode arg_md = std::ios::in,
+			oct_mach_info::float_format flt_fmt = oct_mach_info::native,
+			c_file_ptr_buf::close_fcn cf = c_file_ptr_buf::fclose);
+
+  static octave_stream
+  create (const std::string& n, FILE *f = 0,
+	  std::ios::openmode arg_md = std::ios::in|std::ios::out,
+	  oct_mach_info::float_format flt_fmt = oct_mach_info::native,
+	  c_file_ptr_buf::close_fcn cf = c_file_ptr_buf::fclose);
+
+  // Return non-zero if EOF has been reached on this stream.
+
+  bool eof (void) const { return s ? s->eof () : true; }
+
+  std::istream *input_stream (void) { return s; }
+
+  std::ostream *output_stream (void) { return s; }
+
+  // XXX FIXME XXX -- should not have to cast away const here.
+  c_file_ptr_buf *rdbuf (void) const
+    { return s ? (const_cast<io_c_file_ptr_stream *> (s))->rdbuf () : 0; }
+
+  bool bad (void) const { return s ? s->bad () : true; }
+
+  void clear (void)
+    {
+      if (s)
+	s->clear ();
+    }
+
+  void do_close (void);
+
+protected:
+
+  io_c_file_ptr_stream *s;
+
+  ~octave_iostdiostream (void);
+
+private:
+
+  // No copying!
+
+  octave_iostdiostream (const octave_iostdiostream&);
+
+  octave_iostdiostream& operator = (const octave_iostdiostream&);
+};
+
 #endif
 
 /*
--- a/src/oct-stream.cc	Sat Feb 15 04:54:57 2003 +0000
+++ b/src/oct-stream.cc	Sat Feb 15 23:14:47 2003 +0000
@@ -3161,23 +3161,17 @@
     {
       octave_stream os = list(i);
 
-      if (os)
-	{
-	  std::string mode = octave_stream::mode_as_string (os.mode ());
-
-	  std::string arch =
-	    oct_mach_info::float_format_as_string (os.float_format ());
-
-	  std::string name = os.name ();
-
-	  buf << "  "
-	      << std::setiosflags (std::ios::right)
-	      << std::setw (4) << i << "     "
-	      << std::setiosflags (std::ios::left)
-	      << std::setw (3) << mode.c_str () << "  "
-	      << std::setw (9) << arch.c_str () << "  "
-	      << name << "\n";
-	}
+      buf << "  "
+	  << std::setiosflags (std::ios::right)
+	  << std::setw (4) << i << "     "
+	  << std::setiosflags (std::ios::left)
+	  << std::setw (3)
+	  << octave_stream::mode_as_string (os.mode ())
+	  << "  "
+	  << std::setw (9)
+	  << oct_mach_info::float_format_as_string (os.float_format ())
+	  << "  "
+	  << os.name () << "\n";
     }
 
   buf << "\n" << OSSTREAM_ENDS;
--- a/src/ov-file.cc	Sat Feb 15 04:54:57 2003 +0000
+++ b/src/ov-file.cc	Sat Feb 15 23:14:47 2003 +0000
@@ -67,24 +67,30 @@
 {
   indent (os); os << "{"; newline (os);
 
-  if (stream)
-    {
-      increment_indent_level ();
+  increment_indent_level ();
+
+  indent (os);
+  os << "id = " << number;
+  newline (os);
+
+  indent (os);
+  os << "name = " << stream.name ();
+  newline (os);
 
-      std::string name = stream.name ();
-      std::string mode = octave_stream::mode_as_string (stream.mode ());
-      std::string arch
-	= oct_mach_info::float_format_as_string (stream.float_format ());
-      std::string status = stream.is_open () ? "open" : "closed";
+  indent (os);
+  os << "mode = " << octave_stream::mode_as_string (stream.mode ());
+  newline (os);
 
-      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);
+  indent (os);
+  os << "arch = "
+     << oct_mach_info::float_format_as_string (stream.float_format ());
+  newline (os);
 
-      decrement_indent_level ();
-    }
+  indent (os);
+  os << "status = " << stream.is_open () ? "open" : "closed";
+  newline (os);
+
+  decrement_indent_level ();
 
   indent (os); os << "}";
 }