3Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
4 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
6This file is part of Octave.
8Octave is free software; you can redistribute it and/or modify it
9under the terms of the GNU General Public License as published by the
10Free Software Foundation; either version 3 of the License, or (at your
11option) any later version.
13Octave is distributed in the hope that it will be useful, but WITHOUT
14ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18You should have received a copy of the GNU General Public License
19along with Octave; see the file COPYING. If not, see
20<http://www.gnu.org/licenses/>.
24// Originally written by John C. Campbell <jcc@bevo.che.wisc.edu>
26// Thomas Baier <baier@ci.tuwien.ac.at> added the original versions of
27// the following functions:
31// execute (now popen2.m)
32// sync_system (now merged with system)
33// async_system (now merged with system)
35// Extensively revised by John W. Eaton <jwe@octave.org>,
62#include "oct-locbuf.h"
68#include "oct-iostrm.h"
71#include "oct-prcstrm.h"
72#include "oct-stream.h"
73#include "oct-strstrm.h"
79static octave_value stdin_file;
80static octave_value stdout_file;
81static octave_value stderr_file;
83static octave_stream stdin_stream;
84static octave_stream stdout_stream;
85static octave_stream stderr_stream;
88initialize_file_io (void)
90 stdin_stream = octave_istream::create (&std::cin, "stdin");
92 // This uses octave_stdout (see pager.h), not std::cout so that Octave's
93 // standard output stream will pass through the pager.
95 stdout_stream = octave_ostream::create (&octave_stdout, "stdout");
97 stderr_stream = octave_ostream::create (&std::cerr, "stderr");
99 stdin_file = octave_stream_list::insert (stdin_stream);
100 stdout_file = octave_stream_list::insert (stdout_stream);
101 stderr_file = octave_stream_list::insert (stderr_stream);
107 octave_stream_list::clear ();
110// List of files to delete when we exit or crash.
112// FIXME -- this should really be static, but that causes
113// problems on some systems.
114std::stack <std::string> tmp_files;
117mark_for_deletion (const std::string& file)
119 tmp_files.push (file);
123cleanup_tmp_files (void)
125 while (! tmp_files.empty ())
127 std::string filename = tmp_files.top ();
129 unlink (filename.c_str ());
133static std::ios::openmode
134fopen_mode_to_ios_mode (const std::string& mode_arg)
136 std::ios::openmode retval = std::ios::in;
138 if (! mode_arg.empty ())
140 // Could probably be faster, but does it really matter?
142 std::string mode = mode_arg;
144 // 'W' and 'R' are accepted as 'w' and 'r', but we warn about
145 // them because Matlab says they perform "automatic flushing"
146 // but we don't know precisely what action that implies.
148 size_t pos = mode.find ('W');
150 if (pos != std::string::npos)
152 warning ("fopen: treating mode \"W\" as equivalent to \"w\"");
156 pos = mode.find ('R');
158 if (pos != std::string::npos)
160 warning ("fopen: treating mode \"R\" as equivalent to \"r\"");
164 pos = mode.find ('z');
166 if (pos != std::string::npos)
168#if defined (HAVE_ZLIB)
171 error ("this version of Octave does not support gzipped files");
178 retval = std::ios::in;
179 else if (mode == "wt")
180 retval = std::ios::out | std::ios::trunc;
181 else if (mode == "at")
182 retval = std::ios::out | std::ios::app;
183 else if (mode == "r+t" || mode == "rt+")
184 retval = std::ios::in | std::ios::out;
185 else if (mode == "w+t" || mode == "wt+")
186 retval = std::ios::in | std::ios::out | std::ios::trunc;
187 else if (mode == "a+t" || mode == "at+")
188 retval = std::ios::in | std::ios::out | std::ios::app;
189 else if (mode == "rb" || mode == "r")
190 retval = std::ios::in | std::ios::binary;
191 else if (mode == "wb" || mode == "w")
192 retval = std::ios::out | std::ios::trunc | std::ios::binary;
193 else if (mode == "ab" || mode == "a")
194 retval = std::ios::out | std::ios::app | std::ios::binary;
195 else if (mode == "r+b" || mode == "rb+" || mode == "r+")
196 retval = std::ios::in | std::ios::out | std::ios::binary;
197 else if (mode == "w+b" || mode == "wb+" || mode == "w+")
198 retval = (std::ios::in | std::ios::out | std::ios::trunc
200 else if (mode == "a+b" || mode == "ab+" || mode == "a+")
201 retval = (std::ios::in | std::ios::out | std::ios::app
204 ::error ("invalid mode specified");
211DEFUN (fclose, args, ,
213@deftypefn {Built-in Function} {} fclose (@var{fid})\n\
214Closes the specified file. If successful, @code{fclose} returns 0,\n\
215otherwise, it returns -1.\n\
216@seealso{fopen, fseek, ftell}\n\
219 octave_value retval = -1;
221 int nargin = args.length ();
224 retval = octave_stream_list::remove (args(0), "fclose");
231DEFUN (fclear, args, ,
233@deftypefn {Built-in Function} {} fclear (@var{fid})\n\
234Clear the stream state for the specified file.\n\
239 int nargin = args.length ();
243 int fid = octave_stream_list::get_file_number (args (0));
245 octave_stream os = octave_stream_list::lookup (fid, "fclear");
256DEFUN (fflush, args, ,
258@deftypefn {Built-in Function} {} fflush (@var{fid})\n\
259Flush output to @var{fid}. This is useful for ensuring that all\n\
260pending output makes it to the screen before some other event occurs.\n\
261For example, it is always a good idea to flush the standard output\n\
262stream before calling @code{input}.\n\
264@code{fflush} returns 0 on success and an OS dependent error value\n\
265(@minus{}1 on unix) on error.\n\
266@seealso{fopen, fclose}\n\
269 octave_value retval = -1;
271 int nargin = args.length ();
275 // FIXME -- any way to avoid special case for stdout?
277 int fid = octave_stream_list::get_file_number (args (0));
281 flush_octave_stdout ();
287 octave_stream os = octave_stream_list::lookup (fid, "fflush");
290 retval = os.flush ();
301@deftypefn {Built-in Function} {} fgetl (@var{fid}, @var{len})\n\
302Read characters from a file, stopping after a newline, or EOF,\n\
303or @var{len} characters have been read. The characters read, excluding\n\
304the possible trailing newline, are returned as a string.\n\
306If @var{len} is omitted, @code{fgetl} reads until the next newline\n\
309If there are no more characters to read, @code{fgetl} returns @minus{}1.\n\
310@seealso{fread, fscanf}\n\
313 static std::string who = "fgetl";
315 octave_value_list retval;
320 int nargin = args.length ();
322 if (nargin == 1 || nargin == 2)
324 octave_stream os = octave_stream_list::lookup (args(0), who);
328 octave_value len_arg = (nargin == 2) ? args(1) : octave_value ();
332 std::string tmp = os.getl (len_arg, err, who);
334 if (! (error_state || err))
336 retval(1) = tmp.length ();
349@deftypefn {Built-in Function} {} fgets (@var{fid}, @var{len})\n\
350Read characters from a file, stopping after a newline, or EOF,\n\
351or @var{len} characters have been read. The characters read, including\n\
352the possible trailing newline, are returned as a string.\n\
354If @var{len} is omitted, @code{fgets} reads until the next newline\n\
357If there are no more characters to read, @code{fgets} returns @minus{}1.\n\
358@seealso{fputs, fopen, fread, fscanf}\n\
361 static std::string who = "fgets";
363 octave_value_list retval;
368 int nargin = args.length ();
370 if (nargin == 1 || nargin == 2)
372 octave_stream os = octave_stream_list::lookup (args(0), who);
376 octave_value len_arg = (nargin == 2) ? args(1) : octave_value ();
380 std::string tmp = os.gets (len_arg, err, who);
382 if (! (error_state || err))
384 retval(1) = tmp.length ();
395DEFUN (fskipl, args, ,
397@deftypefn {Built-in Function} {} fskipl (@var{fid}, @var{count})\n\
398Skips a given number of lines, i.e., discards characters until an end-of-line\n\
399is met exactly @var{count}-times, or end-of-file occurs.\n\
400Returns the number of lines skipped (end-of-line sequences encountered).\n\
401If @var{count} is omitted, it defaults to 1. @var{count} may also be\n\
402@code{Inf}, in which case lines are skipped to the end of file.\n\
403This form is suitable for counting lines in a file.\n\
404@seealso{fgetl, fgets}\n\
407 static std::string who = "fskipl";
411 int nargin = args.length ();
413 if (nargin == 1 || nargin == 2)
415 octave_stream os = octave_stream_list::lookup (args(0), who);
419 octave_value count_arg = (nargin == 2) ? args(1) : octave_value ();
423 long tmp = os.skipl (count_arg, err, who);
425 if (! (error_state || err))
437do_stream_open (const std::string& name, const std::string& mode,
438 const std::string& arch, int& fid)
440 octave_stream retval;
444 std::ios::openmode md = fopen_mode_to_ios_mode (mode);
448 oct_mach_info::float_format flt_fmt =
449 oct_mach_info::string_to_float_format (arch);
453 std::string fname = file_ops::tilde_expand (name);
455 file_stat fs (fname);
457 if (! (md & std::ios::out
458 || octave_env::absolute_pathname (fname)
459 || octave_env::rooted_relative_pathname (fname)))
464 = octave_env::make_absolute (load_path::find_file (fname));
468 warning_with_id ("Octave:fopen-file-in-path",
469 "fopen: file found in load path");
477 std::string tmode = mode;
479 // Use binary mode if 't' is not specified, but don't add
480 // 'b' if it is already present.
482 size_t bpos = tmode.find ('b');
483 size_t tpos = tmode.find ('t');
485 if (bpos == std::string::npos && tpos == std::string::npos)
488#if defined (HAVE_ZLIB)
489 size_t pos = tmode.find ('z');
491 if (pos != std::string::npos)
493 tmode.erase (pos, 1);
495 gzFile fptr = ::gzopen (fname.c_str (), tmode.c_str ());
498 retval = octave_zstdiostream::create (fname, fptr, md, flt_fmt);
502 retval.error (::strerror (errno));
508 FILE *fptr = ::fopen (fname.c_str (), tmode.c_str ());
510 retval = octave_stdiostream::create (fname, fptr, md, flt_fmt);
515 retval.error (::strerror (errno));
527do_stream_open (const octave_value& tc_name, const octave_value& tc_mode,
528 const octave_value& tc_arch, const char *fcn, int& fid)
530 octave_stream retval;
534 std::string name = tc_name.string_value ();
538 std::string mode = tc_mode.string_value ();
542 std::string arch = tc_arch.string_value ();
545 retval = do_stream_open (name, mode, arch, fid);
547 ::error ("%s: architecture type must be a string", fcn);
550 ::error ("%s: file mode must be a string", fcn);
553 ::error ("%s: file name must be a string", fcn);
560@deftypefn {Built-in Function} {[@var{fid}, @var{msg}] =} fopen (@var{name}, @var{mode}, @var{arch})\n\
561@deftypefnx {Built-in Function} {@var{fid_list} =} fopen (\"all\")\n\
562@deftypefnx {Built-in Function} {[@var{file}, @var{mode}, @var{arch}] =} fopen (@var{fid})\n\
563The first form of the @code{fopen} function opens the named file with\n\
564the specified mode (read-write, read-only, etc.) and architecture\n\
565interpretation (IEEE big endian, IEEE little endian, etc.), and returns\n\
566an integer value that may be used to refer to the file later. If an\n\
567error occurs, @var{fid} is set to @minus{}1 and @var{msg} contains the\n\
568corresponding system error message. The @var{mode} is a one or two\n\
569character string that specifies whether the file is to be opened for\n\
570reading, writing, or both.\n\
572The second form of the @code{fopen} function returns a vector of file ids\n\
573corresponding to all the currently open files, excluding the\n\
574@code{stdin}, @code{stdout}, and @code{stderr} streams.\n\
576The third form of the @code{fopen} function returns information about the\n\
577open file given its file id.\n\
582myfile = fopen (\"splat.dat\", \"r\", \"ieee-le\");\n\
586opens the file @file{splat.dat} for reading. If necessary, binary\n\
587numeric values will be read assuming they are stored in IEEE format with\n\
588the least significant bit first, and then converted to the native\n\
591Opening a file that is already open simply opens it again and returns a\n\
592separate file id. It is not an error to open a file several times,\n\
593though writing to the same file through several different file ids may\n\
594produce unexpected results.\n\
596The possible values @samp{mode} may have are\n\
600Open a file for reading.\n\
603Open a file for writing. The previous contents are discarded.\n\
606Open or create a file for writing at the end of the file.\n\
609Open an existing file for reading and writing.\n\
612Open a file for reading or writing. The previous contents are\n\
616Open or create a file for reading or writing at the end of the\n\
620Append a \"t\" to the mode string to open the file in text mode or a\n\
621\"b\" to open in binary mode. On Windows and Macintosh systems, text\n\
622mode reading and writing automatically converts linefeeds to the\n\
623appropriate line end character for the system (carriage-return linefeed\n\
624on Windows, carriage-return on Macintosh). The default if no mode is\n\
625specified is binary mode.\n\
627Additionally, you may append a \"z\" to the mode string to open a\n\
628gzipped file for reading or writing. For this to be successful, you\n\
629must also open the file in binary mode.\n\
631The parameter @var{arch} is a string specifying the default data format\n\
632for the file. Valid values for @var{arch} are:\n\
636The format of the current machine (this is the default).\n\
639IEEE big endian format.\n\
642IEEE little endian format.\n\
645VAX D floating format.\n\
648VAX G floating format.\n\
651Cray floating format.\n\
655however, conversions are currently only supported for @samp{native}\n\
656@samp{ieee-be}, and @samp{ieee-le} formats.\n\
657@seealso{fclose, fgets, fputs, fread, fseek, ferror, fprintf, fscanf, ftell, fwrite}\n\
660 octave_value_list retval;
664 int nargin = args.length ();
668 if (args(0).is_string ())
670 // If there is only one argument and it is a string but it
671 // is not the string "all", we assume it is a file to open
672 // with MODE = "r". To open a file called "all", you have
673 // to supply more than one argument.
675 if (args(0).string_value () == "all")
676 return octave_stream_list::open_file_numbers ();
680 string_vector tmp = octave_stream_list::get_info (args(0));
693 if (nargin > 0 && nargin < 4)
695 octave_value mode = (nargin == 2 || nargin == 3)
696 ? args(1) : octave_value ("r");
698 octave_value arch = (nargin == 3)
699 ? args(2) : octave_value ("native");
703 octave_stream os = do_stream_open (args(0), mode, arch, "fopen", fid);
705 if (os && ! error_state)
708 retval(0) = octave_stream_list::insert (os);
712 int error_number = 0;
714 retval(1) = os.error (false, error_number);
724DEFUN (freport, args, ,
726@deftypefn {Built-in Function} {} freport ()\n\
727Print a list of which files have been opened, and whether they are open\n\
728for reading, writing, or both. For example,\n\
734 @print{} number mode name\n\
736 @print{} 0 r stdin\n\
737 @print{} 1 w stdout\n\
738 @print{} 2 w stderr\n\
739 @print{} 3 r myfile\n\
744 octave_value_list retval;
746 int nargin = args.length ();
749 warning ("freport: ignoring extra arguments");
751 octave_stdout << octave_stream_list::list_open_files ();
756DEFUN (frewind, args, nargout,
758@deftypefn {Built-in Function} {} frewind (@var{fid})\n\
759Move the file pointer to the beginning of the file @var{fid}, returning\n\
7600 for success, and -1 if an error was encountered. It is equivalent to\n\
761@code{fseek (@var{fid}, 0, SEEK_SET)}.\n\
768 int nargin = args.length ();
772 octave_stream os = octave_stream_list::lookup (args(0), "frewind");
775 result = os.rewind ();
788@deftypefn {Built-in Function} {} fseek (@var{fid}, @var{offset}, @var{origin})\n\
789Set the file pointer to any location within the file @var{fid}.\n\
791The pointer is positioned @var{offset} characters from the @var{origin},\n\
792which may be one of the predefined variables @w{@code{SEEK_CUR}} (current\n\
793position), @w{@code{SEEK_SET}} (beginning), or @w{@code{SEEK_END}} (end of\n\
794file) or strings \"cof\", \"bof\" or \"eof\". If @var{origin} is omitted,\n\
795@w{@code{SEEK_SET}} is assumed. The offset must be zero, or a value returned\n\
796by @code{ftell} (in which case @var{origin} must be @w{@code{SEEK_SET}}).\n\
798Return 0 on success and -1 on error.\n\
799@seealso{ftell, fopen, fclose}\n\
802 octave_value retval = -1;
804 int nargin = args.length ();
806 if (nargin == 2 || nargin == 3)
808 octave_stream os = octave_stream_list::lookup (args(0), "fseek");
812 octave_value origin_arg = (nargin == 3)
813 ? args(2) : octave_value (-1.0);
815 retval = os.seek (args(1), origin_arg);
826@deftypefn {Built-in Function} {} ftell (@var{fid})\n\
827Return the position of the file pointer as the number of characters\n\
828from the beginning of the file @var{fid}.\n\
829@seealso{fseek, fopen, fclose}\n\
832 octave_value retval = -1;
834 int nargin = args.length ();
838 octave_stream os = octave_stream_list::lookup (args(0), "ftell");
849DEFUN (fprintf, args, nargout,
851@deftypefn {Built-in Function} {} fprintf (@var{fid}, @var{template}, @dots{})\n\
852This function is just like @code{printf}, except that the output is\n\
853written to the stream @var{fid} instead of @code{stdout}.\n\
854If @var{fid} is omitted, the output is written to @code{stdout}.\n\
855@seealso{printf, sprintf, fread, fscanf, fopen, fclose}\n\
858 static std::string who = "fprintf";
864 int nargin = args.length ();
866 if (nargin > 1 || (nargin > 0 && args(0).is_string ()))
871 if (args(0).is_string ())
873 os = octave_stream_list::lookup (1, who);
878 os = octave_stream_list::lookup (args(0), who);
883 if (args(fmt_n).is_string ())
885 octave_value_list tmp_args;
887 if (nargin > 1 + fmt_n)
889 tmp_args.resize (nargin-fmt_n-1, octave_value ());
891 for (int i = fmt_n + 1; i < nargin; i++)
892 tmp_args(i-fmt_n-1) = args(i);
895 result = os.printf (args(fmt_n), tmp_args, who);
898 ::error ("%s: format must be a string", who.c_str ());
910DEFUN (printf, args, nargout,
912@deftypefn {Built-in Function} {} printf (@var{template}, @dots{})\n\
913Print optional arguments under the control of the template string\n\
914@var{template} to the stream @code{stdout} and return the number of\n\
915characters printed.\n\
916@ifclear OCTAVE_MANUAL\n\
918See the Formatted Output section of the GNU Octave manual for a\n\
919complete description of the syntax of the template string.\n\
921@seealso{fprintf, sprintf, scanf}\n\
924 static std::string who = "printf";
930 int nargin = args.length ();
934 if (args(0).is_string ())
936 octave_value_list tmp_args;
940 tmp_args.resize (nargin-1, octave_value ());
942 for (int i = 1; i < nargin; i++)
943 tmp_args(i-1) = args(i);
946 result = stdout_stream.printf (args(0), tmp_args, who);
949 ::error ("%s: format must be a string", who.c_str ());
962@deftypefn {Built-in Function} {} fputs (@var{fid}, @var{string})\n\
963Write a string to a file with no formatting.\n\
965Return a non-negative number on success and EOF on error.\n\
966@seealso{scanf, sscanf, fread, fprintf, fgets, fscanf}\n\
969 static std::string who = "fputs";
971 octave_value retval = -1;
973 int nargin = args.length ();
977 octave_stream os = octave_stream_list::lookup (args(0), who);
980 retval = os.puts (args(1), who);
990@deftypefn {Built-in Function} {} puts (@var{string})\n\
991Write a string to the standard output with no formatting.\n\
993Return a non-negative number on success and EOF on error.\n\
996 static std::string who = "puts";
998 octave_value retval = -1;
1000 if (args.length () == 1)
1001 retval = stdout_stream.puts (args(0), who);
1008DEFUN (sprintf, args, ,
1010@deftypefn {Built-in Function} {} sprintf (@var{template}, @dots{})\n\
1011This is like @code{printf}, except that the output is returned as a\n\
1012string. Unlike the C library function, which requires you to provide a\n\
1013suitably sized string as an argument, Octave's @code{sprintf} function\n\
1014returns the string, automatically sized to hold all of the items\n\
1016@seealso{printf, fprintf, sscanf}\n\
1019 static std::string who = "sprintf";
1021 octave_value_list retval;
1023 int nargin = args.length ();
1028 retval(1) = "unknown error";
1031 octave_ostrstream *ostr = new octave_ostrstream ();
1033 octave_stream os (ostr);
1037 octave_value fmt_arg = args(0);
1039 if (fmt_arg.is_string ())
1041 octave_value_list tmp_args;
1045 tmp_args.resize (nargin-1, octave_value ());
1047 for (int i = 1; i < nargin; i++)
1048 tmp_args(i-1) = args(i);
1051 retval(2) = os.printf (fmt_arg, tmp_args, who);
1052 retval(1) = os.error ();
1053 retval(0) = octave_value (ostr->str (),
1054 fmt_arg.is_sq_string () ? '\'' : '"');
1057 ::error ("%s: format must be a string", who.c_str ());
1060 ::error ("%s: unable to create output buffer", who.c_str ());
1068DEFUN (fscanf, args, ,
1070@deftypefn {Built-in Function} {[@var{val}, @var{count}] =} fscanf (@var{fid}, @var{template}, @var{size})\n\
1071@deftypefnx {Built-in Function} {[@var{v1}, @var{v2}, @dots{}, @var{count}] =} fscanf (@var{fid}, @var{template}, \"C\")\n\
1072In the first form, read from @var{fid} according to @var{template},\n\
1073returning the result in the matrix @var{val}.\n\
1075The optional argument @var{size} specifies the amount of data to read\n\
1080Read as much as possible, returning a column vector.\n\
1083Read up to @var{nr} elements, returning a column vector.\n\
1085@item [@var{nr}, Inf]\n\
1086Read as much as possible, returning a matrix with @var{nr} rows. If the\n\
1087number of elements read is not an exact multiple of @var{nr}, the last\n\
1088column is padded with zeros.\n\
1090@item [@var{nr}, @var{nc}]\n\
1091Read up to @code{@var{nr} * @var{nc}} elements, returning a matrix with\n\
1092@var{nr} rows. If the number of elements read is not an exact multiple\n\
1093of @var{nr}, the last column is padded with zeros.\n\
1097If @var{size} is omitted, a value of @code{Inf} is assumed.\n\
1099A string is returned if @var{template} specifies only character\n\
1102The number of items successfully read is returned in @var{count}.\n\
1104In the second form, read from @var{fid} according to @var{template},\n\
1105with each conversion specifier in @var{template} corresponding to a\n\
1106single scalar return value. This form is more `C-like', and also\n\
1107compatible with previous versions of Octave. The number of successful\n\
1108conversions is returned in @var{count}\n\
1109@ifclear OCTAVE_MANUAL\n\
1111See the Formatted Input section of the GNU Octave manual for a\n\
1112complete description of the syntax of the template string.\n\
1114@seealso{scanf, sscanf, fread, fprintf, fgets, fputs}\n\
1117 static std::string who = "fscanf";
1119 octave_value_list retval;
1121 int nargin = args.length ();
1123 if (nargin == 3 && args(2).is_string ())
1125 octave_stream os = octave_stream_list::lookup (args(0), who);
1129 if (args(1).is_string ())
1130 retval = os.oscanf (args(1), who);
1132 ::error ("%s: format must be a string", who.c_str ());
1138 retval (0) = Matrix ();
1140 if (nargin == 2 || nargin == 3)
1142 octave_stream os = octave_stream_list::lookup (args(0), who);
1146 if (args(1).is_string ())
1148 octave_idx_type count = 0;
1150 Array<double> size = (nargin == 3)
1151 ? args(2).vector_value ()
1152 : Array<double> (1, lo_ieee_inf_value ());
1156 octave_value tmp = os.scanf (args(1), size, count, who);
1166 ::error ("%s: format must be a string", who.c_str ());
1176DEFUN (sscanf, args, ,
1178@deftypefn {Built-in Function} {[@var{val}, @var{count}] =} sscanf (@var{string}, @var{template}, @var{size})\n\
1179@deftypefnx {Built-in Function} {[@var{v1}, @var{v2}, @dots{}, @var{count}] =} sscanf (@var{string}, @var{template}, \"C\")\n\
1180This is like @code{fscanf}, except that the characters are taken from the\n\
1181string @var{string} instead of from a stream. Reaching the end of the\n\
1182string is treated as an end-of-file condition.\n\
1183@seealso{fscanf, scanf, sprintf}\n\
1186 static std::string who = "sscanf";
1188 octave_value_list retval;
1190 int nargin = args.length ();
1192 if (nargin == 3 && args(2).is_string ())
1194 if (args(0).is_string ())
1196 std::string data = args(0).string_value ();
1198 octave_stream os = octave_istrstream::create (data);
1202 if (args(1).is_string ())
1203 retval = os.oscanf (args(1), who);
1205 ::error ("%s: format must be a string", who.c_str ());
1208 ::error ("%s: unable to create temporary input buffer",
1212 ::error ("%s: first argument must be a string", who.c_str ());
1216 if (nargin == 2 || nargin == 3)
1219 retval(2) = "unknown error";
1221 retval(0) = Matrix ();
1223 if (args(0).is_string ())
1225 std::string data = args(0).string_value ();
1227 octave_stream os = octave_istrstream::create (data);
1231 if (args(1).is_string ())
1233 octave_idx_type count = 0;
1235 Array<double> size = (nargin == 3)
1236 ? args(2).vector_value ()
1237 : Array<double> (1, lo_ieee_inf_value ());
1239 octave_value tmp = os.scanf (args(1), size, count, who);
1243 // FIXME -- is this the right thing to do?
1244 // Extract error message first, because getting
1245 // position will clear it.
1246 std::string errmsg = os.error ();
1248 retval(3) = os.tell () + 1;
1255 ::error ("%s: format must be a string", who.c_str ());
1258 ::error ("%s: unable to create temporary input buffer",
1262 ::error ("%s: first argument must be a string", who.c_str ());
1271DEFUN (scanf, args, nargout,
1273@deftypefn {Built-in Function} {[@var{val}, @var{count}] =} scanf (@var{template}, @var{size})\n\
1274@deftypefnx {Built-in Function} {[@var{v1}, @var{v2}, @dots{}, @var{count}]] =} scanf (@var{template}, \"C\")\n\
1275This is equivalent to calling @code{fscanf} with @var{fid} = @code{stdin}.\n\
1277It is currently not useful to call @code{scanf} in interactive\n\
1279@seealso{fscanf, sscanf, printf}\n\
1282 int nargin = args.length ();
1284 octave_value_list tmp_args (nargin+1, octave_value ());
1287 for (int i = 0; i < nargin; i++)
1288 tmp_args (i+1) = args (i);
1290 return Ffscanf (tmp_args, nargout);
1294do_fread (octave_stream& os, const octave_value& size_arg,
1295 const octave_value& prec_arg, const octave_value& skip_arg,
1296 const octave_value& arch_arg, octave_idx_type& count)
1298 octave_value retval;
1302 Array<double> size = size_arg.vector_value ();
1306 std::string prec = prec_arg.string_value ();
1311 oct_data_conv::data_type input_type;
1312 oct_data_conv::data_type output_type;
1314 oct_data_conv::string_to_data_type (prec, block_size,
1315 input_type, output_type);
1319 int skip = skip_arg.int_value (true);
1323 std::string arch = arch_arg.string_value ();
1327 oct_mach_info::float_format flt_fmt
1328 = oct_mach_info::string_to_float_format (arch);
1331 retval = os.read (size, block_size, input_type,
1332 output_type, skip, flt_fmt, count);
1335 ::error ("fread: architecture type must be a string");
1338 ::error ("fread: skip must be an integer");
1341 ::error ("fread: invalid data type specified");
1344 ::error ("fread: precision must be a string");
1347 ::error ("fread: invalid size specified");
1352DEFUN (fread, args, ,
1354@deftypefn {Built-in Function} {[@var{val}, @var{count}] =} fread (@var{fid}, @var{size}, @var{precision}, @var{skip}, @var{arch})\n\
1355Read binary data of type @var{precision} from the specified file ID\n\
1358The optional argument @var{size} specifies the amount of data to read\n\
1363Read as much as possible, returning a column vector.\n\
1366Read up to @var{nr} elements, returning a column vector.\n\
1368@item [@var{nr}, Inf]\n\
1369Read as much as possible, returning a matrix with @var{nr} rows. If the\n\
1370number of elements read is not an exact multiple of @var{nr}, the last\n\
1371column is padded with zeros.\n\
1373@item [@var{nr}, @var{nc}]\n\
1374Read up to @code{@var{nr} * @var{nc}} elements, returning a matrix with\n\
1375@var{nr} rows. If the number of elements read is not an exact multiple\n\
1376of @var{nr}, the last column is padded with zeros.\n\
1380If @var{size} is omitted, a value of @code{Inf} is assumed.\n\
1382The optional argument @var{precision} is a string specifying the type of\n\
1383data to read and may be one of\n\
1387@itemx \"signed char\"\n\
1391@itemx \"unsigned char\"\n\
1392Unsigned character.\n\
1395@itemx \"integer*1\"\n\
13978-bit signed integer.\n\
1400@itemx \"integer*2\"\n\
140116-bit signed integer.\n\
1404@itemx \"integer*4\"\n\
140532-bit signed integer.\n\
1408@itemx \"integer*8\"\n\
140964-bit signed integer.\n\
14128-bit unsigned integer.\n\
141516-bit unsigned integer.\n\
141832-bit unsigned integer.\n\
142164-bit unsigned integer.\n\
1424@itemx \"float32\"\n\
142632-bit floating point number.\n\
1429@itemx \"float64\"\n\
143164-bit floating point number.\n\
1438Short integer (size is platform dependent).\n\
1441Integer (size is platform dependent).\n\
1444Long integer (size is platform dependent).\n\
1447@itemx \"unsigned short\"\n\
1448Unsigned short integer (size is platform dependent).\n\
1451@itemx \"unsigned int\"\n\
1452Unsigned integer (size is platform dependent).\n\
1455@itemx \"unsigned long\"\n\
1456Unsigned long integer (size is platform dependent).\n\
1459Single precision floating point number (size is platform dependent).\n\
1463The default precision is @code{\"uchar\"}.\n\
1465The @var{precision} argument may also specify an optional repeat\n\
1466count. For example, @samp{32*single} causes @code{fread} to read\n\
1467a block of 32 single precision floating point numbers. Reading in\n\
1468blocks is useful in combination with the @var{skip} argument.\n\
1470The @var{precision} argument may also specify a type conversion.\n\
1471For example, @samp{int16=>int32} causes @code{fread} to read 16-bit\n\
1472integer values and return an array of 32-bit integer values. By\n\
1473default, @code{fread} returns a double precision array. The special\n\
1474form @samp{*TYPE} is shorthand for @samp{TYPE=>TYPE}.\n\
1476The conversion and repeat counts may be combined. For example, the\n\
1477specification @samp{32*single=>single} causes @code{fread} to read\n\
1478blocks of single precision floating point values and return an array\n\
1479of single precision values instead of the default array of double\n\
1482The optional argument @var{skip} specifies the number of bytes to skip\n\
1483after each element (or block of elements) is read. If it is not\n\
1484specified, a value of 0 is assumed. If the final block read is not\n\
1485complete, the final skip is omitted. For example,\n\
1488fread (f, 10, \"3*single=>single\", 8)\n\
1492will omit the final 8-byte skip because the last read will not be\n\
1493a complete block of 3 values.\n\
1495The optional argument @var{arch} is a string specifying the data format\n\
1496for the file. Valid values are\n\
1500The format of the current machine.\n\
1506IEEE little endian.\n\
1509VAX D floating format.\n\
1512VAX G floating format.\n\
1515Cray floating format.\n\
1519Conversions are currently only supported for @code{\"ieee-be\"} and\n\
1520@code{\"ieee-le\"} formats.\n\
1522The data read from the file is returned in @var{val}, and the number of\n\
1523values read is returned in @code{count}\n\
1524@seealso{fwrite, fopen, fclose}\n\
1527 octave_value_list retval;
1529 int nargin = args.length ();
1531 if (nargin > 0 && nargin < 6)
1534 retval(0) = Matrix ();
1536 octave_stream os = octave_stream_list::lookup (args(0), "fread");
1540 octave_value size = lo_ieee_inf_value ();
1541 octave_value prec = "uchar";
1542 octave_value skip = 0;
1543 octave_value arch = "unknown";
1547 if (nargin > idx && ! args(idx).is_string ())
1558 else if (skip.is_string ())
1564 octave_idx_type count = -1;
1566 octave_value tmp = do_fread (os, size, prec, skip, arch, count);
1579do_fwrite (octave_stream& os, const octave_value& data,
1580 const octave_value& prec_arg, const octave_value& skip_arg,
1581 const octave_value& arch_arg)
1585 std::string prec = prec_arg.string_value ();
1590 oct_data_conv::data_type output_type;
1592 oct_data_conv::string_to_data_type (prec, block_size, output_type);
1596 int skip = skip_arg.int_value (true);
1600 std::string arch = arch_arg.string_value ();
1604 oct_mach_info::float_format flt_fmt
1605 = oct_mach_info::string_to_float_format (arch);
1608 retval = os.write (data, block_size, output_type,
1612 ::error ("fwrite: architecture type must be a string");
1615 ::error ("fwrite: skip must be an integer");
1618 ::error ("fwrite: invalid precision specified");
1621 ::error ("fwrite: precision must be a string");
1626DEFUN (fwrite, args, ,
1628@deftypefn {Built-in Function} {@var{count} =} fwrite (@var{fid}, @var{data}, @var{precision}, @var{skip}, @var{arch})\n\
1629Write data in binary form of type @var{precision} to the specified file\n\
1630ID @var{fid}, returning the number of values successfully written to the\n\
1633The argument @var{data} is a matrix of values that are to be written to\n\
1634the file. The values are extracted in column-major order.\n\
1636The remaining arguments @var{precision}, @var{skip}, and @var{arch} are\n\
1637optional, and are interpreted as described for @code{fread}.\n\
1639The behavior of @code{fwrite} is undefined if the values in @var{data}\n\
1640are too large to fit in the specified precision.\n\
1641@seealso{fread, fopen, fclose}\n\
1644 octave_value retval = -1;
1646 int nargin = args.length ();
1648 if (nargin > 1 && nargin < 6)
1650 octave_stream os = octave_stream_list::lookup (args(0), "fwrite");
1654 octave_value prec = "uchar";
1655 octave_value skip = 0;
1656 octave_value arch = "unknown";
1660 octave_value data = args(idx++);
1670 else if (skip.is_string ())
1676 double status = do_fwrite (os, data, prec, skip, arch);
1687DEFUNX ("feof", Ffeof, args, ,
1689@deftypefn {Built-in Function} {} feof (@var{fid})\n\
1690Return 1 if an end-of-file condition has been encountered for a given\n\
1691file and 0 otherwise. Note that it will only return 1 if the end of the\n\
1692file has already been encountered, not if the next read operation will\n\
1693result in an end-of-file condition.\n\
1694@seealso{fread, fopen, fclose}\n\
1697 octave_value retval = -1;
1699 int nargin = args.length ();
1703 octave_stream os = octave_stream_list::lookup (args(0), "feof");
1706 retval = os.eof () ? 1.0 : 0.0;
1714DEFUNX ("ferror", Fferror, args, ,
1716@deftypefn {Built-in Function} {[@var{err}, @var{msg}] =} ferror (@var{fid}, \"clear\")\n\
1717Return 1 if an error condition has been encountered for the file ID\n\
1718@var{fid} and 0 otherwise. Note that it will only return 1 if an error\n\
1719has already been encountered, not if the next operation will result in\n\
1720an error condition.\n\
1722The second argument is optional. If it is supplied, also clear the\n\
1726 octave_value_list retval;
1728 int nargin = args.length ();
1730 if (nargin == 1 || nargin == 2)
1732 octave_stream os = octave_stream_list::lookup (args(0), "ferror");
1740 std::string opt = args(1).string_value ();
1743 clear = (opt == "clear");
1748 int error_number = 0;
1750 std::string error_message = os.error (clear, error_number);
1752 retval(1) = error_number;
1753 retval(0) = error_message;
1762DEFUN (popen, args, ,
1764@deftypefn {Built-in Function} {@var{fid} =} popen (@var{command}, @var{mode})\n\
1765Start a process and create a pipe. The name of the command to run is\n\
1766given by @var{command}. The file identifier corresponding to the input\n\
1767or output stream of the process is returned in @var{fid}. The argument\n\
1772The pipe will be connected to the standard output of the process, and\n\
1776The pipe will be connected to the standard input of the process, and\n\
1784fid = popen (\"ls -ltr / | tail -3\", \"r\");\n\
1785while (ischar (s = fgets (fid)))\n\
1786 fputs (stdout, s);\n\
1788 @print{} drwxr-xr-x 33 root root 3072 Feb 15 13:28 etc\n\
1789 @print{} drwxr-xr-x 3 root root 1024 Feb 15 13:28 lib\n\
1790 @print{} drwxrwxrwt 15 root root 2048 Feb 17 14:53 tmp\n\
1795 octave_value retval = -1;
1797 int nargin = args.length ();
1801 std::string name = args(0).string_value ();
1805 std::string mode = args(1).string_value ();
1811 octave_stream ips = octave_iprocstream::create (name);
1813 retval = octave_stream_list::insert (ips);
1815 else if (mode == "w")
1817 octave_stream ops = octave_oprocstream::create (name);
1819 retval = octave_stream_list::insert (ops);
1822 ::error ("popen: invalid mode specified");
1825 ::error ("popen: mode must be a string");
1828 ::error ("popen: name must be a string");
1836DEFUN (pclose, args, ,
1838@deftypefn {Built-in Function} {} pclose (@var{fid})\n\
1839Close a file identifier that was opened by @code{popen}. You may also\n\
1840use @code{fclose} for the same purpose.\n\
1843 octave_value retval = -1;
1845 int nargin = args.length ();
1848 retval = octave_stream_list::remove (args(0), "pclose");
1855DEFUNX ("tmpnam", Ftmpnam, args, ,
1857@deftypefn {Built-in Function} {} tmpnam (@var{dir}, @var{prefix})\n\
1858Return a unique temporary file name as a string.\n\
1860If @var{prefix} is omitted, a value of @code{\"oct-\"} is used.\n\
1861If @var{dir} is also omitted, the default directory for temporary files\n\
1862is used. If @var{dir} is provided, it must exist, otherwise the default\n\
1863directory for temporary files is used. Since the named file is not\n\
1864opened, by @code{tmpnam}, it is possible (though relatively unlikely)\n\
1865that it will not be available by the time your program attempts to open it.\n\
1866@seealso{tmpfile, mkstemp, P_tmpdir}\n\
1869 octave_value retval;
1871 int len = args.length ();
1875 std::string dir = len > 0 ? args(0).string_value () : std::string ();
1880 = len > 1 ? args(1).string_value () : std::string ("oct-");
1883 retval = octave_tempnam (dir, pfx);
1885 ::error ("expecting second argument to be a string");
1888 ::error ("expecting first argument to be a string");
1896DEFALIAS (octave_tmp_file_name, tmpnam);
1898DEFUN (tmpfile, args, ,
1900@deftypefn {Built-in Function} {[@var{fid}, @var{msg}] =} tmpfile ()\n\
1901Return the file ID corresponding to a new temporary file with a unique\n\
1902name. The file is opened in binary read/write (@code{\"w+b\"}) mode.\n\
1903The file will be deleted automatically when it is closed or when Octave\n\
1906If successful, @var{fid} is a valid file ID and @var{msg} is an empty\n\
1907string. Otherwise, @var{fid} is -1 and @var{msg} contains a\n\
1908system-dependent error message.\n\
1909@seealso{tmpnam, mkstemp, P_tmpdir}\n\
1912 octave_value_list retval;
1914 retval(1) = std::string ();
1917 int nargin = args.length ();
1921 FILE *fid = tmpfile ();
1927 std::ios::openmode md = fopen_mode_to_ios_mode ("w+b");
1929 octave_stream s = octave_stdiostream::create (nm, fid, md);
1932 retval(0) = octave_stream_list::insert (s);
1934 error ("tmpfile: failed to create octave_stdiostream object");
1939 using namespace std;
1940 retval(1) = ::strerror (errno);
1950#if defined (HAVE_MKSTEMPS)
1951// Prototype for mkstemps in libiberty
1952extern "C" int mkstemps (char *pattern, int suffix_len);
1955#if ! defined (HAVE_MKSTEMP) && ! defined (HAVE_MKSTEMPS) && defined (_MSC_VER)
1957#include <sys/stat.h>
1958int mkstemp (char *tmpl)
1962 ret = open (tmpl, O_RDWR | O_BINARY | O_CREAT | O_EXCL | _O_SHORT_LIVED,
1963 _S_IREAD | _S_IWRITE);
1966#define HAVE_MKSTEMP 1
1969DEFUN (mkstemp, args, ,
1971@deftypefn {Built-in Function} {[@var{fid}, @var{name}, @var{msg}] =} mkstemp (@var{template}, @var{delete})\n\
1972Return the file ID corresponding to a new temporary file with a unique\n\
1973name created from @var{template}. The last six characters of @var{template}\n\
1974must be @code{XXXXXX} and these are replaced with a string that makes the\n\
1975filename unique. The file is then created with mode read/write and\n\
1976permissions that are system dependent (on GNU/Linux systems, the permissions\n\
1977will be 0600 for versions of glibc 2.0.7 and later). The file is opened\n\
1978with the @w{@code{O_EXCL}} flag.\n\
1980If the optional argument @var{delete} is supplied and is true,\n\
1981the file will be deleted automatically when Octave exits, or when\n\
1982the function @code{purge_tmp_files} is called.\n\
1984If successful, @var{fid} is a valid file ID, @var{name} is the name of\n\
1985the file, and @var{msg} is an empty string. Otherwise, @var{fid}\n\
1986is -1, @var{name} is empty, and @var{msg} contains a system-dependent\n\
1988@seealso{tmpfile, tmpnam, P_tmpdir}\n\
1991 octave_value_list retval;
1993 retval(2) = std::string ();
1994 retval(1) = std::string ();
1997#if defined (HAVE_MKSTEMP) || defined (HAVE_MKSTEMPS)
1999 int nargin = args.length ();
2001 if (nargin == 1 || nargin == 2)
2003 std::string tmpl8 = args(0).string_value ();
2007 OCTAVE_LOCAL_BUFFER (char, tmp, tmpl8.size () + 1);
2008 strcpy (tmp, tmpl8.c_str ());
2010#if defined (HAVE_MKSTEMP)
2011 int fd = mkstemp (tmp);
2013 int fd = mkstemps (tmp, 0);
2018 using namespace std;
2019 retval(2) = ::strerror (errno);
2024 const char *fopen_mode = "w+";
2026 FILE *fid = fdopen (fd, fopen_mode);
2030 std::string nm = tmp;
2032 std::ios::openmode md = fopen_mode_to_ios_mode (fopen_mode);
2034 octave_stream s = octave_stdiostream::create (nm, fid, md);
2039 retval(0) = octave_stream_list::insert (s);
2041 if (nargin == 2 && args(1).is_true ())
2042 mark_for_deletion (nm);
2045 error ("mkstemp: failed to create octave_stdiostream object");
2049 using namespace std;
2050 retval(2) = ::strerror (errno);
2056 error ("mkstemp: expecting string as first argument");
2062 retval(2) = "mkstemp: not supported on this sytem";
2069convert (int x, int ibase, int obase)
2073 int tmp = x % obase;
2075 if (tmp > ibase - 1)
2076 ::error ("umask: invalid digit");
2081 while ((x = (x - tmp) / obase))
2084 if (tmp > ibase - 1)
2086 ::error ("umask: invalid digit");
2089 retval += mult * tmp;
2097DEFUNX ("umask", Fumask, args, ,
2099@deftypefn {Built-in Function} {} umask (@var{mask})\n\
2100Set the permission mask for file creation. The parameter @var{mask}\n\
2101is an integer, interpreted as an octal number. If successful,\n\
2102returns the previous value of the mask (as an integer to be\n\
2103interpreted as an octal number); otherwise an error message is printed.\n\
2106 octave_value_list retval;
2110 if (args.length () == 1)
2112 int mask = args(0).int_value (true);
2119 ::error ("umask: MASK must be a positive integer value");
2123 int oct_mask = convert (mask, 8, 10);
2126 status = convert (octave_umask (oct_mask), 10, 8);
2132 ::error ("umask: expecting integer argument");
2145const_value (const char *, const octave_value_list& args, int val)
2147 octave_value retval;
2149 int nargin = args.length ();
2159#if ! defined (P_tmpdir)
2160#define P_tmpdir "/tmp"
2163DEFUNX ("P_tmpdir", FP_tmpdir, args, ,
2165@deftypefn {Built-in Function} {} P_tmpdir ()\n\
2166Return the default name of the directory for temporary files on\n\
2167this system. The name of this directory is system dependent.\n\
2170 octave_value retval;
2172 int nargin = args.length ();
2182// NOTE: the values of SEEK_SET, SEEK_CUR, and SEEK_END have to be
2183// this way for Matlab compatibility.
2185DEFUNX ("SEEK_SET", FSEEK_SET, args, ,
2187@deftypefn {Built-in Function} {} SEEK_SET ()\n\
2188@deftypefnx {Built-in Function} {} SEEK_CUR ()\n\
2189@deftypefnx {Built-in Function} {} SEEK_END ()\n\
2190Return the value required to request that @code{fseek} perform\n\
2191one of the following actions:\n\
2194Position file relative to the beginning.\n\
2197Position file relative to the current position.\n\
2200Position file relative to the end.\n\
2204 return const_value ("SEEK_SET", args, -1);
2207DEFUNX ("SEEK_CUR", FSEEK_CUR, args, ,
2209@deftypefn {Built-in Function} {} SEEK_CUR ()\n\
2213 return const_value ("SEEK_CUR", args, 0);
2216DEFUNX ("SEEK_END", FSEEK_END, args, ,
2218@deftypefn {Built-in Function} {} SEEK_END ()\n\
2222 return const_value ("SEEK_END", args, 1);
2226const_value (const char *, const octave_value_list& args,
2227 const octave_value& val)
2229 octave_value retval;
2231 int nargin = args.length ();
2241DEFUNX ("stdin", Fstdin, args, ,
2243@deftypefn {Built-in Function} {} stdin ()\n\
2244Return the numeric value corresponding to the standard input stream.\n\
2245When Octave is used interactively, this is filtered through the command\n\
2246line editing functions.\n\
2247@seealso{stdout, stderr}\n\
2250 return const_value ("stdin", args, stdin_file);
2253DEFUNX ("stdout", Fstdout, args, ,
2255@deftypefn {Built-in Function} {} stdout ()\n\
2256Return the numeric value corresponding to the standard output stream.\n\
2257Data written to the standard output is normally filtered through the pager.\n\
2258@seealso{stdin, stderr}\n\
2261 return const_value ("stdout", args, stdout_file);
2264DEFUNX ("stderr", Fstderr, args, ,
2266@deftypefn {Built-in Function} {} stderr ()\n\
2267Return the numeric value corresponding to the standard error stream.\n\
2268Even if paging is turned on, the standard error is not sent to the\n\
2269pager. It is useful for error messages and prompts.\n\
2270@seealso{stdin, stdout}\n\
2273 return const_value ("stderr", args, stderr_file);