GNU Octave  3.8.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
file-io.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 1993-2013 John W. Eaton
4 
5 This file is part of Octave.
6 
7 Octave is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11 
12 Octave is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with Octave; see the file COPYING. If not, see
19 <http://www.gnu.org/licenses/>.
20 
21 */
22 
23 // Originally written by John C. Campbell <[email protected]>
24 //
25 // Thomas Baier <[email protected]> added the original versions of
26 // the following functions:
27 //
28 // popen
29 // pclose
30 // execute (now popen2.m)
31 // sync_system (now merged with system)
32 // async_system (now merged with system)
33 
34 // Extensively revised by John W. Eaton <[email protected]>,
35 // April 1996.
36 
37 #ifdef HAVE_CONFIG_H
38 #include <config.h>
39 #endif
40 
41 #include <cerrno>
42 #include <cstdio>
43 
44 #include <iostream>
45 #include <limits>
46 #include <stack>
47 #include <vector>
48 
49 #include <fcntl.h>
50 #include <sys/types.h>
51 #include <unistd.h>
52 
53 #ifdef HAVE_ZLIB_H
54 #include <zlib.h>
55 #endif
56 
57 #include "error.h"
58 #include "file-ops.h"
59 #include "file-stat.h"
60 #include "lo-ieee.h"
61 #include "oct-env.h"
62 #include "oct-locbuf.h"
63 
64 #include "defun.h"
65 #include "file-io.h"
66 #include "load-path.h"
67 #include "oct-fstrm.h"
68 #include "oct-iostrm.h"
69 #include "oct-map.h"
70 #include "oct-obj.h"
71 #include "oct-prcstrm.h"
72 #include "oct-stream.h"
73 #include "oct-strstrm.h"
74 #include "pager.h"
75 #include "sysdep.h"
76 #include "utils.h"
77 #include "variables.h"
78 
82 
86 
87 void
89 {
90  stdin_stream = octave_istream::create (&std::cin, "stdin");
91 
92  // This uses octave_stdout (see pager.h), not std::cout so that Octave's
93  // standard output stream will pass through the pager.
94 
95  stdout_stream = octave_ostream::create (&octave_stdout, "stdout");
96 
97  stderr_stream = octave_ostream::create (&std::cerr, "stderr");
98 
99  stdin_file = octave_stream_list::insert (stdin_stream);
100  stdout_file = octave_stream_list::insert (stdout_stream);
101  stderr_file = octave_stream_list::insert (stderr_stream);
102 }
103 
104 void
106 {
108 }
109 
110 // List of files to delete when we exit or crash.
111 //
112 // FIXME: this should really be static,
113 // but that causes problems on some systems.
114 std::stack <std::string> tmp_files;
115 
116 void
117 mark_for_deletion (const std::string& file)
118 {
119  tmp_files.push (file);
120 }
121 
122 void
124 {
125  while (! tmp_files.empty ())
126  {
127  std::string filename = tmp_files.top ();
128  tmp_files.pop ();
129  gnulib::unlink (filename.c_str ());
130  }
131 }
132 
133 static void
134 normalize_fopen_mode (std::string& mode, bool& use_zlib)
135 {
136  use_zlib = false;
137 
138  if (! mode.empty ())
139  {
140  // Could probably be faster, but does it really matter?
141 
142  // Accept 'W', 'R', and 'A' as 'w', 'r', and 'a' but we warn about
143  // them because Matlab says they don't perform "automatic
144  // flushing" but we don't know precisely what action that implies.
145 
146  size_t pos = mode.find ('W');
147 
148  if (pos != std::string::npos)
149  {
150  warning_with_id ("Octave:fopen-mode",
151  "fopen: treating mode \"W\" as equivalent to \"w\"");
152  mode[pos] = 'w';
153  }
154 
155  pos = mode.find ('R');
156 
157  if (pos != std::string::npos)
158  {
159  warning_with_id ("Octave:fopen-mode",
160  "fopen: treating mode \"R\" as equivalent to \"r\"");
161  mode[pos] = 'r';
162  }
163 
164  pos = mode.find ('A');
165 
166  if (pos != std::string::npos)
167  {
168  warning_with_id ("Octave:fopen-mode",
169  "fopen: treating mode \"A\" as equivalent to \"a\"");
170  mode[pos] = 'a';
171  }
172 
173  pos = mode.find ('z');
174 
175  if (pos != std::string::npos)
176  {
177 #if defined (HAVE_ZLIB)
178  use_zlib = true;
179  mode.erase (pos, 1);
180 #else
181  error ("this version of Octave does not support gzipped files");
182 #endif
183  }
184 
185  if (! error_state)
186  {
187  // Use binary mode if 't' is not specified, but don't add
188  // 'b' if it is already present.
189 
190  size_t bpos = mode.find ('b');
191  size_t tpos = mode.find ('t');
192 
193  if (bpos == std::string::npos && tpos == std::string::npos)
194  mode += 'b';
195  }
196  }
197 }
198 
199 static std::ios::openmode
200 fopen_mode_to_ios_mode (const std::string& mode)
201 {
202  std::ios::openmode retval = std::ios::in;
203 
204  if (! error_state)
205  {
206  if (mode == "rt")
207  retval = std::ios::in;
208  else if (mode == "wt")
209  retval = std::ios::out | std::ios::trunc;
210  else if (mode == "at")
211  retval = std::ios::out | std::ios::app;
212  else if (mode == "r+t" || mode == "rt+")
213  retval = std::ios::in | std::ios::out;
214  else if (mode == "w+t" || mode == "wt+")
215  retval = std::ios::in | std::ios::out | std::ios::trunc;
216  else if (mode == "a+t" || mode == "at+")
217  retval = std::ios::in | std::ios::out | std::ios::app;
218  else if (mode == "rb" || mode == "r")
219  retval = std::ios::in | std::ios::binary;
220  else if (mode == "wb" || mode == "w")
221  retval = std::ios::out | std::ios::trunc | std::ios::binary;
222  else if (mode == "ab" || mode == "a")
223  retval = std::ios::out | std::ios::app | std::ios::binary;
224  else if (mode == "r+b" || mode == "rb+" || mode == "r+")
225  retval = std::ios::in | std::ios::out | std::ios::binary;
226  else if (mode == "w+b" || mode == "wb+" || mode == "w+")
227  retval = (std::ios::in | std::ios::out | std::ios::trunc
228  | std::ios::binary);
229  else if (mode == "a+b" || mode == "ab+" || mode == "a+")
230  retval = (std::ios::in | std::ios::out | std::ios::app
231  | std::ios::binary);
232  else
233  ::error ("invalid mode specified");
234  }
235 
236  return retval;
237 }
238 
239 DEFUN (fclose, args, ,
240  "-*- texinfo -*-\n\
241 @deftypefn {Built-in Function} {} fclose (@var{fid})\n\
242 @deftypefnx {Built-in Function} {} fclose (\"all\")\n\
243 Close the specified file. If successful, @code{fclose} returns 0,\n\
244 otherwise, it returns -1. The second form of the @code{fclose} call closes\n\
245 all open files except @code{stdout}, @code{stderr}, and @code{stdin}.\n\
246 @seealso{fopen, freport}\n\
247 @end deftypefn")
248 {
249  octave_value retval = -1;
250 
251  int nargin = args.length ();
252 
253  if (nargin == 1)
254  retval = octave_stream_list::remove (args(0), "fclose");
255  else
256  print_usage ();
257 
258  return retval;
259 }
260 
261 DEFUN (fclear, args, ,
262  "-*- texinfo -*-\n\
263 @deftypefn {Built-in Function} {} fclear (@var{fid})\n\
264 Clear the stream state for the specified file.\n\
265 @seealso{fopen}\n\
266 @end deftypefn")
267 {
268  octave_value retval;
269 
270  int nargin = args.length ();
271 
272  if (nargin == 1)
273  {
274  int fid = octave_stream_list::get_file_number (args (0));
275 
276  octave_stream os = octave_stream_list::lookup (fid, "fclear");
277 
278  if (! error_state)
279  os.clearerr ();
280  }
281  else
282  print_usage ();
283 
284  return retval;
285 }
286 
287 DEFUN (fflush, args, ,
288  "-*- texinfo -*-\n\
289 @deftypefn {Built-in Function} {} fflush (@var{fid})\n\
290 Flush output to @var{fid}. This is useful for ensuring that all\n\
291 pending output makes it to the screen before some other event occurs.\n\
292 For example, it is always a good idea to flush the standard output\n\
293 stream before calling @code{input}.\n\
294 \n\
295 @code{fflush} returns 0 on success and an OS dependent error value\n\
296 (@minus{}1 on Unix) on error.\n\
297 @seealso{fopen, fclose}\n\
298 @end deftypefn")
299 {
300  octave_value retval = -1;
301 
302  int nargin = args.length ();
303 
304  if (nargin == 1)
305  {
306  // FIXME: any way to avoid special case for stdout?
307 
308  int fid = octave_stream_list::get_file_number (args (0));
309 
310  if (fid == 1)
311  {
313 
314  retval = 0;
315  }
316  else
317  {
318  octave_stream os = octave_stream_list::lookup (fid, "fflush");
319 
320  if (! error_state)
321  retval = os.flush ();
322  }
323  }
324  else
325  print_usage ();
326 
327  return retval;
328 }
329 
330 DEFUN (fgetl, args, ,
331  "-*- texinfo -*-\n\
332 @deftypefn {Built-in Function} {@var{str} =} fgetl (@var{fid})\n\
333 @deftypefnx {Built-in Function} {@var{str} =} fgetl (@var{fid}, @var{len})\n\
334 Read characters from a file, stopping after a newline, or EOF,\n\
335 or @var{len} characters have been read. The characters read, excluding\n\
336 the possible trailing newline, are returned as a string.\n\
337 \n\
338 If @var{len} is omitted, @code{fgetl} reads until the next newline\n\
339 character.\n\
340 \n\
341 If there are no more characters to read, @code{fgetl} returns @minus{}1.\n\
342 \n\
343 To read a line and return the terminating newline see @code{fgets}.\n\
344 @seealso{fgets, fscanf, fread, fopen}\n\
345 @end deftypefn")
346 {
347  static std::string who = "fgetl";
348 
349  octave_value_list retval;
350 
351  retval(1) = 0;
352  retval(0) = -1;
353 
354  int nargin = args.length ();
355 
356  if (nargin == 1 || nargin == 2)
357  {
358  octave_stream os = octave_stream_list::lookup (args(0), who);
359 
360  if (! error_state)
361  {
362  octave_value len_arg = (nargin == 2) ? args(1) : octave_value ();
363 
364  bool err = false;
365 
366  std::string tmp = os.getl (len_arg, err, who);
367 
368  if (! (error_state || err))
369  {
370  retval(1) = tmp.length ();
371  retval(0) = tmp;
372  }
373  }
374  }
375  else
376  print_usage ();
377 
378  return retval;
379 }
380 
381 DEFUN (fgets, args, ,
382  "-*- texinfo -*-\n\
383 @deftypefn {Built-in Function} {@var{str} =} fgets (@var{fid})\n\
384 @deftypefnx {Built-in Function} {@var{str} =} fgets (@var{fid}, @var{len})\n\
385 Read characters from a file, stopping after a newline, or EOF,\n\
386 or @var{len} characters have been read. The characters read, including\n\
387 the possible trailing newline, are returned as a string.\n\
388 \n\
389 If @var{len} is omitted, @code{fgets} reads until the next newline\n\
390 character.\n\
391 \n\
392 If there are no more characters to read, @code{fgets} returns @minus{}1.\n\
393 \n\
394 To read a line and discard the terminating newline see @code{fgetl}.\n\
395 @seealso{fputs, fgetl, fscanf, fread, fopen}\n\
396 @end deftypefn")
397 {
398  static std::string who = "fgets";
399 
400  octave_value_list retval;
401 
402  retval(1) = 0.0;
403  retval(0) = -1.0;
404 
405  int nargin = args.length ();
406 
407  if (nargin == 1 || nargin == 2)
408  {
409  octave_stream os = octave_stream_list::lookup (args(0), who);
410 
411  if (! error_state)
412  {
413  octave_value len_arg = (nargin == 2) ? args(1) : octave_value ();
414 
415  bool err = false;
416 
417  std::string tmp = os.gets (len_arg, err, who);
418 
419  if (! (error_state || err))
420  {
421  retval(1) = tmp.length ();
422  retval(0) = tmp;
423  }
424  }
425  }
426  else
427  print_usage ();
428 
429  return retval;
430 }
431 
432 DEFUN (fskipl, args, ,
433  "-*- texinfo -*-\n\
434 @deftypefn {Built-in Function} {@var{nlines} =} fskipl (@var{fid})\n\
435 @deftypefnx {Built-in Function} {@var{nlines} =} fskipl (@var{fid}, @var{count})\n\
436 @deftypefnx {Built-in Function} {@var{nlines} =} fskipl (@var{fid}, Inf)\n\
437 Read and skip @var{count} lines from the file descriptor @var{fid}.\n\
438 @code{fskipl} discards characters until an end-of-line is encountered exactly\n\
439 @var{count}-times, or until the end-of-file marker is found.\n\
440 \n\
441 If @var{count} is omitted, it defaults to 1. @var{count} may also be\n\
442 @code{Inf}, in which case lines are skipped until the end of the file.\n\
443 This form is suitable for counting the number of lines in a file.\n\
444 \n\
445 Returns the number of lines skipped (end-of-line sequences encountered).\n\
446 @seealso{fgetl, fgets, fscanf, fopen}\n\
447 @end deftypefn")
448 {
449  static std::string who = "fskipl";
450 
451  octave_value retval;
452 
453  int nargin = args.length ();
454 
455  if (nargin == 1 || nargin == 2)
456  {
457  octave_stream os = octave_stream_list::lookup (args(0), who);
458 
459  if (! error_state)
460  {
461  octave_value count_arg = (nargin == 2) ? args(1) : octave_value ();
462 
463  bool err = false;
464 
465  off_t tmp = os.skipl (count_arg, err, who);
466 
467  if (! (error_state || err))
468  retval = tmp;
469  }
470  }
471  else
472  print_usage ();
473 
474  return retval;
475 }
476 
477 
478 static octave_stream
479 do_stream_open (const std::string& name, const std::string& mode_arg,
480  const std::string& arch, int& fid)
481 {
482  octave_stream retval;
483 
484  fid = -1;
485 
486  std::string mode = mode_arg;
487  bool use_zlib = false;
488  normalize_fopen_mode (mode, use_zlib);
489 
490  std::ios::openmode md = fopen_mode_to_ios_mode (mode);
491 
492  if (! error_state)
493  {
496 
497  if (! error_state)
498  {
499  std::string fname = file_ops::tilde_expand (name);
500 
501  file_stat fs (fname);
502 
503  if (! (md & std::ios::out
506  {
507  if (! fs.exists ())
508  {
509  std::string tmp
511 
512  if (! tmp.empty ())
513  {
514  warning_with_id ("Octave:fopen-file-in-path",
515  "fopen: file found in load path");
516  fname = tmp;
517  }
518  }
519  }
520 
521  if (! fs.is_dir ())
522  {
523 #if defined (HAVE_ZLIB)
524  if (use_zlib)
525  {
526  FILE *fptr = gnulib::fopen (fname.c_str (), mode.c_str ());
527 
528  int fd = fileno (fptr);
529 
530  gzFile gzf = ::gzdopen (fd, mode.c_str ());
531 
532  if (fptr)
533  retval = octave_zstdiostream::create (fname, gzf, fd,
534  md, flt_fmt);
535  else
536  retval.error (gnulib::strerror (errno));
537  }
538  else
539 #endif
540  {
541  FILE *fptr = gnulib::fopen (fname.c_str (), mode.c_str ());
542 
543  retval = octave_stdiostream::create (fname, fptr, md,
544  flt_fmt);
545 
546  if (! fptr)
547  retval.error (gnulib::strerror (errno));
548  }
549 
550  }
551  }
552  }
553 
554  return retval;
555 }
556 
557 static octave_stream
558 do_stream_open (const octave_value& tc_name, const octave_value& tc_mode,
559  const octave_value& tc_arch, const char *fcn, int& fid)
560 {
561  octave_stream retval;
562 
563  fid = -1;
564 
565  std::string name = tc_name.string_value ();
566 
567  if (! error_state)
568  {
569  std::string mode = tc_mode.string_value ();
570 
571  if (! error_state)
572  {
573  std::string arch = tc_arch.string_value ();
574 
575  if (! error_state)
576  retval = do_stream_open (name, mode, arch, fid);
577  else
578  ::error ("%s: architecture type must be a string", fcn);
579  }
580  else
581  ::error ("%s: file mode must be a string", fcn);
582  }
583  else
584  ::error ("%s: file name must be a string", fcn);
585 
586  return retval;
587 }
588 
589 DEFUN (fopen, args, nargout,
590  "-*- texinfo -*-\n\
591 @deftypefn {Built-in Function} {[@var{fid}, @var{msg}] =} fopen (@var{name}, @var{mode}, @var{arch})\n\
592 @deftypefnx {Built-in Function} {@var{fid_list} =} fopen (\"all\")\n\
593 @deftypefnx {Built-in Function} {[@var{file}, @var{mode}, @var{arch}] =} fopen (@var{fid})\n\
594 The first form of the @code{fopen} function opens the named file with\n\
595 the specified mode (read-write, read-only, etc.) and architecture\n\
596 interpretation (IEEE big endian, IEEE little endian, etc.), and returns\n\
597 an integer value that may be used to refer to the file later. If an\n\
598 error occurs, @var{fid} is set to @minus{}1 and @var{msg} contains the\n\
599 corresponding system error message. The @var{mode} is a one or two\n\
600 character string that specifies whether the file is to be opened for\n\
601 reading, writing, or both.\n\
602 \n\
603 The second form of the @code{fopen} function returns a vector of file ids\n\
604 corresponding to all the currently open files, excluding the\n\
605 @code{stdin}, @code{stdout}, and @code{stderr} streams.\n\
606 \n\
607 The third form of the @code{fopen} function returns information about the\n\
608 open file given its file id.\n\
609 \n\
610 For example,\n\
611 \n\
612 @example\n\
613 myfile = fopen (\"splat.dat\", \"r\", \"ieee-le\");\n\
614 @end example\n\
615 \n\
616 @noindent\n\
617 opens the file @file{splat.dat} for reading. If necessary, binary\n\
618 numeric values will be read assuming they are stored in IEEE format with\n\
619 the least significant bit first, and then converted to the native\n\
620 representation.\n\
621 \n\
622 Opening a file that is already open simply opens it again and returns a\n\
623 separate file id. It is not an error to open a file several times,\n\
624 though writing to the same file through several different file ids may\n\
625 produce unexpected results.\n\
626 \n\
627 The possible values @samp{mode} may have are\n\
628 \n\
629 @table @asis\n\
630 @item @samp{r}\n\
631 Open a file for reading.\n\
632 \n\
633 @item @samp{w}\n\
634 Open a file for writing. The previous contents are discarded.\n\
635 \n\
636 @item @samp{a}\n\
637 Open or create a file for writing at the end of the file.\n\
638 \n\
639 @item @samp{r+}\n\
640 Open an existing file for reading and writing.\n\
641 \n\
642 @item @samp{w+}\n\
643 Open a file for reading or writing. The previous contents are\n\
644 discarded.\n\
645 \n\
646 @item @samp{a+}\n\
647 Open or create a file for reading or writing at the end of the\n\
648 file.\n\
649 @end table\n\
650 \n\
651 Append a @qcode{\"t\"} to the mode string to open the file in text mode or a\n\
652 @qcode{\"b\"} to open in binary mode. On Windows and Macintosh systems, text\n\
653 mode reading and writing automatically converts linefeeds to the\n\
654 appropriate line end character for the system (carriage-return linefeed\n\
655 on Windows, carriage-return on Macintosh). The default if no mode is\n\
656 specified is binary mode.\n\
657 \n\
658 Additionally, you may append a @qcode{\"z\"} to the mode string to open a\n\
659 gzipped file for reading or writing. For this to be successful, you\n\
660 must also open the file in binary mode.\n\
661 \n\
662 The parameter @var{arch} is a string specifying the default data format\n\
663 for the file. Valid values for @var{arch} are:\n\
664 \n\
665 @table @samp\n\
666 @item native\n\
667 The format of the current machine (this is the default).\n\
668 \n\
669 @item ieee-be\n\
670 IEEE big endian format.\n\
671 \n\
672 @item ieee-le\n\
673 IEEE little endian format.\n\
674 @end table\n\
675 \n\
676 @noindent\n\
677 however, conversions are currently only supported for @samp{native}\n\
678 @samp{ieee-be}, and @samp{ieee-le} formats.\n\
679 @seealso{fclose, fgets, fgetl, fscanf, fread, fputs, fdisp, fprintf, fwrite, fskipl, fseek, frewind, ftell, feof, ferror, fclear, fflush, freport}\n\
680 @end deftypefn")
681 {
682  octave_value_list retval;
683 
684  retval(0) = -1.0;
685 
686  int nargin = args.length ();
687 
688  if (nargin == 1)
689  {
690  if (args(0).is_string ())
691  {
692  // If there is only one argument and it is a string but it
693  // is not the string "all", we assume it is a file to open
694  // with MODE = "r". To open a file called "all", you have
695  // to supply more than one argument.
696 
697  if (nargout < 2 && args(0).string_value () == "all")
699  }
700  else
701  {
703 
704  if (! error_state)
705  {
706  retval(2) = tmp(2);
707  retval(1) = tmp(1);
708  retval(0) = tmp(0);
709  }
710 
711  return retval;
712  }
713  }
714 
715  if (nargin > 0 && nargin < 4)
716  {
717  octave_value mode = (nargin == 2 || nargin == 3)
718  ? args(1) : octave_value ("r");
719 
720  octave_value arch = (nargin == 3)
721  ? args(2) : octave_value ("native");
722 
723  int fid = -1;
724 
725  octave_stream os = do_stream_open (args(0), mode, arch, "fopen", fid);
726 
727  if (os && ! error_state)
728  {
729  retval(1) = "";
730  retval(0) = octave_stream_list::insert (os);
731  }
732  else
733  {
734  int error_number = 0;
735 
736  retval(1) = os.error (false, error_number);
737  retval(0) = -1.0;
738  }
739  }
740  else
741  print_usage ();
742 
743  return retval;
744 }
745 
746 DEFUN (freport, args, ,
747  "-*- texinfo -*-\n\
748 @deftypefn {Built-in Function} {} freport ()\n\
749 Print a list of which files have been opened, and whether they are open\n\
750 for reading, writing, or both. For example:\n\
751 \n\
752 @example\n\
753 @group\n\
754 freport ()\n\
755 \n\
756  @print{} number mode name\n\
757  @print{}\n\
758  @print{} 0 r stdin\n\
759  @print{} 1 w stdout\n\
760  @print{} 2 w stderr\n\
761  @print{} 3 r myfile\n\
762 @end group\n\
763 @end example\n\
764 @seealso{fopen, fclose}\n\
765 @end deftypefn")
766 {
767  octave_value_list retval;
768 
769  int nargin = args.length ();
770 
771  if (nargin > 0)
772  warning ("freport: ignoring extra arguments");
773 
775 
776  return retval;
777 }
778 
779 DEFUN (frewind, args, nargout,
780  "-*- texinfo -*-\n\
781 @deftypefn {Built-in Function} {} frewind (@var{fid})\n\
782 Move the file pointer to the beginning of the file @var{fid}, returning\n\
783 0 for success, and -1 if an error was encountered. It is equivalent to\n\
784 @code{fseek (@var{fid}, 0, SEEK_SET)}.\n\
785 @seealso{fseek, ftell, fopen}\n\
786 @end deftypefn")
787 {
788  octave_value retval;
789 
790  int result = -1;
791 
792  int nargin = args.length ();
793 
794  if (nargin == 1)
795  {
796  octave_stream os = octave_stream_list::lookup (args(0), "frewind");
797 
798  if (! error_state)
799  result = os.rewind ();
800  }
801  else
802  print_usage ();
803 
804  if (nargout > 0)
805  retval = result;
806 
807  return retval;
808 }
809 
810 DEFUN (fseek, args, ,
811  "-*- texinfo -*-\n\
812 @deftypefn {Built-in Function} {} fseek (@var{fid}, @var{offset})\n\
813 @deftypefnx {Built-in Function} {} fseek (@var{fid}, @var{offset}, @var{origin})\n\
814 @deftypefnx {Built-in Function} {@var{status} =} fseek (@dots{})\n\
815 Set the file pointer to any location within the file @var{fid}.\n\
816 \n\
817 The pointer is positioned @var{offset} characters from the @var{origin},\n\
818 which may be one of the predefined variables @w{@code{SEEK_CUR}} (current\n\
819 position), @w{@code{SEEK_SET}} (beginning), or @w{@code{SEEK_END}} (end of\n\
820 file) or strings @qcode{\"cof\"}, @qcode{\"bof\"} or @qcode{\"eof\"}. If\n\
821 @var{origin} is omitted, @w{@code{SEEK_SET}} is assumed. @var{offset} may\n\
822 be positive, negative, or zero but not all combinations of @var{origin} and\n\
823 @var{offset} can be realized.\n\
824 \n\
825 Return 0 on success and -1 on error.\n\
826 @seealso{fskipl, frewind, ftell, fopen}\n\
827 @end deftypefn")
828 {
829  octave_value retval = -1;
830 
831  int nargin = args.length ();
832 
833  if (nargin == 2 || nargin == 3)
834  {
835  octave_stream os = octave_stream_list::lookup (args(0), "fseek");
836 
837  if (! error_state)
838  {
839  octave_value origin_arg = (nargin == 3)
840  ? args(2) : octave_value (-1.0);
841 
842  retval = os.seek (args(1), origin_arg);
843  }
844  }
845  else
846  print_usage ();
847 
848  return retval;
849 }
850 
851 DEFUN (ftell, args, ,
852  "-*- texinfo -*-\n\
853 @deftypefn {Built-in Function} {} ftell (@var{fid})\n\
854 Return the position of the file pointer as the number of characters\n\
855 from the beginning of the file @var{fid}.\n\
856 @seealso{fseek, feof, fopen}\n\
857 @end deftypefn")
858 {
859  octave_value retval = -1;
860 
861  int nargin = args.length ();
862 
863  if (nargin == 1)
864  {
865  octave_stream os = octave_stream_list::lookup (args(0), "ftell");
866 
867  if (! error_state)
868  retval = os.tell ();
869  }
870  else
871  print_usage ();
872 
873  return retval;
874 }
875 
876 DEFUN (fprintf, args, nargout,
877  "-*- texinfo -*-\n\
878 @deftypefn {Built-in Function} {} fprintf (@var{fid}, @var{template}, @dots{})\n\
879 This function is just like @code{printf}, except that the output is\n\
880 written to the stream @var{fid} instead of @code{stdout}.\n\
881 If @var{fid} is omitted, the output is written to @code{stdout}.\n\
882 @seealso{fputs, fdisp, fwrite, fscanf, printf, sprintf, fopen}\n\
883 @end deftypefn")
884 {
885  static std::string who = "fprintf";
886 
887  octave_value retval;
888 
889  int result = -1;
890 
891  int nargin = args.length ();
892 
893  if (nargin > 1 || (nargin > 0 && args(0).is_string ()))
894  {
895  octave_stream os;
896  int fmt_n = 0;
897 
898  if (args(0).is_string ())
899  {
900  os = octave_stream_list::lookup (1, who);
901  }
902  else
903  {
904  fmt_n = 1;
905  os = octave_stream_list::lookup (args(0), who);
906  }
907 
908  if (! error_state)
909  {
910  if (args(fmt_n).is_string ())
911  {
912  octave_value_list tmp_args;
913 
914  if (nargin > 1 + fmt_n)
915  {
916  tmp_args.resize (nargin-fmt_n-1, octave_value ());
917 
918  for (int i = fmt_n + 1; i < nargin; i++)
919  tmp_args(i-fmt_n-1) = args(i);
920  }
921 
922  result = os.printf (args(fmt_n), tmp_args, who);
923  }
924  else
925  ::error ("%s: format TEMPLATE must be a string", who.c_str ());
926  }
927  }
928  else
929  print_usage ();
930 
931  if (nargout > 0)
932  retval = result;
933 
934  return retval;
935 }
936 
937 DEFUN (printf, args, nargout,
938  "-*- texinfo -*-\n\
939 @deftypefn {Built-in Function} {} printf (@var{template}, @dots{})\n\
940 Print optional arguments under the control of the template string\n\
941 @var{template} to the stream @code{stdout} and return the number of\n\
942 characters printed.\n\
943 @ifclear OCTAVE_MANUAL\n\
944 \n\
945 See the Formatted Output section of the GNU Octave manual for a\n\
946 complete description of the syntax of the template string.\n\
947 @end ifclear\n\
948 @seealso{fprintf, sprintf, scanf}\n\
949 @end deftypefn")
950 {
951  static std::string who = "printf";
952 
953  octave_value retval;
954 
955  int result = -1;
956 
957  int nargin = args.length ();
958 
959  if (nargin > 0)
960  {
961  if (args(0).is_string ())
962  {
963  octave_value_list tmp_args;
964 
965  if (nargin > 1)
966  {
967  tmp_args.resize (nargin-1, octave_value ());
968 
969  for (int i = 1; i < nargin; i++)
970  tmp_args(i-1) = args(i);
971  }
972 
973  result = stdout_stream.printf (args(0), tmp_args, who);
974  }
975  else
976  ::error ("%s: format TEMPLATE must be a string", who.c_str ());
977  }
978  else
979  print_usage ();
980 
981  if (nargout > 0)
982  retval = result;
983 
984  return retval;
985 }
986 
987 DEFUN (fputs, args, ,
988  "-*- texinfo -*-\n\
989 @deftypefn {Built-in Function} {} fputs (@var{fid}, @var{string})\n\
990 Write a string to a file with no formatting.\n\
991 \n\
992 Return a non-negative number on success and EOF on error.\n\
993 @seealso{fdisp, fprintf, fwrite, fopen}\n\
994 @end deftypefn")
995 {
996  static std::string who = "fputs";
997 
998  octave_value retval = -1;
999 
1000  int nargin = args.length ();
1001 
1002  if (nargin == 2)
1003  {
1004  octave_stream os = octave_stream_list::lookup (args(0), who);
1005 
1006  if (! error_state)
1007  retval = os.puts (args(1), who);
1008  }
1009  else
1010  print_usage ();
1011 
1012  return retval;
1013 }
1014 
1015 DEFUN (puts, args, ,
1016  "-*- texinfo -*-\n\
1017 @deftypefn {Built-in Function} {} puts (@var{string})\n\
1018 Write a string to the standard output with no formatting.\n\
1019 \n\
1020 Return a non-negative number on success and EOF on error.\n\
1021 @seealso{fputs, disp}\n\
1022 @end deftypefn")
1023 {
1024  static std::string who = "puts";
1025 
1026  octave_value retval = -1;
1027 
1028  if (args.length () == 1)
1029  retval = stdout_stream.puts (args(0), who);
1030  else
1031  print_usage ();
1032 
1033  return retval;
1034 }
1035 
1036 DEFUN (sprintf, args, ,
1037  "-*- texinfo -*-\n\
1038 @deftypefn {Built-in Function} {} sprintf (@var{template}, @dots{})\n\
1039 This is like @code{printf}, except that the output is returned as a\n\
1040 string. Unlike the C library function, which requires you to provide a\n\
1041 suitably sized string as an argument, Octave's @code{sprintf} function\n\
1042 returns the string, automatically sized to hold all of the items\n\
1043 converted.\n\
1044 @seealso{printf, fprintf, sscanf}\n\
1045 @end deftypefn")
1046 {
1047  static std::string who = "sprintf";
1048 
1049  octave_value_list retval;
1050 
1051  int nargin = args.length ();
1052 
1053  if (nargin > 0)
1054  {
1055  retval(2) = -1.0;
1056  retval(1) = "unknown error";
1057  retval(0) = "";
1058 
1059  octave_ostrstream *ostr = new octave_ostrstream ();
1060 
1061  octave_stream os (ostr);
1062 
1063  if (os.is_valid ())
1064  {
1065  octave_value fmt_arg = args(0);
1066 
1067  if (fmt_arg.is_string ())
1068  {
1069  octave_value_list tmp_args;
1070 
1071  if (nargin > 1)
1072  {
1073  tmp_args.resize (nargin-1, octave_value ());
1074 
1075  for (int i = 1; i < nargin; i++)
1076  tmp_args(i-1) = args(i);
1077  }
1078 
1079  retval(2) = os.printf (fmt_arg, tmp_args, who);
1080  retval(1) = os.error ();
1081  retval(0) = octave_value (ostr->str (),
1082  fmt_arg.is_sq_string () ? '\'' : '"');
1083  }
1084  else
1085  ::error ("%s: format TEMPLATE must be a string", who.c_str ());
1086  }
1087  else
1088  ::error ("%s: unable to create output buffer", who.c_str ());
1089  }
1090  else
1091  print_usage ();
1092 
1093  return retval;
1094 }
1095 
1096 DEFUN (fscanf, args, ,
1097  "-*- texinfo -*-\n\
1098 @deftypefn {Built-in Function} {[@var{val}, @var{count}, @var{errmsg}] =} fscanf (@var{fid}, @var{template}, @var{size})\n\
1099 @deftypefnx {Built-in Function} {[@var{v1}, @var{v2}, @dots{}, @var{count}, @var{errmsg}] =} fscanf (@var{fid}, @var{template}, \"C\")\n\
1100 In the first form, read from @var{fid} according to @var{template},\n\
1101 returning the result in the matrix @var{val}.\n\
1102 \n\
1103 The optional argument @var{size} specifies the amount of data to read\n\
1104 and may be one of\n\
1105 \n\
1106 @table @code\n\
1107 @item Inf\n\
1108 Read as much as possible, returning a column vector.\n\
1109 \n\
1110 @item @var{nr}\n\
1111 Read up to @var{nr} elements, returning a column vector.\n\
1112 \n\
1113 @item [@var{nr}, Inf]\n\
1114 Read as much as possible, returning a matrix with @var{nr} rows. If the\n\
1115 number of elements read is not an exact multiple of @var{nr}, the last\n\
1116 column is padded with zeros.\n\
1117 \n\
1118 @item [@var{nr}, @var{nc}]\n\
1119 Read up to @code{@var{nr} * @var{nc}} elements, returning a matrix with\n\
1120 @var{nr} rows. If the number of elements read is not an exact multiple\n\
1121 of @var{nr}, the last column is padded with zeros.\n\
1122 @end table\n\
1123 \n\
1124 @noindent\n\
1125 If @var{size} is omitted, a value of @code{Inf} is assumed.\n\
1126 \n\
1127 A string is returned if @var{template} specifies only character\n\
1128 conversions.\n\
1129 \n\
1130 The number of items successfully read is returned in @var{count}.\n\
1131 \n\
1132 If an error occurs, @var{errmsg} contains a system-dependent error message.\n\
1133 \n\
1134 In the second form, read from @var{fid} according to @var{template},\n\
1135 with each conversion specifier in @var{template} corresponding to a\n\
1136 single scalar return value. This form is more ``C-like'', and also\n\
1137 compatible with previous versions of Octave. The number of successful\n\
1138 conversions is returned in @var{count}\n\
1139 @ifclear OCTAVE_MANUAL\n\
1140 \n\
1141 See the Formatted Input section of the GNU Octave manual for a\n\
1142 complete description of the syntax of the template string.\n\
1143 @end ifclear\n\
1144 @seealso{fgets, fgetl, fread, scanf, sscanf, fopen}\n\
1145 @end deftypefn")
1146 {
1147  static std::string who = "fscanf";
1148 
1149  octave_value_list retval;
1150 
1151  int nargin = args.length ();
1152 
1153  if (nargin == 3 && args(2).is_string ())
1154  {
1155  octave_stream os = octave_stream_list::lookup (args(0), who);
1156 
1157  if (! error_state)
1158  {
1159  if (args(1).is_string ())
1160  retval = os.oscanf (args(1), who);
1161  else
1162  ::error ("%s: format TEMPLATE must be a string", who.c_str ());
1163  }
1164  }
1165  else
1166  {
1167  retval(2) = "unknown error";
1168  retval(1) = 0.0;
1169  retval(0) = Matrix ();
1170 
1171  if (nargin == 2 || nargin == 3)
1172  {
1173  octave_stream os = octave_stream_list::lookup (args(0), who);
1174 
1175  if (! error_state)
1176  {
1177  if (args(1).is_string ())
1178  {
1179  octave_idx_type count = 0;
1180 
1181  Array<double> size = (nargin == 3)
1182  ? args(2).vector_value ()
1183  : Array<double> (dim_vector (1, 1),
1184  lo_ieee_inf_value ());
1185 
1186  if (! error_state)
1187  {
1188  octave_value tmp = os.scanf (args(1), size, count, who);
1189 
1190  if (! error_state)
1191  {
1192  retval(2) = os.error ();
1193  retval(1) = count;
1194  retval(0) = tmp;
1195  }
1196  }
1197  }
1198  else
1199  ::error ("%s: format must be a string", who.c_str ());
1200  }
1201  }
1202  else
1203  print_usage ();
1204  }
1205 
1206  return retval;
1207 }
1208 
1209 static std::string
1211 {
1212  std::string retval;
1213 
1214  if (val.is_string ())
1215  {
1216  octave_value tmp = val.reshape (dim_vector (1, val.numel ()));
1217 
1218  retval = tmp.string_value ();
1219  }
1220  else
1221  ::error ("sscanf: argument STRING must be a string");
1222 
1223  return retval;
1224 }
1225 
1226 DEFUN (sscanf, args, ,
1227  "-*- texinfo -*-\n\
1228 @deftypefn {Built-in Function} {[@var{val}, @var{count}, @var{errmsg}, @var{pos}] =} sscanf (@var{string}, @var{template}, @var{size})\n\
1229 @deftypefnx {Built-in Function} {[@var{v1}, @var{v2}, @dots{}, @var{count}, @var{errmsg}] =} sscanf (@var{string}, @var{template}, \"C\")\n\
1230 This is like @code{fscanf}, except that the characters are taken from the\n\
1231 string @var{string} instead of from a stream. Reaching the end of the\n\
1232 string is treated as an end-of-file condition. In addition to the values\n\
1233 returned by @code{fscanf}, the index of the next character to be read\n\
1234 is returned in @var{pos}.\n\
1235 @seealso{fscanf, scanf, sprintf}\n\
1236 @end deftypefn")
1237 {
1238  static std::string who = "sscanf";
1239 
1240  octave_value_list retval;
1241 
1242  int nargin = args.length ();
1243 
1244  if (nargin == 3 && args(2).is_string ())
1245  {
1246  std::string data = get_sscanf_data (args(0));
1247 
1248  if (! error_state)
1249  {
1251 
1252  if (os.is_valid ())
1253  {
1254  if (args(1).is_string ())
1255  retval = os.oscanf (args(1), who);
1256  else
1257  ::error ("%s: format TEMPLATE must be a string", who.c_str ());
1258  }
1259  else
1260  ::error ("%s: unable to create temporary input buffer",
1261  who.c_str ());
1262  }
1263  else
1264  ::error ("%s: argument STRING must be a string", who.c_str ());
1265  }
1266  else
1267  {
1268  if (nargin == 2 || nargin == 3)
1269  {
1270  retval(3) = -1.0;
1271  retval(2) = "unknown error";
1272  retval(1) = 0.0;
1273  retval(0) = Matrix ();
1274 
1275  std::string data = get_sscanf_data (args(0));
1276 
1277  if (! error_state)
1278  {
1280 
1281  if (os.is_valid ())
1282  {
1283  if (args(1).is_string ())
1284  {
1285  octave_idx_type count = 0;
1286 
1287  Array<double> size = (nargin == 3)
1288  ? args(2).vector_value ()
1289  : Array<double> (dim_vector (1, 1),
1290  lo_ieee_inf_value ());
1291 
1292  octave_value tmp = os.scanf (args(1), size, count, who);
1293 
1294  if (! error_state)
1295  {
1296  // FIXME: is this the right thing to do?
1297  // Extract error message first, because getting
1298  // position will clear it.
1299  std::string errmsg = os.error ();
1300 
1301  retval(3)
1302  = (os.eof () ? data.length () : os.tell ()) + 1;
1303  retval(2) = errmsg;
1304  retval(1) = count;
1305  retval(0) = tmp;
1306  }
1307  }
1308  else
1309  ::error ("%s: format TEMPLATE must be a string",
1310  who.c_str ());
1311  }
1312  else
1313  ::error ("%s: unable to create temporary input buffer",
1314  who.c_str ());
1315  }
1316  }
1317  else
1318  print_usage ();
1319  }
1320 
1321  return retval;
1322 }
1323 
1324 DEFUN (scanf, args, nargout,
1325  "-*- texinfo -*-\n\
1326 @deftypefn {Built-in Function} {[@var{val}, @var{count}, @var{errmsg}] =} scanf (@var{template}, @var{size})\n\
1327 @deftypefnx {Built-in Function} {[@var{v1}, @var{v2}, @dots{}, @var{count}, @var{errmsg}]] =} scanf (@var{template}, \"C\")\n\
1328 This is equivalent to calling @code{fscanf} with @var{fid} = @code{stdin}.\n\
1329 \n\
1330 It is currently not useful to call @code{scanf} in interactive\n\
1331 programs.\n\
1332 @seealso{fscanf, sscanf, printf}\n\
1333 @end deftypefn")
1334 {
1335  int nargin = args.length ();
1336 
1337  octave_value_list tmp_args (nargin+1, octave_value ());
1338 
1339  tmp_args (0) = 0.0;
1340  for (int i = 0; i < nargin; i++)
1341  tmp_args (i+1) = args (i);
1342 
1343  return Ffscanf (tmp_args, nargout);
1344 }
1345 
1346 static octave_value
1347 do_fread (octave_stream& os, const octave_value& size_arg,
1348  const octave_value& prec_arg, const octave_value& skip_arg,
1349  const octave_value& arch_arg, octave_idx_type& count)
1350 {
1351  octave_value retval;
1352 
1353  count = -1;
1354 
1355  Array<double> size = size_arg.vector_value ();
1356 
1357  if (! error_state)
1358  {
1359  std::string prec = prec_arg.string_value ();
1360 
1361  if (! error_state)
1362  {
1363  int block_size = 1;
1364  oct_data_conv::data_type input_type;
1365  oct_data_conv::data_type output_type;
1366 
1367  oct_data_conv::string_to_data_type (prec, block_size,
1368  input_type, output_type);
1369 
1370  if (! error_state)
1371  {
1372  int skip = skip_arg.int_value (true);
1373 
1374  if (! error_state)
1375  {
1376  std::string arch = arch_arg.string_value ();
1377 
1378  if (! error_state)
1379  {
1382 
1383  if (! error_state)
1384  retval = os.read (size, block_size, input_type,
1385  output_type, skip, flt_fmt, count);
1386  }
1387  else
1388  ::error ("fread: ARCH architecture type must be a string");
1389  }
1390  else
1391  ::error ("fread: SKIP must be an integer");
1392  }
1393  else
1394  ::error ("fread: invalid PRECISION specified");
1395  }
1396  else
1397  ::error ("fread: PRECISION must be a string");
1398  }
1399  else
1400  ::error ("fread: invalid SIZE specified");
1401 
1402  return retval;
1403 }
1404 
1405 DEFUN (fread, args, ,
1406  "-*- texinfo -*-\n\
1407 @deftypefn {Built-in Function} {[@var{val}, @var{count}] =} fread (@var{fid}, @var{size}, @var{precision}, @var{skip}, @var{arch})\n\
1408 Read binary data of type @var{precision} from the specified file ID\n\
1409 @var{fid}.\n\
1410 \n\
1411 The optional argument @var{size} specifies the amount of data to read\n\
1412 and may be one of\n\
1413 \n\
1414 @table @code\n\
1415 @item Inf\n\
1416 Read as much as possible, returning a column vector.\n\
1417 \n\
1418 @item @var{nr}\n\
1419 Read up to @var{nr} elements, returning a column vector.\n\
1420 \n\
1421 @item [@var{nr}, Inf]\n\
1422 Read as much as possible, returning a matrix with @var{nr} rows. If the\n\
1423 number of elements read is not an exact multiple of @var{nr}, the last\n\
1424 column is padded with zeros.\n\
1425 \n\
1426 @item [@var{nr}, @var{nc}]\n\
1427 Read up to @code{@var{nr} * @var{nc}} elements, returning a matrix with\n\
1428 @var{nr} rows. If the number of elements read is not an exact multiple\n\
1429 of @var{nr}, the last column is padded with zeros.\n\
1430 @end table\n\
1431 \n\
1432 @noindent\n\
1433 If @var{size} is omitted, a value of @code{Inf} is assumed.\n\
1434 \n\
1435 The optional argument @var{precision} is a string specifying the type of\n\
1436 data to read and may be one of\n\
1437 \n\
1438 @table @asis\n\
1439 @item @qcode{\"schar\"}\n\
1440 @itemx @qcode{\"signed char\"}\n\
1441 Signed character.\n\
1442 \n\
1443 @item @qcode{\"uchar\"}\n\
1444 @itemx @qcode{\"unsigned char\"}\n\
1445 Unsigned character.\n\
1446 \n\
1447 @item @qcode{\"int8\"}\n\
1448 @itemx @qcode{\"integer*1\"}\n\
1449 \n\
1450 8-bit signed integer.\n\
1451 \n\
1452 @item @qcode{\"int16\"}\n\
1453 @itemx @qcode{\"integer*2\"}\n\
1454 16-bit signed integer.\n\
1455 \n\
1456 @item @qcode{\"int32\"}\n\
1457 @itemx @qcode{\"integer*4\"}\n\
1458 32-bit signed integer.\n\
1459 \n\
1460 @item @qcode{\"int64\"}\n\
1461 @itemx @qcode{\"integer*8\"}\n\
1462 64-bit signed integer.\n\
1463 \n\
1464 @item @qcode{\"uint8\"}\n\
1465 8-bit unsigned integer.\n\
1466 \n\
1467 @item @qcode{\"uint16\"}\n\
1468 16-bit unsigned integer.\n\
1469 \n\
1470 @item @qcode{\"uint32\"}\n\
1471 32-bit unsigned integer.\n\
1472 \n\
1473 @item @qcode{\"uint64\"}\n\
1474 64-bit unsigned integer.\n\
1475 \n\
1476 @item @qcode{\"single\"}\n\
1477 @itemx @qcode{\"float32\"}\n\
1478 @itemx @qcode{\"real*4\"}\n\
1479 32-bit floating point number.\n\
1480 \n\
1481 @item @qcode{\"double\"}\n\
1482 @itemx @qcode{\"float64\"}\n\
1483 @itemx @qcode{\"real*8\"}\n\
1484 64-bit floating point number.\n\
1485 \n\
1486 @item @qcode{\"char\"}\n\
1487 @itemx @qcode{\"char*1\"}\n\
1488 Single character.\n\
1489 \n\
1490 @item @qcode{\"short\"}\n\
1491 Short integer (size is platform dependent).\n\
1492 \n\
1493 @item @qcode{\"int\"}\n\
1494 Integer (size is platform dependent).\n\
1495 \n\
1496 @item @qcode{\"long\"}\n\
1497 Long integer (size is platform dependent).\n\
1498 \n\
1499 @item @qcode{\"ushort\"}\n\
1500 @itemx @qcode{\"unsigned short\"}\n\
1501 Unsigned short integer (size is platform dependent).\n\
1502 \n\
1503 @item @qcode{\"uint\"}\n\
1504 @itemx @qcode{\"unsigned int\"}\n\
1505 Unsigned integer (size is platform dependent).\n\
1506 \n\
1507 @item @qcode{\"ulong\"}\n\
1508 @itemx @qcode{\"unsigned long\"}\n\
1509 Unsigned long integer (size is platform dependent).\n\
1510 \n\
1511 @item @qcode{\"float\"}\n\
1512 Single precision floating point number (size is platform dependent).\n\
1513 @end table\n\
1514 \n\
1515 @noindent\n\
1516 The default precision is @qcode{\"uchar\"}.\n\
1517 \n\
1518 The @var{precision} argument may also specify an optional repeat\n\
1519 count. For example, @samp{32*single} causes @code{fread} to read\n\
1520 a block of 32 single precision floating point numbers. Reading in\n\
1521 blocks is useful in combination with the @var{skip} argument.\n\
1522 \n\
1523 The @var{precision} argument may also specify a type conversion.\n\
1524 For example, @samp{int16=>int32} causes @code{fread} to read 16-bit\n\
1525 integer values and return an array of 32-bit integer values. By\n\
1526 default, @code{fread} returns a double precision array. The special\n\
1527 form @samp{*TYPE} is shorthand for @samp{TYPE=>TYPE}.\n\
1528 \n\
1529 The conversion and repeat counts may be combined. For example, the\n\
1530 specification @samp{32*single=>single} causes @code{fread} to read\n\
1531 blocks of single precision floating point values and return an array\n\
1532 of single precision values instead of the default array of double\n\
1533 precision values.\n\
1534 \n\
1535 The optional argument @var{skip} specifies the number of bytes to skip\n\
1536 after each element (or block of elements) is read. If it is not\n\
1537 specified, a value of 0 is assumed. If the final block read is not\n\
1538 complete, the final skip is omitted. For example,\n\
1539 \n\
1540 @example\n\
1541 fread (f, 10, \"3*single=>single\", 8)\n\
1542 @end example\n\
1543 \n\
1544 @noindent\n\
1545 will omit the final 8-byte skip because the last read will not be\n\
1546 a complete block of 3 values.\n\
1547 \n\
1548 The optional argument @var{arch} is a string specifying the data format\n\
1549 for the file. Valid values are\n\
1550 \n\
1551 @table @code\n\
1552 @item @qcode{\"native\"}\n\
1553 The format of the current machine.\n\
1554 \n\
1555 @item \"ieee-be\"\n\
1556 IEEE big endian.\n\
1557 \n\
1558 @item \"ieee-le\"\n\
1559 IEEE little endian.\n\
1560 @end table\n\
1561 \n\
1562 The data read from the file is returned in @var{val}, and the number of\n\
1563 values read is returned in @code{count}\n\
1564 @seealso{fwrite, fgets, fgetl, fscanf, fopen}\n\
1565 @end deftypefn")
1566 {
1567  octave_value_list retval;
1568 
1569  int nargin = args.length ();
1570 
1571  if (nargin > 0 && nargin < 6)
1572  {
1573  retval(1) = -1.0;
1574  retval(0) = Matrix ();
1575 
1576  octave_stream os = octave_stream_list::lookup (args(0), "fread");
1577 
1578  if (! error_state)
1579  {
1581  octave_value prec = "uchar";
1582  octave_value skip = 0;
1583  octave_value arch = "unknown";
1584 
1585  int idx = 1;
1586 
1587  if (nargin > idx && ! args(idx).is_string ())
1588  size = args(idx++);
1589 
1590  if (nargin > idx)
1591  prec = args(idx++);
1592 
1593  if (nargin > idx)
1594  skip = args(idx++);
1595 
1596  if (nargin > idx)
1597  arch = args(idx++);
1598  else if (skip.is_string ())
1599  {
1600  arch = skip;
1601  skip = 0;
1602  }
1603 
1604  octave_idx_type count = -1;
1605 
1606  octave_value tmp = do_fread (os, size, prec, skip, arch, count);
1607 
1608  retval(1) = count;
1609  retval(0) = tmp;
1610  }
1611  }
1612  else
1613  print_usage ();
1614 
1615  return retval;
1616 }
1617 
1618 static int
1620  const octave_value& prec_arg, const octave_value& skip_arg,
1621  const octave_value& arch_arg)
1622 {
1623  int retval = -1;
1624 
1625  std::string prec = prec_arg.string_value ();
1626 
1627  if (! error_state)
1628  {
1629  int block_size = 1;
1630  oct_data_conv::data_type output_type;
1631 
1632  oct_data_conv::string_to_data_type (prec, block_size, output_type);
1633 
1634  if (! error_state)
1635  {
1636  int skip = skip_arg.int_value (true);
1637 
1638  if (! error_state)
1639  {
1640  std::string arch = arch_arg.string_value ();
1641 
1642  if (! error_state)
1643  {
1646 
1647  if (! error_state)
1648  retval = os.write (data, block_size, output_type,
1649  skip, flt_fmt);
1650  }
1651  else
1652  ::error ("fwrite: ARCH architecture type must be a string");
1653  }
1654  else
1655  ::error ("fwrite: SKIP must be an integer");
1656  }
1657  else
1658  ::error ("fwrite: invalid PRECISION specified");
1659  }
1660  else
1661  ::error ("fwrite: PRECISION must be a string");
1662 
1663  return retval;
1664 }
1665 
1666 DEFUN (fwrite, args, ,
1667  "-*- texinfo -*-\n\
1668 @deftypefn {Built-in Function} {@var{count} =} fwrite (@var{fid}, @var{data}, @var{precision}, @var{skip}, @var{arch})\n\
1669 Write data in binary form of type @var{precision} to the specified file\n\
1670 ID @var{fid}, returning the number of values successfully written to the\n\
1671 file.\n\
1672 \n\
1673 The argument @var{data} is a matrix of values that are to be written to\n\
1674 the file. The values are extracted in column-major order.\n\
1675 \n\
1676 The remaining arguments @var{precision}, @var{skip}, and @var{arch} are\n\
1677 optional, and are interpreted as described for @code{fread}.\n\
1678 \n\
1679 The behavior of @code{fwrite} is undefined if the values in @var{data}\n\
1680 are too large to fit in the specified precision.\n\
1681 @seealso{fread, fputs, fprintf, fopen}\n\
1682 @end deftypefn")
1683 {
1684  octave_value retval = -1;
1685 
1686  int nargin = args.length ();
1687 
1688  if (nargin > 1 && nargin < 6)
1689  {
1690  octave_stream os = octave_stream_list::lookup (args(0), "fwrite");
1691 
1692  if (! error_state)
1693  {
1694  octave_value prec = "uchar";
1695  octave_value skip = 0;
1696  octave_value arch = "unknown";
1697 
1698  int idx = 1;
1699 
1700  octave_value data = args(idx++);
1701 
1702  if (nargin > idx)
1703  prec = args(idx++);
1704 
1705  if (nargin > idx)
1706  skip = args(idx++);
1707 
1708  if (nargin > idx)
1709  arch = args(idx++);
1710  else if (skip.is_string ())
1711  {
1712  arch = skip;
1713  skip = 0;
1714  }
1715 
1716  double status = do_fwrite (os, data, prec, skip, arch);
1717 
1718  retval = status;
1719  }
1720  }
1721  else
1722  print_usage ();
1723 
1724  return retval;
1725 }
1726 
1727 DEFUNX ("feof", Ffeof, args, ,
1728  "-*- texinfo -*-\n\
1729 @deftypefn {Built-in Function} {} feof (@var{fid})\n\
1730 Return 1 if an end-of-file condition has been encountered for a given\n\
1731 file and 0 otherwise. Note that it will only return 1 if the end of the\n\
1732 file has already been encountered, not if the next read operation will\n\
1733 result in an end-of-file condition.\n\
1734 @seealso{fread, fopen}\n\
1735 @end deftypefn")
1736 {
1737  octave_value retval = -1;
1738 
1739  int nargin = args.length ();
1740 
1741  if (nargin == 1)
1742  {
1743  octave_stream os = octave_stream_list::lookup (args(0), "feof");
1744 
1745  if (! error_state)
1746  retval = os.eof () ? 1.0 : 0.0;
1747  }
1748  else
1749  print_usage ();
1750 
1751  return retval;
1752 }
1753 
1754 DEFUNX ("ferror", Fferror, args, ,
1755  "-*- texinfo -*-\n\
1756 @deftypefn {Built-in Function} {[@var{err}, @var{msg}] =} ferror (@var{fid})\n\
1757 @deftypefnx {Built-in Function} {[@var{err}, @var{msg}] =} ferror (@var{fid}, \"clear\")\n\
1758 Return 1 if an error condition has been encountered for the file ID\n\
1759 @var{fid} and 0 otherwise. Note that it will only return 1 if an error\n\
1760 has already been encountered, not if the next operation will result in\n\
1761 an error condition.\n\
1762 \n\
1763 The second argument is optional. If it is supplied, also clear the\n\
1764 error condition.\n\
1765 @seealso{fclear, fopen}\n\
1766 @end deftypefn")
1767 {
1768  octave_value_list retval;
1769 
1770  int nargin = args.length ();
1771 
1772  if (nargin == 1 || nargin == 2)
1773  {
1774  octave_stream os = octave_stream_list::lookup (args(0), "ferror");
1775 
1776  if (! error_state)
1777  {
1778  bool clear = false;
1779 
1780  if (nargin == 2)
1781  {
1782  std::string opt = args(1).string_value ();
1783 
1784  if (! error_state)
1785  clear = (opt == "clear");
1786  else
1787  return retval;
1788  }
1789 
1790  int error_number = 0;
1791 
1792  std::string error_message = os.error (clear, error_number);
1793 
1794  retval(1) = error_number;
1795  retval(0) = error_message;
1796  }
1797  }
1798  else
1799  print_usage ();
1800 
1801  return retval;
1802 }
1803 
1804 DEFUN (popen, args, ,
1805  "-*- texinfo -*-\n\
1806 @deftypefn {Built-in Function} {@var{fid} =} popen (@var{command}, @var{mode})\n\
1807 Start a process and create a pipe. The name of the command to run is\n\
1808 given by @var{command}. The file identifier corresponding to the input\n\
1809 or output stream of the process is returned in @var{fid}. The argument\n\
1810 @var{mode} may be\n\
1811 \n\
1812 @table @code\n\
1813 @item @qcode{\"r\"}\n\
1814 The pipe will be connected to the standard output of the process, and\n\
1815 open for reading.\n\
1816 \n\
1817 @item @qcode{\"w\"}\n\
1818 The pipe will be connected to the standard input of the process, and\n\
1819 open for writing.\n\
1820 @end table\n\
1821 \n\
1822 For example:\n\
1823 \n\
1824 @example\n\
1825 @group\n\
1826 fid = popen (\"ls -ltr / | tail -3\", \"r\");\n\
1827 while (ischar (s = fgets (fid)))\n\
1828  fputs (stdout, s);\n\
1829 endwhile\n\
1830 \n\
1831  @print{} drwxr-xr-x 33 root root 3072 Feb 15 13:28 etc\n\
1832  @print{} drwxr-xr-x 3 root root 1024 Feb 15 13:28 lib\n\
1833  @print{} drwxrwxrwt 15 root root 2048 Feb 17 14:53 tmp\n\
1834 @end group\n\
1835 @end example\n\
1836 @end deftypefn")
1837 {
1838  octave_value retval = -1;
1839 
1840  int nargin = args.length ();
1841 
1842  if (nargin == 2)
1843  {
1844  std::string name = args(0).string_value ();
1845 
1846  if (! error_state)
1847  {
1848  std::string mode = args(1).string_value ();
1849 
1850  if (! error_state)
1851  {
1852  if (mode == "r")
1853  {
1855 
1856  retval = octave_stream_list::insert (ips);
1857  }
1858  else if (mode == "w")
1859  {
1861 
1862  retval = octave_stream_list::insert (ops);
1863  }
1864  else
1865  ::error ("popen: invalid MODE specified");
1866  }
1867  else
1868  ::error ("popen: MODE must be a string");
1869  }
1870  else
1871  ::error ("popen: COMMAND must be a string");
1872  }
1873  else
1874  print_usage ();
1875 
1876  return retval;
1877 }
1878 
1879 DEFUNX ("pclose", Fpclose, args, ,
1880  "-*- texinfo -*-\n\
1881 @deftypefn {Built-in Function} {} pclose (@var{fid})\n\
1882 Close a file identifier that was opened by @code{popen}. You may also\n\
1883 use @code{fclose} for the same purpose.\n\
1884 @end deftypefn")
1885 {
1886  octave_value retval = -1;
1887 
1888  int nargin = args.length ();
1889 
1890  if (nargin == 1)
1891  retval = octave_stream_list::remove (args(0), "pclose");
1892  else
1893  print_usage ();
1894 
1895  return retval;
1896 }
1897 
1898 DEFUNX ("tmpnam", Ftmpnam, args, ,
1899  "-*- texinfo -*-\n\
1900 @c List other forms of function in documentation index\n\
1901 @findex octave_tmp_file_name\n\
1902 \n\
1903 @deftypefn {Built-in Function} {} tmpnam ()\n\
1904 @deftypefnx {Built-in Function} {} tmpnam (@var{dir})\n\
1905 @deftypefnx {Built-in Function} {} tmpnam (@var{dir}, @var{prefix})\n\
1906 Return a unique temporary file name as a string.\n\
1907 \n\
1908 If @var{prefix} is omitted, a value of @qcode{\"oct-\"} is used.\n\
1909 If @var{dir} is also omitted, the default directory for temporary files\n\
1910 is used. If @var{dir} is provided, it must exist, otherwise the default\n\
1911 directory for temporary files is used. Since the named file is not\n\
1912 opened, by @code{tmpnam}, it is possible (though relatively unlikely)\n\
1913 that it will not be available by the time your program attempts to open it.\n\
1914 @seealso{tmpfile, mkstemp, P_tmpdir}\n\
1915 @end deftypefn")
1916 {
1917  octave_value retval;
1918 
1919  int len = args.length ();
1920 
1921  if (len < 3)
1922  {
1923  std::string dir = len > 0 ? args(0).string_value () : std::string ();
1924 
1925  if (! error_state)
1926  {
1927  std::string pfx
1928  = len > 1 ? args(1).string_value () : std::string ("oct-");
1929 
1930  if (! error_state)
1931  retval = octave_tempnam (dir, pfx);
1932  else
1933  ::error ("PREFIX must be a string");
1934  }
1935  else
1936  ::error ("DIR argument must be a string");
1937  }
1938  else
1939  print_usage ();
1940 
1941  return retval;
1942 }
1943 
1944 DEFALIAS (octave_tmp_file_name, tmpnam);
1945 
1946 DEFUN (tmpfile, args, ,
1947  "-*- texinfo -*-\n\
1948 @deftypefn {Built-in Function} {[@var{fid}, @var{msg}] =} tmpfile ()\n\
1949 Return the file ID corresponding to a new temporary file with a unique\n\
1950 name. The file is opened in binary read/write (@qcode{\"w+b\"}) mode.\n\
1951 The file will be deleted automatically when it is closed or when Octave\n\
1952 exits.\n\
1953 \n\
1954 If successful, @var{fid} is a valid file ID and @var{msg} is an empty\n\
1955 string. Otherwise, @var{fid} is -1 and @var{msg} contains a\n\
1956 system-dependent error message.\n\
1957 @seealso{tmpnam, mkstemp, P_tmpdir}\n\
1958 @end deftypefn")
1959 {
1960  octave_value_list retval;
1961 
1962  retval(1) = std::string ();
1963  retval(0) = -1;
1964 
1965  int nargin = args.length ();
1966 
1967  if (nargin == 0)
1968  {
1969  FILE *fid = gnulib::tmpfile ();
1970 
1971  if (fid)
1972  {
1973  std::string nm;
1974 
1975  std::ios::openmode md = fopen_mode_to_ios_mode ("w+b");
1976 
1977  octave_stream s = octave_stdiostream::create (nm, fid, md);
1978 
1979  if (s)
1980  retval(0) = octave_stream_list::insert (s);
1981  else
1982  error ("tmpfile: failed to create octave_stdiostream object");
1983 
1984  }
1985  else
1986  {
1987  retval(1) = gnulib::strerror (errno);
1988  retval(0) = -1;
1989  }
1990  }
1991  else
1992  print_usage ();
1993 
1994  return retval;
1995 }
1996 
1997 DEFUN (mkstemp, args, ,
1998  "-*- texinfo -*-\n\
1999 @deftypefn {Built-in Function} {[@var{fid}, @var{name}, @var{msg}] =} mkstemp (@var{template}, @var{delete})\n\
2000 Return the file ID corresponding to a new temporary file with a unique\n\
2001 name created from @var{template}. The last six characters of @var{template}\n\
2002 must be @code{XXXXXX} and these are replaced with a string that makes the\n\
2003 filename unique. The file is then created with mode read/write and\n\
2004 permissions that are system dependent (on GNU/Linux systems, the permissions\n\
2005 will be 0600 for versions of glibc 2.0.7 and later). The file is opened\n\
2006 in binary mode and with the @w{@code{O_EXCL}} flag.\n\
2007 \n\
2008 If the optional argument @var{delete} is supplied and is true,\n\
2009 the file will be deleted automatically when Octave exits.\n\
2010 \n\
2011 If successful, @var{fid} is a valid file ID, @var{name} is the name of\n\
2012 the file, and @var{msg} is an empty string. Otherwise, @var{fid}\n\
2013 is -1, @var{name} is empty, and @var{msg} contains a system-dependent\n\
2014 error message.\n\
2015 @seealso{tmpfile, tmpnam, P_tmpdir}\n\
2016 @end deftypefn")
2017 {
2018  octave_value_list retval;
2019 
2020  retval(2) = std::string ();
2021  retval(1) = std::string ();
2022  retval(0) = -1;
2023 
2024  int nargin = args.length ();
2025 
2026  if (nargin == 1 || nargin == 2)
2027  {
2028  std::string tmpl8 = args(0).string_value ();
2029 
2030  if (! error_state)
2031  {
2032  OCTAVE_LOCAL_BUFFER (char, tmp, tmpl8.size () + 1);
2033  strcpy (tmp, tmpl8.c_str ());
2034 
2035  int fd = gnulib::mkostemp (tmp, O_BINARY);
2036 
2037  if (fd < 0)
2038  {
2039  retval(2) = gnulib::strerror (errno);
2040  retval(0) = fd;
2041  }
2042  else
2043  {
2044  const char *fopen_mode = "w+b";
2045 
2046  FILE *fid = fdopen (fd, fopen_mode);
2047 
2048  if (fid)
2049  {
2050  std::string nm = tmp;
2051 
2052  std::ios::openmode md = fopen_mode_to_ios_mode (fopen_mode);
2053 
2054  octave_stream s = octave_stdiostream::create (nm, fid, md);
2055 
2056  if (s)
2057  {
2058  retval(1) = nm;
2059  retval(0) = octave_stream_list::insert (s);
2060 
2061  if (nargin == 2 && args(1).is_true ())
2062  mark_for_deletion (nm);
2063  }
2064  else
2065  error ("mkstemp: failed to create octave_stdiostream object");
2066  }
2067  else
2068  {
2069  retval(2) = gnulib::strerror (errno);
2070  retval(0) = -1;
2071  }
2072  }
2073  }
2074  else
2075  error ("mkstemp: TEMPLATE argument must be a string");
2076  }
2077  else
2078  print_usage ();
2079 
2080  return retval;
2081 }
2082 
2083 static int
2084 convert (int x, int ibase, int obase)
2085 {
2086  int retval = 0;
2087 
2088  int tmp = x % obase;
2089 
2090  if (tmp > ibase - 1)
2091  ::error ("umask: invalid digit");
2092  else
2093  {
2094  retval = tmp;
2095  int mult = ibase;
2096  while ((x = (x - tmp) / obase))
2097  {
2098  tmp = x % obase;
2099  if (tmp > ibase - 1)
2100  {
2101  ::error ("umask: invalid digit");
2102  break;
2103  }
2104  retval += mult * tmp;
2105  mult *= ibase;
2106  }
2107  }
2108 
2109  return retval;
2110 }
2111 
2112 DEFUNX ("umask", Fumask, args, ,
2113  "-*- texinfo -*-\n\
2114 @deftypefn {Built-in Function} {} umask (@var{mask})\n\
2115 Set the permission mask for file creation. The parameter @var{mask}\n\
2116 is an integer, interpreted as an octal number. If successful,\n\
2117 returns the previous value of the mask (as an integer to be\n\
2118 interpreted as an octal number); otherwise an error message is printed.\n\
2119 @end deftypefn")
2120 {
2121  octave_value_list retval;
2122 
2123  int status = 0;
2124 
2125  if (args.length () == 1)
2126  {
2127  int mask = args(0).int_value (true);
2128 
2129  if (! error_state)
2130  {
2131  if (mask < 0)
2132  {
2133  status = -1;
2134  ::error ("umask: MASK must be a positive integer value");
2135  }
2136  else
2137  {
2138  int oct_mask = convert (mask, 8, 10);
2139 
2140  if (! error_state)
2141  status = convert (octave_umask (oct_mask), 10, 8);
2142  }
2143  }
2144  else
2145  {
2146  status = -1;
2147  ::error ("umask: MASK must be an integer");
2148  }
2149  }
2150  else
2151  print_usage ();
2152 
2153  if (status >= 0)
2154  retval(0) = status;
2155 
2156  return retval;
2157 }
2158 
2159 static octave_value
2160 const_value (const char *, const octave_value_list& args, int val)
2161 {
2162  octave_value retval;
2163 
2164  int nargin = args.length ();
2165 
2166  if (nargin == 0)
2167  retval = val;
2168  else
2169  print_usage ();
2170 
2171  return retval;
2172 }
2173 
2174 DEFUNX ("P_tmpdir", FP_tmpdir, args, ,
2175  "-*- texinfo -*-\n\
2176 @deftypefn {Built-in Function} {} P_tmpdir ()\n\
2177 Return the default name of the directory for temporary files on\n\
2178 this system. The name of this directory is system dependent.\n\
2179 @end deftypefn")
2180 {
2181  octave_value retval;
2182 
2183  int nargin = args.length ();
2184 
2185  if (nargin == 0)
2186  retval = get_P_tmpdir ();
2187  else
2188  print_usage ();
2189 
2190  return retval;
2191 }
2192 
2193 // NOTE: the values of SEEK_SET, SEEK_CUR, and SEEK_END have to be
2194 // this way for Matlab compatibility.
2195 
2196 DEFUNX ("SEEK_SET", FSEEK_SET, args, ,
2197  "-*- texinfo -*-\n\
2198 @deftypefn {Built-in Function} {} SEEK_SET ()\n\
2199 @deftypefnx {Built-in Function} {} SEEK_CUR ()\n\
2200 @deftypefnx {Built-in Function} {} SEEK_END ()\n\
2201 Return the numerical value to pass to @code{fseek} to perform\n\
2202 one of the following actions:\n\
2203 \n\
2204 @table @code\n\
2205 @item SEEK_SET\n\
2206 Position file relative to the beginning.\n\
2207 \n\
2208 @item SEEK_CUR\n\
2209 Position file relative to the current position.\n\
2210 \n\
2211 @item SEEK_END\n\
2212 Position file relative to the end.\n\
2213 @end table\n\
2214 @seealso{fseek}\n\
2215 @end deftypefn")
2216 {
2217  return const_value ("SEEK_SET", args, -1);
2218 }
2219 
2220 DEFUNX ("SEEK_CUR", FSEEK_CUR, args, ,
2221  "-*- texinfo -*-\n\
2222 @deftypefn {Built-in Function} {} SEEK_CUR ()\n\
2223 Return the numerical value to pass to @code{fseek} to\n\
2224 position the file pointer relative to the current position.\n\
2225 @seealso{SEEK_SET, SEEK_END}\n\
2226 @end deftypefn")
2227 {
2228  return const_value ("SEEK_CUR", args, 0);
2229 }
2230 
2231 DEFUNX ("SEEK_END", FSEEK_END, args, ,
2232  "-*- texinfo -*-\n\
2233 @deftypefn {Built-in Function} {} SEEK_END ()\n\
2234 Return the numerical value to pass to @code{fseek} to\n\
2235 position the file pointer relative to the end of the file.\n\
2236 @seealso{SEEK_SET, SEEK_CUR}\n\
2237 @end deftypefn")
2238 {
2239  return const_value ("SEEK_END", args, 1);
2240 }
2241 
2242 static octave_value
2243 const_value (const char *, const octave_value_list& args,
2244  const octave_value& val)
2245 {
2246  octave_value retval;
2247 
2248  int nargin = args.length ();
2249 
2250  if (nargin == 0)
2251  retval = val;
2252  else
2253  print_usage ();
2254 
2255  return retval;
2256 }
2257 
2258 DEFUNX ("stdin", Fstdin, args, ,
2259  "-*- texinfo -*-\n\
2260 @deftypefn {Built-in Function} {} stdin ()\n\
2261 Return the numeric value corresponding to the standard input stream.\n\
2262 When Octave is used interactively, this is filtered through the command\n\
2263 line editing functions.\n\
2264 @seealso{stdout, stderr}\n\
2265 @end deftypefn")
2266 {
2267  return const_value ("stdin", args, stdin_file);
2268 }
2269 
2270 DEFUNX ("stdout", Fstdout, args, ,
2271  "-*- texinfo -*-\n\
2272 @deftypefn {Built-in Function} {} stdout ()\n\
2273 Return the numeric value corresponding to the standard output stream.\n\
2274 Data written to the standard output is normally filtered through the pager.\n\
2275 @seealso{stdin, stderr}\n\
2276 @end deftypefn")
2277 {
2278  return const_value ("stdout", args, stdout_file);
2279 }
2280 
2281 DEFUNX ("stderr", Fstderr, args, ,
2282  "-*- texinfo -*-\n\
2283 @deftypefn {Built-in Function} {} stderr ()\n\
2284 Return the numeric value corresponding to the standard error stream.\n\
2285 Even if paging is turned on, the standard error is not sent to the\n\
2286 pager. It is useful for error messages and prompts.\n\
2287 @seealso{stdin, stdout}\n\
2288 @end deftypefn")
2289 {
2290  return const_value ("stderr", args, stderr_file);
2291 }