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>,
51#ifdef HAVE_SYS_TYPES_H
66#include "oct-locbuf.h"
72#include "oct-iostrm.h"
75#include "oct-prcstrm.h"
76#include "oct-stream.h"
77#include "oct-strstrm.h"
83static octave_value stdin_file;
84static octave_value stdout_file;
85static octave_value stderr_file;
87static octave_stream stdin_stream;
88static octave_stream stdout_stream;
89static octave_stream stderr_stream;
92initialize_file_io (void)
94 stdin_stream = octave_istream::create (&std::cin, "stdin");
96 // This uses octave_stdout (see pager.h), not std::cout so that Octave's
97 // standard output stream will pass through the pager.
99 stdout_stream = octave_ostream::create (&octave_stdout, "stdout");
101 stderr_stream = octave_ostream::create (&std::cerr, "stderr");
103 stdin_file = octave_stream_list::insert (stdin_stream);
104 stdout_file = octave_stream_list::insert (stdout_stream);
105 stderr_file = octave_stream_list::insert (stderr_stream);
111 octave_stream_list::clear ();
114// List of files to delete when we exit or crash.
116// FIXME -- this should really be static, but that causes
117// problems on some systems.
118std::stack <std::string> tmp_files;
121mark_for_deletion (const std::string& file)
123 tmp_files.push (file);
127cleanup_tmp_files (void)
129 while (! tmp_files.empty ())
131 std::string filename = tmp_files.top ();
133 unlink (filename.c_str ());
137static std::ios::openmode
138fopen_mode_to_ios_mode (const std::string& mode_arg)
140 std::ios::openmode retval = std::ios::in;
142 if (! mode_arg.empty ())
144 // Could probably be faster, but does it really matter?
146 std::string mode = mode_arg;
148 // 'W' and 'R' are accepted as 'w' and 'r', but we warn about
149 // them because Matlab says they perform "automatic flushing"
150 // but we don't know precisely what action that implies.
152 size_t pos = mode.find ('W');
154 if (pos != std::string::npos)
156 warning ("fopen: treating mode \"W\" as equivalent to \"w\"");
160 pos = mode.find ('R');
162 if (pos != std::string::npos)
164 warning ("fopen: treating mode \"R\" as equivalent to \"r\"");
168 pos = mode.find ('z');
170 if (pos != std::string::npos)
172#if defined (HAVE_ZLIB)
175 error ("this version of Octave does not support gzipped files");
182 retval = std::ios::in;
183 else if (mode == "wt")
184 retval = std::ios::out | std::ios::trunc;
185 else if (mode == "at")
186 retval = std::ios::out | std::ios::app;
187 else if (mode == "r+t")
188 retval = std::ios::in | std::ios::out;
189 else if (mode == "w+t")
190 retval = std::ios::in | std::ios::out | std::ios::trunc;
191 else if (mode == "a+t")
192 retval = std::ios::in | std::ios::out | std::ios::app;
193 else if (mode == "rb" || mode == "r")
194 retval = std::ios::in | std::ios::binary;
195 else if (mode == "wb" || mode == "w")
196 retval = std::ios::out | std::ios::trunc | std::ios::binary;
197 else if (mode == "ab" || mode == "a")
198 retval = std::ios::out | std::ios::app | std::ios::binary;
199 else if (mode == "r+b" || mode == "r+")
200 retval = std::ios::in | std::ios::out | std::ios::binary;
201 else if (mode == "w+b" || mode == "w+")
202 retval = (std::ios::in | std::ios::out | std::ios::trunc
204 else if (mode == "a+b" || mode == "a+")
205 retval = (std::ios::in | std::ios::out | std::ios::app
208 ::error ("invalid mode specified");
215DEFUN (fclose, args, ,
217@deftypefn {Built-in Function} {} fclose (@var{fid})\n\
218Closes the specified file. If successful, @code{fclose} returns 0,\n\
219otherwise, it returns -1.\n\
220@seealso{fopen, fseek, ftell}\n\
223 octave_value retval = -1;
225 int nargin = args.length ();
228 retval = octave_stream_list::remove (args(0), "fclose");
235DEFUN (fclear, args, ,
237@deftypefn {Built-in Function} {} fclear (@var{fid})\n\
238Clear the stream state for the specified file.\n\
243 int nargin = args.length ();
247 int fid = octave_stream_list::get_file_number (args (0));
249 octave_stream os = octave_stream_list::lookup (fid, "fclear");
260DEFUN (fflush, args, ,
262@deftypefn {Built-in Function} {} fflush (@var{fid})\n\
263Flush output to @var{fid}. This is useful for ensuring that all\n\
264pending output makes it to the screen before some other event occurs.\n\
265For example, it is always a good idea to flush the standard output\n\
266stream before calling @code{input}.\n\
268@code{fflush} returns 0 on success and an OS dependent error value\n\
269(@minus{}1 on unix) on error.\n\
270@seealso{fopen, fclose}\n\
273 octave_value retval = -1;
275 int nargin = args.length ();
279 // FIXME -- any way to avoid special case for stdout?
281 int fid = octave_stream_list::get_file_number (args (0));
285 flush_octave_stdout ();
291 octave_stream os = octave_stream_list::lookup (fid, "fflush");
294 retval = os.flush ();
305@deftypefn {Built-in Function} {} fgetl (@var{fid}, @var{len})\n\
306Read characters from a file, stopping after a newline, or EOF,\n\
307or @var{len} characters have been read. The characters read, excluding\n\
308the possible trailing newline, are returned as a string.\n\
310If @var{len} is omitted, @code{fgetl} reads until the next newline\n\
313If there are no more characters to read, @code{fgetl} returns @minus{}1.\n\
314@seealso{fread, fscanf}\n\
317 static std::string who = "fgetl";
319 octave_value_list retval;
324 int nargin = args.length ();
326 if (nargin == 1 || nargin == 2)
328 octave_stream os = octave_stream_list::lookup (args(0), who);
332 octave_value len_arg = (nargin == 2) ? args(1) : octave_value ();
336 std::string tmp = os.getl (len_arg, err, who);
338 if (! (error_state || err))
340 retval(1) = tmp.length ();
353@deftypefn {Built-in Function} {} fgets (@var{fid}, @var{len})\n\
354Read characters from a file, stopping after a newline, or EOF,\n\
355or @var{len} characters have been read. The characters read, including\n\
356the possible trailing newline, are returned as a string.\n\
358If @var{len} is omitted, @code{fgets} reads until the next newline\n\
361If there are no more characters to read, @code{fgets} returns @minus{}1.\n\
362@seealso{fputs, fopen, fread, fscanf}\n\
365 static std::string who = "fgets";
367 octave_value_list retval;
372 int nargin = args.length ();
374 if (nargin == 1 || nargin == 2)
376 octave_stream os = octave_stream_list::lookup (args(0), who);
380 octave_value len_arg = (nargin == 2) ? args(1) : octave_value ();
384 std::string tmp = os.gets (len_arg, err, who);
386 if (! (error_state || err))
388 retval(1) = tmp.length ();
399DEFUN (fskipl, args, ,
401@deftypefn {Built-in Function} {} fskipl (@var{fid}, @var{count})\n\
402Skips a given number of lines, i.e., discards characters until an end-of-line\n\
403is met exactly @var{count}-times, or end-of-file occurs.\n\
404Returns the number of lines skipped (end-of-line sequences encountered).\n\
405If @var{count} is omitted, it defaults to 1. @var{count} may also be\n\
406@code{Inf}, in which case lines are skipped to the end of file.\n\
407This form is suitable for counting lines in a file.\n\
408@seealso{fgetl, fgets}\n\
411 static std::string who = "fskipl";
415 int nargin = args.length ();
417 if (nargin == 1 || nargin == 2)
419 octave_stream os = octave_stream_list::lookup (args(0), who);
423 octave_value count_arg = (nargin == 2) ? args(1) : octave_value ();
427 long tmp = os.skipl (count_arg, err, who);
429 if (! (error_state || err))
441do_stream_open (const std::string& name, const std::string& mode,
442 const std::string& arch, int& fid)
444 octave_stream retval;
448 std::ios::openmode md = fopen_mode_to_ios_mode (mode);
452 oct_mach_info::float_format flt_fmt =
453 oct_mach_info::string_to_float_format (arch);
457 std::string fname = file_ops::tilde_expand (name);
459 file_stat fs (fname);
461 if (! (md & std::ios::out
462 || octave_env::absolute_pathname (fname)
463 || octave_env::rooted_relative_pathname (fname)))
467 std::string tmp = octave_env::make_absolute
468 (load_path::find_file (fname), octave_env::getcwd ());
472 warning_with_id ("Octave:fopen-file-in-path",
473 "fopen: file found in load path");
481 std::string tmode = mode;
483 // Use binary mode if 't' is not specified, but don't add
484 // 'b' if it is already present.
486 size_t bpos = tmode.find ('b');
487 size_t tpos = tmode.find ('t');
489 if (bpos == std::string::npos && tpos == std::string::npos)
492#if defined (HAVE_ZLIB)
493 size_t pos = tmode.find ('z');
495 if (pos != std::string::npos)
497 tmode.erase (pos, 1);
499 gzFile fptr = ::gzopen (fname.c_str (), tmode.c_str ());
502 retval = octave_zstdiostream::create (fname, fptr, md, flt_fmt);
506 retval.error (::strerror (errno));
512 FILE *fptr = ::fopen (fname.c_str (), tmode.c_str ());
514 retval = octave_stdiostream::create (fname, fptr, md, flt_fmt);
519 retval.error (::strerror (errno));
531do_stream_open (const octave_value& tc_name, const octave_value& tc_mode,
532 const octave_value& tc_arch, const char *fcn, int& fid)
534 octave_stream retval;
538 std::string name = tc_name.string_value ();
542 std::string mode = tc_mode.string_value ();
546 std::string arch = tc_arch.string_value ();
549 retval = do_stream_open (name, mode, arch, fid);
551 ::error ("%s: architecture type must be a string", fcn);
554 ::error ("%s: file mode must be a string", fcn);
557 ::error ("%s: file name must be a string", fcn);
564@deftypefn {Built-in Function} {[@var{fid}, @var{msg}] =} fopen (@var{name}, @var{mode}, @var{arch})\n\
565@deftypefnx {Built-in Function} {@var{fid_list} =} fopen (\"all\")\n\
566@deftypefnx {Built-in Function} {[@var{file}, @var{mode}, @var{arch}] =} fopen (@var{fid})\n\
567The first form of the @code{fopen} function opens the named file with\n\
568the specified mode (read-write, read-only, etc.) and architecture\n\
569interpretation (IEEE big endian, IEEE little endian, etc.), and returns\n\
570an integer value that may be used to refer to the file later. If an\n\
571error occurs, @var{fid} is set to @minus{}1 and @var{msg} contains the\n\
572corresponding system error message. The @var{mode} is a one or two\n\
573character string that specifies whether the file is to be opened for\n\
574reading, writing, or both.\n\
576The second form of the @code{fopen} function returns a vector of file ids\n\
577corresponding to all the currently open files, excluding the\n\
578@code{stdin}, @code{stdout}, and @code{stderr} streams.\n\
580The third form of the @code{fopen} function returns information about the\n\
581open file given its file id.\n\
586myfile = fopen (\"splat.dat\", \"r\", \"ieee-le\");\n\
590opens the file @file{splat.dat} for reading. If necessary, binary\n\
591numeric values will be read assuming they are stored in IEEE format with\n\
592the least significant bit first, and then converted to the native\n\
595Opening a file that is already open simply opens it again and returns a\n\
596separate file id. It is not an error to open a file several times,\n\
597though writing to the same file through several different file ids may\n\
598produce unexpected results.\n\
600The possible values @samp{mode} may have are\n\
604Open a file for reading.\n\
607Open a file for writing. The previous contents are discarded.\n\
610Open or create a file for writing at the end of the file.\n\
613Open an existing file for reading and writing.\n\
616Open a file for reading or writing. The previous contents are\n\
620Open or create a file for reading or writing at the end of the\n\
624Append a \"t\" to the mode string to open the file in text mode or a\n\
625\"b\" to open in binary mode. On Windows and Macintosh systems, text\n\
626mode reading and writing automatically converts linefeeds to the\n\
627appropriate line end character for the system (carriage-return linefeed\n\
628on Windows, carriage-return on Macintosh). The default if no mode is\n\
629specified is binary mode.\n\
631Additionally, you may append a \"z\" to the mode string to open a\n\
632gzipped file for reading or writing. For this to be successful, you\n\
633must also open the file in binary mode.\n\
635The parameter @var{arch} is a string specifying the default data format\n\
636for the file. Valid values for @var{arch} are:\n\
640The format of the current machine (this is the default).\n\
643IEEE big endian format.\n\
646IEEE little endian format.\n\
649VAX D floating format.\n\
652VAX G floating format.\n\
655Cray floating format.\n\
659however, conversions are currently only supported for @samp{native}\n\
660@samp{ieee-be}, and @samp{ieee-le} formats.\n\
661@seealso{fclose, fgets, fputs, fread, fseek, ferror, fprintf, fscanf, ftell, fwrite}\n\
664 octave_value_list retval;
668 int nargin = args.length ();
672 if (args(0).is_string ())
674 // If there is only one argument and it is a string but it
675 // is not the string "all", we assume it is a file to open
676 // with MODE = "r". To open a file called "all", you have
677 // to supply more than one argument.
679 if (args(0).string_value () == "all")
680 return octave_stream_list::open_file_numbers ();
684 string_vector tmp = octave_stream_list::get_info (args(0));
697 if (nargin > 0 && nargin < 4)
699 octave_value mode = (nargin == 2 || nargin == 3)
700 ? args(1) : octave_value ("r");
702 octave_value arch = (nargin == 3)
703 ? args(2) : octave_value ("native");
707 octave_stream os = do_stream_open (args(0), mode, arch, "fopen", fid);
709 if (os && ! error_state)
712 retval(0) = octave_stream_list::insert (os);
716 int error_number = 0;
718 retval(1) = os.error (false, error_number);
728DEFUN (freport, args, ,
730@deftypefn {Built-in Function} {} freport ()\n\
731Print a list of which files have been opened, and whether they are open\n\
732for reading, writing, or both. For example,\n\
738 @print{} number mode name\n\
740 @print{} 0 r stdin\n\
741 @print{} 1 w stdout\n\
742 @print{} 2 w stderr\n\
743 @print{} 3 r myfile\n\
748 octave_value_list retval;
750 int nargin = args.length ();
753 warning ("freport: ignoring extra arguments");
755 octave_stdout << octave_stream_list::list_open_files ();
760DEFUN (frewind, args, nargout,
762@deftypefn {Built-in Function} {} frewind (@var{fid})\n\
763Move the file pointer to the beginning of the file @var{fid}, returning\n\
7640 for success, and -1 if an error was encountered. It is equivalent to\n\
765@code{fseek (@var{fid}, 0, SEEK_SET)}.\n\
772 int nargin = args.length ();
776 octave_stream os = octave_stream_list::lookup (args(0), "frewind");
779 result = os.rewind ();
792@deftypefn {Built-in Function} {} fseek (@var{fid}, @var{offset}, @var{origin})\n\
793Set the file pointer to any location within the file @var{fid}.\n\
795The pointer is positioned @var{offset} characters from the @var{origin},\n\
796which may be one of the predefined variables @w{@code{SEEK_CUR}} (current\n\
797position), @w{@code{SEEK_SET}} (beginning), or @w{@code{SEEK_END}} (end of\n\
798file) or strings \"cof\", \"bof\" or \"eof\". If @var{origin} is omitted,\n\
799@w{@code{SEEK_SET}} is assumed. The offset must be zero, or a value returned\n\
800by @code{ftell} (in which case @var{origin} must be @w{@code{SEEK_SET}}).\n\
802Return 0 on success and -1 on error.\n\
803@seealso{ftell, fopen, fclose}\n\
806 octave_value retval = -1;
808 int nargin = args.length ();
810 if (nargin == 2 || nargin == 3)
812 octave_stream os = octave_stream_list::lookup (args(0), "fseek");
816 octave_value origin_arg = (nargin == 3)
817 ? args(2) : octave_value (-1.0);
819 retval = os.seek (args(1), origin_arg);
830@deftypefn {Built-in Function} {} ftell (@var{fid})\n\
831Return the position of the file pointer as the number of characters\n\
832from the beginning of the file @var{fid}.\n\
833@seealso{fseek, fopen, fclose}\n\
836 octave_value retval = -1;
838 int nargin = args.length ();
842 octave_stream os = octave_stream_list::lookup (args(0), "ftell");
853DEFUN (fprintf, args, nargout,
855@deftypefn {Built-in Function} {} fprintf (@var{fid}, @var{template}, @dots{})\n\
856This function is just like @code{printf}, except that the output is\n\
857written to the stream @var{fid} instead of @code{stdout}.\n\
858If @var{fid} is omitted, the output is written to @code{stdout}.\n\
859@seealso{printf, sprintf, fread, fscanf, fopen, fclose}\n\
862 static std::string who = "fprintf";
868 int nargin = args.length ();
870 if (nargin > 1 || (nargin > 0 && args(0).is_string ()))
875 if (args(0).is_string ())
877 os = octave_stream_list::lookup (1, who);
882 os = octave_stream_list::lookup (args(0), who);
887 if (args(fmt_n).is_string ())
889 octave_value_list tmp_args;
891 if (nargin > 1 + fmt_n)
893 tmp_args.resize (nargin-fmt_n-1, octave_value ());
895 for (int i = fmt_n + 1; i < nargin; i++)
896 tmp_args(i-fmt_n-1) = args(i);
899 result = os.printf (args(fmt_n), tmp_args, who);
902 ::error ("%s: format must be a string", who.c_str ());
914DEFUN (printf, args, nargout,
916@deftypefn {Built-in Function} {} printf (@var{template}, @dots{})\n\
917Print optional arguments under the control of the template string\n\
918@var{template} to the stream @code{stdout} and return the number of\n\
919characters printed.\n\
920@ifclear OCTAVE_MANUAL\n\
922See the Formatted Output section of the GNU Octave manual for a\n\
923complete description of the syntax of the template string.\n\
925@seealso{fprintf, sprintf, scanf}\n\
928 static std::string who = "printf";
934 int nargin = args.length ();
938 if (args(0).is_string ())
940 octave_value_list tmp_args;
944 tmp_args.resize (nargin-1, octave_value ());
946 for (int i = 1; i < nargin; i++)
947 tmp_args(i-1) = args(i);
950 result = stdout_stream.printf (args(0), tmp_args, who);
953 ::error ("%s: format must be a string", who.c_str ());
966@deftypefn {Built-in Function} {} fputs (@var{fid}, @var{string})\n\
967Write a string to a file with no formatting.\n\
969Return a non-negative number on success and EOF on error.\n\
970@seealso{scanf, sscanf, fread, fprintf, fgets, fscanf}\n\
973 static std::string who = "fputs";
975 octave_value retval = -1;
977 int nargin = args.length ();
981 octave_stream os = octave_stream_list::lookup (args(0), who);
984 retval = os.puts (args(1), who);
994@deftypefn {Built-in Function} {} puts (@var{string})\n\
995Write a string to the standard output with no formatting.\n\
997Return a non-negative number on success and EOF on error.\n\
1000 static std::string who = "puts";
1002 octave_value retval = -1;
1004 if (args.length () == 1)
1005 retval = stdout_stream.puts (args(0), who);
1012DEFUN (sprintf, args, ,
1014@deftypefn {Built-in Function} {} sprintf (@var{template}, @dots{})\n\
1015This is like @code{printf}, except that the output is returned as a\n\
1016string. Unlike the C library function, which requires you to provide a\n\
1017suitably sized string as an argument, Octave's @code{sprintf} function\n\
1018returns the string, automatically sized to hold all of the items\n\
1020@seealso{printf, fprintf, sscanf}\n\
1023 static std::string who = "sprintf";
1025 octave_value_list retval;
1027 int nargin = args.length ();
1032 retval(1) = "unknown error";
1035 octave_ostrstream *ostr = new octave_ostrstream ();
1037 octave_stream os (ostr);
1041 octave_value fmt_arg = args(0);
1043 if (fmt_arg.is_string ())
1045 octave_value_list tmp_args;
1049 tmp_args.resize (nargin-1, octave_value ());
1051 for (int i = 1; i < nargin; i++)
1052 tmp_args(i-1) = args(i);
1055 retval(2) = os.printf (fmt_arg, tmp_args, who);
1056 retval(1) = os.error ();
1057 retval(0) = octave_value (ostr->str (),
1058 fmt_arg.is_sq_string () ? '\'' : '"');
1061 ::error ("%s: format must be a string", who.c_str ());
1064 ::error ("%s: unable to create output buffer", who.c_str ());
1072DEFUN (fscanf, args, ,
1074@deftypefn {Built-in Function} {[@var{val}, @var{count}] =} fscanf (@var{fid}, @var{template}, @var{size})\n\
1075@deftypefnx {Built-in Function} {[@var{v1}, @var{v2}, @dots{}, @var{count}] =} fscanf (@var{fid}, @var{template}, \"C\")\n\
1076In the first form, read from @var{fid} according to @var{template},\n\
1077returning the result in the matrix @var{val}.\n\
1079The optional argument @var{size} specifies the amount of data to read\n\
1084Read as much as possible, returning a column vector.\n\
1087Read up to @var{nr} elements, returning a column vector.\n\
1089@item [@var{nr}, Inf]\n\
1090Read as much as possible, returning a matrix with @var{nr} rows. If the\n\
1091number of elements read is not an exact multiple of @var{nr}, the last\n\
1092column is padded with zeros.\n\
1094@item [@var{nr}, @var{nc}]\n\
1095Read up to @code{@var{nr} * @var{nc}} elements, returning a matrix with\n\
1096@var{nr} rows. If the number of elements read is not an exact multiple\n\
1097of @var{nr}, the last column is padded with zeros.\n\
1101If @var{size} is omitted, a value of @code{Inf} is assumed.\n\
1103A string is returned if @var{template} specifies only character\n\
1106The number of items successfully read is returned in @var{count}.\n\
1108In the second form, read from @var{fid} according to @var{template},\n\
1109with each conversion specifier in @var{template} corresponding to a\n\
1110single scalar return value. This form is more `C-like', and also\n\
1111compatible with previous versions of Octave. The number of successful\n\
1112conversions is returned in @var{count}\n\
1113@ifclear OCTAVE_MANUAL\n\
1115See the Formatted Input section of the GNU Octave manual for a\n\
1116complete description of the syntax of the template string.\n\
1118@seealso{scanf, sscanf, fread, fprintf, fgets, fputs}\n\
1121 static std::string who = "fscanf";
1123 octave_value_list retval;
1125 int nargin = args.length ();
1127 if (nargin == 3 && args(2).is_string ())
1129 octave_stream os = octave_stream_list::lookup (args(0), who);
1133 if (args(1).is_string ())
1134 retval = os.oscanf (args(1), who);
1136 ::error ("%s: format must be a string", who.c_str ());
1142 retval (0) = Matrix ();
1144 if (nargin == 2 || nargin == 3)
1146 octave_stream os = octave_stream_list::lookup (args(0), who);
1150 if (args(1).is_string ())
1152 octave_idx_type count = 0;
1154 Array<double> size = (nargin == 3)
1155 ? args(2).vector_value ()
1156 : Array<double> (1, lo_ieee_inf_value ());
1160 octave_value tmp = os.scanf (args(1), size, count, who);
1170 ::error ("%s: format must be a string", who.c_str ());
1180DEFUN (sscanf, args, ,
1182@deftypefn {Built-in Function} {[@var{val}, @var{count}] =} sscanf (@var{string}, @var{template}, @var{size})\n\
1183@deftypefnx {Built-in Function} {[@var{v1}, @var{v2}, @dots{}, @var{count}] =} sscanf (@var{string}, @var{template}, \"C\")\n\
1184This is like @code{fscanf}, except that the characters are taken from the\n\
1185string @var{string} instead of from a stream. Reaching the end of the\n\
1186string is treated as an end-of-file condition.\n\
1187@seealso{fscanf, scanf, sprintf}\n\
1190 static std::string who = "sscanf";
1192 octave_value_list retval;
1194 int nargin = args.length ();
1196 if (nargin == 3 && args(2).is_string ())
1198 if (args(0).is_string ())
1200 std::string data = args(0).string_value ();
1202 octave_stream os = octave_istrstream::create (data);
1206 if (args(1).is_string ())
1207 retval = os.oscanf (args(1), who);
1209 ::error ("%s: format must be a string", who.c_str ());
1212 ::error ("%s: unable to create temporary input buffer",
1216 ::error ("%s: first argument must be a string", who.c_str ());
1220 if (nargin == 2 || nargin == 3)
1223 retval(2) = "unknown error";
1225 retval(0) = Matrix ();
1227 if (args(0).is_string ())
1229 std::string data = args(0).string_value ();
1231 octave_stream os = octave_istrstream::create (data);
1235 if (args(1).is_string ())
1237 octave_idx_type count = 0;
1239 Array<double> size = (nargin == 3)
1240 ? args(2).vector_value ()
1241 : Array<double> (1, lo_ieee_inf_value ());
1243 octave_value tmp = os.scanf (args(1), size, count, who);
1247 // FIXME -- is this the right thing to do?
1248 // Extract error message first, because getting
1249 // position will clear it.
1250 std::string errmsg = os.error ();
1252 retval(3) = os.tell () + 1;
1259 ::error ("%s: format must be a string", who.c_str ());
1262 ::error ("%s: unable to create temporary input buffer",
1266 ::error ("%s: first argument must be a string", who.c_str ());
1275DEFUN (scanf, args, nargout,
1277@deftypefn {Built-in Function} {[@var{val}, @var{count}] =} scanf (@var{template}, @var{size})\n\
1278@deftypefnx {Built-in Function} {[@var{v1}, @var{v2}, @dots{}, @var{count}]] =} scanf (@var{template}, \"C\")\n\
1279This is equivalent to calling @code{fscanf} with @var{fid} = @code{stdin}.\n\
1281It is currently not useful to call @code{scanf} in interactive\n\
1283@seealso{fscanf, sscanf, printf}\n\
1286 int nargin = args.length ();
1288 octave_value_list tmp_args (nargin+1, octave_value ());
1291 for (int i = 0; i < nargin; i++)
1292 tmp_args (i+1) = args (i);
1294 return Ffscanf (tmp_args, nargout);
1298do_fread (octave_stream& os, const octave_value& size_arg,
1299 const octave_value& prec_arg, const octave_value& skip_arg,
1300 const octave_value& arch_arg, octave_idx_type& count)
1302 octave_value retval;
1306 Array<double> size = size_arg.vector_value ();
1310 std::string prec = prec_arg.string_value ();
1315 oct_data_conv::data_type input_type;
1316 oct_data_conv::data_type output_type;
1318 oct_data_conv::string_to_data_type (prec, block_size,
1319 input_type, output_type);
1323 int skip = skip_arg.int_value (true);
1327 std::string arch = arch_arg.string_value ();
1331 oct_mach_info::float_format flt_fmt
1332 = oct_mach_info::string_to_float_format (arch);
1335 retval = os.read (size, block_size, input_type,
1336 output_type, skip, flt_fmt, count);
1339 ::error ("fread: architecture type must be a string");
1342 ::error ("fread: skip must be an integer");
1345 ::error ("fread: invalid data type specified");
1348 ::error ("fread: precision must be a string");
1351 ::error ("fread: invalid size specified");
1356DEFUN (fread, args, ,
1358@deftypefn {Built-in Function} {[@var{val}, @var{count}] =} fread (@var{fid}, @var{size}, @var{precision}, @var{skip}, @var{arch})\n\
1359Read binary data of type @var{precision} from the specified file ID\n\
1362The optional argument @var{size} specifies the amount of data to read\n\
1367Read as much as possible, returning a column vector.\n\
1370Read up to @var{nr} elements, returning a column vector.\n\
1372@item [@var{nr}, Inf]\n\
1373Read as much as possible, returning a matrix with @var{nr} rows. If the\n\
1374number of elements read is not an exact multiple of @var{nr}, the last\n\
1375column is padded with zeros.\n\
1377@item [@var{nr}, @var{nc}]\n\
1378Read up to @code{@var{nr} * @var{nc}} elements, returning a matrix with\n\
1379@var{nr} rows. If the number of elements read is not an exact multiple\n\
1380of @var{nr}, the last column is padded with zeros.\n\
1384If @var{size} is omitted, a value of @code{Inf} is assumed.\n\
1386The optional argument @var{precision} is a string specifying the type of\n\
1387data to read and may be one of\n\
1391@itemx \"signed char\"\n\
1395@itemx \"unsigned char\"\n\
1396Unsigned character.\n\
1399@itemx \"integer*1\"\n\
14018-bit signed integer.\n\
1404@itemx \"integer*2\"\n\
140516-bit signed integer.\n\
1408@itemx \"integer*4\"\n\
140932-bit signed integer.\n\
1412@itemx \"integer*8\"\n\
141364-bit signed integer.\n\
14168-bit unsigned integer.\n\
141916-bit unsigned integer.\n\
142232-bit unsigned integer.\n\
142564-bit unsigned integer.\n\
1428@itemx \"float32\"\n\
143032-bit floating point number.\n\
1433@itemx \"float64\"\n\
143564-bit floating point number.\n\
1442Short integer (size is platform dependent).\n\
1445Integer (size is platform dependent).\n\
1448Long integer (size is platform dependent).\n\
1451@itemx \"unsigned short\"\n\
1452Unsigned short integer (size is platform dependent).\n\
1455@itemx \"unsigned int\"\n\
1456Unsigned integer (size is platform dependent).\n\
1459@itemx \"unsigned long\"\n\
1460Unsigned long integer (size is platform dependent).\n\
1463Single precision floating point number (size is platform dependent).\n\
1467The default precision is @code{\"uchar\"}.\n\
1469The @var{precision} argument may also specify an optional repeat\n\
1470count. For example, @samp{32*single} causes @code{fread} to read\n\
1471a block of 32 single precision floating point numbers. Reading in\n\
1472blocks is useful in combination with the @var{skip} argument.\n\
1474The @var{precision} argument may also specify a type conversion.\n\
1475For example, @samp{int16=>int32} causes @code{fread} to read 16-bit\n\
1476integer values and return an array of 32-bit integer values. By\n\
1477default, @code{fread} returns a double precision array. The special\n\
1478form @samp{*TYPE} is shorthand for @samp{TYPE=>TYPE}.\n\
1480The conversion and repeat counts may be combined. For example, the\n\
1481specification @samp{32*single=>single} causes @code{fread} to read\n\
1482blocks of single precision floating point values and return an array\n\
1483of single precision values instead of the default array of double\n\
1486The optional argument @var{skip} specifies the number of bytes to skip\n\
1487after each element (or block of elements) is read. If it is not\n\
1488specified, a value of 0 is assumed. If the final block read is not\n\
1489complete, the final skip is omitted. For example,\n\
1492fread (f, 10, \"3*single=>single\", 8)\n\
1496will omit the final 8-byte skip because the last read will not be\n\
1497a complete block of 3 values.\n\
1499The optional argument @var{arch} is a string specifying the data format\n\
1500for the file. Valid values are\n\
1504The format of the current machine.\n\
1510IEEE little endian.\n\
1513VAX D floating format.\n\
1516VAX G floating format.\n\
1519Cray floating format.\n\
1523Conversions are currently only supported for @code{\"ieee-be\"} and\n\
1524@code{\"ieee-le\"} formats.\n\
1526The data read from the file is returned in @var{val}, and the number of\n\
1527values read is returned in @code{count}\n\
1528@seealso{fwrite, fopen, fclose}\n\
1531 octave_value_list retval;
1533 int nargin = args.length ();
1535 if (nargin > 0 && nargin < 6)
1538 retval(0) = Matrix ();
1540 octave_stream os = octave_stream_list::lookup (args(0), "fread");
1544 octave_value size = lo_ieee_inf_value ();
1545 octave_value prec = "uchar";
1546 octave_value skip = 0;
1547 octave_value arch = "unknown";
1551 if (nargin > idx && ! args(idx).is_string ())
1562 else if (skip.is_string ())
1568 octave_idx_type count = -1;
1570 octave_value tmp = do_fread (os, size, prec, skip, arch, count);
1583do_fwrite (octave_stream& os, const octave_value& data,
1584 const octave_value& prec_arg, const octave_value& skip_arg,
1585 const octave_value& arch_arg)
1589 std::string prec = prec_arg.string_value ();
1594 oct_data_conv::data_type output_type;
1596 oct_data_conv::string_to_data_type (prec, block_size, output_type);
1600 int skip = skip_arg.int_value (true);
1604 std::string arch = arch_arg.string_value ();
1608 oct_mach_info::float_format flt_fmt
1609 = oct_mach_info::string_to_float_format (arch);
1612 retval = os.write (data, block_size, output_type,
1616 ::error ("fwrite: architecture type must be a string");
1619 ::error ("fwrite: skip must be an integer");
1622 ::error ("fwrite: invalid precision specified");
1625 ::error ("fwrite: precision must be a string");
1630DEFUN (fwrite, args, ,
1632@deftypefn {Built-in Function} {@var{count} =} fwrite (@var{fid}, @var{data}, @var{precision}, @var{skip}, @var{arch})\n\
1633Write data in binary form of type @var{precision} to the specified file\n\
1634ID @var{fid}, returning the number of values successfully written to the\n\
1637The argument @var{data} is a matrix of values that are to be written to\n\
1638the file. The values are extracted in column-major order.\n\
1640The remaining arguments @var{precision}, @var{skip}, and @var{arch} are\n\
1641optional, and are interpreted as described for @code{fread}.\n\
1643The behavior of @code{fwrite} is undefined if the values in @var{data}\n\
1644are too large to fit in the specified precision.\n\
1645@seealso{fread, fopen, fclose}\n\
1648 octave_value retval = -1;
1650 int nargin = args.length ();
1652 if (nargin > 1 && nargin < 6)
1654 octave_stream os = octave_stream_list::lookup (args(0), "fwrite");
1658 octave_value prec = "uchar";
1659 octave_value skip = 0;
1660 octave_value arch = "unknown";
1664 octave_value data = args(idx++);
1674 else if (skip.is_string ())
1680 double status = do_fwrite (os, data, prec, skip, arch);
1691DEFUNX ("feof", Ffeof, args, ,
1693@deftypefn {Built-in Function} {} feof (@var{fid})\n\
1694Return 1 if an end-of-file condition has been encountered for a given\n\
1695file and 0 otherwise. Note that it will only return 1 if the end of the\n\
1696file has already been encountered, not if the next read operation will\n\
1697result in an end-of-file condition.\n\
1698@seealso{fread, fopen, fclose}\n\
1701 octave_value retval = -1;
1703 int nargin = args.length ();
1707 octave_stream os = octave_stream_list::lookup (args(0), "feof");
1710 retval = os.eof () ? 1.0 : 0.0;
1718DEFUNX ("ferror", Fferror, args, ,
1720@deftypefn {Built-in Function} {[@var{err}, @var{msg}] =} ferror (@var{fid}, \"clear\")\n\
1721Return 1 if an error condition has been encountered for the file ID\n\
1722@var{fid} and 0 otherwise. Note that it will only return 1 if an error\n\
1723has already been encountered, not if the next operation will result in\n\
1724an error condition.\n\
1726The second argument is optional. If it is supplied, also clear the\n\
1730 octave_value_list retval;
1732 int nargin = args.length ();
1734 if (nargin == 1 || nargin == 2)
1736 octave_stream os = octave_stream_list::lookup (args(0), "ferror");
1744 std::string opt = args(1).string_value ();
1747 clear = (opt == "clear");
1752 int error_number = 0;
1754 std::string error_message = os.error (clear, error_number);
1756 retval(1) = error_number;
1757 retval(0) = error_message;
1766DEFUN (popen, args, ,
1768@deftypefn {Built-in Function} {@var{fid} =} popen (@var{command}, @var{mode})\n\
1769Start a process and create a pipe. The name of the command to run is\n\
1770given by @var{command}. The file identifier corresponding to the input\n\
1771or output stream of the process is returned in @var{fid}. The argument\n\
1776The pipe will be connected to the standard output of the process, and\n\
1780The pipe will be connected to the standard input of the process, and\n\
1788fid = popen (\"ls -ltr / | tail -3\", \"r\");\n\
1789while (ischar (s = fgets (fid)))\n\
1790 fputs (stdout, s);\n\
1792 @print{} drwxr-xr-x 33 root root 3072 Feb 15 13:28 etc\n\
1793 @print{} drwxr-xr-x 3 root root 1024 Feb 15 13:28 lib\n\
1794 @print{} drwxrwxrwt 15 root root 2048 Feb 17 14:53 tmp\n\
1799 octave_value retval = -1;
1801 int nargin = args.length ();
1805 std::string name = args(0).string_value ();
1809 std::string mode = args(1).string_value ();
1815 octave_stream ips = octave_iprocstream::create (name);
1817 retval = octave_stream_list::insert (ips);
1819 else if (mode == "w")
1821 octave_stream ops = octave_oprocstream::create (name);
1823 retval = octave_stream_list::insert (ops);
1826 ::error ("popen: invalid mode specified");
1829 ::error ("popen: mode must be a string");
1832 ::error ("popen: name must be a string");
1840DEFUN (pclose, args, ,
1842@deftypefn {Built-in Function} {} pclose (@var{fid})\n\
1843Close a file identifier that was opened by @code{popen}. You may also\n\
1844use @code{fclose} for the same purpose.\n\
1847 octave_value retval = -1;
1849 int nargin = args.length ();
1852 retval = octave_stream_list::remove (args(0), "pclose");
1859DEFUN (tmpnam, args, ,
1861@deftypefn {Built-in Function} {} tmpnam (@var{dir}, @var{prefix})\n\
1862Return a unique temporary file name as a string.\n\
1864If @var{prefix} is omitted, a value of @code{\"oct-\"} is used.\n\
1865If @var{dir} is also omitted, the default directory for temporary files\n\
1866is used. If @var{dir} is provided, it must exist, otherwise the default\n\
1867directory for temporary files is used. Since the named file is not\n\
1868opened, by @code{tmpnam}, it is possible (though relatively unlikely)\n\
1869that it will not be available by the time your program attempts to open it.\n\
1870@seealso{tmpfile, mkstemp, P_tmpdir}\n\
1873 octave_value retval;
1875 int len = args.length ();
1879 std::string dir = len > 0 ? args(0).string_value () : std::string ();
1884 = len > 1 ? args(1).string_value () : std::string ("oct-");
1887 retval = file_ops::tempnam (dir, pfx);
1889 ::error ("expecting second argument to be a string");
1892 ::error ("expecting first argument to be a string");
1900DEFALIAS (octave_tmp_file_name, tmpnam);
1902DEFUN (tmpfile, args, ,
1904@deftypefn {Built-in Function} {[@var{fid}, @var{msg}] =} tmpfile ()\n\
1905Return the file ID corresponding to a new temporary file with a unique\n\
1906name. The file is opened in binary read/write (@code{\"w+b\"}) mode.\n\
1907The file will be deleted automatically when it is closed or when Octave\n\
1910If successful, @var{fid} is a valid file ID and @var{msg} is an empty\n\
1911string. Otherwise, @var{fid} is -1 and @var{msg} contains a\n\
1912system-dependent error message.\n\
1913@seealso{tmpnam, mkstemp, P_tmpdir}\n\
1916 octave_value_list retval;
1918 retval(1) = std::string ();
1921 int nargin = args.length ();
1925 FILE *fid = tmpfile ();
1931 std::ios::openmode md = fopen_mode_to_ios_mode ("w+b");
1933 octave_stream s = octave_stdiostream::create (nm, fid, md);
1936 retval(0) = octave_stream_list::insert (s);
1938 error ("tmpfile: failed to create octave_stdiostream object");
1943 using namespace std;
1944 retval(1) = ::strerror (errno);
1954#if defined (HAVE_MKSTEMPS)
1955// Prototype for mkstemps in libiberty
1956extern "C" int mkstemps (char *pattern, int suffix_len);
1959#if ! defined (HAVE_MKSTEMP) && ! defined (HAVE_MKSTEMPS) && defined (_MSC_VER)
1960# if defined (HAVE_FCNTL_H)
1963# if defined (HAVE_SYS_STAT_H)
1964# include <sys/stat.h>
1966int mkstemp (char *tmpl)
1970 ret = open (tmpl, O_RDWR | O_BINARY | O_CREAT | O_EXCL | _O_SHORT_LIVED,
1971 _S_IREAD | _S_IWRITE);
1974#define HAVE_MKSTEMP 1
1977DEFUN (mkstemp, args, ,
1979@deftypefn {Built-in Function} {[@var{fid}, @var{name}, @var{msg}] =} mkstemp (@var{template}, @var{delete})\n\
1980Return the file ID corresponding to a new temporary file with a unique\n\
1981name created from @var{template}. The last six characters of @var{template}\n\
1982must be @code{XXXXXX} and these are replaced with a string that makes the\n\
1983filename unique. The file is then created with mode read/write and\n\
1984permissions that are system dependent (on GNU/Linux systems, the permissions\n\
1985will be 0600 for versions of glibc 2.0.7 and later). The file is opened\n\
1986with the @w{@code{O_EXCL}} flag.\n\
1988If the optional argument @var{delete} is supplied and is true,\n\
1989the file will be deleted automatically when Octave exits, or when\n\
1990the function @code{purge_tmp_files} is called.\n\
1992If successful, @var{fid} is a valid file ID, @var{name} is the name of\n\
1993the file, and @var{msg} is an empty string. Otherwise, @var{fid}\n\
1994is -1, @var{name} is empty, and @var{msg} contains a system-dependent\n\
1996@seealso{tmpfile, tmpnam, P_tmpdir}\n\
1999 octave_value_list retval;
2001 retval(2) = std::string ();
2002 retval(1) = std::string ();
2005#if defined (HAVE_MKSTEMP) || defined (HAVE_MKSTEMPS)
2007 int nargin = args.length ();
2009 if (nargin == 1 || nargin == 2)
2011 std::string tmpl8 = args(0).string_value ();
2015 OCTAVE_LOCAL_BUFFER (char, tmp, tmpl8.size () + 1);
2016 strcpy (tmp, tmpl8.c_str ());
2018#if defined (HAVE_MKSTEMP)
2019 int fd = mkstemp (tmp);
2021 int fd = mkstemps (tmp, 0);
2026 using namespace std;
2027 retval(2) = ::strerror (errno);
2032 const char *fopen_mode = "w+";
2034 FILE *fid = fdopen (fd, fopen_mode);
2038 std::string nm = tmp;
2040 std::ios::openmode md = fopen_mode_to_ios_mode (fopen_mode);
2042 octave_stream s = octave_stdiostream::create (nm, fid, md);
2047 retval(0) = octave_stream_list::insert (s);
2049 if (nargin == 2 && args(1).is_true ())
2050 mark_for_deletion (nm);
2053 error ("mkstemp: failed to create octave_stdiostream object");
2057 using namespace std;
2058 retval(2) = ::strerror (errno);
2064 error ("mkstemp: expecting string as first argument");
2070 retval(2) = "mkstemp: not supported on this sytem";
2077convert (int x, int ibase, int obase)
2081 int tmp = x % obase;
2083 if (tmp > ibase - 1)
2084 ::error ("umask: invalid digit");
2089 while ((x = (x - tmp) / obase))
2092 if (tmp > ibase - 1)
2094 ::error ("umask: invalid digit");
2097 retval += mult * tmp;
2105DEFUN (umask, args, ,
2107@deftypefn {Built-in Function} {} umask (@var{mask})\n\
2108Set the permission mask for file creation. The parameter @var{mask}\n\
2109is an integer, interpreted as an octal number. If successful,\n\
2110returns the previous value of the mask (as an integer to be\n\
2111interpreted as an octal number); otherwise an error message is printed.\n\
2114 octave_value_list retval;
2118 if (args.length () == 1)
2120 int mask = args(0).int_value (true);
2127 ::error ("umask: MASK must be a positive integer value");
2131 int oct_mask = convert (mask, 8, 10);
2134 status = convert (file_ops::umask (oct_mask), 10, 8);
2140 ::error ("umask: expecting integer argument");
2153const_value (const char *, const octave_value_list& args, int val)
2155 octave_value retval;
2157 int nargin = args.length ();
2167#if ! defined (P_tmpdir)
2168#define P_tmpdir "/tmp"
2171DEFUNX ("P_tmpdir", FP_tmpdir, args, ,
2173@deftypefn {Built-in Function} {} P_tmpdir ()\n\
2174Return the default name of the directory for temporary files on\n\
2175this system. The name of this directory is system dependent.\n\
2178 octave_value retval;
2180 int nargin = args.length ();
2190// NOTE: the values of SEEK_SET, SEEK_CUR, and SEEK_END have to be
2191// this way for Matlab compatibility.
2193DEFUNX ("SEEK_SET", FSEEK_SET, args, ,
2195@deftypefn {Built-in Function} {} SEEK_SET ()\n\
2196@deftypefnx {Built-in Function} {} SEEK_CUR ()\n\
2197@deftypefnx {Built-in Function} {} SEEK_END ()\n\
2198Return the value required to request that @code{fseek} perform\n\
2199one of the following actions:\n\
2202Position file relative to the beginning.\n\
2205Position file relative to the current position.\n\
2208Position file relative to the end.\n\
2212 return const_value ("SEEK_SET", args, -1);
2215DEFUNX ("SEEK_CUR", FSEEK_CUR, args, ,
2217@deftypefn {Built-in Function} {} SEEK_CUR ()\n\
2221 return const_value ("SEEK_CUR", args, 0);
2224DEFUNX ("SEEK_END", FSEEK_END, args, ,
2226@deftypefn {Built-in Function} {} SEEK_END ()\n\
2230 return const_value ("SEEK_END", args, 1);
2234const_value (const char *, const octave_value_list& args,
2235 const octave_value& val)
2237 octave_value retval;
2239 int nargin = args.length ();
2249DEFUNX ("stdin", Fstdin, args, ,
2251@deftypefn {Built-in Function} {} stdin ()\n\
2252Return the numeric value corresponding to the standard input stream.\n\
2253When Octave is used interactively, this is filtered through the command\n\
2254line editing functions.\n\
2255@seealso{stdout, stderr}\n\
2258 return const_value ("stdin", args, stdin_file);
2261DEFUNX ("stdout", Fstdout, args, ,
2263@deftypefn {Built-in Function} {} stdout ()\n\
2264Return the numeric value corresponding to the standard output stream.\n\
2265Data written to the standard output is normally filtered through the pager.\n\
2266@seealso{stdin, stderr}\n\
2269 return const_value ("stdout", args, stdout_file);
2272DEFUNX ("stderr", Fstderr, args, ,
2274@deftypefn {Built-in Function} {} stderr ()\n\
2275Return the numeric value corresponding to the standard error stream.\n\
2276Even if paging is turned on, the standard error is not sent to the\n\
2277pager. It is useful for error messages and prompts.\n\
2278@seealso{stdin, stdout}\n\
2281 return const_value ("stderr", args, stderr_file);
2285;;; Local Variables: ***