file-io.cc

Go to the documentation of this file.
00001 /*
00002 
00003 Copyright (C) 1993-2012 John W. Eaton
00004 
00005 This file is part of Octave.
00006 
00007 Octave is free software; you can redistribute it and/or modify it
00008 under the terms of the GNU General Public License as published by the
00009 Free Software Foundation; either version 3 of the License, or (at your
00010 option) any later version.
00011 
00012 Octave is distributed in the hope that it will be useful, but WITHOUT
00013 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00014 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00015 for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Octave; see the file COPYING.  If not, see
00019 <http://www.gnu.org/licenses/>.
00020 
00021 */
00022 
00023 // Originally written by John C. Campbell <jcc@bevo.che.wisc.edu>
00024 //
00025 // Thomas Baier <baier@ci.tuwien.ac.at> added the original versions of
00026 // the following functions:
00027 //
00028 //   popen
00029 //   pclose
00030 //   execute       (now popen2.m)
00031 //   sync_system   (now merged with system)
00032 //   async_system  (now merged with system)
00033 
00034 // Extensively revised by John W. Eaton <jwe@octave.org>,
00035 // April 1996.
00036 
00037 #ifdef HAVE_CONFIG_H
00038 #include <config.h>
00039 #endif
00040 
00041 #include <cerrno>
00042 #include <climits>
00043 #include <cstdio>
00044 
00045 #include <iostream>
00046 #include <stack>
00047 #include <vector>
00048 
00049 #include <fcntl.h>
00050 #include <sys/types.h>
00051 #include <unistd.h>
00052 
00053 #ifdef HAVE_ZLIB_H
00054 #include <zlib.h>
00055 #endif
00056 
00057 #include "error.h"
00058 #include "file-ops.h"
00059 #include "file-stat.h"
00060 #include "lo-ieee.h"
00061 #include "oct-env.h"
00062 #include "oct-locbuf.h"
00063 
00064 #include "defun.h"
00065 #include "file-io.h"
00066 #include "load-path.h"
00067 #include "oct-fstrm.h"
00068 #include "oct-iostrm.h"
00069 #include "oct-map.h"
00070 #include "oct-obj.h"
00071 #include "oct-prcstrm.h"
00072 #include "oct-stream.h"
00073 #include "oct-strstrm.h"
00074 #include "pager.h"
00075 #include "sysdep.h"
00076 #include "utils.h"
00077 #include "variables.h"
00078 
00079 static octave_value stdin_file;
00080 static octave_value stdout_file;
00081 static octave_value stderr_file;
00082 
00083 static octave_stream stdin_stream;
00084 static octave_stream stdout_stream;
00085 static octave_stream stderr_stream;
00086 
00087 void
00088 initialize_file_io (void)
00089 {
00090   stdin_stream = octave_istream::create (&std::cin, "stdin");
00091 
00092   // This uses octave_stdout (see pager.h), not std::cout so that Octave's
00093   // standard output stream will pass through the pager.
00094 
00095   stdout_stream = octave_ostream::create (&octave_stdout, "stdout");
00096 
00097   stderr_stream = octave_ostream::create (&std::cerr, "stderr");
00098 
00099   stdin_file = octave_stream_list::insert (stdin_stream);
00100   stdout_file = octave_stream_list::insert (stdout_stream);
00101   stderr_file = octave_stream_list::insert (stderr_stream);
00102 }
00103 
00104 void
00105 close_files (void)
00106 {
00107   octave_stream_list::clear ();
00108 }
00109 
00110 // List of files to delete when we exit or crash.
00111 //
00112 // FIXME -- this should really be static, but that causes
00113 // problems on some systems.
00114 std::stack <std::string> tmp_files;
00115 
00116 void
00117 mark_for_deletion (const std::string& file)
00118 {
00119   tmp_files.push (file);
00120 }
00121 
00122 void
00123 cleanup_tmp_files (void)
00124 {
00125   while (! tmp_files.empty ())
00126     {
00127       std::string filename = tmp_files.top ();
00128       tmp_files.pop ();
00129       gnulib::unlink (filename.c_str ());
00130     }
00131 }
00132 
00133 static std::ios::openmode
00134 fopen_mode_to_ios_mode (const std::string& mode_arg)
00135 {
00136   std::ios::openmode retval = std::ios::in;
00137 
00138   if (! mode_arg.empty ())
00139     {
00140       // Could probably be faster, but does it really matter?
00141 
00142       std::string mode = mode_arg;
00143 
00144       // 'W' and 'R' are accepted as 'w' and 'r', but we warn about
00145       // them because Matlab says they perform "automatic flushing"
00146       // but we don't know precisely what action that implies.
00147 
00148       size_t pos = mode.find ('W');
00149 
00150       if (pos != std::string::npos)
00151         {
00152           warning ("fopen: treating mode \"W\" as equivalent to \"w\"");
00153           mode[pos] = 'w';
00154         }
00155 
00156       pos = mode.find ('R');
00157 
00158       if (pos != std::string::npos)
00159         {
00160           warning ("fopen: treating mode \"R\" as equivalent to \"r\"");
00161           mode[pos] = 'r';
00162         }
00163 
00164       pos = mode.find ('z');
00165 
00166       if (pos != std::string::npos)
00167         {
00168 #if defined (HAVE_ZLIB)
00169           mode.erase (pos, 1);
00170 #else
00171           error ("this version of Octave does not support gzipped files");
00172 #endif
00173         }
00174 
00175       if (! error_state)
00176         {
00177           if (mode == "rt")
00178             retval = std::ios::in;
00179           else if (mode == "wt")
00180             retval = std::ios::out | std::ios::trunc;
00181           else if (mode == "at")
00182             retval = std::ios::out | std::ios::app;
00183           else if (mode == "r+t" || mode == "rt+")
00184             retval = std::ios::in | std::ios::out;
00185           else if (mode == "w+t" || mode == "wt+")
00186             retval = std::ios::in | std::ios::out | std::ios::trunc;
00187           else if (mode == "a+t" || mode == "at+")
00188             retval = std::ios::in | std::ios::out | std::ios::app;
00189           else if (mode == "rb" || mode == "r")
00190             retval = std::ios::in | std::ios::binary;
00191           else if (mode == "wb" || mode == "w")
00192             retval = std::ios::out | std::ios::trunc | std::ios::binary;
00193           else if (mode == "ab" || mode == "a")
00194             retval = std::ios::out | std::ios::app | std::ios::binary;
00195           else if (mode == "r+b" || mode == "rb+" || mode == "r+")
00196             retval = std::ios::in | std::ios::out | std::ios::binary;
00197           else if (mode == "w+b" || mode == "wb+" || mode == "w+")
00198             retval = (std::ios::in | std::ios::out | std::ios::trunc
00199                       | std::ios::binary);
00200           else if (mode == "a+b" || mode == "ab+" || mode == "a+")
00201             retval = (std::ios::in | std::ios::out | std::ios::app
00202                       | std::ios::binary);
00203           else
00204             ::error ("invalid mode specified");
00205         }
00206     }
00207 
00208   return retval;
00209 }
00210 
00211 DEFUN (fclose, args, ,
00212   "-*- texinfo -*-\n\
00213 @deftypefn  {Built-in Function} {} fclose (@var{fid})\n\
00214 @deftypefnx {Built-in Function} {} fclose (\"all\")\n\
00215 Close the specified file.  If successful, @code{fclose} returns 0,\n\
00216 otherwise, it returns -1.  The second form of the @code{fclose} call closes\n\
00217 all open files except @code{stdout}, @code{stderr}, and @code{stdin}.\n\
00218 @seealso{fopen, fseek, ftell}\n\
00219 @end deftypefn")
00220 {
00221   octave_value retval = -1;
00222 
00223   int nargin = args.length ();
00224 
00225   if (nargin == 1)
00226     retval = octave_stream_list::remove (args(0), "fclose");
00227   else
00228     print_usage ();
00229 
00230   return retval;
00231 }
00232 
00233 DEFUN (fclear, args, ,
00234   "-*- texinfo -*-\n\
00235 @deftypefn {Built-in Function} {} fclear (@var{fid})\n\
00236 Clear the stream state for the specified file.\n\
00237 @end deftypefn")
00238 {
00239   octave_value retval;
00240 
00241   int nargin = args.length ();
00242 
00243   if (nargin == 1)
00244     {
00245       int fid = octave_stream_list::get_file_number (args (0));
00246 
00247       octave_stream os = octave_stream_list::lookup (fid, "fclear");
00248 
00249       if (! error_state)
00250         os.clearerr ();
00251     }
00252   else
00253     print_usage ();
00254 
00255   return retval;
00256 }
00257 
00258 DEFUN (fflush, args, ,
00259   "-*- texinfo -*-\n\
00260 @deftypefn {Built-in Function} {} fflush (@var{fid})\n\
00261 Flush output to @var{fid}.  This is useful for ensuring that all\n\
00262 pending output makes it to the screen before some other event occurs.\n\
00263 For example, it is always a good idea to flush the standard output\n\
00264 stream before calling @code{input}.\n\
00265 \n\
00266 @code{fflush} returns 0 on success and an OS dependent error value\n\
00267 (@minus{}1 on Unix) on error.\n\
00268 @seealso{fopen, fclose}\n\
00269 @end deftypefn")
00270 {
00271   octave_value retval = -1;
00272 
00273   int nargin = args.length ();
00274 
00275   if (nargin == 1)
00276     {
00277       // FIXME -- any way to avoid special case for stdout?
00278 
00279       int fid = octave_stream_list::get_file_number (args (0));
00280 
00281       if (fid == 1)
00282         {
00283           flush_octave_stdout ();
00284 
00285           retval = 0;
00286         }
00287       else
00288         {
00289           octave_stream os = octave_stream_list::lookup (fid, "fflush");
00290 
00291           if (! error_state)
00292             retval = os.flush ();
00293         }
00294     }
00295   else
00296     print_usage ();
00297 
00298   return retval;
00299 }
00300 
00301 DEFUN (fgetl, args, ,
00302   "-*- texinfo -*-\n\
00303 @deftypefn {Built-in Function} {} fgetl (@var{fid}, @var{len})\n\
00304 Read characters from a file, stopping after a newline, or EOF,\n\
00305 or @var{len} characters have been read.  The characters read, excluding\n\
00306 the possible trailing newline, are returned as a string.\n\
00307 \n\
00308 If @var{len} is omitted, @code{fgetl} reads until the next newline\n\
00309 character.\n\
00310 \n\
00311 If there are no more characters to read, @code{fgetl} returns @minus{}1.\n\
00312 @seealso{fread, fscanf}\n\
00313 @end deftypefn")
00314 {
00315   static std::string who = "fgetl";
00316 
00317   octave_value_list retval;
00318 
00319   retval(1) = 0;
00320   retval(0) = -1;
00321 
00322   int nargin = args.length ();
00323 
00324   if (nargin == 1 || nargin == 2)
00325     {
00326       octave_stream os = octave_stream_list::lookup (args(0), who);
00327 
00328       if (! error_state)
00329         {
00330           octave_value len_arg = (nargin == 2) ? args(1) : octave_value ();
00331 
00332           bool err = false;
00333 
00334           std::string tmp = os.getl (len_arg, err, who);
00335 
00336           if (! (error_state || err))
00337             {
00338               retval(1) = tmp.length ();
00339               retval(0) = tmp;
00340             }
00341         }
00342     }
00343   else
00344     print_usage ();
00345 
00346   return retval;
00347 }
00348 
00349 DEFUN (fgets, args, ,
00350   "-*- texinfo -*-\n\
00351 @deftypefn  {Built-in Function} {} fgets (@var{fid})\n\
00352 @deftypefnx {Built-in Function} {} fgets (@var{fid}, @var{len})\n\
00353 Read characters from a file, stopping after a newline, or EOF,\n\
00354 or @var{len} characters have been read.  The characters read, including\n\
00355 the possible trailing newline, are returned as a string.\n\
00356 \n\
00357 If @var{len} is omitted, @code{fgets} reads until the next newline\n\
00358 character.\n\
00359 \n\
00360 If there are no more characters to read, @code{fgets} returns @minus{}1.\n\
00361 @seealso{fputs, fopen, fread, fscanf}\n\
00362 @end deftypefn")
00363 {
00364   static std::string who = "fgets";
00365 
00366   octave_value_list retval;
00367 
00368   retval(1) = 0.0;
00369   retval(0) = -1.0;
00370 
00371   int nargin = args.length ();
00372 
00373   if (nargin == 1 || nargin == 2)
00374     {
00375       octave_stream os = octave_stream_list::lookup (args(0), who);
00376 
00377       if (! error_state)
00378         {
00379           octave_value len_arg = (nargin == 2) ? args(1) : octave_value ();
00380 
00381           bool err = false;
00382 
00383           std::string tmp = os.gets (len_arg, err, who);
00384 
00385           if (! (error_state || err))
00386             {
00387               retval(1) = tmp.length ();
00388               retval(0) = tmp;
00389             }
00390         }
00391     }
00392   else
00393     print_usage ();
00394 
00395   return retval;
00396 }
00397 
00398 DEFUN (fskipl, args, ,
00399   "-*- texinfo -*-\n\
00400 @deftypefn {Built-in Function} {} fskipl (@var{fid}, @var{count})\n\
00401 Skip a given number of lines, i.e., discards characters until an end-of-line\n\
00402 is met exactly @var{count}-times, or end-of-file occurs.\n\
00403 Returns the number of lines skipped (end-of-line sequences encountered).\n\
00404 If @var{count} is omitted, it defaults to 1. @var{count} may also be\n\
00405 @code{Inf}, in which case lines are skipped to the end of file.\n\
00406 This form is suitable for counting lines in a file.\n\
00407 @seealso{fgetl, fgets}\n\
00408 @end deftypefn")
00409 {
00410   static std::string who = "fskipl";
00411 
00412   octave_value retval;
00413 
00414   int nargin = args.length ();
00415 
00416   if (nargin == 1 || nargin == 2)
00417     {
00418       octave_stream os = octave_stream_list::lookup (args(0), who);
00419 
00420       if (! error_state)
00421         {
00422           octave_value count_arg = (nargin == 2) ? args(1) : octave_value ();
00423 
00424           bool err = false;
00425 
00426           long tmp = os.skipl (count_arg, err, who);
00427 
00428           if (! (error_state || err))
00429             retval = tmp;
00430         }
00431     }
00432   else
00433     print_usage ();
00434 
00435   return retval;
00436 }
00437 
00438 
00439 static octave_stream
00440 do_stream_open (const std::string& name, const std::string& mode,
00441                 const std::string& arch, int& fid)
00442 {
00443   octave_stream retval;
00444 
00445   fid = -1;
00446 
00447   std::ios::openmode md = fopen_mode_to_ios_mode (mode);
00448 
00449   if (! error_state)
00450     {
00451       oct_mach_info::float_format flt_fmt =
00452         oct_mach_info::string_to_float_format (arch);
00453 
00454       if (! error_state)
00455         {
00456           std::string fname = file_ops::tilde_expand (name);
00457 
00458           file_stat fs (fname);
00459 
00460           if (! (md & std::ios::out
00461                  || octave_env::absolute_pathname (fname)
00462                  || octave_env::rooted_relative_pathname (fname)))
00463             {
00464               if (! fs.exists ())
00465                 {
00466                   std::string tmp
00467                     = octave_env::make_absolute (load_path::find_file (fname));
00468 
00469                   if (! tmp.empty ())
00470                     {
00471                       warning_with_id ("Octave:fopen-file-in-path",
00472                                        "fopen: file found in load path");
00473                       fname = tmp;
00474                     }
00475                 }
00476             }
00477 
00478           if (! fs.is_dir ())
00479             {
00480               std::string tmode = mode;
00481 
00482               // Use binary mode if 't' is not specified, but don't add
00483               // 'b' if it is already present.
00484 
00485               size_t bpos = tmode.find ('b');
00486               size_t tpos = tmode.find ('t');
00487 
00488               if (bpos == std::string::npos && tpos == std::string::npos)
00489                 tmode += 'b';
00490 
00491 #if defined (HAVE_ZLIB)
00492               size_t pos = tmode.find ('z');
00493 
00494               if (pos != std::string::npos)
00495                 {
00496                   tmode.erase (pos, 1);
00497 
00498                   FILE *fptr = gnulib::fopen (fname.c_str (), tmode.c_str ());
00499 
00500                   int fd = fileno (fptr);
00501 
00502                   gzFile gzf = ::gzdopen (fd, tmode.c_str ());
00503 
00504                   if (fptr)
00505                     retval = octave_zstdiostream::create (fname, gzf, fd,
00506                                                           md, flt_fmt);
00507                   else
00508                     retval.error (gnulib::strerror (errno));
00509                 }
00510               else
00511 #endif
00512                 {
00513                   FILE *fptr = gnulib::fopen (fname.c_str (), tmode.c_str ());
00514 
00515                   retval = octave_stdiostream::create (fname, fptr, md, flt_fmt);
00516 
00517                   if (! fptr)
00518                     retval.error (gnulib::strerror (errno));
00519                 }
00520 
00521             }
00522         }
00523     }
00524 
00525   return retval;
00526 }
00527 
00528 static octave_stream
00529 do_stream_open (const octave_value& tc_name, const octave_value& tc_mode,
00530                 const octave_value& tc_arch, const char *fcn, int& fid)
00531 {
00532   octave_stream retval;
00533 
00534   fid = -1;
00535 
00536   std::string name = tc_name.string_value ();
00537 
00538   if (! error_state)
00539     {
00540       std::string mode = tc_mode.string_value ();
00541 
00542       if (! error_state)
00543         {
00544           std::string arch = tc_arch.string_value ();
00545 
00546           if (! error_state)
00547             retval = do_stream_open (name, mode, arch, fid);
00548           else
00549             ::error ("%s: architecture type must be a string", fcn);
00550         }
00551       else
00552         ::error ("%s: file mode must be a string", fcn);
00553     }
00554   else
00555     ::error ("%s: file name must be a string", fcn);
00556 
00557   return retval;
00558 }
00559 
00560 DEFUN (fopen, args, nargout,
00561   "-*- texinfo -*-\n\
00562 @deftypefn  {Built-in Function} {[@var{fid}, @var{msg}] =} fopen (@var{name}, @var{mode}, @var{arch})\n\
00563 @deftypefnx {Built-in Function} {@var{fid_list} =} fopen (\"all\")\n\
00564 @deftypefnx {Built-in Function} {[@var{file}, @var{mode}, @var{arch}] =} fopen (@var{fid})\n\
00565 The first form of the @code{fopen} function opens the named file with\n\
00566 the specified mode (read-write, read-only, etc.) and architecture\n\
00567 interpretation (IEEE big endian, IEEE little endian, etc.), and returns\n\
00568 an integer value that may be used to refer to the file later.  If an\n\
00569 error occurs, @var{fid} is set to @minus{}1 and @var{msg} contains the\n\
00570 corresponding system error message.  The @var{mode} is a one or two\n\
00571 character string that specifies whether the file is to be opened for\n\
00572 reading, writing, or both.\n\
00573 \n\
00574 The second form of the @code{fopen} function returns a vector of file ids\n\
00575 corresponding to all the currently open files, excluding the\n\
00576 @code{stdin}, @code{stdout}, and @code{stderr} streams.\n\
00577 \n\
00578 The third form of the @code{fopen} function returns information about the\n\
00579 open file given its file id.\n\
00580 \n\
00581 For example,\n\
00582 \n\
00583 @example\n\
00584 myfile = fopen (\"splat.dat\", \"r\", \"ieee-le\");\n\
00585 @end example\n\
00586 \n\
00587 @noindent\n\
00588 opens the file @file{splat.dat} for reading.  If necessary, binary\n\
00589 numeric values will be read assuming they are stored in IEEE format with\n\
00590 the least significant bit first, and then converted to the native\n\
00591 representation.\n\
00592 \n\
00593 Opening a file that is already open simply opens it again and returns a\n\
00594 separate file id.  It is not an error to open a file several times,\n\
00595 though writing to the same file through several different file ids may\n\
00596 produce unexpected results.\n\
00597 \n\
00598 The possible values @samp{mode} may have are\n\
00599 \n\
00600 @table @asis\n\
00601 @item @samp{r}\n\
00602 Open a file for reading.\n\
00603 \n\
00604 @item @samp{w}\n\
00605 Open a file for writing.  The previous contents are discarded.\n\
00606 \n\
00607 @item @samp{a}\n\
00608 Open or create a file for writing at the end of the file.\n\
00609 \n\
00610 @item @samp{r+}\n\
00611 Open an existing file for reading and writing.\n\
00612 \n\
00613 @item @samp{w+}\n\
00614 Open a file for reading or writing.  The previous contents are\n\
00615 discarded.\n\
00616 \n\
00617 @item @samp{a+}\n\
00618 Open or create a file for reading or writing at the end of the\n\
00619 file.\n\
00620 @end table\n\
00621 \n\
00622 Append a \"t\" to the mode string to open the file in text mode or a\n\
00623 \"b\" to open in binary mode.  On Windows and Macintosh systems, text\n\
00624 mode reading and writing automatically converts linefeeds to the\n\
00625 appropriate line end character for the system (carriage-return linefeed\n\
00626 on Windows, carriage-return on Macintosh).  The default if no mode is\n\
00627 specified is binary mode.\n\
00628 \n\
00629 Additionally, you may append a \"z\" to the mode string to open a\n\
00630 gzipped file for reading or writing.  For this to be successful, you\n\
00631 must also open the file in binary mode.\n\
00632 \n\
00633 The parameter @var{arch} is a string specifying the default data format\n\
00634 for the file.  Valid values for @var{arch} are:\n\
00635 \n\
00636 @table @asis\n\
00637 @samp{native}\n\
00638 The format of the current machine (this is the default).\n\
00639 \n\
00640 @samp{ieee-be}\n\
00641 IEEE big endian format.\n\
00642 \n\
00643 @samp{ieee-le}\n\
00644 IEEE little endian format.\n\
00645 \n\
00646 @samp{vaxd}\n\
00647 VAX D floating format.\n\
00648 \n\
00649 @samp{vaxg}\n\
00650 VAX G floating format.\n\
00651 \n\
00652 @samp{cray}\n\
00653 Cray floating format.\n\
00654 @end table\n\
00655 \n\
00656 @noindent\n\
00657 however, conversions are currently only supported for @samp{native}\n\
00658 @samp{ieee-be}, and @samp{ieee-le} formats.\n\
00659 @seealso{fclose, fgets, fputs, fread, fseek, ferror, fprintf, fscanf, ftell, fwrite}\n\
00660 @end deftypefn")
00661 {
00662   octave_value_list retval;
00663 
00664   retval(0) = -1.0;
00665 
00666   int nargin = args.length ();
00667 
00668   if (nargin == 1)
00669     {
00670       if (args(0).is_string ())
00671         {
00672           // If there is only one argument and it is a string but it
00673           // is not the string "all", we assume it is a file to open
00674           // with MODE = "r".  To open a file called "all", you have
00675           // to supply more than one argument.
00676 
00677           if (nargout < 2 && args(0).string_value () == "all")
00678             return octave_stream_list::open_file_numbers ();
00679         }
00680       else
00681         {
00682           string_vector tmp = octave_stream_list::get_info (args(0));
00683 
00684           if (! error_state)
00685             {
00686               retval(2) = tmp(2);
00687               retval(1) = tmp(1);
00688               retval(0) = tmp(0);
00689             }
00690 
00691           return retval;
00692         }
00693     }
00694 
00695   if (nargin > 0 && nargin < 4)
00696     {
00697       octave_value mode = (nargin == 2 || nargin == 3)
00698         ? args(1) : octave_value ("r");
00699 
00700       octave_value arch = (nargin == 3)
00701         ? args(2) : octave_value ("native");
00702 
00703       int fid = -1;
00704 
00705       octave_stream os = do_stream_open (args(0), mode, arch, "fopen", fid);
00706 
00707       if (os && ! error_state)
00708         {
00709           retval(1) = "";
00710           retval(0) = octave_stream_list::insert (os);
00711         }
00712       else
00713         {
00714           int error_number = 0;
00715 
00716           retval(1) = os.error (false, error_number);
00717           retval(0) = -1.0;
00718         }
00719     }
00720   else
00721     print_usage ();
00722 
00723   return retval;
00724 }
00725 
00726 DEFUN (freport, args, ,
00727   "-*- texinfo -*-\n\
00728 @deftypefn {Built-in Function} {} freport ()\n\
00729 Print a list of which files have been opened, and whether they are open\n\
00730 for reading, writing, or both.  For example:\n\
00731 \n\
00732 @example\n\
00733 @group\n\
00734 freport ()\n\
00735 \n\
00736      @print{}  number  mode  name\n\
00737      @print{}\n\
00738      @print{}       0     r  stdin\n\
00739      @print{}       1     w  stdout\n\
00740      @print{}       2     w  stderr\n\
00741      @print{}       3     r  myfile\n\
00742 @end group\n\
00743 @end example\n\
00744 @end deftypefn")
00745 {
00746   octave_value_list retval;
00747 
00748   int nargin = args.length ();
00749 
00750   if (nargin > 0)
00751     warning ("freport: ignoring extra arguments");
00752 
00753   octave_stdout << octave_stream_list::list_open_files ();
00754 
00755   return retval;
00756 }
00757 
00758 DEFUN (frewind, args, nargout,
00759   "-*- texinfo -*-\n\
00760 @deftypefn {Built-in Function} {} frewind (@var{fid})\n\
00761 Move the file pointer to the beginning of the file @var{fid}, returning\n\
00762 0 for success, and -1 if an error was encountered.  It is equivalent to\n\
00763 @code{fseek (@var{fid}, 0, SEEK_SET)}.\n\
00764 @end deftypefn")
00765 {
00766   octave_value retval;
00767 
00768   int result = -1;
00769 
00770   int nargin = args.length ();
00771 
00772   if (nargin == 1)
00773     {
00774       octave_stream os = octave_stream_list::lookup (args(0), "frewind");
00775 
00776       if (! error_state)
00777         result = os.rewind ();
00778     }
00779   else
00780     print_usage ();
00781 
00782   if (nargout > 0)
00783     retval = result;
00784 
00785   return retval;
00786 }
00787 
00788 DEFUN (fseek, args, ,
00789   "-*- texinfo -*-\n\
00790 @deftypefn {Built-in Function} {} fseek (@var{fid}, @var{offset}, @var{origin})\n\
00791 Set the file pointer to any location within the file @var{fid}.\n\
00792 \n\
00793 The pointer is positioned @var{offset} characters from the @var{origin},\n\
00794 which may be one of the predefined variables @w{@code{SEEK_CUR}} (current\n\
00795 position), @w{@code{SEEK_SET}} (beginning), or @w{@code{SEEK_END}} (end of\n\
00796 file) or strings \"cof\", \"bof\" or \"eof\".  If @var{origin} is omitted,\n\
00797 @w{@code{SEEK_SET}} is assumed.  The offset must be zero, or a value returned\n\
00798 by @code{ftell} (in which case @var{origin} must be @w{@code{SEEK_SET}}).\n\
00799 \n\
00800 Return 0 on success and -1 on error.\n\
00801 @seealso{ftell, fopen, fclose}\n\
00802 @end deftypefn")
00803 {
00804   octave_value retval = -1;
00805 
00806   int nargin = args.length ();
00807 
00808   if (nargin == 2 || nargin == 3)
00809     {
00810       octave_stream os = octave_stream_list::lookup (args(0), "fseek");
00811 
00812       if (! error_state)
00813         {
00814           octave_value origin_arg = (nargin == 3)
00815             ? args(2) : octave_value (-1.0);
00816 
00817           retval = os.seek (args(1), origin_arg);
00818         }
00819     }
00820   else
00821     print_usage ();
00822 
00823   return retval;
00824 }
00825 
00826 DEFUN (ftell, args, ,
00827   "-*- texinfo -*-\n\
00828 @deftypefn {Built-in Function} {} ftell (@var{fid})\n\
00829 Return the position of the file pointer as the number of characters\n\
00830 from the beginning of the file @var{fid}.\n\
00831 @seealso{fseek, fopen, fclose}\n\
00832 @end deftypefn")
00833 {
00834   octave_value retval = -1;
00835 
00836   int nargin = args.length ();
00837 
00838   if (nargin == 1)
00839     {
00840       octave_stream os = octave_stream_list::lookup (args(0), "ftell");
00841 
00842       if (! error_state)
00843         retval = os.tell ();
00844     }
00845   else
00846     print_usage ();
00847 
00848   return retval;
00849 }
00850 
00851 DEFUN (fprintf, args, nargout,
00852   "-*- texinfo -*-\n\
00853 @deftypefn {Built-in Function} {} fprintf (@var{fid}, @var{template}, @dots{})\n\
00854 This function is just like @code{printf}, except that the output is\n\
00855 written to the stream @var{fid} instead of @code{stdout}.\n\
00856 If @var{fid} is omitted, the output is written to @code{stdout}.\n\
00857 @seealso{printf, sprintf, fread, fscanf, fopen, fclose}\n\
00858 @end deftypefn")
00859 {
00860   static std::string who = "fprintf";
00861 
00862   octave_value retval;
00863 
00864   int result = -1;
00865 
00866   int nargin = args.length ();
00867 
00868   if (nargin > 1 || (nargin > 0 && args(0).is_string ()))
00869     {
00870       octave_stream os;
00871       int fmt_n = 0;
00872 
00873       if (args(0).is_string ())
00874         {
00875           os = octave_stream_list::lookup (1, who);
00876         }
00877       else
00878         {
00879           fmt_n = 1;
00880           os = octave_stream_list::lookup (args(0), who);
00881         }
00882 
00883       if (! error_state)
00884         {
00885           if (args(fmt_n).is_string ())
00886             {
00887               octave_value_list tmp_args;
00888 
00889               if (nargin > 1 + fmt_n)
00890                 {
00891                   tmp_args.resize (nargin-fmt_n-1, octave_value ());
00892 
00893                   for (int i = fmt_n + 1; i < nargin; i++)
00894                     tmp_args(i-fmt_n-1) = args(i);
00895                 }
00896 
00897               result = os.printf (args(fmt_n), tmp_args, who);
00898             }
00899           else
00900             ::error ("%s: format TEMPLATE must be a string", who.c_str ());
00901         }
00902     }
00903   else
00904     print_usage ();
00905 
00906   if (nargout > 0)
00907     retval = result;
00908 
00909   return retval;
00910 }
00911 
00912 DEFUN (printf, args, nargout,
00913   "-*- texinfo -*-\n\
00914 @deftypefn {Built-in Function} {} printf (@var{template}, @dots{})\n\
00915 Print optional arguments under the control of the template string\n\
00916 @var{template} to the stream @code{stdout} and return the number of\n\
00917 characters printed.\n\
00918 @ifclear OCTAVE_MANUAL\n\
00919 \n\
00920 See the Formatted Output section of the GNU Octave manual for a\n\
00921 complete description of the syntax of the template string.\n\
00922 @end ifclear\n\
00923 @seealso{fprintf, sprintf, scanf}\n\
00924 @end deftypefn")
00925 {
00926   static std::string who = "printf";
00927 
00928   octave_value retval;
00929 
00930   int result = -1;
00931 
00932   int nargin = args.length ();
00933 
00934   if (nargin > 0)
00935     {
00936       if (args(0).is_string ())
00937         {
00938           octave_value_list tmp_args;
00939 
00940           if (nargin > 1)
00941             {
00942               tmp_args.resize (nargin-1, octave_value ());
00943 
00944               for (int i = 1; i < nargin; i++)
00945                 tmp_args(i-1) = args(i);
00946             }
00947 
00948           result = stdout_stream.printf (args(0), tmp_args, who);
00949         }
00950       else
00951         ::error ("%s: format TEMPLATE must be a string", who.c_str ());
00952     }
00953   else
00954     print_usage ();
00955 
00956   if (nargout > 0)
00957     retval = result;
00958 
00959   return retval;
00960 }
00961 
00962 DEFUN (fputs, args, ,
00963   "-*- texinfo -*-\n\
00964 @deftypefn {Built-in Function} {} fputs (@var{fid}, @var{string})\n\
00965 Write a string to a file with no formatting.\n\
00966 \n\
00967 Return a non-negative number on success and EOF on error.\n\
00968 @seealso{scanf, sscanf, fread, fprintf, fgets, fscanf}\n\
00969 @end deftypefn")
00970 {
00971   static std::string who = "fputs";
00972 
00973   octave_value retval = -1;
00974 
00975   int nargin = args.length ();
00976 
00977   if (nargin == 2)
00978     {
00979       octave_stream os = octave_stream_list::lookup (args(0), who);
00980 
00981       if (! error_state)
00982         retval = os.puts (args(1), who);
00983     }
00984   else
00985     print_usage ();
00986 
00987   return retval;
00988 }
00989 
00990 DEFUN (puts, args, ,
00991   "-*- texinfo -*-\n\
00992 @deftypefn {Built-in Function} {} puts (@var{string})\n\
00993 Write a string to the standard output with no formatting.\n\
00994 \n\
00995 Return a non-negative number on success and EOF on error.\n\
00996 @end deftypefn")
00997 {
00998   static std::string who = "puts";
00999 
01000   octave_value retval = -1;
01001 
01002   if (args.length () == 1)
01003     retval = stdout_stream.puts (args(0), who);
01004   else
01005     print_usage ();
01006 
01007   return retval;
01008 }
01009 
01010 DEFUN (sprintf, args, ,
01011   "-*- texinfo -*-\n\
01012 @deftypefn {Built-in Function} {} sprintf (@var{template}, @dots{})\n\
01013 This is like @code{printf}, except that the output is returned as a\n\
01014 string.  Unlike the C library function, which requires you to provide a\n\
01015 suitably sized string as an argument, Octave's @code{sprintf} function\n\
01016 returns the string, automatically sized to hold all of the items\n\
01017 converted.\n\
01018 @seealso{printf, fprintf, sscanf}\n\
01019 @end deftypefn")
01020 {
01021   static std::string who = "sprintf";
01022 
01023   octave_value_list retval;
01024 
01025   int nargin = args.length ();
01026 
01027   if (nargin > 0)
01028     {
01029       retval(2) = -1.0;
01030       retval(1) = "unknown error";
01031       retval(0) = "";
01032 
01033       octave_ostrstream *ostr = new octave_ostrstream ();
01034 
01035       octave_stream os (ostr);
01036 
01037       if (os.is_valid ())
01038         {
01039           octave_value fmt_arg = args(0);
01040 
01041           if (fmt_arg.is_string ())
01042             {
01043               octave_value_list tmp_args;
01044 
01045               if (nargin > 1)
01046                 {
01047                   tmp_args.resize (nargin-1, octave_value ());
01048 
01049                   for (int i = 1; i < nargin; i++)
01050                     tmp_args(i-1) = args(i);
01051                 }
01052 
01053               retval(2) = os.printf (fmt_arg, tmp_args, who);
01054               retval(1) = os.error ();
01055               retval(0) = octave_value (ostr->str (),
01056                                         fmt_arg.is_sq_string () ? '\'' : '"');
01057             }
01058           else
01059             ::error ("%s: format TEMPLATE must be a string", who.c_str ());
01060         }
01061       else
01062         ::error ("%s: unable to create output buffer", who.c_str ());
01063     }
01064   else
01065     print_usage ();
01066 
01067   return retval;
01068 }
01069 
01070 DEFUN (fscanf, args, ,
01071   "-*- texinfo -*-\n\
01072 @deftypefn  {Built-in Function} {[@var{val}, @var{count}, @var{errmsg}] =} fscanf (@var{fid}, @var{template}, @var{size})\n\
01073 @deftypefnx {Built-in Function} {[@var{v1}, @var{v2}, @dots{}, @var{count}, @var{errmsg}] =} fscanf (@var{fid}, @var{template}, \"C\")\n\
01074 In the first form, read from @var{fid} according to @var{template},\n\
01075 returning the result in the matrix @var{val}.\n\
01076 \n\
01077 The optional argument @var{size} specifies the amount of data to read\n\
01078 and may be one of\n\
01079 \n\
01080 @table @code\n\
01081 @item Inf\n\
01082 Read as much as possible, returning a column vector.\n\
01083 \n\
01084 @item @var{nr}\n\
01085 Read up to @var{nr} elements, returning a column vector.\n\
01086 \n\
01087 @item [@var{nr}, Inf]\n\
01088 Read as much as possible, returning a matrix with @var{nr} rows.  If the\n\
01089 number of elements read is not an exact multiple of @var{nr}, the last\n\
01090 column is padded with zeros.\n\
01091 \n\
01092 @item [@var{nr}, @var{nc}]\n\
01093 Read up to @code{@var{nr} * @var{nc}} elements, returning a matrix with\n\
01094 @var{nr} rows.  If the number of elements read is not an exact multiple\n\
01095 of @var{nr}, the last column is padded with zeros.\n\
01096 @end table\n\
01097 \n\
01098 @noindent\n\
01099 If @var{size} is omitted, a value of @code{Inf} is assumed.\n\
01100 \n\
01101 A string is returned if @var{template} specifies only character\n\
01102 conversions.\n\
01103 \n\
01104 The number of items successfully read is returned in @var{count}.\n\
01105 \n\
01106 If an error occurs, @var{errmsg} contains a system-dependent error message.\n\
01107 \n\
01108 In the second form, read from @var{fid} according to @var{template},\n\
01109 with each conversion specifier in @var{template} corresponding to a\n\
01110 single scalar return value.  This form is more `C-like', and also\n\
01111 compatible with previous versions of Octave.  The number of successful\n\
01112 conversions is returned in @var{count}\n\
01113 @ifclear OCTAVE_MANUAL\n\
01114 \n\
01115 See the Formatted Input section of the GNU Octave manual for a\n\
01116 complete description of the syntax of the template string.\n\
01117 @end ifclear\n\
01118 @seealso{scanf, sscanf, fread, fprintf, fgets, fputs}\n\
01119 @end deftypefn")
01120 {
01121   static std::string who = "fscanf";
01122 
01123   octave_value_list retval;
01124 
01125   int nargin = args.length ();
01126 
01127   if (nargin == 3 && args(2).is_string ())
01128     {
01129       octave_stream os = octave_stream_list::lookup (args(0), who);
01130 
01131       if (! error_state)
01132         {
01133           if (args(1).is_string ())
01134             retval = os.oscanf (args(1), who);
01135           else
01136             ::error ("%s: format TEMPLATE must be a string", who.c_str ());
01137         }
01138     }
01139   else
01140     {
01141       retval(2) = "unknown error";
01142       retval(1) = 0.0;
01143       retval(0) = Matrix ();
01144 
01145       if (nargin == 2 || nargin == 3)
01146         {
01147           octave_stream os = octave_stream_list::lookup (args(0), who);
01148 
01149           if (! error_state)
01150             {
01151               if (args(1).is_string ())
01152                 {
01153                   octave_idx_type count = 0;
01154 
01155                   Array<double> size = (nargin == 3)
01156                     ? args(2).vector_value ()
01157                     : Array<double> (dim_vector (1, 1), lo_ieee_inf_value ());
01158 
01159                   if (! error_state)
01160                     {
01161                       octave_value tmp = os.scanf (args(1), size, count, who);
01162 
01163                       if (! error_state)
01164                         {
01165                           retval(2) = os.error ();
01166                           retval(1) = count;
01167                           retval(0) = tmp;
01168                         }
01169                     }
01170                 }
01171               else
01172                 ::error ("%s: format must be a string", who.c_str ());
01173             }
01174         }
01175       else
01176         print_usage ();
01177     }
01178 
01179   return retval;
01180 }
01181 
01182 static std::string
01183 get_sscanf_data (const octave_value& val)
01184 {
01185   std::string retval;
01186 
01187   if (val.is_string ())
01188     {
01189       octave_value tmp = val.reshape (dim_vector (1, val.numel ()));
01190 
01191       retval = tmp.string_value ();
01192     }
01193   else
01194     ::error ("sscanf: argument STRING must be a string");
01195 
01196   return retval;
01197 }
01198 
01199 DEFUN (sscanf, args, ,
01200   "-*- texinfo -*-\n\
01201 @deftypefn  {Built-in Function} {[@var{val}, @var{count}, @var{errmsg}, @var{pos}] =} sscanf (@var{string}, @var{template}, @var{size})\n\
01202 @deftypefnx {Built-in Function} {[@var{v1}, @var{v2}, @dots{}, @var{count}, @var{errmsg}] =} sscanf (@var{string}, @var{template}, \"C\")\n\
01203 This is like @code{fscanf}, except that the characters are taken from the\n\
01204 string @var{string} instead of from a stream.  Reaching the end of the\n\
01205 string is treated as an end-of-file condition.  In addition to the values\n\
01206 returned by @code{fscanf}, the index of the next character to be read\n\
01207 is returned in @var{pos}.\n\
01208 @seealso{fscanf, scanf, sprintf}\n\
01209 @end deftypefn")
01210 {
01211   static std::string who = "sscanf";
01212 
01213   octave_value_list retval;
01214 
01215   int nargin = args.length ();
01216 
01217   if (nargin == 3 && args(2).is_string ())
01218     {
01219       std::string data = get_sscanf_data (args(0));
01220 
01221       if (! error_state)
01222         {
01223           octave_stream os = octave_istrstream::create (data);
01224 
01225           if (os.is_valid ())
01226             {
01227               if (args(1).is_string ())
01228                 retval = os.oscanf (args(1), who);
01229               else
01230                 ::error ("%s: format TEMPLATE must be a string", who.c_str ());
01231             }
01232           else
01233             ::error ("%s: unable to create temporary input buffer",
01234                      who.c_str ());
01235         }
01236       else
01237         ::error ("%s: argument STRING must be a string", who.c_str ());
01238     }
01239   else
01240     {
01241       if (nargin == 2 || nargin == 3)
01242         {
01243           retval(3) = -1.0;
01244           retval(2) = "unknown error";
01245           retval(1) = 0.0;
01246           retval(0) = Matrix ();
01247 
01248           std::string data = get_sscanf_data (args(0));
01249 
01250           if (! error_state)
01251             {
01252               octave_stream os = octave_istrstream::create (data);
01253 
01254               if (os.is_valid ())
01255                 {
01256                   if (args(1).is_string ())
01257                     {
01258                       octave_idx_type count = 0;
01259 
01260                       Array<double> size = (nargin == 3)
01261                         ? args(2).vector_value ()
01262                         : Array<double> (dim_vector (1, 1),
01263                                          lo_ieee_inf_value ());
01264 
01265                       octave_value tmp = os.scanf (args(1), size, count, who);
01266 
01267                       if (! error_state)
01268                         {
01269                           // FIXME -- is this the right thing to do?
01270                           // Extract error message first, because getting
01271                           // position will clear it.
01272                           std::string errmsg = os.error ();
01273 
01274                           retval(3)
01275                             = (os.eof () ? data.length () : os.tell ()) + 1;
01276                           retval(2) = errmsg;
01277                           retval(1) = count;
01278                           retval(0) = tmp;
01279                         }
01280                     }
01281                   else
01282                     ::error ("%s: format TEMPLATE must be a string", who.c_str ());
01283                 }
01284               else
01285                 ::error ("%s: unable to create temporary input buffer",
01286                          who.c_str  ());
01287             }
01288         }
01289       else
01290         print_usage ();
01291     }
01292 
01293   return retval;
01294 }
01295 
01296 DEFUN (scanf, args, nargout,
01297   "-*- texinfo -*-\n\
01298 @deftypefn  {Built-in Function} {[@var{val}, @var{count}, @var{errmsg}] =} scanf (@var{template}, @var{size})\n\
01299 @deftypefnx {Built-in Function} {[@var{v1}, @var{v2}, @dots{}, @var{count}, @var{errmsg}]] =} scanf (@var{template}, \"C\")\n\
01300 This is equivalent to calling @code{fscanf} with @var{fid} = @code{stdin}.\n\
01301 \n\
01302 It is currently not useful to call @code{scanf} in interactive\n\
01303 programs.\n\
01304 @seealso{fscanf, sscanf, printf}\n\
01305 @end deftypefn")
01306 {
01307   int nargin = args.length ();
01308 
01309   octave_value_list tmp_args (nargin+1, octave_value ());
01310 
01311   tmp_args (0) = 0.0;
01312   for (int i = 0; i < nargin; i++)
01313     tmp_args (i+1) = args (i);
01314 
01315   return Ffscanf (tmp_args, nargout);
01316 }
01317 
01318 static octave_value
01319 do_fread (octave_stream& os, const octave_value& size_arg,
01320           const octave_value& prec_arg, const octave_value& skip_arg,
01321           const octave_value& arch_arg, octave_idx_type& count)
01322 {
01323   octave_value retval;
01324 
01325   count = -1;
01326 
01327   Array<double> size = size_arg.vector_value ();
01328 
01329   if (! error_state)
01330     {
01331       std::string prec = prec_arg.string_value ();
01332 
01333       if (! error_state)
01334         {
01335           int block_size = 1;
01336           oct_data_conv::data_type input_type;
01337           oct_data_conv::data_type output_type;
01338 
01339           oct_data_conv::string_to_data_type (prec, block_size,
01340                                               input_type, output_type);
01341 
01342           if (! error_state)
01343             {
01344               int skip = skip_arg.int_value (true);
01345 
01346               if (! error_state)
01347                 {
01348                   std::string arch = arch_arg.string_value ();
01349 
01350                   if (! error_state)
01351                     {
01352                       oct_mach_info::float_format flt_fmt
01353                         = oct_mach_info::string_to_float_format (arch);
01354 
01355                       if (! error_state)
01356                         retval = os.read (size, block_size, input_type,
01357                                           output_type, skip, flt_fmt, count);
01358                     }
01359                   else
01360                     ::error ("fread: ARCH architecture type must be a string");
01361                 }
01362               else
01363                 ::error ("fread: SKIP must be an integer");
01364             }
01365           else
01366             ::error ("fread: invalid PRECISION specified");
01367         }
01368       else
01369         ::error ("fread: PRECISION must be a string");
01370     }
01371   else
01372     ::error ("fread: invalid SIZE specified");
01373 
01374   return retval;
01375 }
01376 
01377 DEFUN (fread, args, ,
01378   "-*- texinfo -*-\n\
01379 @deftypefn {Built-in Function} {[@var{val}, @var{count}] =} fread (@var{fid}, @var{size}, @var{precision}, @var{skip}, @var{arch})\n\
01380 Read binary data of type @var{precision} from the specified file ID\n\
01381 @var{fid}.\n\
01382 \n\
01383 The optional argument @var{size} specifies the amount of data to read\n\
01384 and may be one of\n\
01385 \n\
01386 @table @code\n\
01387 @item Inf\n\
01388 Read as much as possible, returning a column vector.\n\
01389 \n\
01390 @item @var{nr}\n\
01391 Read up to @var{nr} elements, returning a column vector.\n\
01392 \n\
01393 @item [@var{nr}, Inf]\n\
01394 Read as much as possible, returning a matrix with @var{nr} rows.  If the\n\
01395 number of elements read is not an exact multiple of @var{nr}, the last\n\
01396 column is padded with zeros.\n\
01397 \n\
01398 @item [@var{nr}, @var{nc}]\n\
01399 Read up to @code{@var{nr} * @var{nc}} elements, returning a matrix with\n\
01400 @var{nr} rows.  If the number of elements read is not an exact multiple\n\
01401 of @var{nr}, the last column is padded with zeros.\n\
01402 @end table\n\
01403 \n\
01404 @noindent\n\
01405 If @var{size} is omitted, a value of @code{Inf} is assumed.\n\
01406 \n\
01407 The optional argument @var{precision} is a string specifying the type of\n\
01408 data to read and may be one of\n\
01409 \n\
01410 @table @asis\n\
01411 @item \"schar\"\n\
01412 @itemx \"signed char\"\n\
01413 Signed character.\n\
01414 \n\
01415 @item \"uchar\"\n\
01416 @itemx \"unsigned char\"\n\
01417 Unsigned character.\n\
01418 \n\
01419 @item \"int8\"\n\
01420 @itemx \"integer*1\"\n\
01421 \n\
01422 8-bit signed integer.\n\
01423 \n\
01424 @item \"int16\"\n\
01425 @itemx \"integer*2\"\n\
01426 16-bit signed integer.\n\
01427 \n\
01428 @item \"int32\"\n\
01429 @itemx \"integer*4\"\n\
01430 32-bit signed integer.\n\
01431 \n\
01432 @item \"int64\"\n\
01433 @itemx \"integer*8\"\n\
01434 64-bit signed integer.\n\
01435 \n\
01436 @item \"uint8\"\n\
01437 8-bit unsigned integer.\n\
01438 \n\
01439 @item \"uint16\"\n\
01440 16-bit unsigned integer.\n\
01441 \n\
01442 @item \"uint32\"\n\
01443 32-bit unsigned integer.\n\
01444 \n\
01445 @item \"uint64\"\n\
01446 64-bit unsigned integer.\n\
01447 \n\
01448 @item \"single\"\n\
01449 @itemx \"float32\"\n\
01450 @itemx \"real*4\"\n\
01451 32-bit floating point number.\n\
01452 \n\
01453 @item \"double\"\n\
01454 @itemx \"float64\"\n\
01455 @itemx \"real*8\"\n\
01456 64-bit floating point number.\n\
01457 \n\
01458 @item \"char\"\n\
01459 @itemx \"char*1\"\n\
01460 Single character.\n\
01461 \n\
01462 @item \"short\"\n\
01463 Short integer (size is platform dependent).\n\
01464 \n\
01465 @item \"int\"\n\
01466 Integer (size is platform dependent).\n\
01467 \n\
01468 @item \"long\"\n\
01469 Long integer (size is platform dependent).\n\
01470 \n\
01471 @item \"ushort\"\n\
01472 @itemx \"unsigned short\"\n\
01473 Unsigned short integer (size is platform dependent).\n\
01474 \n\
01475 @item \"uint\"\n\
01476 @itemx \"unsigned int\"\n\
01477 Unsigned integer (size is platform dependent).\n\
01478 \n\
01479 @item \"ulong\"\n\
01480 @itemx \"unsigned long\"\n\
01481 Unsigned long integer (size is platform dependent).\n\
01482 \n\
01483 @item \"float\"\n\
01484 Single precision floating point number (size is platform dependent).\n\
01485 @end table\n\
01486 \n\
01487 @noindent\n\
01488 The default precision is @code{\"uchar\"}.\n\
01489 \n\
01490 The @var{precision} argument may also specify an optional repeat\n\
01491 count.  For example, @samp{32*single} causes @code{fread} to read\n\
01492 a block of 32 single precision floating point numbers.  Reading in\n\
01493 blocks is useful in combination with the @var{skip} argument.\n\
01494 \n\
01495 The @var{precision} argument may also specify a type conversion.\n\
01496 For example, @samp{int16=>int32} causes @code{fread} to read 16-bit\n\
01497 integer values and return an array of 32-bit integer values.  By\n\
01498 default, @code{fread} returns a double precision array.  The special\n\
01499 form @samp{*TYPE} is shorthand for @samp{TYPE=>TYPE}.\n\
01500 \n\
01501 The conversion and repeat counts may be combined.  For example, the\n\
01502 specification @samp{32*single=>single} causes @code{fread} to read\n\
01503 blocks of single precision floating point values and return an array\n\
01504 of single precision values instead of the default array of double\n\
01505 precision values.\n\
01506 \n\
01507 The optional argument @var{skip} specifies the number of bytes to skip\n\
01508 after each element (or block of elements) is read.  If it is not\n\
01509 specified, a value of 0 is assumed.  If the final block read is not\n\
01510 complete, the final skip is omitted.  For example,\n\
01511 \n\
01512 @example\n\
01513 fread (f, 10, \"3*single=>single\", 8)\n\
01514 @end example\n\
01515 \n\
01516 @noindent\n\
01517 will omit the final 8-byte skip because the last read will not be\n\
01518 a complete block of 3 values.\n\
01519 \n\
01520 The optional argument @var{arch} is a string specifying the data format\n\
01521 for the file.  Valid values are\n\
01522 \n\
01523 @table @code\n\
01524 @item \"native\"\n\
01525 The format of the current machine.\n\
01526 \n\
01527 @item \"ieee-be\"\n\
01528 IEEE big endian.\n\
01529 \n\
01530 @item \"ieee-le\"\n\
01531 IEEE little endian.\n\
01532 \n\
01533 @item \"vaxd\"\n\
01534 VAX D floating format.\n\
01535 \n\
01536 @item \"vaxg\"\n\
01537 VAX G floating format.\n\
01538 \n\
01539 @item \"cray\"\n\
01540 Cray floating format.\n\
01541 @end table\n\
01542 \n\
01543 @noindent\n\
01544 Conversions are currently only supported for @code{\"ieee-be\"} and\n\
01545 @code{\"ieee-le\"} formats.\n\
01546 \n\
01547 The data read from the file is returned in @var{val}, and the number of\n\
01548 values read is returned in @code{count}\n\
01549 @seealso{fwrite, fopen, fclose}\n\
01550 @end deftypefn")
01551 {
01552   octave_value_list retval;
01553 
01554   int nargin = args.length ();
01555 
01556   if (nargin > 0 && nargin < 6)
01557     {
01558       retval(1) = -1.0;
01559       retval(0) = Matrix ();
01560 
01561       octave_stream os = octave_stream_list::lookup (args(0), "fread");
01562 
01563       if (! error_state)
01564         {
01565           octave_value size = lo_ieee_inf_value ();
01566           octave_value prec = "uchar";
01567           octave_value skip = 0;
01568           octave_value arch = "unknown";
01569 
01570           int idx = 1;
01571 
01572           if (nargin > idx && ! args(idx).is_string ())
01573             size = args(idx++);
01574 
01575           if (nargin > idx)
01576             prec = args(idx++);
01577 
01578           if (nargin > idx)
01579             skip = args(idx++);
01580 
01581           if (nargin > idx)
01582             arch = args(idx++);
01583           else if (skip.is_string ())
01584             {
01585               arch = skip;
01586               skip = 0;
01587             }
01588 
01589           octave_idx_type count = -1;
01590 
01591           octave_value tmp = do_fread (os, size, prec, skip, arch, count);
01592 
01593           retval(1) = count;
01594           retval(0) = tmp;
01595         }
01596     }
01597   else
01598     print_usage ();
01599 
01600   return retval;
01601 }
01602 
01603 static int
01604 do_fwrite (octave_stream& os, const octave_value& data,
01605            const octave_value& prec_arg, const octave_value& skip_arg,
01606            const octave_value& arch_arg)
01607 {
01608   int retval = -1;
01609 
01610   std::string prec = prec_arg.string_value ();
01611 
01612   if (! error_state)
01613     {
01614       int block_size = 1;
01615       oct_data_conv::data_type output_type;
01616 
01617       oct_data_conv::string_to_data_type (prec, block_size, output_type);
01618 
01619       if (! error_state)
01620         {
01621           int skip = skip_arg.int_value (true);
01622 
01623           if (! error_state)
01624             {
01625               std::string arch = arch_arg.string_value ();
01626 
01627               if (! error_state)
01628                 {
01629                   oct_mach_info::float_format flt_fmt
01630                     = oct_mach_info::string_to_float_format (arch);
01631 
01632                   if (! error_state)
01633                     retval = os.write (data, block_size, output_type,
01634                                        skip, flt_fmt);
01635                 }
01636               else
01637                 ::error ("fwrite: ARCH architecture type must be a string");
01638             }
01639           else
01640             ::error ("fwrite: SKIP must be an integer");
01641         }
01642       else
01643         ::error ("fwrite: invalid PRECISION specified");
01644     }
01645   else
01646     ::error ("fwrite: PRECISION must be a string");
01647 
01648   return retval;
01649 }
01650 
01651 DEFUN (fwrite, args, ,
01652   "-*- texinfo -*-\n\
01653 @deftypefn {Built-in Function} {@var{count} =} fwrite (@var{fid}, @var{data}, @var{precision}, @var{skip}, @var{arch})\n\
01654 Write data in binary form of type @var{precision} to the specified file\n\
01655 ID @var{fid}, returning the number of values successfully written to the\n\
01656 file.\n\
01657 \n\
01658 The argument @var{data} is a matrix of values that are to be written to\n\
01659 the file.  The values are extracted in column-major order.\n\
01660 \n\
01661 The remaining arguments @var{precision}, @var{skip}, and @var{arch} are\n\
01662 optional, and are interpreted as described for @code{fread}.\n\
01663 \n\
01664 The behavior of @code{fwrite} is undefined if the values in @var{data}\n\
01665 are too large to fit in the specified precision.\n\
01666 @seealso{fread, fopen, fclose}\n\
01667 @end deftypefn")
01668 {
01669   octave_value retval = -1;
01670 
01671   int nargin = args.length ();
01672 
01673   if (nargin > 1 && nargin < 6)
01674     {
01675       octave_stream os = octave_stream_list::lookup (args(0), "fwrite");
01676 
01677       if (! error_state)
01678         {
01679           octave_value prec = "uchar";
01680           octave_value skip = 0;
01681           octave_value arch = "unknown";
01682 
01683           int idx = 1;
01684 
01685           octave_value data = args(idx++);
01686 
01687           if (nargin > idx)
01688             prec = args(idx++);
01689 
01690           if (nargin > idx)
01691             skip = args(idx++);
01692 
01693           if (nargin > idx)
01694             arch = args(idx++);
01695           else if (skip.is_string ())
01696             {
01697               arch = skip;
01698               skip = 0;
01699             }
01700 
01701           double status = do_fwrite (os, data, prec, skip, arch);
01702 
01703           retval = status;
01704         }
01705     }
01706   else
01707     print_usage ();
01708 
01709   return retval;
01710 }
01711 
01712 DEFUNX ("feof", Ffeof, args, ,
01713   "-*- texinfo -*-\n\
01714 @deftypefn {Built-in Function} {} feof (@var{fid})\n\
01715 Return 1 if an end-of-file condition has been encountered for a given\n\
01716 file and 0 otherwise.  Note that it will only return 1 if the end of the\n\
01717 file has already been encountered, not if the next read operation will\n\
01718 result in an end-of-file condition.\n\
01719 @seealso{fread, fopen, fclose}\n\
01720 @end deftypefn")
01721 {
01722   octave_value retval = -1;
01723 
01724   int nargin = args.length ();
01725 
01726   if (nargin == 1)
01727     {
01728       octave_stream os = octave_stream_list::lookup (args(0), "feof");
01729 
01730       if (! error_state)
01731         retval = os.eof () ? 1.0 : 0.0;
01732     }
01733   else
01734     print_usage ();
01735 
01736   return retval;
01737 }
01738 
01739 DEFUNX ("ferror", Fferror, args, ,
01740   "-*- texinfo -*-\n\
01741 @deftypefn {Built-in Function} {[@var{err}, @var{msg}] =} ferror (@var{fid}, \"clear\")\n\
01742 Return 1 if an error condition has been encountered for the file ID\n\
01743 @var{fid} and 0 otherwise.  Note that it will only return 1 if an error\n\
01744 has already been encountered, not if the next operation will result in\n\
01745 an error condition.\n\
01746 \n\
01747 The second argument is optional.  If it is supplied, also clear the\n\
01748 error condition.\n\
01749 @end deftypefn")
01750 {
01751   octave_value_list retval;
01752 
01753   int nargin = args.length ();
01754 
01755   if (nargin == 1 || nargin == 2)
01756     {
01757       octave_stream os = octave_stream_list::lookup (args(0), "ferror");
01758 
01759       if (! error_state)
01760         {
01761           bool clear = false;
01762 
01763           if (nargin == 2)
01764             {
01765               std::string opt = args(1).string_value ();
01766 
01767               if (! error_state)
01768                 clear = (opt == "clear");
01769               else
01770                 return retval;
01771             }
01772 
01773           int error_number = 0;
01774 
01775           std::string error_message = os.error (clear, error_number);
01776 
01777           retval(1) = error_number;
01778           retval(0) = error_message;
01779         }
01780     }
01781   else
01782     print_usage ();
01783 
01784   return retval;
01785 }
01786 
01787 DEFUN (popen, args, ,
01788   "-*- texinfo -*-\n\
01789 @deftypefn {Built-in Function} {@var{fid} =} popen (@var{command}, @var{mode})\n\
01790 Start a process and create a pipe.  The name of the command to run is\n\
01791 given by @var{command}.  The file identifier corresponding to the input\n\
01792 or output stream of the process is returned in @var{fid}.  The argument\n\
01793 @var{mode} may be\n\
01794 \n\
01795 @table @code\n\
01796 @item \"r\"\n\
01797 The pipe will be connected to the standard output of the process, and\n\
01798 open for reading.\n\
01799 \n\
01800 @item \"w\"\n\
01801 The pipe will be connected to the standard input of the process, and\n\
01802 open for writing.\n\
01803 @end table\n\
01804 \n\
01805 For example:\n\
01806 \n\
01807 @example\n\
01808 @group\n\
01809 fid = popen (\"ls -ltr / | tail -3\", \"r\");\n\
01810 while (ischar (s = fgets (fid)))\n\
01811   fputs (stdout, s);\n\
01812 endwhile\n\
01813      @print{} drwxr-xr-x  33 root  root  3072 Feb 15 13:28 etc\n\
01814      @print{} drwxr-xr-x   3 root  root  1024 Feb 15 13:28 lib\n\
01815      @print{} drwxrwxrwt  15 root  root  2048 Feb 17 14:53 tmp\n\
01816 @end group\n\
01817 @end example\n\
01818 @end deftypefn")
01819 {
01820   octave_value retval = -1;
01821 
01822   int nargin = args.length ();
01823 
01824   if (nargin == 2)
01825     {
01826       std::string name = args(0).string_value ();
01827 
01828       if (! error_state)
01829         {
01830           std::string mode = args(1).string_value ();
01831 
01832           if (! error_state)
01833             {
01834               if (mode == "r")
01835                 {
01836                   octave_stream ips = octave_iprocstream::create (name);
01837 
01838                   retval = octave_stream_list::insert (ips);
01839                 }
01840               else if (mode == "w")
01841                 {
01842                   octave_stream ops = octave_oprocstream::create (name);
01843 
01844                   retval = octave_stream_list::insert (ops);
01845                 }
01846               else
01847                 ::error ("popen: invalid MODE specified");
01848             }
01849           else
01850             ::error ("popen: MODE must be a string");
01851         }
01852       else
01853         ::error ("popen: COMMAND must be a string");
01854     }
01855   else
01856     print_usage ();
01857 
01858   return retval;
01859 }
01860 
01861 DEFUN (pclose, args, ,
01862   "-*- texinfo -*-\n\
01863 @deftypefn {Built-in Function} {} pclose (@var{fid})\n\
01864 Close a file identifier that was opened by @code{popen}.  You may also\n\
01865 use @code{fclose} for the same purpose.\n\
01866 @end deftypefn")
01867 {
01868   octave_value retval = -1;
01869 
01870   int nargin = args.length ();
01871 
01872   if (nargin == 1)
01873     retval = octave_stream_list::remove (args(0), "pclose");
01874   else
01875     print_usage ();
01876 
01877   return retval;
01878 }
01879 
01880 DEFUNX ("tmpnam", Ftmpnam, args, ,
01881  "-*- texinfo -*-\n\
01882 @c List other forms of function in documentation index\n\
01883 @findex octave_tmp_file_name\n\
01884 \n\
01885 @deftypefn  {Built-in Function} {} tmpnam ()\n\
01886 @deftypefnx {Built-in Function} {} tmpnam (@var{dir})\n\
01887 @deftypefnx {Built-in Function} {} tmpnam (@var{dir}, @var{prefix})\n\
01888 Return a unique temporary file name as a string.\n\
01889 \n\
01890 If @var{prefix} is omitted, a value of @code{\"oct-\"} is used.\n\
01891 If @var{dir} is also omitted, the default directory for temporary files\n\
01892 is used.  If @var{dir} is provided, it must exist, otherwise the default\n\
01893 directory for temporary files is used.  Since the named file is not\n\
01894 opened, by @code{tmpnam}, it is possible (though relatively unlikely)\n\
01895 that it will not be available by the time your program attempts to open it.\n\
01896 @seealso{tmpfile, mkstemp, P_tmpdir}\n\
01897 @end deftypefn")
01898 {
01899   octave_value retval;
01900 
01901   int len = args.length ();
01902 
01903   if (len < 3)
01904     {
01905       std::string dir = len > 0 ? args(0).string_value () : std::string ();
01906 
01907       if (! error_state)
01908         {
01909           std::string pfx
01910             = len > 1 ? args(1).string_value () : std::string ("oct-");
01911 
01912           if (! error_state)
01913             retval = octave_tempnam (dir, pfx);
01914           else
01915             ::error ("PREFIX must be a string");
01916         }
01917       else
01918         ::error ("DIR argument must be a string");
01919     }
01920   else
01921     print_usage ();
01922 
01923   return retval;
01924 }
01925 
01926 DEFALIAS (octave_tmp_file_name, tmpnam);
01927 
01928 DEFUN (tmpfile, args, ,
01929   "-*- texinfo -*-\n\
01930 @deftypefn {Built-in Function} {[@var{fid}, @var{msg}] =} tmpfile ()\n\
01931 Return the file ID corresponding to a new temporary file with a unique\n\
01932 name.  The file is opened in binary read/write (@code{\"w+b\"}) mode.\n\
01933 The file will be deleted automatically when it is closed or when Octave\n\
01934 exits.\n\
01935 \n\
01936 If successful, @var{fid} is a valid file ID and @var{msg} is an empty\n\
01937 string.  Otherwise, @var{fid} is -1 and @var{msg} contains a\n\
01938 system-dependent error message.\n\
01939 @seealso{tmpnam, mkstemp, P_tmpdir}\n\
01940 @end deftypefn")
01941 {
01942   octave_value_list retval;
01943 
01944   retval(1) = std::string ();
01945   retval(0) = -1;
01946 
01947   int nargin = args.length ();
01948 
01949   if (nargin == 0)
01950     {
01951       FILE *fid = gnulib::tmpfile ();
01952 
01953       if (fid)
01954         {
01955           std::string nm;
01956 
01957           std::ios::openmode md = fopen_mode_to_ios_mode ("w+b");
01958 
01959           octave_stream s = octave_stdiostream::create (nm, fid, md);
01960 
01961           if (s)
01962             retval(0) = octave_stream_list::insert (s);
01963           else
01964             error ("tmpfile: failed to create octave_stdiostream object");
01965 
01966         }
01967       else
01968         {
01969           retval(1) = gnulib::strerror (errno);
01970           retval(0) = -1;
01971         }
01972     }
01973   else
01974     print_usage ();
01975 
01976   return retval;
01977 }
01978 
01979 DEFUN (mkstemp, args, ,
01980   "-*- texinfo -*-\n\
01981 @deftypefn {Built-in Function} {[@var{fid}, @var{name}, @var{msg}] =} mkstemp (@var{template}, @var{delete})\n\
01982 Return the file ID corresponding to a new temporary file with a unique\n\
01983 name created from @var{template}.  The last six characters of @var{template}\n\
01984 must be @code{XXXXXX} and these are replaced with a string that makes the\n\
01985 filename unique.  The file is then created with mode read/write and\n\
01986 permissions that are system dependent (on GNU/Linux systems, the permissions\n\
01987 will be 0600 for versions of glibc 2.0.7 and later).  The file is opened\n\
01988 in binary mode and with the @w{@code{O_EXCL}} flag.\n\
01989 \n\
01990 If the optional argument @var{delete} is supplied and is true,\n\
01991 the file will be deleted automatically when Octave exits, or when\n\
01992 the function @code{purge_tmp_files} is called.\n\
01993 \n\
01994 If successful, @var{fid} is a valid file ID, @var{name} is the name of\n\
01995 the file, and @var{msg} is an empty string.  Otherwise, @var{fid}\n\
01996 is -1, @var{name} is empty, and @var{msg} contains a system-dependent\n\
01997 error message.\n\
01998 @seealso{tmpfile, tmpnam, P_tmpdir}\n\
01999 @end deftypefn")
02000 {
02001   octave_value_list retval;
02002 
02003   retval(2) = std::string ();
02004   retval(1) = std::string ();
02005   retval(0) = -1;
02006 
02007   int nargin = args.length ();
02008 
02009   if (nargin == 1 || nargin == 2)
02010     {
02011       std::string tmpl8 = args(0).string_value ();
02012 
02013       if (! error_state)
02014         {
02015           OCTAVE_LOCAL_BUFFER (char, tmp, tmpl8.size () + 1);
02016           strcpy (tmp, tmpl8.c_str ());
02017 
02018           int fd = gnulib::mkostemp (tmp, O_BINARY);
02019 
02020           if (fd < 0)
02021             {
02022               retval(2) = gnulib::strerror (errno);
02023               retval(0) = fd;
02024             }
02025           else
02026             {
02027               const char *fopen_mode = "w+b";
02028 
02029               FILE *fid = fdopen (fd, fopen_mode);
02030 
02031               if (fid)
02032                 {
02033                   std::string nm = tmp;
02034 
02035                   std::ios::openmode md = fopen_mode_to_ios_mode (fopen_mode);
02036 
02037                   octave_stream s = octave_stdiostream::create (nm, fid, md);
02038 
02039                   if (s)
02040                     {
02041                       retval(1) = nm;
02042                       retval(0) = octave_stream_list::insert (s);
02043 
02044                       if (nargin == 2 && args(1).is_true ())
02045                         mark_for_deletion (nm);
02046                     }
02047                   else
02048                     error ("mkstemp: failed to create octave_stdiostream object");
02049                 }
02050               else
02051                 {
02052                   retval(2) = gnulib::strerror (errno);
02053                   retval(0) = -1;
02054                 }
02055             }
02056         }
02057       else
02058         error ("mkstemp: TEMPLATE argument must be a string");
02059     }
02060   else
02061     print_usage ();
02062 
02063   return retval;
02064 }
02065 
02066 static int
02067 convert (int x, int ibase, int obase)
02068 {
02069   int retval = 0;
02070 
02071   int tmp = x % obase;
02072 
02073   if (tmp > ibase - 1)
02074     ::error ("umask: invalid digit");
02075   else
02076     {
02077       retval = tmp;
02078       int mult = ibase;
02079       while ((x = (x - tmp) / obase))
02080         {
02081           tmp = x % obase;
02082           if (tmp > ibase - 1)
02083             {
02084               ::error ("umask: invalid digit");
02085               break;
02086             }
02087           retval += mult * tmp;
02088           mult *= ibase;
02089         }
02090     }
02091 
02092   return retval;
02093 }
02094 
02095 DEFUNX ("umask", Fumask, args, ,
02096   "-*- texinfo -*-\n\
02097 @deftypefn {Built-in Function} {} umask (@var{mask})\n\
02098 Set the permission mask for file creation.  The parameter @var{mask}\n\
02099 is an integer, interpreted as an octal number.  If successful,\n\
02100 returns the previous value of the mask (as an integer to be\n\
02101 interpreted as an octal number); otherwise an error message is printed.\n\
02102 @end deftypefn")
02103 {
02104   octave_value_list retval;
02105 
02106   int status = 0;
02107 
02108   if (args.length () == 1)
02109     {
02110       int mask = args(0).int_value (true);
02111 
02112       if (! error_state)
02113         {
02114           if (mask < 0)
02115             {
02116               status = -1;
02117               ::error ("umask: MASK must be a positive integer value");
02118             }
02119           else
02120             {
02121               int oct_mask = convert (mask, 8, 10);
02122 
02123               if (! error_state)
02124                 status = convert (octave_umask (oct_mask), 10, 8);
02125             }
02126         }
02127       else
02128         {
02129           status = -1;
02130           ::error ("umask: MASK must be an integer");
02131         }
02132     }
02133   else
02134     print_usage ();
02135 
02136   if (status >= 0)
02137     retval(0) = status;
02138 
02139   return retval;
02140 }
02141 
02142 static octave_value
02143 const_value (const char *, const octave_value_list& args, int val)
02144 {
02145   octave_value retval;
02146 
02147   int nargin = args.length ();
02148 
02149   if (nargin == 0)
02150     retval = val;
02151   else
02152     print_usage ();
02153 
02154   return retval;
02155 }
02156 
02157 DEFUNX ("P_tmpdir", FP_tmpdir, args, ,
02158   "-*- texinfo -*-\n\
02159 @deftypefn {Built-in Function} {} P_tmpdir ()\n\
02160 Return the default name of the directory for temporary files on\n\
02161 this system.  The name of this directory is system dependent.\n\
02162 @end deftypefn")
02163 {
02164   octave_value retval;
02165 
02166   int nargin = args.length ();
02167 
02168   if (nargin == 0)
02169     retval = get_P_tmpdir ();
02170   else
02171     print_usage ();
02172 
02173   return retval;
02174 }
02175 
02176 // NOTE: the values of SEEK_SET, SEEK_CUR, and SEEK_END have to be
02177 // this way for Matlab compatibility.
02178 
02179 DEFUNX ("SEEK_SET", FSEEK_SET, args, ,
02180   "-*- texinfo -*-\n\
02181 @deftypefn  {Built-in Function} {} SEEK_SET ()\n\
02182 @deftypefnx {Built-in Function} {} SEEK_CUR ()\n\
02183 @deftypefnx {Built-in Function} {} SEEK_END ()\n\
02184 Return the numerical value to pass to @code{fseek} to perform\n\
02185 one of the following actions:\n\
02186 @table @code\n\
02187 @item SEEK_SET\n\
02188 Position file relative to the beginning.\n\
02189 \n\
02190 @item SEEK_CUR\n\
02191 Position file relative to the current position.\n\
02192 \n\
02193 @item SEEK_END\n\
02194 Position file relative to the end.\n\
02195 @end table\n\
02196 @seealso{fseek}\n\
02197 @end deftypefn")
02198 {
02199   return const_value ("SEEK_SET", args, -1);
02200 }
02201 
02202 DEFUNX ("SEEK_CUR", FSEEK_CUR, args, ,
02203   "-*- texinfo -*-\n\
02204 @deftypefn {Built-in Function} {} SEEK_CUR ()\n\
02205 Return the numerical value to pass to @code{fseek} to\n\
02206 position the file pointer relative to the current position.\n\
02207 @seealso{SEEK_SET, SEEK_END}.\n\
02208 @end deftypefn")
02209 {
02210   return const_value ("SEEK_CUR", args, 0);
02211 }
02212 
02213 DEFUNX ("SEEK_END", FSEEK_END, args, ,
02214   "-*- texinfo -*-\n\
02215 @deftypefn {Built-in Function} {} SEEK_END ()\n\
02216 Return the numerical value to pass to @code{fseek} to\n\
02217 position the file pointer relative to the end of the file.\n\
02218 @seealso{SEEK_SET, SEEK_CUR}.\n\
02219 @end deftypefn")
02220 {
02221   return const_value ("SEEK_END", args, 1);
02222 }
02223 
02224 static octave_value
02225 const_value (const char *, const octave_value_list& args,
02226              const octave_value& val)
02227 {
02228   octave_value retval;
02229 
02230   int nargin = args.length ();
02231 
02232   if (nargin == 0)
02233     retval = val;
02234   else
02235     print_usage ();
02236 
02237   return retval;
02238 }
02239 
02240 DEFUNX ("stdin", Fstdin, args, ,
02241   "-*- texinfo -*-\n\
02242 @deftypefn {Built-in Function} {} stdin ()\n\
02243 Return the numeric value corresponding to the standard input stream.\n\
02244 When Octave is used interactively, this is filtered through the command\n\
02245 line editing functions.\n\
02246 @seealso{stdout, stderr}\n\
02247 @end deftypefn")
02248 {
02249   return const_value ("stdin", args, stdin_file);
02250 }
02251 
02252 DEFUNX ("stdout", Fstdout, args, ,
02253   "-*- texinfo -*-\n\
02254 @deftypefn {Built-in Function} {} stdout ()\n\
02255 Return the numeric value corresponding to the standard output stream.\n\
02256 Data written to the standard output is normally filtered through the pager.\n\
02257 @seealso{stdin, stderr}\n\
02258 @end deftypefn")
02259 {
02260   return const_value ("stdout", args, stdout_file);
02261 }
02262 
02263 DEFUNX ("stderr", Fstderr, args, ,
02264   "-*- texinfo -*-\n\
02265 @deftypefn {Built-in Function} {} stderr ()\n\
02266 Return the numeric value corresponding to the standard error stream.\n\
02267 Even if paging is turned on, the standard error is not sent to the\n\
02268 pager.  It is useful for error messages and prompts.\n\
02269 @seealso{stdin, stdout}\n\
02270 @end deftypefn")
02271 {
02272   return const_value ("stderr", args, stderr_file);
02273 }
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines