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