# HG changeset patch # User jwe # Date 1045350887 0 # Node ID 1cae4472c6249a5560e3e483e3349237ad06dadb # Parent f30803e587ac691ba45ffa88eaf550841a2cd4e7 [project @ 2003-02-15 23:14:47 by jwe] diff --git a/src/ChangeLog b/src/ChangeLog --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,16 @@ +2003-02-15 John W. Eaton + + * 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 * octave.cc (maximum_braindamage): Set boolean built-in variables diff --git a/src/c-file-ptr-stream.cc b/src/c-file-ptr-stream.cc --- a/src/c-file-ptr-stream.cc +++ b/src/c-file-ptr-stream.cc @@ -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++ *** diff --git a/src/c-file-ptr-stream.h b/src/c-file-ptr-stream.h --- a/src/c-file-ptr-stream.h +++ b/src/c-file-ptr-stream.h @@ -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: diff --git a/src/file-io.cc b/src/file-io.cc --- a/src/file-io.cc +++ b/src/file-io.cc @@ -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 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) { diff --git a/src/oct-prcstrm.cc b/src/oct-prcstrm.cc --- a/src/oct-prcstrm.cc +++ b/src/oct-prcstrm.cc @@ -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) { } diff --git a/src/oct-stdstrm.cc b/src/oct-stdstrm.cc --- a/src/oct-stdstrm.cc +++ b/src/oct-stdstrm.cc @@ -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++ *** diff --git a/src/oct-stdstrm.h b/src/oct-stdstrm.h --- a/src/oct-stdstrm.h +++ b/src/oct-stdstrm.h @@ -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 (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 /* diff --git a/src/oct-stream.cc b/src/oct-stream.cc --- a/src/oct-stream.cc +++ b/src/oct-stream.cc @@ -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; diff --git a/src/ov-file.cc b/src/ov-file.cc --- a/src/ov-file.cc +++ b/src/ov-file.cc @@ -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 << "}"; }