GNU Octave  6.2.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
file-io.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 1993-2021 The Octave Project Developers
4 //
5 // See the file COPYRIGHT.md in the top-level directory of this
6 // distribution or <https://octave.org/copyright/>.
7 //
8 // This file is part of Octave.
9 //
10 // Octave is free software: you can redistribute it and/or modify it
11 // under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // Octave is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with Octave; see the file COPYING. If not, see
22 // <https://www.gnu.org/licenses/>.
23 //
24 ////////////////////////////////////////////////////////////////////////
25 
26 // Originally written by John C. Campbell <jcc@bevo.che.wisc.edu>
27 //
28 // Thomas Baier <baier@ci.tuwien.ac.at> added the original versions of
29 // the following functions:
30 //
31 // popen
32 // pclose
33 // execute (now popen2.m)
34 // sync_system (now merged with system)
35 // async_system (now merged with system)
36 
37 // Extensively revised by John W. Eaton <jwe@octave.org>,
38 // April 1996.
39 
40 #if defined (HAVE_CONFIG_H)
41 # include "config.h"
42 #endif
43 
44 #include <cerrno>
45 #include <cstdio>
46 
47 #include <iomanip>
48 #include <string>
49 
50 #if defined (HAVE_ZLIB_H)
51 # include <zlib.h>
52 #endif
53 
54 #include "file-ops.h"
55 #include "file-stat.h"
56 #include "iconv-wrappers.h"
57 #include "lo-ieee.h"
58 #include "lo-sysdep.h"
59 #include "localcharset-wrapper.h"
60 #include "mkostemp-wrapper.h"
61 #include "oct-env.h"
62 #include "oct-locbuf.h"
63 #include "tmpfile-wrapper.h"
64 #include "unistd-wrappers.h"
65 
66 #include "builtin-defun-decls.h"
67 #include "defun.h"
68 #include "error.h"
69 #include "errwarn.h"
70 #include "file-io.h"
71 #include "interpreter-private.h"
72 #include "interpreter.h"
73 #include "load-path.h"
74 #include "oct-fstrm.h"
75 #include "oct-iostrm.h"
76 #include "oct-map.h"
77 #include "oct-prcstrm.h"
78 #include "oct-stream.h"
79 #include "oct-strstrm.h"
80 #include "ov.h"
81 #include "ovl.h"
82 #include "pager.h"
83 #include "sysdep.h"
84 #include "utils.h"
85 #include "variables.h"
86 
87 static void
88 normalize_fopen_mode (std::string& mode, bool& use_zlib)
89 {
90  use_zlib = false;
91 
92  if (! mode.empty ())
93  {
94  // Matlab uses 'A' and 'W' to indicate that buffered writing should
95  // take place. Octave already does that. Theoretically, we should
96  // warn about using 'a', 'r', or 'w' because Octave does not enable
97  // automatic flushing with these modes. The performance hit is ~4X
98  // when using automatic flushing and seems completely unnecessary.
99  // See bug #52644.
100 
101  size_t pos = mode.find ('W');
102 
103  if (pos != std::string::npos)
104  mode[pos] = 'w';
105 
106  pos = mode.find ('R');
107 
108  if (pos != std::string::npos)
109  mode[pos] = 'r';
110 
111  pos = mode.find ('A');
112 
113  if (pos != std::string::npos)
114  mode[pos] = 'a';
115 
116  pos = mode.find ('z');
117 
118  if (pos != std::string::npos)
119  {
120 #if defined (HAVE_ZLIB)
121  use_zlib = true;
122  mode.erase (pos, 1);
123 #else
124  err_disabled_feature ("", "gzipped files (zlib)");
125 #endif
126  }
127 
128  // Use binary mode if 't' is not specified, but don't add
129  // 'b' if it is already present.
130 
131  size_t bpos = mode.find ('b');
132  size_t tpos = mode.find ('t');
133 
134  if (bpos == std::string::npos && tpos == std::string::npos)
135  mode += 'b';
136  }
137 }
138 
139 static std::ios::openmode
140 fopen_mode_to_ios_mode (const std::string& mode)
141 {
142  std::ios::openmode retval = std::ios::in;
143 
144  if (mode == "rt")
145  retval = std::ios::in;
146  else if (mode == "wt")
147  retval = std::ios::out | std::ios::trunc;
148  else if (mode == "at")
149  retval = std::ios::out | std::ios::app;
150  else if (mode == "r+t" || mode == "rt+")
151  retval = std::ios::in | std::ios::out;
152  else if (mode == "w+t" || mode == "wt+")
153  retval = std::ios::in | std::ios::out | std::ios::trunc;
154  else if (mode == "a+t" || mode == "at+")
155  retval = std::ios::in | std::ios::out | std::ios::app;
156  else if (mode == "rb" || mode == "r")
157  retval = std::ios::in | std::ios::binary;
158  else if (mode == "wb" || mode == "w")
159  retval = std::ios::out | std::ios::trunc | std::ios::binary;
160  else if (mode == "ab" || mode == "a")
161  retval = std::ios::out | std::ios::app | std::ios::binary;
162  else if (mode == "r+b" || mode == "rb+" || mode == "r+")
163  retval = std::ios::in | std::ios::out | std::ios::binary;
164  else if (mode == "w+b" || mode == "wb+" || mode == "w+")
165  retval = (std::ios::in | std::ios::out | std::ios::trunc
166  | std::ios::binary);
167  else if (mode == "a+b" || mode == "ab+" || mode == "a+")
168  retval = (std::ios::in | std::ios::out | std::ios::app
169  | std::ios::binary);
170  else
171  error ("invalid mode specified");
172 
173  return retval;
174 }
175 
176 DEFMETHOD (fclose, interp, args, ,
177  doc: /* -*- texinfo -*-
178 @deftypefn {} {} fclose (@var{fid})
179 @deftypefnx {} {} fclose ("all")
180 @deftypefnx {} {@var{status} =} fclose ("all")
181 Close the file specified by the file descriptor @var{fid}.
182 
183 If successful, @code{fclose} returns 0, otherwise, it returns -1. The
184 second form of the @code{fclose} call closes all open files except
185 @code{stdin}, @code{stdout}, @code{stderr}, and any FIDs associated
186 with gnuplot.
187 @seealso{fopen, fflush, freport}
188 @end deftypefn */)
189 {
190  if (args.length () != 1)
191  print_usage ();
192 
193  octave::stream_list& streams = interp.get_stream_list ();
194 
195  return ovl (streams.remove (args(0), "fclose"));
196 }
197 
198 DEFMETHOD (fclear, interp, args, ,
199  doc: /* -*- texinfo -*-
200 @deftypefn {} {} fclear (@var{fid})
201 Clear the stream state for the file specified by the file descriptor
202 @var{fid}.
203 @seealso{ferror, fopen}
204 @end deftypefn */)
205 {
206  if (args.length () != 1)
207  print_usage ();
208 
209  octave::stream_list& streams = interp.get_stream_list ();
210 
211  int fid = streams.get_file_number (args(0));
212 
213  octave::stream os = streams.lookup (fid, "fclear");
214 
215  os.clearerr ();
216 
217  return ovl ();
218 }
219 
220 DEFMETHOD (fflush, interp, args, ,
221  doc: /* -*- texinfo -*-
222 @deftypefn {} {} fflush (@var{fid})
223 Flush output to file descriptor @var{fid}.
224 
225 @code{fflush} returns 0 on success and an OS dependent error value
226 (@minus{}1 on Unix) on error.
227 
228 Programming Note: Flushing is useful for ensuring that all pending output
229 makes it to the screen before some other event occurs. For example, it is
230 always a good idea to flush the standard output stream before calling
231 @code{input}.
232 @seealso{fopen, fclose}
233 @end deftypefn */)
234 {
235  if (args.length () != 1)
236  print_usage ();
237 
238  octave_value retval = -1;
239 
240  octave::stream_list& streams = interp.get_stream_list ();
241 
242  // FIXME: any way to avoid special case for stdout?
243  int fid = streams.get_file_number (args(0));
244 
245  if (fid == 1)
246  {
248 
249  retval = 0;
250  }
251  else
252  {
253  octave::stream os = streams.lookup (fid, "fflush");
254 
255  retval = os.flush ();
256  }
257 
258  return retval;
259 }
260 
261 DEFMETHOD (fgetl, interp, args, ,
262  doc: /* -*- texinfo -*-
263 @deftypefn {} {@var{str} =} fgetl (@var{fid})
264 @deftypefnx {} {@var{str} =} fgetl (@var{fid}, @var{len})
265 Read characters from a file, stopping after a newline, or EOF,
266 or @var{len} characters have been read.
267 
268 The characters read, excluding the possible trailing newline, are returned
269 as a string.
270 
271 If @var{len} is omitted, @code{fgetl} reads until the next newline
272 character.
273 
274 If there are no more characters to read, @code{fgetl} returns @minus{}1.
275 
276 To read a line and return the terminating newline see @code{fgets}.
277 @seealso{fgets, fscanf, fread, fopen}
278 @end deftypefn */)
279 {
280  static const std::string who = "fgetl";
281 
282  int nargin = args.length ();
283 
284  if (nargin < 1 || nargin > 2)
285  print_usage ();
286 
287  octave::stream_list& streams = interp.get_stream_list ();
288 
289  octave::stream os = streams.lookup (args(0), who);
290 
291  octave_value len_arg = (nargin == 2) ? args(1) : octave_value ();
292 
293  bool err = false;
294 
295  std::string tmp = os.getl (len_arg, err, who);
296 
297  if (! err)
298  return ovl (tmp, tmp.length ());
299  else
300  return ovl (-1, 0);
301 }
302 
303 DEFMETHOD (fgets, interp, args, ,
304  doc: /* -*- texinfo -*-
305 @deftypefn {} {@var{str} =} fgets (@var{fid})
306 @deftypefnx {} {@var{str} =} fgets (@var{fid}, @var{len})
307 Read characters from a file, stopping after a newline, or EOF,
308 or @var{len} characters have been read.
309 
310 The characters read, including the possible trailing newline, are returned
311 as a string.
312 
313 If @var{len} is omitted, @code{fgets} reads until the next newline
314 character.
315 
316 If there are no more characters to read, @code{fgets} returns @minus{}1.
317 
318 To read a line and discard the terminating newline see @code{fgetl}.
319 @seealso{fputs, fgetl, fscanf, fread, fopen}
320 @end deftypefn */)
321 {
322  static const std::string who = "fgets";
323 
324  int nargin = args.length ();
325 
326  if (nargin < 1 || nargin > 2)
327  print_usage ();
328 
329  octave::stream_list& streams = interp.get_stream_list ();
330 
331  octave::stream os = streams.lookup (args(0), who);
332 
333  octave_value len_arg = (nargin == 2) ? args(1) : octave_value ();
334 
335  bool err = false;
336 
337  std::string tmp = os.gets (len_arg, err, who);
338 
339  if (! err)
340  return ovl (tmp, tmp.length ());
341  else
342  return ovl (-1.0, 0.0);
343 }
344 
345 DEFMETHOD (fskipl, interp, args, ,
346  doc: /* -*- texinfo -*-
347 @deftypefn {} {@var{nlines} =} fskipl (@var{fid})
348 @deftypefnx {} {@var{nlines} =} fskipl (@var{fid}, @var{count})
349 @deftypefnx {} {@var{nlines} =} fskipl (@var{fid}, Inf)
350 Read and skip @var{count} lines from the file specified by the file
351 descriptor @var{fid}.
352 
353 @code{fskipl} discards characters until an end-of-line is encountered
354 exactly @var{count}-times, or until the end-of-file marker is found.
355 
356 If @var{count} is omitted, it defaults to 1. @var{count} may also be
357 @code{Inf}, in which case lines are skipped until the end of the file.
358 This form is suitable for counting the number of lines in a file.
359 
360 Returns the number of lines skipped (end-of-line sequences encountered).
361 @seealso{fgetl, fgets, fscanf, fopen}
362 @end deftypefn */)
363 {
364  static const std::string who = "fskipl";
365 
366  int nargin = args.length ();
367 
368  if (nargin < 1 || nargin > 2)
369  print_usage ();
370 
371  octave::stream_list& streams = interp.get_stream_list ();
372 
373  octave::stream os = streams.lookup (args(0), who);
374 
375  octave_value count_arg = (nargin == 2) ? args(1) : octave_value ();
376 
377  bool err = false;
378 
379  off_t tmp = os.skipl (count_arg, err, who);
380 
381  if (! err)
382  return ovl (tmp);
383  else
384  return ovl ();
385 }
386 
387 static octave::stream
388 do_stream_open (const std::string& name, const std::string& mode_arg,
389  const std::string& arch, std::string encoding, int& fid)
390 {
392 
393  fid = -1;
394 
395  // Valid names for encodings consist of ASCII characters only.
396  std::transform (encoding.begin (), encoding.end (), encoding.begin (),
397  ::tolower);
398  if (encoding.compare ("utf-8"))
399  {
400  // check if encoding is valid
401  void *codec = octave_iconv_open_wrapper (encoding.c_str (), "utf-8");
402  if (codec == reinterpret_cast<void *> (-1))
403  {
404  if (errno == EINVAL)
405  error ("fopen: conversion from codepage '%s' not supported",
406  encoding.c_str ());
407  }
408  else
410  }
411 
412  std::string mode = mode_arg;
413  bool use_zlib = false;
414  normalize_fopen_mode (mode, use_zlib);
415 
416  std::ios::openmode md = fopen_mode_to_ios_mode (mode);
417 
420 
421  std::string fname = octave::sys::file_ops::tilde_expand (name);
422 
423  octave::sys::file_stat fs (fname);
424 
425  if (! (md & std::ios::out))
426  fname = octave::find_data_file_in_load_path ("fopen", fname);
427 
428  if (! fs.is_dir ())
429  {
430 #if defined (HAVE_ZLIB)
431  if (use_zlib)
432  {
433  FILE *fptr = octave::sys::fopen (fname.c_str (), mode.c_str ());
434 
435  if (fptr)
436  {
437  int fd = fileno (fptr);
438 
439  gzFile gzf = ::gzdopen (fd, mode.c_str ());
440 
441  retval = octave_zstdiostream::create (fname, gzf, fd, md,
442  flt_fmt, encoding);
443  }
444  else
445  retval.error (std::strerror (errno));
446  }
447  else
448 #endif
449  {
450  FILE *fptr = octave::sys::fopen (fname, mode);
451 
452  retval = octave_stdiostream::create (fname, fptr, md, flt_fmt,
453  encoding);
454 
455  if (! fptr)
456  retval.error (std::strerror (errno));
457  }
458 
459  }
460 
461  return retval;
462 }
463 
464 static octave::stream
465 do_stream_open (const octave_value& tc_name, const octave_value& tc_mode,
466  const octave_value& tc_arch, const octave_value& tc_encoding,
467  const char *fcn, int& fid)
468 {
470 
471  fid = -1;
472 
473  std::string name = tc_name.xstring_value ("%s: filename must be a string", fcn);
474  std::string mode = tc_mode.xstring_value ("%s: file mode must be a string", fcn);
475  std::string arch = tc_arch.xstring_value ("%s: architecture type must be a string", fcn);
476  std::string encoding = tc_encoding.xstring_value ("%s: ENCODING must be a string", fcn);
477 
478  retval = do_stream_open (name, mode, arch, encoding, fid);
479 
480  return retval;
481 }
482 
483 DEFMETHOD (fopen, interp, args, nargout,
484  doc: /* -*- texinfo -*-
485 @deftypefn {} {@var{fid} =} fopen (@var{name})
486 @deftypefnx {} {@var{fid} =} fopen (@var{name}, @var{mode})
487 @deftypefnx {} {@var{fid} =} fopen (@var{name}, @var{mode}, @var{arch})
488 @deftypefnx {} {@var{fid} =} fopen (@var{name}, @var{mode}, @var{arch}, @var{encoding})
489 @deftypefnx {} {[@var{fid}, @var{msg}] =} fopen (@dots{})
490 @deftypefnx {} {@var{fid_list} =} fopen ("all")
491 @deftypefnx {} {[@var{file}, @var{mode}, @var{arch}, @var{encoding}] =} fopen (@var{fid})
492 Open a file for low-level I/O or query open files and file descriptors.
493 
494 The first form of the @code{fopen} function opens the named file with
495 the specified mode (read-write, read-only, etc.@:), architecture
496 interpretation (IEEE big endian, IEEE little endian, etc.@:) and file encoding,
497 and returns an integer value that may be used to refer to the file later. If
498 an error occurs, @var{fid} is set to @minus{}1 and @var{msg} contains the
499 corresponding system error message. The @var{mode} is a one or two
500 character string that specifies whether the file is to be opened for
501 reading, writing, or both. The @var{encoding} is a character string with a
502 valid encoding identifier. This encoding is used when strings are read from
503 or written to the file. By default, the same encoding specified for reading
504 @file{.m} files is used for interpreting user files.
505 
506 The second form of the @code{fopen} function returns a vector of file ids
507 corresponding to all the currently open files, excluding the
508 @code{stdin}, @code{stdout}, and @code{stderr} streams.
509 
510 The third form of the @code{fopen} function returns information about the
511 open file given its file id.
512 
513 For example,
514 
515 @example
516 myfile = fopen ("splat.dat", "r", "ieee-le");
517 @end example
518 
519 @noindent
520 opens the file @file{splat.dat} for reading. If necessary, binary
521 numeric values will be read assuming they are stored in IEEE format with
522 the least significant bit first, and then converted to the native
523 representation.
524 
525 Opening a file that is already open simply opens it again and returns a
526 separate file id. It is not an error to open a file several times,
527 though writing to the same file through several different file ids may
528 produce unexpected results.
529 
530 The possible values of @var{mode} are
531 
532 @table @asis
533 @item @samp{r} (default)
534 Open a file for reading.
535 
536 @item @samp{w}
537 Open a file for writing. The previous contents are discarded.
538 
539 @item @samp{a}
540 Open or create a file for writing at the end of the file.
541 
542 @item @samp{r+}
543 Open an existing file for reading and writing.
544 
545 @item @samp{w+}
546 Open a file for reading or writing. The previous contents are
547 discarded.
548 
549 @item @samp{a+}
550 Open or create a file for reading or writing at the end of the
551 file.
552 @end table
553 
554 Append a @qcode{"t"} to the mode string to open the file in text mode or a
555 @qcode{"b"} to open in binary mode. On Windows systems,
556 text mode reading and writing automatically converts linefeeds to the
557 appropriate line end character for the system (carriage-return linefeed on
558 Windows). The default when no mode is specified is binary.
559 
560 Additionally, you may append a @qcode{"z"} to the mode string to open a
561 gzipped file for reading or writing. For this to be successful, you
562 must also open the file in binary mode.
563 
564 The parameter @var{arch} is a string specifying the default data format
565 for the file. Valid values for @var{arch} are:
566 
567 @table @asis
568 @item @qcode{"native"} or @qcode{"n"} (default)
569 The format of the current machine.
570 
571 @item @qcode{"ieee-be"} or @qcode{"b"}
572 IEEE big endian format.
573 
574 @item @qcode{"ieee-le"} or @qcode{"l"}
575 IEEE little endian format.
576 @end table
577 
578 When opening a new file that does not yet exist, permissions will be set to
579 @code{0666 - @var{umask}}.
580 
581 Compatibility Note: Octave opens files using buffered I/O. Small writes are
582 accumulated until an internal buffer is filled, and then everything is written
583 in a single operation. This is very efficient and improves performance.
584 @sc{matlab}, however, opens files using flushed I/O where every write operation
585 is immediately performed. If the write operation must be performed immediately
586 after data has been written then the write should be followed by a call to
587 @code{fflush} to flush the internal buffer.
588 @seealso{fclose, fgets, fgetl, fscanf, fread, fputs, fdisp, fprintf, fwrite, fskipl, fseek, frewind, ftell, feof, ferror, fclear, fflush, freport, umask}
589 @end deftypefn */)
590 {
591  int nargin = args.length ();
592 
593  if (nargin < 1 || nargin > 4)
594  print_usage ();
595 
596  octave_value_list retval = ovl (-1.0);
597 
598  octave::stream_list& streams = interp.get_stream_list ();
599 
600  if (nargin == 1)
601  {
602  if (args(0).is_string ())
603  {
604  // If there is only one argument and it is a string but it
605  // is not the string "all", we assume it is a file to open
606  // with MODE = "r". To open a file called "all", you have
607  // to supply more than one argument.
608  if (nargout < 2 && args(0).string_value () == "all")
609  return streams.open_file_numbers ();
610  }
611  else
612  {
613  string_vector tmp = streams.get_info (args(0));
614 
615  retval = ovl (tmp(0), tmp(1), tmp(2), tmp(3));
616 
617  return retval;
618  }
619  }
620 
621  octave_value mode = (nargin > 1) ? args(1) : octave_value ("r");
622 
623  octave_value arch = (nargin > 2) ? args(2) : octave_value ("native");
624 
625  octave::input_system& input_sys = interp.get_input_system ();
626  octave_value encoding = (nargin > 3) ? args(3)
627  : octave_value (input_sys.mfile_encoding ());
628  if (encoding.string_value () == "system")
630 
631  int fid = -1;
632 
633  octave::stream os = do_stream_open (args(0), mode, arch, encoding, "fopen",
634  fid);
635 
636  if (os)
637  retval = ovl (streams.insert (os), "");
638  else
639  {
640  int error_number = 0;
641 
642  retval = ovl (-1.0, os.error (false, error_number));
643  }
644 
645  return retval;
646 }
647 
648 /*
649 ## Further tests are in io.tst
650 %!test # Uses hardcoded value of 1 for stdout
651 %! [name, mode, arch, encoding] = fopen (1);
652 %! assert (name, "stdout");
653 %! assert (mode, "w");
654 %! assert (encoding, "utf-8");
655 
656 %!test # Query of non-existent stream returns all ""
657 %! [name, mode, arch] = fopen (-1);
658 %! assert (name, "");
659 %! assert (mode, "");
660 %! assert (arch, "");
661 */
662 
663 DEFMETHOD (freport, interp, args, ,
664  doc: /* -*- texinfo -*-
665 @deftypefn {} {} freport ()
666 Print a list of which files have been opened, and whether they are open
667 for reading, writing, or both.
668 
669 For example:
670 
671 @example
672 @group
673 freport ()
674 
675  @print{} number mode arch name
676  @print{} ------ ---- ---- ----
677  @print{} 0 r ieee-le stdin
678  @print{} 1 w ieee-le stdout
679  @print{} 2 w ieee-le stderr
680  @print{} 3 r ieee-le myfile
681 @end group
682 @end example
683 @seealso{fopen, fclose, is_valid_file_id}
684 @end deftypefn */)
685 {
686  if (args.length () > 0)
687  warning ("freport: ignoring extra arguments");
688 
689  octave::stream_list& streams = interp.get_stream_list ();
690 
691  octave_stdout << streams.list_open_files ();
692 
693  return ovl ();
694 }
695 
696 DEFMETHOD (frewind, interp, args, nargout,
697  doc: /* -*- texinfo -*-
698 @deftypefn {} {} frewind (@var{fid})
699 @deftypefnx {} {@var{status} =} frewind (@var{fid})
700 Move the file pointer to the beginning of the file specified by file
701 descriptor @var{fid}.
702 
703 @code{frewind} returns 0 for success, and -1 if an error is encountered. It
704 is equivalent to @code{fseek (@var{fid}, 0, SEEK_SET)}.
705 @seealso{fseek, ftell, fopen}
706 @end deftypefn */)
707 {
708  if (args.length () != 1)
709  print_usage ();
710 
711  int result = -1;
712 
713  octave::stream_list& streams = interp.get_stream_list ();
714 
715  octave::stream os = streams.lookup (args(0), "frewind");
716 
717  result = os.rewind ();
718 
719  if (nargout > 0)
720  return ovl (result);
721  else
722  return ovl ();
723 }
724 
725 DEFMETHOD (fseek, interp, args, ,
726  doc: /* -*- texinfo -*-
727 @deftypefn {} {} fseek (@var{fid}, @var{offset})
728 @deftypefnx {} {} fseek (@var{fid}, @var{offset}, @var{origin})
729 @deftypefnx {} {@var{status} =} fseek (@dots{})
730 Set the file pointer to the location @var{offset} within the file @var{fid}.
731 
732 The pointer is positioned @var{offset} characters from the @var{origin}, which
733 may be one of the predefined variables @w{@qcode{SEEK_SET}} (beginning),
734 @w{@qcode{SEEK_CUR}} (current position), or @w{@qcode{SEEK_END}} (end of file)
735 or strings @nospell{@qcode{"bof"}}, @nospell{@qcode{"cof"}}, or
736 @nospell{@qcode{"eof"}}. If @var{origin} is omitted, @w{@qcode{SEEK_SET}} is
737 assumed. @var{offset} may be positive, negative, or zero but not all
738 combinations of @var{origin} and @var{offset} can be realized.
739 
740 @code{fseek} returns 0 on success and -1 on error.
741 @seealso{fskipl, frewind, ftell, fopen, SEEK_SET, SEEK_CUR, SEEK_END}
742 @end deftypefn */)
743 {
744  int nargin = args.length ();
745 
746  if (nargin < 2 || nargin > 3)
747  print_usage ();
748 
749  octave::stream_list& streams = interp.get_stream_list ();
750 
751  octave::stream os = streams.lookup (args(0), "fseek");
752 
753  octave_value origin_arg = (nargin == 3) ? args(2) : octave_value (-1.0);
754 
755  return ovl (os.seek (args(1), origin_arg));
756 }
757 
758 DEFMETHOD (ftell, interp, args, ,
759  doc: /* -*- texinfo -*-
760 @deftypefn {} {@var{pos} =} ftell (@var{fid})
761 Return the position of the file pointer as the number of characters from the
762 beginning of the file specified by file descriptor @var{fid}.
763 @seealso{fseek, frewind, feof, fopen}
764 @end deftypefn */)
765 {
766  if (args.length () != 1)
767  print_usage ();
768 
769  octave::stream_list& streams = interp.get_stream_list ();
770 
771  octave::stream os = streams.lookup (args(0), "ftell");
772 
773  return ovl (os.tell ());
774 }
775 
776 static octave_value_list
777 printf_internal (octave::interpreter& interp, const std::string& who,
778  const octave_value_list& args, int nargout)
779 {
780  int nargin = args.length ();
781 
782  if (! (nargin > 1 || (nargin > 0 && args(0).is_string ())))
783  print_usage ();
784 
785  int result;
786 
787  octave::stream os;
788  int fmt_n = 0;
789 
790  octave::stream_list& streams = interp.get_stream_list ();
791 
792  if (args(0).is_string ())
793  os = streams.lookup (1, who);
794  else
795  {
796  fmt_n = 1;
797  os = streams.lookup (args(0), who);
798  }
799 
800  if (! args(fmt_n).is_string ())
801  error ("%s: format TEMPLATE must be a string", who.c_str ());
802 
803  octave_value_list tmp_args;
804 
805  if (nargin > 1 + fmt_n)
806  {
807  tmp_args.resize (nargin-fmt_n-1, octave_value ());
808 
809  for (int i = fmt_n + 1; i < nargin; i++)
810  tmp_args(i-fmt_n-1) = args(i);
811  }
812 
813  result = os.printf (args(fmt_n), tmp_args, who);
814 
815  if (nargout > 0)
816  return ovl (result);
817  else
818  return ovl ();
819 }
820 
821 DEFMETHOD (fprintf, interp, args, nargout,
822  doc: /* -*- texinfo -*-
823 @deftypefn {} {} fprintf (@var{fid}, @var{template}, @dots{})
824 @deftypefnx {} {} fprintf (@var{template}, @dots{})
825 @deftypefnx {} {@var{numbytes} =} fprintf (@dots{})
826 This function is equivalent to @code{printf}, except that the output is
827 written to the file descriptor @var{fid} instead of @code{stdout}.
828 
829 If @var{fid} is omitted, the output is written to @code{stdout} making the
830 function exactly equivalent to @code{printf}.
831 
832 The optional output returns the number of bytes written to the file.
833 
834 Implementation Note: For compatibility with @sc{matlab}, escape sequences in
835 the template string (e.g., @qcode{"@xbackslashchar{}n"} => newline) are
836 expanded even when the template string is defined with single quotes.
837 @seealso{fputs, fdisp, fwrite, fscanf, printf, sprintf, fopen}
838 @end deftypefn */)
839 {
840  static const std::string who = "fprintf";
841 
842  return printf_internal (interp, who, args, nargout);
843 }
844 
845 DEFMETHOD (printf, interp, args, nargout,
846  doc: /* -*- texinfo -*-
847 @deftypefn {} {} printf (@var{template}, @dots{})
848 Print optional arguments under the control of the template string
849 @var{template} to the stream @code{stdout} and return the number of
850 characters printed.
851 @ifclear OCTAVE_MANUAL
852 
853 See the Formatted Output section of the GNU Octave manual for a
854 complete description of the syntax of the template string.
855 @end ifclear
856 
857 Implementation Note: For compatibility with @sc{matlab}, escape sequences in
858 the template string (e.g., @qcode{"@xbackslashchar{}n"} => newline) are
859 expanded even when the template string is defined with single quotes.
860 @seealso{fprintf, sprintf, scanf}
861 @end deftypefn */)
862 {
863  static const std::string who = "printf";
864 
865  octave_value_list tmp_args = args;
866 
867  return printf_internal (interp, who, tmp_args.prepend (octave_value (1)),
868  nargout);
869 }
870 
871 static octave_value_list
872 puts_internal (octave::interpreter& interp, const std::string& who,
873  const octave_value_list& args)
874 {
875  if (args.length () != 2)
876  print_usage ();
877 
878  octave::stream_list& streams = interp.get_stream_list ();
879 
880  octave::stream os = streams.lookup (args(0), who);
881 
882  return ovl (os.puts (args(1), who));
883 }
884 
885 DEFMETHOD (fputs, interp, args, ,
886  doc: /* -*- texinfo -*-
887 @deftypefn {} {} fputs (@var{fid}, @var{string})
888 @deftypefnx {} {@var{status} =} fputs (@var{fid}, @var{string})
889 Write the string @var{string} to the file with file descriptor @var{fid}.
890 
891 The string is written to the file with no additional formatting. Use
892 @code{fdisp} instead to automatically append a newline character appropriate
893 for the local machine.
894 
895 Return a non-negative number on success or EOF on error.
896 @seealso{fdisp, fprintf, fwrite, fopen}
897 @end deftypefn */)
898 {
899  static const std::string who = "fputs";
900 
901  return puts_internal (interp, who, args);
902 }
903 
904 DEFMETHOD (puts, interp, args, ,
905  doc: /* -*- texinfo -*-
906 @deftypefn {} {} puts (@var{string})
907 @deftypefnx {} {@var{status} =} puts (@var{string})
908 Write a string to the standard output with no formatting.
909 
910 The string is written verbatim to the standard output. Use @code{disp} to
911 automatically append a newline character appropriate for the local machine.
912 
913 Return a non-negative number on success and EOF on error.
914 @seealso{fputs, disp}
915 @end deftypefn */)
916 {
917  static const std::string who = "puts";
918 
919  octave_value_list tmp_args = args;
920 
921  return puts_internal (interp, who, tmp_args.prepend (octave_value (1)));
922 }
923 
924 DEFUN (sprintf, args, ,
925  doc: /* -*- texinfo -*-
926 @deftypefn {} {} sprintf (@var{template}, @dots{})
927 This is like @code{printf}, except that the output is returned as a
928 string.
929 
930 Unlike the C library function, which requires you to provide a suitably
931 sized string as an argument, Octave's @code{sprintf} function returns the
932 string, automatically sized to hold all of the items converted.
933 
934 Implementation Note: For compatibility with @sc{matlab}, escape sequences in
935 the template string (e.g., @qcode{"@xbackslashchar{}n"} => newline) are
936 expanded even when the template string is defined with single quotes.
937 @seealso{printf, fprintf, sscanf}
938 @end deftypefn */)
939 {
940  static const std::string who = "sprintf";
941 
942  int nargin = args.length ();
943 
944  if (nargin == 0)
945  print_usage ();
946 
947  // We don't use octave_ostrstream::create here because need direct
948  // access to the OSTR object so that we can extract a string object
949  // from it to return.
950  octave_ostrstream *ostr = new octave_ostrstream ();
951 
952  // The octave::stream destructor will delete OSTR for us.
953  octave::stream os (ostr);
954 
955  if (! os.is_valid ())
956  error ("%s: unable to create output buffer", who.c_str ());
957 
958  octave_value fmt_arg = args(0);
959 
960  if (! fmt_arg.is_string ())
961  error ("%s: format TEMPLATE must be a string", who.c_str ());
962 
964 
965  octave_value_list tmp_args;
966  if (nargin > 1)
967  {
968  tmp_args.resize (nargin-1, octave_value ());
969 
970  for (int i = 1; i < nargin; i++)
971  tmp_args(i-1) = args(i);
972  }
973 
974  // NOTE: Call to os.error must precede next call to ostr which might reset it.
975  retval(2) = os.printf (fmt_arg, tmp_args, who);
976  retval(1) = os.error ();
977 
978  std::string result = ostr->str ();
979  char type = (fmt_arg.is_sq_string () ? '\'' : '"');
980 
981  retval(0) = (result.empty () ? octave_value (charMatrix (1, 0), type)
982  : octave_value (result, type));
983 
984  return retval;
985 }
986 
987 static octave_value_list
988 scanf_internal (octave::interpreter& interp, const std::string& who,
989  const octave_value_list& args)
990 {
991  int nargin = args.length ();
992 
993  if (nargin < 2 || nargin > 3)
994  print_usage ();
995 
997 
998  octave::stream_list& streams = interp.get_stream_list ();
999 
1000  octave::stream os = streams.lookup (args(0), who);
1001 
1002  if (! args(1).is_string ())
1003  error ("%s: format TEMPLATE must be a string", who.c_str ());
1004 
1005  if (nargin == 3 && args(2).is_string ())
1006  {
1007  retval = os.oscanf (args(1), who);
1008  }
1009  else
1010  {
1011  octave_idx_type count = 0;
1012 
1013  Array<double> size
1014  = (nargin == 3
1015  ? args(2).vector_value ()
1016  : Array<double> (dim_vector (1, 1), lo_ieee_inf_value ()));
1017 
1018  octave_value tmp = os.scanf (args(1), size, count, who);
1019 
1020  retval = ovl (tmp, count, os.error ());
1021  }
1022 
1023  return retval;
1024 }
1025 
1026 DEFMETHOD (fscanf, interp, args, ,
1027  doc: /* -*- texinfo -*-
1028 @deftypefn {} {[@var{val}, @var{count}, @var{errmsg}] =} fscanf (@var{fid}, @var{template}, @var{size})
1029 @deftypefnx {} {[@var{v1}, @var{v2}, @dots{}, @var{count}, @var{errmsg}] =} fscanf (@var{fid}, @var{template}, "C")
1030 In the first form, read from @var{fid} according to @var{template},
1031 returning the result in the matrix @var{val}.
1032 
1033 The optional argument @var{size} specifies the amount of data to read
1034 and may be one of
1035 
1036 @table @code
1037 @item Inf
1038 Read as much as possible, returning a column vector.
1039 
1040 @item @var{nr}
1041 Read up to @var{nr} elements, returning a column vector.
1042 
1043 @item [@var{nr}, Inf]
1044 Read as much as possible, returning a matrix with @var{nr} rows. If the
1045 number of elements read is not an exact multiple of @var{nr}, the last
1046 column is padded with zeros.
1047 
1048 @item [@var{nr}, @var{nc}]
1049 Read up to @code{@var{nr} * @var{nc}} elements, returning a matrix with
1050 @var{nr} rows. If the number of elements read is not an exact multiple
1051 of @var{nr}, the last column is padded with zeros.
1052 @end table
1053 
1054 @noindent
1055 If @var{size} is omitted, a value of @code{Inf} is assumed.
1056 
1057 A string is returned if @var{template} specifies only character conversions.
1058 
1059 The number of items successfully read is returned in @var{count}.
1060 
1061 If an error occurs, @var{errmsg} contains a system-dependent error message.
1062 
1063 In the second form, read from @var{fid} according to @var{template},
1064 with each conversion specifier in @var{template} corresponding to a
1065 single scalar return value. This form is more ``C-like'', and also
1066 compatible with previous versions of Octave. The number of successful
1067 conversions is returned in @var{count}
1068 @ifclear OCTAVE_MANUAL
1069 
1070 See the Formatted Input section of the GNU Octave manual for a
1071 complete description of the syntax of the template string.
1072 @end ifclear
1073 @seealso{fgets, fgetl, fread, scanf, sscanf, fopen}
1074 @end deftypefn */)
1075 {
1076  static const std::string who = "fscanf";
1077 
1078  return scanf_internal (interp, who, args);
1079 }
1080 
1081 static std::string
1082 get_scan_string_data (const octave_value& val, const std::string& who)
1083 {
1084  std::string retval;
1085 
1086  if (! val.is_string ())
1087  error ("%s: argument STRING must be a string", who.c_str ());
1088 
1089  octave_value tmp = val.reshape (dim_vector (1, val.numel ()));
1090 
1091  retval = tmp.string_value ();
1092 
1093  return retval;
1094 }
1095 
1096 DEFUN (sscanf, args, ,
1097  doc: /* -*- texinfo -*-
1098 @deftypefn {} {[@var{val}, @var{count}, @var{errmsg}, @var{pos}] =} sscanf (@var{string}, @var{template}, @var{size})
1099 @deftypefnx {} {[@var{v1}, @var{v2}, @dots{}, @var{count}, @var{errmsg}] =} sscanf (@var{string}, @var{template}, "C")
1100 This is like @code{fscanf}, except that the characters are taken from the
1101 string @var{string} instead of from a stream.
1102 
1103 Reaching the end of the string is treated as an end-of-file condition. In
1104 addition to the values returned by @code{fscanf}, the index of the next
1105 character to be read is returned in @var{pos}.
1106 @seealso{fscanf, scanf, sprintf}
1107 @end deftypefn */)
1108 {
1109  static const std::string who = "sscanf";
1110 
1111  int nargin = args.length ();
1112 
1113  if (nargin < 2 || nargin > 3)
1114  print_usage ();
1115 
1117 
1118  std::string data = get_scan_string_data (args(0), who);
1119 
1121 
1122  if (! os.is_valid ())
1123  error ("%s: unable to create temporary input buffer", who.c_str ());
1124 
1125  if (! args(1).is_string ())
1126  error ("%s: format TEMPLATE must be a string", who.c_str ());
1127 
1128  if (nargin == 3 && args(2).is_string ())
1129  {
1130  retval = os.oscanf (args(1), who);
1131  }
1132  else
1133  {
1134  octave_idx_type count = 0;
1135 
1136  Array<double> size = (nargin == 3) ? args(2).vector_value ()
1137  : Array<double> (dim_vector (1, 1),
1138  lo_ieee_inf_value ());
1139 
1140  octave_value tmp = os.scanf (args(1), size, count, who);
1141 
1142  // FIXME: is this the right thing to do?
1143  // Extract error message first, because getting
1144  // position will clear it.
1145  std::string errmsg = os.error ();
1146 
1147  retval = ovl (tmp, count, errmsg,
1148  (os.eof () ? data.length () : os.tell ()) + 1);
1149  }
1150 
1151  return retval;
1152 }
1153 
1154 /*
1155 %!test <*56396>
1156 %! [val, count, errmsg, nextpos] = sscanf ('1234a6', '%2d', 3);
1157 %! assert (val, [12; 34]);
1158 %! assert (count, 2);
1159 %! assert (errmsg, "sscanf: format failed to match");
1160 %! assert (nextpos, 5);
1161 */
1162 
1163 DEFMETHOD (scanf, interp, args, ,
1164  doc: /* -*- texinfo -*-
1165 @deftypefn {} {[@var{val}, @var{count}, @var{errmsg}] =} scanf (@var{template}, @var{size})
1166 @deftypefnx {} {[@var{v1}, @var{v2}, @dots{}, @var{count}, @var{errmsg}] =} scanf (@var{template}, "C")
1167 This is equivalent to calling @code{fscanf} with @var{fid} = @code{stdin}.
1168 
1169 It is currently not useful to call @code{scanf} in interactive programs.
1170 @seealso{fscanf, sscanf, printf}
1171 @end deftypefn */)
1172 {
1173  static const std::string who = "scanf";
1174 
1175  octave_value_list tmp_args = args;
1176 
1177  return scanf_internal (interp, who, tmp_args.prepend (octave_value (0)));
1178 }
1179 
1180 static octave_value_list
1181 textscan_internal (octave::interpreter& interp, const std::string& who,
1182  const octave_value_list& args)
1183 {
1184  if (args.length () < 1)
1185  print_usage (who);
1186 
1187  octave::stream os;
1188 
1189  if (args(0).is_string ())
1190  {
1191  std::string data = get_scan_string_data (args(0), who);
1192 
1193  os = octave_istrstream::create (data);
1194 
1195  if (! os.is_valid ())
1196  error ("%s: unable to create temporary input buffer", who.c_str ());
1197  }
1198  else
1199  {
1200  octave::stream_list& streams = interp.get_stream_list ();
1201 
1202  os = streams.lookup (args(0), who);
1203  }
1204 
1205  int nskip = 1;
1206 
1207  std::string fmt;
1208 
1209  if (args.length () == 1)
1210  {
1211  // omitted format = %f. explicit "" = width from file
1212  fmt = "%f";
1213  }
1214  else if (args(1).is_string ())
1215  {
1216  fmt = args(1).string_value ();
1217 
1218  if (args(1).is_sq_string ())
1219  fmt = octave::do_string_escapes (fmt);
1220 
1221  nskip++;
1222  }
1223  else
1224  error ("%s: FORMAT must be a string", who.c_str ());
1225 
1226  octave_idx_type ntimes = -1;
1227 
1228  if (args.length () > 2)
1229  {
1230  if (args(2).isnumeric ())
1231  {
1232  ntimes = args(2).idx_type_value ();
1233 
1234  if (ntimes < args(2).double_value ())
1235  error ("%s: REPEAT = %g is too large",
1236  who.c_str (), args(2).double_value ());
1237 
1238  nskip++;
1239  }
1240  }
1241 
1242  octave_value_list options = args.splice (0, nskip);
1243 
1244  octave_idx_type count = 0;
1245 
1246  octave_value result = os.textscan (fmt, ntimes, options, who, count);
1247 
1248  std::string errmsg = os.error ();
1249 
1250  return ovl (result, count, errmsg);
1251 }
1252 
1253 DEFMETHOD (textscan, interp, args, ,
1254  doc: /* -*- texinfo -*-
1255 @deftypefn {} {@var{C} =} textscan (@var{fid}, @var{format})
1256 @deftypefnx {} {@var{C} =} textscan (@var{fid}, @var{format}, @var{repeat})
1257 @deftypefnx {} {@var{C} =} textscan (@var{fid}, @var{format}, @var{param}, @var{value}, @dots{})
1258 @deftypefnx {} {@var{C} =} textscan (@var{fid}, @var{format}, @var{repeat}, @var{param}, @var{value}, @dots{})
1259 @deftypefnx {} {@var{C} =} textscan (@var{str}, @dots{})
1260 @deftypefnx {} {[@var{C}, @var{position}, @var{errmsg}] =} textscan (@dots{})
1261 Read data from a text file or string.
1262 
1263 The string @var{str} or file associated with @var{fid} is read from and
1264 parsed according to @var{format}. The function is an extension of
1265 @code{strread} and @code{textread}. Differences include: the ability to
1266 read from either a file or a string, additional options, and additional
1267 format specifiers.
1268 
1269 The input is interpreted as a sequence of words, delimiters (such as
1270 whitespace), and literals. The characters that form delimiters and
1271 whitespace are determined by the options. The format consists of format
1272 specifiers interspersed between literals. In the format, whitespace forms
1273 a delimiter between consecutive literals, but is otherwise ignored.
1274 
1275 The output @var{C} is a cell array where the number of columns is determined
1276 by the number of format specifiers.
1277 
1278 The first word of the input is matched to the first specifier of the format
1279 and placed in the first column of the output; the second is matched to the
1280 second specifier and placed in the second column and so forth. If there
1281 are more words than specifiers then the process is repeated until all words
1282 have been processed or the limit imposed by @var{repeat} has been met (see
1283 below).
1284 
1285 The string @var{format} describes how the words in @var{str} should be
1286 parsed. As in @var{fscanf}, any (non-whitespace) text in the format that is
1287 not one of these specifiers is considered a literal. If there is a literal
1288 between two format specifiers then that same literal must appear in the
1289 input stream between the matching words.
1290 
1291 The following specifiers are valid:
1292 
1293 @table @code
1294 @item %f
1295 @itemx %f64
1296 @itemx %n
1297 The word is parsed as a number and converted to double.
1298 
1299 @item %f32
1300 The word is parsed as a number and converted to single (float).
1301 
1302 @item %d
1303 @itemx %d8
1304 @itemx %d16
1305 @itemx %d32
1306 @itemx %d64
1307 The word is parsed as a number and converted to int8, int16, int32, or
1308 int64. If no size is specified then int32 is used.
1309 
1310 @item %u
1311 @itemx %u8
1312 @itemx %u16
1313 @itemx %u32
1314 @itemx %u64
1315 The word is parsed as a number and converted to uint8, uint16, uint32, or
1316 uint64. If no size is specified then uint32 is used.
1317 
1318 @item %s
1319 The word is parsed as a string ending at the last character before
1320 whitespace, an end-of-line, or a delimiter specified in the options.
1321 
1322 @item %q
1323 The word is parsed as a "quoted string".
1324 If the first character of the string is a double quote (") then the string
1325 includes everything until a matching double quote---including whitespace,
1326 delimiters, and end-of-line characters. If a pair of consecutive double
1327 quotes appears in the input, it is replaced in the output by a single
1328 double quote. For examples, the input "He said ""Hello""" would
1329 return the value 'He said "Hello"'.
1330 
1331 @item %c
1332 The next character of the input is read.
1333 This includes delimiters, whitespace, and end-of-line characters.
1334 
1335 @item %[@dots{}]
1336 @itemx %[^@dots{}]
1337 In the first form, the word consists of the longest run consisting of only
1338 characters between the brackets. Ranges of characters can be specified by
1339 a hyphen; for example, %[0-9a-zA-Z] matches all alphanumeric characters (if
1340 the underlying character set is ASCII). Since @sc{matlab} treats hyphens
1341 literally, this expansion only applies to alphanumeric characters. To
1342 include '-' in the set, it should appear first or last in the brackets; to
1343 include ']', it should be the first character. If the first character is
1344 '^' then the word consists of characters @strong{not} listed.
1345 
1346 @item %N@dots{}
1347 For %s, %c %d, %f, %n, %u, an optional width can be specified as %Ns, etc.
1348 where N is an integer > 1. For %c, this causes exactly N characters to be
1349 read instead of a single character. For the other specifiers, it is an
1350 upper bound on the number of characters read; normal delimiters can cause
1351 fewer characters to be read. For complex numbers, this limit applies to
1352 the real and imaginary components individually. For %f and %n, format
1353 specifiers like %N.Mf are allowed, where M is an upper bound on number of
1354 characters after the decimal point to be considered; subsequent digits are
1355 skipped. For example, the specifier %8.2f would read 12.345e6 as 1.234e7.
1356 
1357 @item %*@dots{}
1358 The word specified by the remainder of the conversion specifier is skipped.
1359 
1360 @item literals
1361 In addition the format may contain literal character strings; these will be
1362 skipped during reading. If the input string does not match this literal,
1363 the processing terminates.
1364 @end table
1365 
1366 Parsed words corresponding to the first specifier are returned in the first
1367 output argument and likewise for the rest of the specifiers.
1368 
1369 By default, if there is only one input argument, @var{format} is @t{"%f"}.
1370 This means that numbers are read from the input into a single column vector.
1371 If @var{format} is explicitly empty (@qcode{""}) then textscan will
1372 return data in a number of columns matching the number of fields on the
1373 first data line of the input. Either of these is suitable only when the
1374 input is exclusively numeric.
1375 
1376 For example, the string
1377 
1378 @smallexample
1379 @group
1380 @var{str} = "\
1381 Bunny Bugs 5.5\n\
1382 Duck Daffy -7.5e-5\n\
1383 Penguin Tux 6"
1384 @end group
1385 @end smallexample
1386 
1387 @noindent
1388 can be read using
1389 
1390 @example
1391 @var{a} = textscan (@var{str}, "%s %s %f");
1392 @end example
1393 
1394 The optional numeric argument @var{repeat} can be used for limiting the
1395 number of items read:
1396 
1397 @table @asis
1398 @item -1
1399 Read all of the string or file until the end (default).
1400 
1401 @item N
1402 Read until the first of two conditions occurs: 1) the format has been
1403 processed N times, or 2) N lines of the input have been processed. Zero
1404 (0) is an acceptable value for @var{repeat}. Currently, end-of-line
1405 characters inside %q, %c, and %[@dots{}]$ conversions do not contribute to
1406 the line count. This is incompatible with @sc{matlab} and may change in
1407 future.
1408 @end table
1409 
1410 The behavior of @code{textscan} can be changed via property/value pairs.
1411 The following properties are recognized:
1412 
1413 @table @asis
1414 @item @qcode{"BufSize"}
1415 This specifies the number of bytes to use for the internal buffer.
1416 A modest speed improvement may be obtained by setting this to a large value
1417 when reading a large file, especially if the input contains long strings.
1418 The default is 4096, or a value dependent on @var{n} if that is specified.
1419 
1420 @item @qcode{"CollectOutput"}
1421 A value of 1 or true instructs @code{textscan} to concatenate consecutive
1422 columns of the same class in the output cell array. A value of 0 or false
1423 (default) leaves output in distinct columns.
1424 
1425 @item @qcode{"CommentStyle"}
1426 Specify parts of the input which are considered comments and will be
1427 skipped. @var{value} is the comment style and can be either (1) A string
1428 or 1x1 cell string, to skip everything to the right of it; (2) A cell array
1429 of two strings, to skip everything between the first and second strings.
1430 Comments are only parsed where whitespace is accepted and do not act as
1431 delimiters.
1432 
1433 @item @qcode{"Delimiter"}
1434 If @var{value} is a string, any character in @var{value} will be used to
1435 split the input into words. If @var{value} is a cell array of strings,
1436 any string in the array will be used to split the input into words.
1437 (default value = any whitespace.)
1438 
1439 @item @qcode{"EmptyValue"}
1440 Value to return for empty numeric values in non-whitespace delimited data.
1441 The default is NaN@. When the data type does not support NaN (int32 for
1442 example), then the default is zero.
1443 
1444 @item @qcode{"EndOfLine"}
1445 @var{value} can be either an empty or one character specifying the
1446 end-of-line character, or the pair
1447 @qcode{"@xbackslashchar{}r@xbackslashchar{}n"} (CRLF).
1448 In the latter case, any of
1449 @qcode{"@xbackslashchar{}r"}, @qcode{"@xbackslashchar{}n"} or
1450 @qcode{"@xbackslashchar{}r@xbackslashchar{}n"} is counted as a (single)
1451 newline. If no value is given,
1452 @qcode{"@xbackslashchar{}r@xbackslashchar{}n"} is used.
1453 @c If set to "" (empty string) EOLs are ignored as delimiters and added
1454 @c to whitespace.
1455 
1456 @c When reading from a character string, optional input argument @var{n}
1457 @c specifies the number of times @var{format} should be used (i.e., to limit
1458 @c the amount of data read).
1459 @c When reading from file, @var{n} specifies the number of data lines to read;
1460 @c in this sense it differs slightly from the format repeat count in strread.
1461 
1462 @item @qcode{"HeaderLines"}
1463 The first @var{value} number of lines of @var{fid} are skipped. Note that
1464 this does not refer to the first non-comment lines, but the first lines of
1465 any type.
1466 
1467 @item @qcode{"MultipleDelimsAsOne"}
1468 If @var{value} is nonzero, treat a series of consecutive delimiters,
1469 without whitespace in between, as a single delimiter. Consecutive
1470 delimiter series need not be vertically aligned. Without this option, a
1471 single delimiter before the end of the line does not cause the line to be
1472 considered to end with an empty value, but a single delimiter at the start
1473 of a line causes the line to be considered to start with an empty value.
1474 
1475 @item @qcode{"TreatAsEmpty"}
1476 Treat single occurrences (surrounded by delimiters or whitespace) of the
1477 string(s) in @var{value} as missing values.
1478 
1479 @item @qcode{"ReturnOnError"}
1480 If set to numerical 1 or true, return normally as soon as an error is
1481 encountered, such as trying to read a string using @code{%f}.
1482 If set to 0 or false, return an error and no data.
1483 
1484 @item @qcode{"Whitespace"}
1485 Any character in @var{value} will be interpreted as whitespace and trimmed;
1486 The default value for whitespace is
1487 @c Note: the next line specifically has a newline which generates a space
1488 @c in the output of qcode, but keeps the next line < 80 characters.
1489 @qcode{"
1490 @xbackslashchar{}b@xbackslashchar{}r@xbackslashchar{}n@xbackslashchar{}t"}
1491 (note the space). Unless whitespace is set to @qcode{""} (empty) AND at
1492 least one @qcode{"%s"} format conversion specifier is supplied, a space is
1493 always part of whitespace.
1494 
1495 @end table
1496 
1497 When the number of words in @var{str} or @var{fid} doesn't match an exact
1498 multiple of the number of format conversion specifiers, @code{textscan}'s
1499 behavior depends on whether the last character of the string or file is an
1500 end-of-line as specified by the @code{EndOfLine} option:
1501 
1502 @table @asis
1503 @item last character = end-of-line
1504 Data columns are padded with empty fields, NaN or 0 (for integer fields) so
1505 that all columns have equal length
1506 
1507 @item last character is not end-of-line
1508 Data columns are not padded; @code{textscan} returns columns of unequal
1509 length
1510 @end table
1511 
1512 The second output @var{position} provides the location, in characters
1513 from the beginning of the file or string, where processing stopped.
1514 
1515 @seealso{dlmread, fscanf, load, strread, textread}
1516 @end deftypefn */)
1517 {
1518  static const std::string who = "textscan";
1519 
1520  return textscan_internal (interp, who, args);
1521 }
1522 
1523 DEFMETHOD (__textscan__, interp, args, ,
1524  doc: /* -*- texinfo -*-
1525 @deftypefn {} {@var{C} =} __textscan__ (@var{who}, @dots{})
1526 Like @code{textscan} but accept additional argument @var{who} to use
1527 as the name of the function when reporting errors.
1528 @end deftypefn */)
1529 {
1530  if (args.length () == 0)
1531  print_usage ();
1532 
1533  return textscan_internal (interp, args(0).string_value (),
1534  args.splice (0, 1));
1535 }
1536 
1537 /*
1538 %!test
1539 %! str = "1, 2, 3, 4\n 5, , , 8\n 9, 10, 11, 12";
1540 %! fmtstr = "%f %d %f %s";
1541 %! c = textscan (str, fmtstr, 2, "delimiter", ",", "emptyvalue", -Inf);
1542 %! assert (c{1}, [1;5]);
1543 %! assert (c{3}, [3; -Inf]);
1544 %! assert (iscellstr (c{4}));
1545 
1546 %!test
1547 %! b = [10:10:100];
1548 %! b = [b; 8*b/5];
1549 %! str = sprintf ("%g miles/hr = %g kilometers/hr\n", b);
1550 %! fmt = "%f miles/hr = %f kilometers/hr";
1551 %! c = textscan (str, fmt);
1552 %! assert (c{1}, b(1,:)', 1e-5);
1553 %! assert (c{2}, b(2,:)', 1e-5);
1554 
1555 %!test
1556 %! str = "13, -, NA, str1, -25\r\n// Middle line\r\n36, na, 05, str3, 6";
1557 %! c = textscan (str, "%d %n %f %s %n", "delimiter", ",",
1558 %! "treatAsEmpty", {"NA", "na", "-"}, "commentStyle", "//");
1559 %! assert (c{1}, int32 ([13; 36]));
1560 %! assert (c{2}, [NaN; NaN]);
1561 %! assert (c{3}, [NaN; 5]);
1562 %! assert (c{4}, {"str1"; "str3"});
1563 %! assert (c{5}, [-25; 6]);
1564 
1565 %!test
1566 %! str = "Km:10 = hhhBjjj miles16hour\r\n";
1567 %! str = [str "Km:15 = hhhJjjj miles241hour\r\n"];
1568 %! str = [str "Km:2 = hhhRjjj miles3hour\r\n"];
1569 %! str = [str "Km:25 = hhhZ\r\n"];
1570 %! fmt = "Km:%d = hhh%1sjjj miles%dhour";
1571 %! c = textscan (str, fmt, "delimiter", " ");
1572 %! assert (c{1}', int32 ([10, 15, 2, 25]));
1573 %! assert (c{2}', {'B' 'J' 'R' 'Z'});
1574 %! assert (c{3}', int32 ([16, 241, 3, 0]));
1575 
1576 ## Test with default EndOfLine parameter
1577 %!test
1578 %! c = textscan ("L1\nL2", "%s");
1579 %! assert (c{:}, {"L1"; "L2"});
1580 
1581 ## Test with EndofLine parameter set to "" (empty) - newline should be in word
1582 %!test
1583 %! c = textscan ("L1\nL2", "%s", "endofline", "");
1584 %! assert (int8 ([c{:}{:}]), int8 ([76, 49, 10, 76, 50]));
1585 
1586 ## Matlab fails this test. A literal after a conversion is not a delimiter
1587 %!#test
1588 %! ## No delimiters at all besides EOL. Skip fields, even empty fields
1589 %! str = "Text1Text2Text\nTextText4Text\nText57Text";
1590 %! c = textscan (str, "Text%*dText%dText");
1591 %! assert (c{1}, int32 ([2; 4; 0]));
1592 
1593 ## CollectOutput test
1594 %!test
1595 %! b = [10:10:100];
1596 %! b = [b; 8*b/5; 8*b*1000/5];
1597 %! str = sprintf ("%g miles/hr = %g (%g) kilometers (meters)/hr\n", b);
1598 %! fmt = "%f miles%s %s %f (%f) kilometers %*s";
1599 %! c = textscan (str, fmt, "collectoutput", 1);
1600 %! assert (size (c{3}), [10, 2]);
1601 %! assert (size (c{2}), [10, 2]);
1602 
1603 ## CollectOutput test with uneven column length files
1604 %!test
1605 %! b = [10:10:100];
1606 %! b = [b; 8*b/5; 8*b*1000/5];
1607 %! str = sprintf ("%g miles/hr = %g (%g) kilometers (meters)/hr\n", b);
1608 %! str = [str "110 miles/hr"];
1609 %! fmt = "%f miles%s %s %f (%f) kilometers %*s";
1610 %! c = textscan (str, fmt, "collectoutput", 1);
1611 %! assert (size (c{1}), [11, 1]);
1612 %! assert (size (c{3}), [11, 2]);
1613 %! assert (size (c{2}), [11, 2]);
1614 %! assert (c{3}(end), NaN);
1615 %! assert (c{2}{11, 1}, "/hr");
1616 %! assert (isempty (c{2}{11, 2}), true);
1617 
1618 ## Double quoted string
1619 %!test
1620 %! str = 'First "the second called ""the middle""" third';
1621 %! fmt = "%q";
1622 %! c = textscan (str, fmt);
1623 %! assert (c{1}, {"First"; 'the second called "the middle"'; "third"});
1624 
1625 ## Arbitrary character
1626 %!test
1627 %! c = textscan ("a first, \n second, third", "%s %c %11c", "delimiter", " ,");
1628 %! assert (c{1}, {"a"; "ond"});
1629 %! assert (c{2}, {"f"; "t"});
1630 %! assert (c{3}, {"irst, \n sec"; "hird"});
1631 
1632 ## Field width and non-standard delimiters
1633 %!test
1634 %! str = "12;34;123456789;7";
1635 %! c = textscan (str, "%4d %4d", "delimiter", ";", "collectOutput", 1);
1636 %! assert (c, {[12, 34; 1234, 5678; 9, 7]});
1637 
1638 ## Field width and non-standard delimiters (2)
1639 %!test
1640 %! str = "12;34;123456789;7";
1641 %! c = textscan (str, "%4f %f", "delimiter", ";", "collectOutput", 1);
1642 %! assert (c, {[12, 34; 1234, 56789; 7, NaN]});
1643 
1644 ## Ignore trailing delimiter, but use leading one
1645 %!test
1646 %! str = "12.234e+2,34, \n12345.789-9876j,78\n,10|3";
1647 %! c = textscan (str, "%10.2f %f", "delimiter", ",", "collectOutput", 1,
1648 %! "expChars", "e|");
1649 %! assert (c, {[1223, 34; 12345.79-9876j, 78; NaN, 10000]}, 1e-6);
1650 
1651 ## Multi-character delimiter
1652 %!test
1653 %! str = "99end2 space88gap 4564";
1654 %! c = textscan (str, "%d %s", "delimiter", {"end", "gap", "space"});
1655 %! assert (c{1}, int32 ([99; 88]));
1656 %! assert (c{2}, {"2 "; "4564"});
1657 
1658 ## FIXME: Following two tests still fail (4/13/2016).
1659 ## Delimiters as part of literals, and following literals
1660 %!#test
1661 %! str = "12 R&D & 7";
1662 %! c = textscan (str, "%f R&D %f", "delimiter", "&", "collectOutput", 1,
1663 %! "EmptyValue", -99);
1664 %! assert (c, {[12, -99; 7, -99]});
1665 
1666 ## Delimiters as part of literals, and before literals
1667 %!#test
1668 %! str = "12 & R&D 7";
1669 %! c = textscan (str, "%f R&D %f", "delimiter", "&", "collectOutput", 1);
1670 %! assert (c, {[12 7]});
1671 
1672 ## Check number of lines read, not number of passes through format string
1673 %!test
1674 %! f = tempname ();
1675 %! fid = fopen (f, "w+");
1676 %! fprintf (fid, "1\n2\n3\n4\n5\n6");
1677 %! fseek (fid, 0, "bof");
1678 %! c = textscan (fid, "%f %f", 2);
1679 %! E = feof (fid);
1680 %! fclose (fid);
1681 %! unlink (f);
1682 %! assert (c, {1, 2});
1683 %! assert (! E);
1684 
1685 ## Check number of lines read, not number of passes through format string
1686 %!test
1687 %! f = tempname ();
1688 %! fid = fopen (f, "w+");
1689 %! fprintf (fid, "1\r\n2\r3\n4\r\n5\n6");
1690 %! fseek (fid, 0, "bof");
1691 %! c = textscan (fid, "%f %f", 4);
1692 %! fclose (fid);
1693 %! unlink (f);
1694 %! assert (c, {[1;3], [2;4]});
1695 
1696 ## Check number of lines read, with multiple delimiters
1697 %!test
1698 %! f = tempname ();
1699 %! fid = fopen (f, "w+");
1700 %! fprintf (fid, "1-\r\n-2\r3-\n-4\r\n5\n6");
1701 %! fseek (fid, 0, "bof");
1702 %! c = textscan (fid, "%f %f", 4, "delimiter", "-", "multipleDelimsAsOne", 1);
1703 %! fclose (fid);
1704 %! unlink (f);
1705 %! assert (c, {[1;3], [2;4]});
1706 
1707 ## Check ReturnOnError
1708 %!test
1709 %! f = tempname ();
1710 %! fid = fopen (f, "w+");
1711 %! str = "1 2 3\n4 s 6";
1712 %! fprintf (fid, str);
1713 %! fseek (fid, 0, "bof");
1714 %! c = textscan (fid, "%f %f %f", "ReturnOnError", 1);
1715 %! fseek (fid, 0, "bof");
1716 %! fclose (fid);
1717 %! unlink (f);
1718 %! u = textscan (str, "%f %f %f", "ReturnOnError", 1);
1719 %! assert (c, {[1;4], [2], [3]});
1720 %! assert (u, {[1;4], [2], [3]});
1721 
1722 %! ## Check ReturnOnError (2)
1723 %!test
1724 %! f = tempname ();
1725 %! fid = fopen (f, "w+");
1726 %! str = "1 2 3\n4 s 6\n";
1727 %! fprintf (fid, str);
1728 %! fseek (fid, 0, "bof");
1729 %! c = textscan (fid, "%f %f %f", "ReturnOnError", 1);
1730 %! fseek (fid, 0, "bof");
1731 %! fclose (fid);
1732 %! unlink (f);
1733 %! u = textscan (str, "%f %f %f", "ReturnOnError", 1);
1734 %! assert (c, {[1;4], 2, 3});
1735 %! assert (u, {[1;4], 2, 3});
1736 
1737 %!error <Read error in field 2 of row 2>
1738 %! textscan ("1 2 3\n4 s 6", "%f %f %f", "ReturnOnError", 0);
1739 
1740 ## Check ReturnOnError (3)
1741 %!test
1742 %! f = tempname ();
1743 %! fid = fopen (f, "w+");
1744 %! fprintf (fid, "1 s 3\n4 5 6");
1745 %! fseek (fid, 0, "bof");
1746 %! c = textscan (fid, "", "ReturnOnError", 1);
1747 %! fseek (fid, 0, "bof");
1748 %! fclose (fid);
1749 %! unlink (f);
1750 %! assert (c, {1});
1751 
1752 ## Check ReturnOnError with empty fields
1753 %!test
1754 %! c = textscan ("1,,3\n4,5,6", "", "Delimiter", ",", "ReturnOnError", 1);
1755 %! assert (c, {[1;4], [NaN;5], [3;6]});
1756 
1757 ## Check ReturnOnError with empty fields (2)
1758 %!test
1759 %! c = textscan ("1,,3\n4,5,6", "%f %f %f", "Delimiter", ",",
1760 %! "ReturnOnError", 1);
1761 %! assert (c, {[1;4], [NaN;5], [3;6]});
1762 
1763 ## Check ReturnOnError in first column
1764 %!test
1765 %! c = textscan ("1 2 3\ns 5 6", "", "ReturnOnError", 1);
1766 %! assert (c, {1, 2, 3});
1767 
1768 ## FIXME: This test fails (4/14/16)
1769 ## Test incomplete first data line
1770 %!#test
1771 %! R = textscan (['Empty1' char(10)], 'Empty%d %f');
1772 %! assert (R{1}, int32 (1));
1773 %! assert (isempty (R{2}), true);
1774 
1775 %!test <*37023>
1776 %! data = textscan (" 1. 1 \n 2 3\n", '%f %f');
1777 %! assert (data{1}, [1; 2], 1e-15);
1778 %! assert (data{2}, [1; 3], 1e-15);
1779 
1780 ## Whitespace test using delimiter ";"
1781 %!test <*37333>
1782 %! tc{1, 1} = "C:/code;";
1783 %! tc{1, end+1} = "C:/code/meas;";
1784 %! tc{1, end+1} = " C:/code/sim;";
1785 %! tc{1, end+1} = "C:/code/utils;";
1786 %! string = [tc{:}];
1787 %! c = textscan (string, "%s", "delimiter", ";");
1788 %! for k = 1:max (numel (c{1}), numel (tc))
1789 %! lh = c{1}{k};
1790 %! rh = tc{k};
1791 %! rh(rh == ";") = "";
1792 %! rh = strtrim (rh);
1793 %! assert (strcmp (lh, rh));
1794 %! endfor
1795 
1796 ## Whitespace test, adding multipleDelimsAsOne true arg
1797 %!test <*37333>
1798 %! tc{1, 1} = "C:/code;";
1799 %! tc{1, end+1} = " C:/code/meas;";
1800 %! tc{1, end+1} = "C:/code/sim;;";
1801 %! tc{1, end+1} = "C:/code/utils;";
1802 %! string = [tc{:}];
1803 %! c = textscan (string, "%s", "delimiter", ";", "multipleDelimsAsOne", 1);
1804 %! for k = 1:max (numel (c{1}), numel (tc))
1805 %! lh = c{1}{k};
1806 %! rh = tc{k};
1807 %! rh(rh == ";") = "";
1808 %! rh = strtrim (rh);
1809 %! assert (strcmp (lh, rh));
1810 %! endfor
1811 
1812 ## Whitespace test (bug #37333), adding multipleDelimsAsOne false arg
1813 %!test <*37333>
1814 %! tc{1, 1} = "C:/code;";
1815 %! tc{1, end+1} = " C:/code/meas;";
1816 %! tc{1, end+1} = "C:/code/sim;;";
1817 %! tc{1, end+1} = "";
1818 %! tc{1, end+1} = "C:/code/utils;";
1819 %! string = [tc{:}];
1820 %! c = textscan (string, "%s", "delimiter", ";", "multipleDelimsAsOne", 0);
1821 %! for k = 1:max (numel (c{1}), numel (tc))
1822 %! lh = c{1}{k};
1823 %! rh = tc{k};
1824 %! rh(rh == ";") = "";
1825 %! rh = strtrim (rh);
1826 %! assert (strcmp (lh, rh));
1827 %! endfor
1828 
1829 ## Whitespace test (bug #37333) whitespace "" arg
1830 %!test <*37333>
1831 %! tc{1, 1} = "C:/code;";
1832 %! tc{1, end+1} = " C:/code/meas;";
1833 %! tc{1, end+1} = "C:/code/sim;";
1834 %! tc{1, end+1} = "C:/code/utils;";
1835 %! string = [tc{:}];
1836 %! c = textscan (string, "%s", "delimiter", ";", "whitespace", "");
1837 %! for k = 1:max (numel (c{1}), numel (tc))
1838 %! lh = c{1}{k};
1839 %! rh = tc{k};
1840 %! rh(rh == ";") = "";
1841 %! assert (strcmp (lh, rh));
1842 %! endfor
1843 
1844 ## Whitespace test (bug #37333), whitespace " " arg
1845 %!test <*37333>
1846 %! tc{1, 1} = "C:/code;";
1847 %! tc{1, end+1} = " C:/code/meas;";
1848 %! tc{1, end+1} = "C:/code/sim;";
1849 %! tc{1, end+1} = "C:/code/utils;";
1850 %! string = [tc{:}];
1851 %! c = textscan (string, "%s", "delimiter", ";", "whitespace", " ");
1852 %! for k = 1:max (numel (c{1}), numel (tc))
1853 %! lh = c{1}{k};
1854 %! rh = tc{k};
1855 %! rh(rh == ";") = "";
1856 %! rh = strtrim (rh);
1857 %! assert (strcmp (lh, rh));
1858 %! endfor
1859 
1860 ## Tests reading with empty format, should return proper nr of columns
1861 %!test
1862 %! f = tempname ();
1863 %! fid = fopen (f, "w+");
1864 %! fprintf (fid, " 1 2 3 4\n5 6 7 8");
1865 %! fseek (fid, 0, "bof");
1866 %! C = textscan (fid, "");
1867 %! E = feof (fid);
1868 %! fclose (fid);
1869 %! unlink (f);
1870 %! assert (C{1}, [1 ; 5], 1e-6);
1871 %! assert (C{2}, [2 ; 6], 1e-6);
1872 %! assert (C{3}, [3 ; 7], 1e-6);
1873 %! assert (C{4}, [4 ; 8], 1e-6);
1874 %! assert (E);
1875 
1876 ## Test leaving the file at the correct position on exit
1877 %!test
1878 %! f = tempname ();
1879 %! fid = fopen (f, "w+");
1880 %! fprintf (fid, "1,2\n3,4\n");
1881 %! fseek (fid, 0, "bof");
1882 %! C = textscan (fid, "%s %f", 2, "Delimiter", ",");
1883 %! E = ftell (fid);
1884 %! fclose (fid);
1885 %! unlink (f);
1886 %! assert (E, 8);
1887 
1888 ## Tests reading with empty format; empty fields & incomplete lower row
1889 %!test
1890 %! f = tempname ();
1891 %! fid = fopen (f, "w+");
1892 %! fprintf (fid, " ,2,,4\n5,6");
1893 %! fseek (fid, 0, "bof");
1894 %! C = textscan (fid, "", "delimiter", ",", "EmptyValue", 999,
1895 %! "CollectOutput" , 1);
1896 %! fclose (fid);
1897 %! unlink (f);
1898 %! assert (C{1}, [999, 2, 999, 4; 5, 6, 999, 999], 1e-6);
1899 
1900 ## Error message tests
1901 
1902 %!test
1903 %! f = tempname ();
1904 %! fid = fopen (f, "w+");
1905 %! msg1 = "textscan: 1 parameters given, but only 0 values";
1906 %! try
1907 %! C = textscan (fid, "", "headerlines");
1908 %! end_try_catch;
1909 %! assert (! feof (fid));
1910 %! fclose (fid);
1911 %! unlink (f);
1912 %! assert (msg1, lasterr);
1913 
1914 %!test
1915 %! f = tempname ();
1916 %! fid = fopen (f, "w+");
1917 %! msg1 = "textscan: HeaderLines must be numeric";
1918 %! try
1919 %! C = textscan (fid, "", "headerlines", "hh");
1920 %! end_try_catch;
1921 %! fclose (fid);
1922 %! unlink (f);
1923 %! assert (msg1, lasterr);
1924 
1925 ## Skip headerlines
1926 %!test
1927 %! C = textscan ("field 1 field2\n 1 2\n3 4", "", "headerlines", 1,
1928 %! "collectOutput", 1);
1929 %! assert (C, {[1 2; 3 4]});
1930 
1931 ## Skip headerlines with non-default EOL
1932 %!test
1933 %! C = textscan ("field 1 field2\r 1 2\r3 4", "", "headerlines", 2,
1934 %! "collectOutput", 1, "EndOfLine", '\r');
1935 %! assert (C, {[3 4]});
1936 
1937 %!test
1938 %! f = tempname ();
1939 %! fid = fopen (f, "w+");
1940 %! fprintf (fid,"some_string");
1941 %! fseek (fid, 0, "bof");
1942 %! msg1 = "textscan: EndOfLine must be at most one character or '\\r\\n'";
1943 %! try
1944 %! C = textscan (fid, "%f", "EndOfLine", "\n\r");
1945 %! end_try_catch;
1946 %! fclose (fid);
1947 %! unlink (f);
1948 %! assert (msg1, lasterr);
1949 
1950 %!test
1951 %! f = tempname ();
1952 %! fid = fopen (f, "w+");
1953 %! fprintf (fid,"some_string");
1954 %! fseek (fid, 0, "bof");
1955 %! msg1 = "textscan: EndOfLine must be at most one character or '\\r\\n'";
1956 %! try
1957 %! C = textscan (fid, "%f", "EndOfLine", 33);
1958 %! end_try_catch;
1959 %! fclose (fid);
1960 %! unlink (f);
1961 %! assert (msg1, lasterr);
1962 
1963 %!assert <*41824> (textscan ("123", "", "whitespace", " "){:}, 123);
1964 
1965 ## just test supplied emptyvalue
1966 %!assert <*42343> (textscan (",NaN", "", "delimiter", "," ,"emptyValue" ,Inf),
1967 %! {Inf, NaN})
1968 
1969 ## test padding with supplied emptyvalue
1970 %!test <*42343>
1971 %! c = textscan (",1,,4\nInf, ,NaN\n", "", "delimiter", ",",
1972 %! "emptyvalue", -10);
1973 %! assert (cell2mat (c), [-10, 1, -10, 4; Inf, -10, NaN, -10]);
1974 
1975 %!test <*42528>
1976 %! assert (textscan ("1i", ""){1}, 0+1i);
1977 %! C = textscan ("3, 2-4i, NaN\n -i, 1, 23.4+2.2i\n 1+1 1+1j", "",
1978 %! "delimiter", ",");
1979 %! assert (cell2mat (C), [3+0i, 2-4i, NaN+0i; 0-i, 1+0i, 23.4+2.2i; 1 1 1+1i]);
1980 
1981 %!test
1982 %! ## TreatAsEmpty
1983 %! C = textscan ("1,2,3,NN,5,6\n", "%d%d%d%f", "delimiter", ",",
1984 %! "TreatAsEmpty", "NN");
1985 %! assert (C{3}(1), int32 (3));
1986 %! assert (C{4}(1), NaN);
1987 
1988 ## MultipleDelimsAsOne
1989 %!test
1990 %! str = "11, 12, 13,, 15\n21,, 23, 24, 25\n,, 33, 34, 35\n";
1991 %! C = textscan (str, "%f %f %f %f", "delimiter", ",",
1992 %! "multipledelimsasone", 1, "endofline", "\n");
1993 %! assert (C{1}', [11, 21, 33]);
1994 %! assert (C{2}', [12, 23, 34]);
1995 %! assert (C{3}', [13, 24, 35]);
1996 %! assert (C{4}', [15, 25, NaN]);
1997 
1998 ## Single-quoted escape sequences
1999 %!test
2000 %! str = "11\t12\t13\r21\t22\t23";
2001 %! c = textscan (str, "", "delimiter", '\t', "EndOfLine", '\r');
2002 %! assert (c{1}', [11, 21]);
2003 %! assert (c{2}', [12, 22]);
2004 %! assert (c{3}', [13, 23]);
2005 
2006 %!test <*44750>
2007 %! c = textscan ("/home/foo/", "%s", "delimiter", "/",
2008 %! "MultipleDelimsAsOne", 1);
2009 %! assert (c{1}, {"home"; "foo"});
2010 
2011 ## FIXME: Test still fails (4/13/2016).
2012 ## Allow cuddling %sliteral, but warn it is ambiguous
2013 %!#test
2014 %! C = textscan ("abcxyz51\nxyz83\n##xyz101", "%s xyz %d");
2015 %! assert (C{1}([1 3]), {"abc"; "##"});
2016 %! assert (isempty (C{1}{2}), true);
2017 %! assert (C{2}, int32 ([51; 83; 101]));
2018 
2019 ## Literals are not delimiters.
2020 
2021 ## Test for false positives in check for non-supported format specifiers
2022 %!test
2023 %! c = textscan ("Total: 32.5 % (of cm values)",
2024 %! "Total: %f %% (of cm values)");
2025 %! assert (c{1}, 32.5, 1e-5);
2026 
2027 ## Test various forms of string format specifiers
2028 %!test <*45712>
2029 %! str = "14 :1 z:2 z:3 z:5 z:11";
2030 %! C = textscan (str, "%f %s %*s %3s %*3s %f", "delimiter", ":");
2031 %! assert (C, {14, {"1 z"}, {"3 z"}, 11});
2032 
2033 ## Bit width, fixed width conversion specifiers
2034 %!test
2035 %! str2 = "123456789012345 ";
2036 %! str2 = [str2 str2 str2 str2 str2 str2 str2 str2];
2037 %! str2 = [str2 "123456789.01234 1234567890.1234 12345.678901234 12345.678901234"];
2038 %! pttrn = "%3u8%*s %5u16%*s %10u32%*s %15u64 %3d8%*s %5d16%*s %10d32%*s %15d64 %9f32%*s %14f64%*s %10.2f32%*s %12.2f64%*s";
2039 %! C = textscan (str2, pttrn, "delimiter", " ");
2040 %! assert (C{1}, uint8 (123));
2041 %! assert (C{2}, uint16 (12345));
2042 %! assert (C{3}, uint32 (1234567890));
2043 %! assert (C{4}, uint64 (123456789012345));
2044 %! assert (C{5}, int8 (123));
2045 %! assert (C{6}, int16 (12345));
2046 %! assert (C{7}, int32 (1234567890));
2047 %! assert (C{8}, int64 (123456789012345));
2048 %! assert (C{9}, single (123456789), 1e-12);
2049 %! assert (C{10}, double (1234567890.123), 1e-15);
2050 %! assert (C{11}, single (12345.68), 1e-5);
2051 %! assert (C{12}, double (12345.68), 1e-11);
2052 
2053 ## Bit width, fixed width conv. specifiers -- check the right amount is left
2054 %!test
2055 %! str2 = "123456789012345 ";
2056 %! str2 = [str2 str2 "123456789.01234"];
2057 %! pttrn = "%3u8 %5u16 %10u32 %3d8 %5d16 %10d32 %9f32 %9f";
2058 %! C = textscan (str2, pttrn, "delimiter", " ");
2059 %! assert (C{1}, uint8 (123));
2060 %! assert (C{2}, uint16 (45678));
2061 %! assert (C{3}, uint32 (9012345));
2062 %! assert (C{4}, int8 (123));
2063 %! assert (C{5}, int16 (45678));
2064 %! assert (C{6}, int32 (9012345));
2065 %! assert (C{7}, single (123456789), 1e-12);
2066 %! assert (C{8}, double (0.01234), 1e-12);
2067 
2068 %!test
2069 %! C = textscan ("123.123", "%2f %3f %3f");
2070 %! assert (C{1}, 12);
2071 %! assert (C{2}, 3.1, 1e-11);
2072 %! assert (C{3}, 23);
2073 
2074 %!test
2075 %! C = textscan ("123.123", "%3f %3f %3f");
2076 %! assert (C{1}, 123);
2077 %! assert (C{2}, 0.12, 1e-11);
2078 %! assert (C{3}, 3);
2079 
2080 %!test
2081 %! C = textscan ("123.123", "%4f %3f");
2082 %! assert (C{1}, 123);
2083 %! assert (C{2}, 123);
2084 
2085 ## field width interrupts exponent. (Matlab incorrectly gives [12, 2e12])
2086 %!test
2087 %! assert (textscan ("12e12", "%4f"), {[120; 2]});
2088 %! assert (textscan ("12e+12", "%5f"), {[120; 2]});
2089 %! assert (textscan ("125e-12","%6f"), {[12.5; 2]});
2090 
2091 ## %[] tests
2092 ## Plain [..] and *[..]
2093 %!test
2094 %! ar = "abcdefguvwxAny\nacegxyzTrailing\nJunk";
2095 %! C = textscan (ar, "%[abcdefg] %*[uvwxyz] %s");
2096 %! assert (C{1}, {"abcdefg"; "aceg"; ""});
2097 %! assert (C{2}, {"Any"; "Trailing"; "Junk"});
2098 
2099 %!test
2100 %! assert (textscan ("A2 B2 C3", "%*[ABC]%d", 3), {int32([2; 2; 3])});
2101 
2102 ## [^..] and *[^..]
2103 %!test
2104 %! br = "abcdefguvwx1Any\nacegxyz2Trailing\n3Junk";
2105 %! C = textscan (br, "%[abcdefg] %*[^0123456789] %s");
2106 %! assert (C{1}, {"abcdefg"; "aceg"; ""});
2107 %! assert (C{2}, {"1Any"; "2Trailing"; "3Junk"});
2108 
2109 ## [..] and [^..] containing delimiters
2110 %!test
2111 %! cr = "ab cd efguv wx1Any\na ce gx yz2Trailing\n 3Junk";
2112 %! C = textscan (cr, "%[ abcdefg] %*[^0123456789] %s", "delimiter", " \n",
2113 %! "whitespace", "");
2114 %! assert (C{1}, {"ab cd efg"; "a ce g"; " "});
2115 %! assert (C{2}, {"1Any"; "2Trailing"; "3Junk"});
2116 
2117 %!assert <*36464> (textscan ("1 2 3 4 5 6", "%*n%n%*[^\n]"){1}, 2);
2118 
2119 ## test %[]] and %[^]]
2120 %!test
2121 %! assert (textscan ("345]", "%*[123456]%[]]"){1}{1}, "]");
2122 %! assert (textscan ("345]", "%*[^]]%s"){1}{1}, "]");
2123 
2124 ## Test that "-i" checks the next two characters
2125 %!test
2126 %! C = textscan ("-i -in -inf -infinity", "%f %f%s %f %f %s");
2127 %! assert (C, {-i, -i, {"n"}, -Inf, -Inf, {"inity"}});
2128 
2129 ## Again for "+i", this time with custom parser
2130 %!test
2131 %! C = textscan ("+i +in +inf +infinity", "%f %f%s %f %f %s", "ExpChars", "eE");
2132 %! assert (C, {i, i, {"n"}, Inf, Inf, {"inity"}});
2133 
2134 ## Check single quoted format interprets control sequences
2135 %!test
2136 %! C = textscan ("1 2\t3 4", '%f %[^\t] %f %f');
2137 %! assert (C, {1, {"2"}, 3, 4});
2138 
2139 ## Check a non-empty line with no valid conversion registers empytValue
2140 %!test
2141 %! C = textscan ("Empty\n", "Empty%f %f");
2142 %! assert (C, { NaN, NaN });
2143 
2144 ## Check overflow and underflow of integer types
2145 %!test
2146 %! a = "-1e90 ";
2147 %! b = "1e90 ";
2148 %! fmt = "%d8 %d16 %d32 %d64 %u8 %u16 %u32 %u64 ";
2149 %! C = textscan ([a a a a a a a a b b b b b b b b], fmt);
2150 %! assert (C{1}, int8 ([-128; 127]));
2151 %! assert (C{2}, int16 ([-32768; 32767]));
2152 %! assert (C{3}, int32 ([-2147483648; 2147483647]));
2153 %! assert (C{4}, int64 ([-9223372036854775808; 9223372036854775807]));
2154 %! assert (C{5}, uint8 ([0; 255]));
2155 %! assert (C{6}, uint16 ([0; 65535]));
2156 %! assert (C{7}, uint32 ([0; 4294967295]));
2157 %! assert (C{8}, uint64 ([0; 18446744073709551615]));
2158 
2159 ## Tests from Matlab (does The MathWorks have any copyright over the input?)
2160 %!test
2161 %! f = tempname ();
2162 %! fid = fopen (f, "w+");
2163 %! fprintf (fid,"09/12/2005 Level1 12.34 45 1.23e10 inf Nan Yes 5.1+3i\n");
2164 %! fprintf (fid,"10/12/2005 Level2 23.54 60 9e19 -inf 0.001 No 2.2-.5i\n");
2165 %! fprintf (fid,"11/12/2005 Level3 34.90 12 2e5 10 100 No 3.1+.1i\n");
2166 %! fseek (fid, 0, "bof");
2167 %! C = textscan (fid,"%s %s %f32 %d8 %u %f %f %s %f");
2168 %! %assert (C{1}, {"09/12/2005";"10/12/2005";"11/12/2005"});
2169 %! assert (C{2}, {"Level1";"Level2";"Level3"});
2170 %! assert (C{3}, [single(12.34);single(23.54);single(34.90)]);
2171 %! assert (C{4}, [int8(45);int8(60);int8(12)]);
2172 %! assert (C{5}, [uint32(4294967295);uint32(4294967295);uint32(200000)]);
2173 %! assert (C{6}, [inf;-inf;10]);
2174 %! assert (C{7}, [NaN;0.001;100], eps);
2175 %! assert (C{8}, {"Yes";"No";"No"});
2176 %! assert (C{9}, [5.1+3i;2.2-0.5i;3.1+0.1i]);
2177 %! fseek (fid, 0, "bof");
2178 %! C = textscan (fid,"%s Level%d %f32 %d8 %u %f %f %s %f");
2179 %! assert (C{2}, [int32(1);int32(2);int32(3)]);
2180 %! assert (C{3}, [single(12.34);single(23.54);single(34.90)]);
2181 %! fseek (fid, 0, "bof");
2182 %! C = textscan (fid, '%s %*[^\n]');
2183 %! fclose (fid);
2184 %! unlink (f);
2185 %! assert (C, {{"09/12/2005";"10/12/2005";"11/12/2005"}});
2186 
2187 %!test
2188 %! f = tempname ();
2189 %! fid = fopen (f, "w+");
2190 %! fprintf (fid,"1, 2, 3, 4, , 6\n");
2191 %! fprintf (fid,"7, 8, 9, , 11, 12\n");
2192 %! fseek (fid, 0, "bof");
2193 %! C = textscan (fid,"%f %f %f %f %u8 %f", "Delimiter",",","EmptyValue",-Inf);
2194 %! fclose (fid);
2195 %! unlink (f);
2196 %! assert (C{4}, [4; -Inf]);
2197 %! assert (C{5}, uint8 ([0; 11]));
2198 
2199 %!test
2200 %! f = tempname ();
2201 %! fid = fopen (f, "w+");
2202 %! fprintf (fid,"abc, 2, NA, 3, 4\n");
2203 %! fprintf (fid,"// Comment Here\n");
2204 %! fprintf (fid,"def, na, 5, 6, 7\n");
2205 %! fseek (fid, 0, "bof");
2206 %! C = textscan (fid, "%s %n %n %n %n", "Delimiter", ",",
2207 %! "TreatAsEmpty", {"NA","na"}, "CommentStyle", "//");
2208 %! fclose (fid);
2209 %! unlink (f);
2210 %! assert (C{1}, {"abc";"def"});
2211 %! assert (C{2}, [2; NaN]);
2212 %! assert (C{3}, [NaN; 5]);
2213 %! assert (C{4}, [3; 6]);
2214 %! assert (C{5}, [4; 7]);
2215 
2216 ## FIXME: Almost passes. Second return value is {"/"}. Tested 4/14/16.
2217 ## Test start of comment as string
2218 %!#test
2219 %! c = textscan ("1 / 2 // 3", "%n %s %u8", "CommentStyle", {"//"});
2220 %! assert (c(1), {1, "/", 2});
2221 
2222 %!assert (textscan (["1 2 3 4"; "5 6 7 8"], "%f"), {[15; 26; 37; 48]})
2223 
2224 ## Check for delimiter after exponent
2225 %!assert (textscan ("1e-3|42", "%f", "delimiter", "|"), {[1e-3; 42]})
2226 
2227 %!test <*52479>
2228 %! str = "\t\ta\tb\tc\n";
2229 %! ret = textscan (str, "%s", "delimiter", "\t");
2230 %! assert (ret, { {''; ''; 'a'; 'b'; 'c'} });
2231 
2232 %!test <*52479>
2233 %! str = "\t\ta\tb\tc\n";
2234 %! ret = textscan (str, "%s", "delimiter", {"\t"});
2235 %! assert (ret, { {''; ''; 'a'; 'b'; 'c'} });
2236 
2237 %!test <*52550>
2238 %! str = ",,1,2,3\n";
2239 %! obs = textscan (str, "%d", "delimiter", ",");
2240 %! assert (obs, { [0; 0; 1; 2; 3] });
2241 %! obs = textscan (str, "%d", "delimiter", {","});
2242 %! assert (obs, { [0; 0; 1; 2; 3] });
2243 
2244 %!test <*52550>
2245 %! str = " , ,1,2,3\n";
2246 %! obs = textscan (str, "%d", "delimiter", ",");
2247 %! assert (obs, { [0; 0; 1; 2; 3] });
2248 %! textscan (str, "%d", "delimiter", {","});
2249 %! assert (obs, { [0; 0; 1; 2; 3] });
2250 
2251 %!test <*52550>
2252 %! str = " 0 , 5+6j , -INF+INFj ,NaN,3\n";
2253 %! obs = textscan (str, "%f", "delimiter", ",");
2254 %! assert (obs, { [0; 5+6i; complex(-Inf,Inf); NaN; 3] });
2255 %! obs = textscan (str, "%f", "delimiter", {","});
2256 %! assert (obs, { [0; 5+6i; complex(-Inf,Inf); NaN; 3] });
2257 
2258 %!test <*52550>
2259 %! str = " 0;,;,1;,2;,3\n";
2260 %! assert (textscan (str, "%f", "delimiter", {";,"}), { [0; NaN; 1; 2; 3] });
2261 
2262 %!test <*52550>
2263 %! str = " 0 ;1 , $ 2 ;3\n";
2264 %! obs = textscan (str, "%f", "delimiter", ",;$");
2265 %! assert (obs, { [0; 1; NaN; 2; 3] });
2266 %! obs = textscan (str, "%f", "delimiter", {",",";","$"});
2267 %! assert (obs, { [0; 1; NaN; 2; 3] });
2268 
2269 ## file stream with encoding
2270 %!test
2271 %! f = tempname ();
2272 %! fid = fopen (f, "w+", "n", "iso-8859-1");
2273 %! unwind_protect
2274 %! fprintf (fid, "abc,äöü\n");
2275 %! fseek (fid, 0, "bof");
2276 %! obs = textscan (fid, "%s", "delimiter", ",");
2277 %! fclose (fid);
2278 %! assert (obs, { {"abc"; "äöü"} });
2279 %! unwind_protect_cleanup
2280 %! unlink (f);
2281 %! end_unwind_protect
2282 
2283 %!test <*56917>
2284 %! str = '"a,b","c"';
2285 %! obs = textscan (str, "%q", "delimiter", ",");
2286 %! assert (obs, { { "a,b"; "c" } });
2287 
2288 */
2289 // These tests have end-comment sequences, so can't just be in a comment
2290 #if 0
2291 ## Test unfinished comment
2292 %!test
2293 %! c = textscan ("1 2 /* half comment", "%n %u8", "CommentStyle", {"/*", "*/"});
2294 %! assert (c, {1, 2});
2295 
2296 ## Test reading from a real file
2297 %!test
2298 %! f = tempname ();
2299 %! fid = fopen (f, "w+");
2300 %! d = rand (1, 4);
2301 %! fprintf (fid, " %f %f /* comment */ %f %f ", d);
2302 %! fseek (fid, 0, "bof");
2303 %! A = textscan (fid, "%f %f", "CommentStyle", {"/*", "*/"});
2304 %! E = feof (fid);
2305 %! fclose (fid);
2306 %! unlink (f);
2307 %! assert (A{1}, [d(1); d(3)], 1e-6);
2308 %! assert (A{2}, [d(2); d(4)], 1e-6);
2309 %! assert (E);
2310 #endif
2311 
2312 /*
2313 ## Test input validation
2314 %!error textscan ()
2315 %!error <file id must be> textscan (single (4))
2316 %!error <file id must be> textscan ({4})
2317 %!error <must be a string> textscan ("Hello World", 2)
2318 %!error <at most one character or>
2319 %! textscan ("Hello World", "%s", "EndOfLine", 3);
2320 %!error <'%z' is not a valid format specifier> textscan ("1.0", "%z")
2321 %!error <no valid format conversion specifiers> textscan ("1.0", "foo")
2322 */
2323 
2324 static octave_value
2325 do_fread (octave::stream& os, const octave_value& size_arg,
2326  const octave_value& prec_arg, const octave_value& skip_arg,
2327  const octave_value& arch_arg, octave_idx_type& count)
2328 {
2329  count = -1;
2330 
2331  Array<double> size = size_arg.xvector_value ("fread: invalid SIZE specified");
2332 
2333  std::string prec = prec_arg.xstring_value ("fread: PRECISION must be a string");
2334 
2335  int block_size = 1;
2336  oct_data_conv::data_type input_type;
2337  oct_data_conv::data_type output_type;
2338 
2339  try
2340  {
2341  oct_data_conv::string_to_data_type (prec, block_size,
2342  input_type, output_type);
2343  }
2344  catch (octave::execution_exception& e)
2345  {
2346  error (e, "fread: invalid PRECISION specified");
2347  }
2348 
2349  int skip = 0;
2350 
2351  try
2352  {
2353  skip = skip_arg.int_value (true);
2354  }
2355  catch (octave::execution_exception& e)
2356  {
2357  error (e, "fread: SKIP must be an integer");
2358  }
2359 
2360  std::string arch = arch_arg.xstring_value ("fread: ARCH architecture type must be a string");
2361 
2364 
2365  return os.read (size, block_size, input_type, output_type, skip,
2366  flt_fmt, count);
2367 }
2368 
2369 DEFMETHOD (fread, interp, args, ,
2370  doc: /* -*- texinfo -*-
2371 @deftypefn {} {@var{val} =} fread (@var{fid})
2372 @deftypefnx {} {@var{val} =} fread (@var{fid}, @var{size})
2373 @deftypefnx {} {@var{val} =} fread (@var{fid}, @var{size}, @var{precision})
2374 @deftypefnx {} {@var{val} =} fread (@var{fid}, @var{size}, @var{precision}, @var{skip})
2375 @deftypefnx {} {@var{val} =} fread (@var{fid}, @var{size}, @var{precision}, @var{skip}, @var{arch})
2376 @deftypefnx {} {[@var{val}, @var{count}] =} fread (@dots{})
2377 Read binary data from the file specified by the file descriptor @var{fid}.
2378 
2379 The optional argument @var{size} specifies the amount of data to read
2380 and may be one of
2381 
2382 @table @code
2383 @item Inf
2384 Read as much as possible, returning a column vector.
2385 
2386 @item @var{nr}
2387 Read up to @var{nr} elements, returning a column vector.
2388 
2389 @item [@var{nr}, Inf]
2390 Read as much as possible, returning a matrix with @var{nr} rows. If the
2391 number of elements read is not an exact multiple of @var{nr}, the last
2392 column is padded with zeros.
2393 
2394 @item [@var{nr}, @var{nc}]
2395 Read up to @code{@var{nr} * @var{nc}} elements, returning a matrix with
2396 @var{nr} rows. If the number of elements read is not an exact multiple
2397 of @var{nr}, the last column is padded with zeros.
2398 @end table
2399 
2400 @noindent
2401 If @var{size} is omitted, a value of @code{Inf} is assumed.
2402 
2403 The optional argument @var{precision} is a string specifying the type of
2404 data to read and may be one of
2405 
2406 @table @asis
2407 @item @qcode{"uint8"} (default)
2408 8-bit unsigned integer.
2409 
2410 @item @qcode{"int8"}
2411 @itemx @qcode{"integer*1"}
2412 8-bit signed integer.
2413 
2414 @item @qcode{"uint16"}
2415 @itemx @qcode{"ushort"}
2416 @itemx @qcode{"unsigned short"}
2417 16-bit unsigned integer.
2418 
2419 @item @qcode{"int16"}
2420 @itemx @qcode{"integer*2"}
2421 @itemx @qcode{"short"}
2422 16-bit signed integer.
2423 
2424 @item @qcode{"uint"}
2425 @itemx @qcode{"uint32"}
2426 @itemx @qcode{"unsigned int"}
2427 @itemx @qcode{"ulong"}
2428 @itemx @qcode{"unsigned long"}
2429 32-bit unsigned integer.
2430 
2431 @item @qcode{"int"}
2432 @itemx @qcode{"int32"}
2433 @itemx @qcode{"integer*4"}
2434 @itemx @qcode{"long"}
2435 32-bit signed integer.
2436 
2437 @item @qcode{"uint64"}
2438 64-bit unsigned integer.
2439 
2440 @item @qcode{"int64"}
2441 @itemx @qcode{"integer*8"}
2442 64-bit signed integer.
2443 
2444 @item @qcode{"single"}
2445 @itemx @qcode{"float"}
2446 @itemx @qcode{"float32"}
2447 @itemx @qcode{"real*4"}
2448 32-bit floating point number.
2449 
2450 @item @qcode{"double"}
2451 @itemx @qcode{"float64"}
2452 @itemx @qcode{"real*8"}
2453 64-bit floating point number.
2454 
2455 @item @qcode{"char"}
2456 @itemx @qcode{"char*1"}
2457 8-bit single character.
2458 
2459 @item @qcode{"uchar"}
2460 @itemx @qcode{"unsigned char"}
2461 8-bit unsigned character.
2462 
2463 @item @qcode{"schar"}
2464 @itemx @qcode{"signed char"}
2465 8-bit signed character.
2466 
2467 @end table
2468 
2469 @noindent
2470 The default precision is @qcode{"uint8"}.
2471 
2472 The @var{precision} argument may also specify an optional repeat
2473 count. For example, @samp{32*single} causes @code{fread} to read
2474 a block of 32 single precision floating point numbers. Reading in
2475 blocks is useful in combination with the @var{skip} argument.
2476 
2477 The @var{precision} argument may also specify a type conversion.
2478 For example, @samp{int16=>int32} causes @code{fread} to read 16-bit
2479 integer values and return an array of 32-bit integer values. By
2480 default, @code{fread} returns a double precision array. The special
2481 form @samp{*TYPE} is shorthand for @samp{TYPE=>TYPE}.
2482 
2483 The conversion and repeat counts may be combined. For example, the
2484 specification @samp{32*single=>single} causes @code{fread} to read
2485 blocks of single precision floating point values and return an array
2486 of single precision values instead of the default array of double
2487 precision values.
2488 
2489 The optional argument @var{skip} specifies the number of bytes to skip
2490 after each element (or block of elements) is read. If it is not
2491 specified, a value of 0 is assumed. If the final block read is not
2492 complete, the final skip is omitted. For example,
2493 
2494 @example
2495 fread (f, 10, "3*single=>single", 8)
2496 @end example
2497 
2498 @noindent
2499 will omit the final 8-byte skip because the last read will not be
2500 a complete block of 3 values.
2501 
2502 The optional argument @var{arch} is a string specifying the data format
2503 for the file. Valid values are
2504 
2505 @table @asis
2506 @item @qcode{"native"} or @qcode{"n"}
2507 The format of the current machine.
2508 
2509 @item @qcode{"ieee-be"} or @qcode{"b"}
2510 IEEE big endian.
2511 
2512 @item @qcode{"ieee-le"} or @qcode{"l"}
2513 IEEE little endian.
2514 @end table
2515 
2516 If no @var{arch} is given the value used in the call to @code{fopen} which
2517 created the file descriptor is used. Otherwise, the value specified with
2518 @code{fread} overrides that of @code{fopen} and determines the data format.
2519 
2520 The output argument @var{val} contains the data read from the file.
2521 
2522 The optional return value @var{count} contains the number of elements read.
2523 @seealso{fwrite, fgets, fgetl, fscanf, fopen}
2524 @end deftypefn */)
2525 {
2526  int nargin = args.length ();
2527 
2528  if (nargin < 1 || nargin > 5)
2529  print_usage ();
2530 
2531  octave::stream_list& streams = interp.get_stream_list ();
2532 
2533  octave::stream os = streams.lookup (args(0), "fread");
2534 
2535  octave_value size = lo_ieee_inf_value ();
2536  octave_value prec = "uint8";
2537  octave_value skip = 0;
2538  octave_value arch = "unknown";
2539 
2540  int idx = 1;
2541 
2542  if (nargin > idx && ! args(idx).is_string ())
2543  size = args(idx++);
2544 
2545  if (nargin > idx)
2546  prec = args(idx++);
2547 
2548  if (nargin > idx)
2549  skip = args(idx++);
2550 
2551  if (nargin > idx)
2552  arch = args(idx++);
2553  else if (skip.is_string ())
2554  {
2555  arch = skip;
2556  skip = 0;
2557  }
2558 
2559  octave_idx_type count = -1;
2560 
2561  octave_value tmp = do_fread (os, size, prec, skip, arch, count);
2562 
2563  return ovl (tmp, count);
2564 }
2565 
2566 static int
2568  const octave_value& prec_arg, const octave_value& skip_arg,
2569  const octave_value& arch_arg)
2570 {
2571  std::string prec = prec_arg.xstring_value ("fwrite: PRECISION must be a string");
2572 
2573  int block_size = 1;
2574  oct_data_conv::data_type output_type;
2575 
2576  try
2577  {
2578  oct_data_conv::string_to_data_type (prec, block_size, output_type);
2579  }
2580  catch (octave::execution_exception& e)
2581  {
2582  error (e, "fwrite: invalid PRECISION specified");
2583  }
2584 
2585  int skip = 0;
2586 
2587  try
2588  {
2589  skip = skip_arg.int_value (true);
2590  }
2591  catch (octave::execution_exception& e)
2592  {
2593  error (e, "fwrite: SKIP must be an integer");
2594  }
2595 
2596  std::string arch = arch_arg.xstring_value ("fwrite: ARCH architecture type must be a string");
2597 
2600 
2601  return os.write (data, block_size, output_type, skip, flt_fmt);
2602 }
2603 
2604 DEFMETHOD (fwrite, interp, args, ,
2605  doc: /* -*- texinfo -*-
2606 @deftypefn {} {} fwrite (@var{fid}, @var{data})
2607 @deftypefnx {} {} fwrite (@var{fid}, @var{data}, @var{precision})
2608 @deftypefnx {} {} fwrite (@var{fid}, @var{data}, @var{precision}, @var{skip})
2609 @deftypefnx {} {} fwrite (@var{fid}, @var{data}, @var{precision}, @var{skip}, @var{arch})
2610 @deftypefnx {} {@var{count} =} fwrite (@dots{})
2611 Write data in binary form to the file specified by the file descriptor
2612 @var{fid}, returning the number of values @var{count} successfully written
2613 to the file.
2614 
2615 The argument @var{data} is a matrix of values that are to be written to
2616 the file. The values are extracted in column-major order.
2617 
2618 The remaining arguments @var{precision}, @var{skip}, and @var{arch} are
2619 optional, and are interpreted as described for @code{fread}.
2620 
2621 The behavior of @code{fwrite} is undefined if the values in @var{data}
2622 are too large to fit in the specified precision.
2623 @seealso{fread, fputs, fprintf, fopen}
2624 @end deftypefn */)
2625 {
2626  int nargin = args.length ();
2627 
2628  if (nargin < 2 || nargin > 5)
2629  print_usage ();
2630 
2631  octave::stream_list& streams = interp.get_stream_list ();
2632 
2633  octave::stream os = streams.lookup (args(0), "fwrite");
2634 
2635  octave_value prec = "uchar";
2636  octave_value skip = 0;
2637  octave_value arch = "unknown";
2638 
2639  int idx = 1;
2640 
2641  octave_value data = args(idx++);
2642 
2643  if (nargin > idx)
2644  prec = args(idx++);
2645 
2646  if (nargin > idx)
2647  skip = args(idx++);
2648 
2649  if (nargin > idx)
2650  arch = args(idx++);
2651  else if (skip.is_string ())
2652  {
2653  arch = skip;
2654  skip = 0;
2655  }
2656 
2657  return ovl (do_fwrite (os, data, prec, skip, arch));
2658 }
2659 
2660 DEFMETHODX ("feof", Ffeof, interp, args, ,
2661  doc: /* -*- texinfo -*-
2662 @deftypefn {} {@var{status} =} feof (@var{fid})
2663 Return 1 if an end-of-file condition has been encountered for the file
2664 specified by file descriptor @var{fid} and 0 otherwise.
2665 
2666 Note that @code{feof} will only return 1 if the end of the file has already
2667 been encountered, not if the next read operation will result in an
2668 end-of-file condition.
2669 @seealso{fread, frewind, fseek, fclear, fopen}
2670 @end deftypefn */)
2671 {
2672  if (args.length () != 1)
2673  print_usage ();
2674 
2675  octave::stream_list& streams = interp.get_stream_list ();
2676 
2677  octave::stream os = streams.lookup (args(0), "feof");
2678 
2679  return ovl (os.eof () ? 1.0 : 0.0);
2680 }
2681 
2682 DEFMETHODX ("ferror", Fferror, interp, args, ,
2683  doc: /* -*- texinfo -*-
2684 @deftypefn {} {@var{msg} =} ferror (@var{fid})
2685 @deftypefnx {} {[@var{msg}, @var{err}] =} ferror (@var{fid})
2686 @deftypefnx {} {[@dots{}] =} ferror (@var{fid}, "clear")
2687 Query the error status of the stream specified by file descriptor @var{fid}.
2688 
2689 If an error condition exists then return a string @var{msg} describing the
2690 error. Otherwise, return an empty string @qcode{""}.
2691 
2692 The second input @qcode{"clear"} is optional. If supplied, the error
2693 state on the stream will be cleared.
2694 
2695 The optional second output is a numeric indication of the error status.
2696 @var{err} is 1 if an error condition has been encountered and 0 otherwise.
2697 
2698 Note that @code{ferror} indicates if an error has already occurred, not
2699 whether the next operation will result in an error condition.
2700 @seealso{fclear, fopen}
2701 @end deftypefn */)
2702 {
2703  int nargin = args.length ();
2704 
2705  if (nargin < 1 || nargin > 2)
2706  print_usage ();
2707 
2708  octave::stream_list& streams = interp.get_stream_list ();
2709 
2710  octave::stream os = streams.lookup (args(0), "ferror");
2711 
2712  bool clear = false;
2713 
2714  if (nargin == 2)
2715  {
2716  std::string opt = args(1).string_value ();
2717 
2718  clear = (opt == "clear");
2719  }
2720 
2721  int error_number = 0;
2722 
2723  std::string error_message = os.error (clear, error_number);
2724 
2725  return ovl (error_message, error_number);
2726 }
2727 
2728 DEFMETHODX ("popen", Fpopen, interp, args, ,
2729  doc: /* -*- texinfo -*-
2730 @deftypefn {} {@var{fid} =} popen (@var{command}, @var{mode})
2731 Start a process and create a pipe.
2732 
2733 The name of the command to run is given by @var{command}. The argument
2734 @var{mode} may be
2735 
2736 @table @asis
2737 @item @qcode{"r"}
2738 The pipe will be connected to the standard output of the process, and
2739 open for reading.
2740 
2741 @item @qcode{"w"}
2742 The pipe will be connected to the standard input of the process, and
2743 open for writing.
2744 @end table
2745 
2746 The file identifier corresponding to the input or output stream of the
2747 process is returned in @var{fid}.
2748 
2749 For example:
2750 
2751 @example
2752 @group
2753 fid = popen ("ls -ltr / | tail -3", "r");
2754 while (ischar (s = fgets (fid)))
2755  fputs (stdout, s);
2756 endwhile
2757 
2758  @print{} drwxr-xr-x 33 root root 3072 Feb 15 13:28 etc
2759  @print{} drwxr-xr-x 3 root root 1024 Feb 15 13:28 lib
2760  @print{} drwxrwxrwt 15 root root 2048 Feb 17 14:53 tmp
2761 @end group
2762 @end example
2763 @seealso{popen2}
2764 @end deftypefn */)
2765 {
2766  if (args.length () != 2)
2767  print_usage ();
2768 
2769  std::string name = args(0).xstring_value ("popen: COMMAND must be a string");
2770  std::string mode = args(1).xstring_value ("popen: MODE must be a string");
2771 
2773 
2774  octave::stream_list& streams = interp.get_stream_list ();
2775 
2776  if (mode == "r")
2777  {
2779 
2780  retval = streams.insert (ips);
2781  }
2782  else if (mode == "w")
2783  {
2785 
2786  retval = streams.insert (ops);
2787  }
2788  else
2789  error ("popen: invalid MODE specified");
2790 
2791  return retval;
2792 }
2793 
2794 DEFMETHODX ("pclose", Fpclose, interp, args, ,
2795  doc: /* -*- texinfo -*-
2796 @deftypefn {} {} pclose (@var{fid})
2797 Close a file identifier that was opened by @code{popen}.
2798 
2799 The function @code{fclose} may also be used for the same purpose.
2800 @seealso{fclose, popen}
2801 @end deftypefn */)
2802 {
2803  if (args.length () != 1)
2804  print_usage ();
2805 
2806  octave::stream_list& streams = interp.get_stream_list ();
2807 
2808  return ovl (streams.remove (args(0), "pclose"));
2809 }
2810 
2811 DEFUN (tempname, args, ,
2812  doc: /* -*- texinfo -*-
2813 @deftypefn {} {@var{fname} =} tempname ()
2814 @deftypefnx {} {@var{fname} =} tempname (@var{dir})
2815 @deftypefnx {} {@var{fname} =} tempname (@var{dir}, @var{prefix})
2816 Return a unique temporary filename as a string.
2817 
2818 If @var{prefix} is omitted, a value of @qcode{"oct-"} is used.
2819 
2820 If @var{dir} is also omitted, the default directory for temporary files
2821 (@code{P_tmpdir}) is used. If @var{dir} is provided, it must exist,
2822 otherwise the default directory for temporary files is used.
2823 
2824 Programming Note: Because the named file is not opened by @code{tempname},
2825 it is possible, though relatively unlikely, that it will not be available
2826 by the time your program attempts to open it. If this is a concern,
2827 see @code{tmpfile}.
2828 @seealso{mkstemp, tempdir, P_tmpdir, tmpfile}
2829 @end deftypefn */)
2830 {
2831  int nargin = args.length ();
2832 
2833  if (nargin > 2)
2834  print_usage ();
2835 
2836  std::string dir;
2837 
2838  if (nargin > 0)
2839  dir = args(0).xstring_value ("tempname: DIR must be a string");
2840  else
2841  dir = octave::sys::env::getenv ("TMPDIR");
2842 
2843  std::string pfx ("oct-");
2844 
2845  if (nargin > 1)
2846  pfx = args(1).xstring_value ("tempname: PREFIX must be a string");
2847 
2848  return ovl (octave::sys::tempnam (dir, pfx));
2849 }
2850 
2851 /*
2852 %!test
2853 %! envvar = {"TMPDIR", "TMP"};
2854 %! envdir = cellfun (@(x) getenv (x), envvar, "uniformoutput", false);
2855 %! unwind_protect
2856 %! cellfun (@(x) unsetenv (x), envvar);
2857 %! envname = "TMPDIR";
2858 %! def_tmpdir = P_tmpdir;
2859 %! ## Strip trailing file separators from P_tmpdir
2860 %! while (length (def_tmpdir) > 2 && any (def_tmpdir(end) == filesep ("all")))
2861 %! def_tmpdir(end) = [];
2862 %! endwhile
2863 %!
2864 %! ## Test 0-argument form
2865 %! fname = tempname ();
2866 %! [tmpdir, tmpfname] = fileparts (fname);
2867 %! assert (tmpdir, def_tmpdir);
2868 %! assert (tmpfname (1:4), "oct-");
2869 %! ## Test 1-argument form
2870 %! tmp_tmpdir = [def_tmpdir filesep() substr(tmpfname, -5)];
2871 %! mkdir (tmp_tmpdir) || error ("Unable to create tmp dir");
2872 %! setenv (envname, def_tmpdir);
2873 %! fname = tempname (tmp_tmpdir);
2874 %! [tmpdir, tmpfname] = fileparts (fname);
2875 %! assert (tmpdir, tmp_tmpdir);
2876 %! assert (tmpfname (1:4), "oct-");
2877 %! ## Test 1-argument form w/null tmpdir
2878 %! fname = tempname ("");
2879 %! [tmpdir, tmpfname] = fileparts (fname);
2880 %! assert (tmpdir, def_tmpdir);
2881 %! assert (tmpfname (1:4), "oct-");
2882 %! ## Test 2-argument form
2883 %! fname = tempname (tmp_tmpdir, "pfx-");
2884 %! [tmpdir, tmpfname] = fileparts (fname);
2885 %! assert (tmpdir, tmp_tmpdir);
2886 %! assert (tmpfname (1:4), "pfx-");
2887 %! ## Test 2-argument form w/null prefix
2888 %! fname = tempname (tmp_tmpdir, "");
2889 %! [tmpdir, tmpfname] = fileparts (fname);
2890 %! assert (tmpdir, tmp_tmpdir);
2891 %! assert (tmpfname (1:4), "file");
2892 %! unwind_protect_cleanup
2893 %! rmdir (tmp_tmpdir);
2894 %! for i = 1:numel (envvar)
2895 %! if (isempty (envdir{i}))
2896 %! unsetenv (envvar{i});
2897 %! else
2898 %! setenv (envvar{i}, envdir{i});
2899 %! endif
2900 %! endfor
2901 %! end_unwind_protect
2902 */
2903 
2904 DEFMETHOD (tmpfile, interp, args, ,
2905  doc: /* -*- texinfo -*-
2906 @deftypefn {} {[@var{fid}, @var{msg}] =} tmpfile ()
2907 Return the file ID corresponding to a new temporary file with a unique
2908 name.
2909 
2910 The file is opened in binary read/write (@qcode{"w+b"}) mode and will be
2911 deleted automatically when it is closed or when Octave exits.
2912 
2913 If successful, @var{fid} is a valid file ID and @var{msg} is an empty
2914 string. Otherwise, @var{fid} is -1 and @var{msg} contains a
2915 system-dependent error message.
2916 @seealso{tempname, mkstemp, tempdir, P_tmpdir}
2917 @end deftypefn */)
2918 {
2919  if (args.length () != 0)
2920  print_usage ();
2921 
2923 
2924  FILE *fid = octave_tmpfile_wrapper ();
2925 
2926  if (fid)
2927  {
2928  std::string nm;
2929 
2930  std::ios::openmode md = fopen_mode_to_ios_mode ("w+b");
2931 
2932  octave::stream s = octave_stdiostream::create (nm, fid, md);
2933 
2934  if (! s)
2935  {
2936  fclose (fid);
2937 
2938  error ("tmpfile: failed to create octave_stdiostream object");
2939  }
2940 
2941  octave::stream_list& streams = interp.get_stream_list ();
2942 
2943  retval = ovl (streams.insert (s), "");
2944  }
2945  else
2946  retval = ovl (-1, std::strerror (errno));
2947 
2948  return retval;
2949 }
2950 
2951 DEFMETHOD (mkstemp, interp, args, ,
2952  doc: /* -*- texinfo -*-
2953 @deftypefn {} {[@var{fid}, @var{name}, @var{msg}] =} mkstemp ("@var{template}")
2954 @deftypefnx {} {[@var{fid}, @var{name}, @var{msg}] =} mkstemp ("@var{template}", @var{delete})
2955 Return the file descriptor @var{fid} corresponding to a new temporary file
2956 with a unique name created from @var{template}.
2957 
2958 The last six characters of @var{template} must be @qcode{"XXXXXX"} and
2959 these are replaced with a string that makes the filename unique. The file
2960 is then created with mode read/write and permissions that are system
2961 dependent (on GNU/Linux systems, the permissions will be 0600 for versions
2962 of glibc 2.0.7 and later). The file is opened in binary mode and with the
2963 @w{@code{O_EXCL}} flag.
2964 
2965 If the optional argument @var{delete} is supplied and is true, the file will
2966 be deleted automatically when Octave exits.
2967 
2968 If successful, @var{fid} is a valid file ID, @var{name} is the name of the
2969 file, and @var{msg} is an empty string. Otherwise, @var{fid} is -1,
2970 @var{name} is empty, and @var{msg} contains a system-dependent error
2971 message.
2972 @seealso{tempname, tempdir, P_tmpdir, tmpfile, fopen}
2973 @end deftypefn */)
2974 {
2975  int nargin = args.length ();
2976 
2977  if (nargin < 1 || nargin > 2)
2978  print_usage ();
2979 
2980  std::string tmpl8 = args(0).xstring_value ("mkstemp: TEMPLATE argument must be a string");
2981 
2982  octave_value_list retval = ovl (-1, "", "");
2983 
2984  OCTAVE_LOCAL_BUFFER (char, tmp, tmpl8.size () + 1);
2985  strcpy (tmp, tmpl8.c_str ());
2986 
2987  int fd = octave_mkostemp_wrapper (tmp);
2988 
2989  if (fd < 0)
2990  {
2991  retval(0) = fd;
2992  retval(2) = std::strerror (errno);
2993  }
2994  else
2995  {
2996  const char *fopen_mode = "w+b";
2997 
2998  FILE *fid = fdopen (fd, fopen_mode);
2999 
3000  if (! fid)
3001  {
3002  retval(0) = -1;
3003  retval(2) = std::strerror (errno);
3004  }
3005  else
3006  {
3007  std::string nm = tmp;
3008 
3009  std::ios::openmode md = fopen_mode_to_ios_mode (fopen_mode);
3010 
3011  octave::stream s = octave_stdiostream::create (nm, fid, md);
3012 
3013  if (! s)
3014  error ("mkstemp: failed to create octave_stdiostream object");
3015 
3016  octave::stream_list& streams = interp.get_stream_list ();
3017 
3018  retval(0) = streams.insert (s);
3019  retval(1) = nm;
3020 
3021  if (nargin == 2 && args(1).is_true ())
3022  interp.mark_for_deletion (nm);
3023  }
3024  }
3025 
3026  return retval;
3027 }
3028 
3029 // FIXME: This routine also exists verbatim in syscalls.cc.
3030 // Maybe change to be a general utility routine.
3031 static int
3032 convert (int x, int ibase, int obase)
3033 {
3034  int retval = 0;
3035 
3036  int tmp = x % obase;
3037 
3038  if (tmp > ibase - 1)
3039  error ("umask: invalid digit");
3040 
3041  retval = tmp;
3042  int mult = ibase;
3043  while ((x = (x - tmp) / obase))
3044  {
3045  tmp = x % obase;
3046 
3047  if (tmp > ibase - 1)
3048  error ("umask: invalid digit");
3049 
3050  retval += mult * tmp;
3051  mult *= ibase;
3052  }
3053 
3054  return retval;
3055 }
3056 
3057 DEFUNX ("umask", Fumask, args, ,
3058  doc: /* -*- texinfo -*-
3059 @deftypefn {} {} umask (@var{mask})
3060 Set the permission mask for file creation.
3061 
3062 The parameter @var{mask} is an integer, interpreted as an octal number.
3063 
3064 If successful, returns the previous value of the mask (as an integer to be
3065 interpreted as an octal number); otherwise an error message is printed.
3066 
3067 The permission mask is a UNIX concept used when creating new objects on a
3068 file system such as files, directories, or named FIFOs. The object to be
3069 created has base permissions in an octal number @var{mode} which are
3070 modified according to the octal value of @var{mask}. The final permissions
3071 for the new object are @code{@var{mode} - @var{mask}}.
3072 @seealso{fopen, mkdir, mkfifo}
3073 @end deftypefn */)
3074 {
3075  if (args.length () != 1)
3076  print_usage ();
3077 
3078  int mask = args(0).xint_value ("umask: MASK must be an integer");
3079 
3080  if (mask < 0)
3081  error ("umask: MASK must be a positive integer value");
3082 
3083  int oct_mask = convert (mask, 8, 10);
3084 
3085  int status = convert (octave::sys::umask (oct_mask), 10, 8);
3086 
3087  if (status >= 0)
3088  return ovl (status);
3089  else
3090  return ovl ();
3091 }
3092 
3093 static octave_value
3094 const_value (const char *, const octave_value_list& args, int val)
3095 {
3096  if (args.length () != 0)
3097  print_usage ();
3098 
3099  return octave_value (val);
3100 }
3101 
3102 DEFUNX ("P_tmpdir", FP_tmpdir, args, ,
3103  doc: /* -*- texinfo -*-
3104 @deftypefn {} {} P_tmpdir ()
3105 Return the name of the host system's @strong{default} directory for
3106 temporary files.
3107 
3108 Programming Note: The value returned by @code{P_tmpdir} is always the
3109 default location. This value may not agree with that returned from
3110 @code{tempdir} if the user has overridden the default with the @env{TMPDIR}
3111 environment variable.
3112 @seealso{tempdir, tempname, mkstemp, tmpfile}
3113 @end deftypefn */)
3114 {
3115  if (args.length () != 0)
3116  print_usage ();
3117 
3118  return ovl (octave::get_P_tmpdir ());
3119 }
3120 
3121 // NOTE: the values of SEEK_SET, SEEK_CUR, and SEEK_END have to be
3122 // this way for Matlab compatibility.
3123 
3124 DEFUNX ("SEEK_SET", FSEEK_SET, args, ,
3125  doc: /* -*- texinfo -*-
3126 @deftypefn {} {} SEEK_SET ()
3127 Return the numerical value to pass to @code{fseek} to position the file pointer
3128 relative to the beginning of the file.
3129 @seealso{SEEK_CUR, SEEK_END, fseek}
3130 @end deftypefn */)
3131 {
3132  return const_value ("SEEK_SET", args, -1);
3133 }
3134 
3135 DEFUNX ("SEEK_CUR", FSEEK_CUR, args, ,
3136  doc: /* -*- texinfo -*-
3137 @deftypefn {} {} SEEK_CUR ()
3138 Return the numerical value to pass to @code{fseek} to position the file pointer
3139 relative to the current position.
3140 @seealso{SEEK_SET, SEEK_END, fseek}
3141 @end deftypefn */)
3142 {
3143  return const_value ("SEEK_CUR", args, 0);
3144 }
3145 
3146 DEFUNX ("SEEK_END", FSEEK_END, args, ,
3147  doc: /* -*- texinfo -*-
3148 @deftypefn {} {} SEEK_END ()
3149 Return the numerical value to pass to @code{fseek} to position the file pointer
3150 relative to the end of the file.
3151 @seealso{SEEK_SET, SEEK_CUR, fseek}
3152 @end deftypefn */)
3153 {
3154  return const_value ("SEEK_END", args, 1);
3155 }
3156 
3157 static octave_value
3158 const_value (const char *, const octave_value_list& args,
3159  const octave_value& val)
3160 {
3161  if (args.length () != 0)
3162  print_usage ();
3163 
3164  return octave_value (val);
3165 }
3166 
3167 DEFMETHODX ("stdin", Fstdin, interp, args, ,
3168  doc: /* -*- texinfo -*-
3169 @deftypefn {} {} stdin ()
3170 Return the numeric value corresponding to the standard input stream.
3171 
3172 When Octave is used interactively, stdin is filtered through the command
3173 line editing functions.
3174 @seealso{stdout, stderr}
3175 @end deftypefn */)
3176 {
3177  octave::stream_list& streams = interp.get_stream_list ();
3178 
3179  return const_value ("stdin", args, streams.stdin_file ());
3180 }
3181 
3182 DEFMETHODX ("stdout", Fstdout, interp, args, ,
3183  doc: /* -*- texinfo -*-
3184 @deftypefn {} {} stdout ()
3185 Return the numeric value corresponding to the standard output stream.
3186 
3187 Data written to the standard output may be filtered through the pager.
3188 @seealso{stdin, stderr, page_screen_output}
3189 @end deftypefn */)
3190 {
3191  octave::stream_list& streams = interp.get_stream_list ();
3192 
3193  return const_value ("stdout", args, streams.stdout_file ());
3194 }
3195 
3196 DEFMETHODX ("stderr", Fstderr, interp, args, ,
3197  doc: /* -*- texinfo -*-
3198 @deftypefn {} {} stderr ()
3199 Return the numeric value corresponding to the standard error stream.
3200 
3201 Even if paging is turned on, the standard error is not sent to the pager.
3202 It is useful for error messages and prompts.
3203 @seealso{stdin, stdout}
3204 @end deftypefn */)
3205 {
3206  octave::stream_list& streams = interp.get_stream_list ();
3207 
3208  return const_value ("stderr", args, streams.stderr_file ());
3209 }
3210 
3211 // Deprecated variables and functions.
3212 
3213 // Deprecated in Octave 6.
3214 void
3215 mark_for_deletion (const std::string& file)
3216 {
3217  octave::interpreter& interp
3218  = octave::__get_interpreter__ ("mark_for_deletion");
3219 
3220  interp.mark_for_deletion (file);
3221 }
3222 
3223 // Deprecated in Octave 6.
3224 void
3226 {
3227  octave::interpreter& interp
3228  = octave::__get_interpreter__ ("cleanup_tmp_files");
3229 
3230  interp.cleanup_tmp_files ();
3231 }
template class OCTAVE_API Array< double >
Definition: Array-d.cc:168
Vector representing the dimensions (size) of an Array.
Definition: dim-vector.h:95
static data_type string_to_data_type(const std::string &s)
Definition: data-conv.cc:293
octave_value mfile_encoding(const octave_value_list &args, int nargout)
void cleanup_tmp_files(void)
stream_list & get_stream_list(void)
void mark_for_deletion(const std::string &file)
int remove(int fid, const std::string &who="")
Definition: oct-stream.cc:7458
std::string list_open_files(void) const
Definition: oct-stream.cc:7590
octave_value stdin_file(void) const
Definition: oct-stream.cc:7680
int get_file_number(const octave_value &fid) const
Definition: oct-stream.cc:7640
int insert(stream &os)
Definition: oct-stream.cc:7387
octave_value stderr_file(void) const
Definition: oct-stream.cc:7690
octave_value open_file_numbers(void) const
Definition: oct-stream.cc:7622
stream lookup(int fid, const std::string &who="") const
Definition: oct-stream.cc:7427
octave_value stdout_file(void) const
Definition: oct-stream.cc:7685
string_vector get_info(int fid) const
Definition: oct-stream.cc:7543
bool eof(void) const
Definition: oct-stream.cc:7267
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, mach_info::float_format flt_fmt, octave_idx_type &count)
Definition: oct-stream.cc:6580
int puts(const std::string &s, const std::string &who)
Definition: oct-stream.cc:7235
octave_idx_type write(const octave_value &data, octave_idx_type block_size, oct_data_conv::data_type output_type, octave_idx_type skip, mach_info::float_format flt_fmt)
Definition: oct-stream.cc:6777
octave_value scanf(const std::string &fmt, const Array< double > &size, octave_idx_type &count, const std::string &who)
Definition: oct-stream.cc:7119
off_t skipl(off_t count, bool &err, const std::string &who)
Definition: oct-stream.cc:6151
octave_value textscan(const std::string &fmt, octave_idx_type ntimes, const octave_value_list &options, const std::string &who, octave_idx_type &count)
Definition: oct-stream.cc:7189
int flush(void)
Definition: oct-stream.cc:6070
void clearerr(void)
Definition: oct-stream.h:390
std::string gets(octave_idx_type max_len, bool &err, const std::string &who)
Definition: oct-stream.cc:6116
std::string getl(octave_idx_type max_len, bool &err, const std::string &who)
Definition: oct-stream.cc:6081
int seek(off_t offset, int origin)
Definition: oct-stream.cc:6192
int rewind(void)
Definition: oct-stream.cc:6320
octave_value_list oscanf(const std::string &fmt, const std::string &who)
Definition: oct-stream.cc:7155
int printf(const std::string &fmt, const octave_value_list &args, const std::string &who)
Definition: oct-stream.cc:7199
bool is_valid(void) const
Definition: oct-stream.h:361
off_t tell(void)
Definition: oct-stream.cc:6309
std::string error(bool clear, int &err_num)
Definition: oct-stream.cc:7278
bool is_dir(void) const
Definition: file-stat.cc:65
static std::string getenv(const std::string &name)
Definition: oct-env.cc:271
static octave::stream create(const std::string &n, std::ios::openmode arg_md=std::ios::in, octave::mach_info::float_format flt_fmt=octave::mach_info::native_float_format(), const std::string &encoding="utf-8")
Definition: oct-prcstrm.cc:36
static octave::stream create(const char *data, std::ios::openmode arg_md=std::ios::out, octave::mach_info::float_format ff=octave::mach_info::native_float_format(), const std::string &encoding="utf-8")
Definition: oct-strstrm.cc:55
static octave::stream create(const std::string &n, std::ios::openmode arg_md=std::ios::out, octave::mach_info::float_format flt_fmt=octave::mach_info::native_float_format(), const std::string &encoding="utf-8")
Definition: oct-prcstrm.cc:57
std::string str(void)
Definition: oct-strstrm.h:183
static octave::stream create(const std::string &n, FILE *f=nullptr, std::ios::openmode m=std::ios::in|std::ios::out, octave::mach_info::float_format ff=octave::mach_info::native_float_format(), const std::string &encoding="utf-8", c_file_ptr_buf::close_fcn cf=c_file_ptr_buf::file_close)
Definition: oct-stdstrm.h:139
void resize(octave_idx_type n, const octave_value &rfv=octave_value())
Definition: ovl.h:117
octave_idx_type length(void) const
Definition: ovl.h:113
octave_value_list splice(octave_idx_type offset, octave_idx_type len, const octave_value_list &lst=octave_value_list()) const
Definition: ovl.cc:139
octave_value_list & prepend(const octave_value &val)
Definition: ovl.cc:80
int int_value(bool req_int=false, bool frc_str_conv=false) const
Definition: ov.h:765
octave_idx_type numel(void) const
Definition: ov.h:518
bool is_string(void) const
Definition: ov.h:593
octave_value reshape(const dim_vector &dv) const
Definition: ov.h:530
std::string string_value(bool force=false) const
Definition: ov.h:927
std::string xstring_value(const char *fmt,...) const
bool is_sq_string(void) const
Definition: ov.h:596
Array< double > xvector_value(const char *fmt,...) const
static octave::stream create(const std::string &n, gzFile f=nullptr, int fid=0, std::ios::openmode m=std::ios::in|std::ios::out, octave::mach_info::float_format ff=octave::mach_info::native_float_format(), const std::string &encoding="utf-8", c_zfile_ptr_buf::close_fcn cf=c_zfile_ptr_buf::file_close)
Definition: oct-stdstrm.h:179
OCTINTERP_API void print_usage(void)
Definition: defun.cc:53
#define DEFMETHOD(name, interp_name, args_name, nargout_name, doc)
Macro to define a builtin method.
Definition: defun.h:138
#define DEFUN(name, args_name, nargout_name, doc)
Macro to define a builtin function.
Definition: defun.h:56
#define DEFUNX(name, fname, args_name, nargout_name, doc)
Macro to define a builtin function with certain internal name.
Definition: defun.h:85
void warning(const char *fmt,...)
Definition: error.cc:1050
void error(const char *fmt,...)
Definition: error.cc:968
void err_disabled_feature(const std::string &fcn, const std::string &feature, const std::string &pkg)
Definition: errwarn.cc:53
void mark_for_deletion(const std::string &file)
Definition: file-io.cc:3215
static octave_value_list textscan_internal(octave::interpreter &interp, const std::string &who, const octave_value_list &args)
Definition: file-io.cc:1181
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:2567
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:2325
static octave::stream do_stream_open(const std::string &name, const std::string &mode_arg, const std::string &arch, std::string encoding, int &fid)
Definition: file-io.cc:388
OCTAVE_EXPORT octave_value_list Fstdout(octave::interpreter &interp, const octave_value_list &args, int)
Definition: file-io.cc:3189
OCTAVE_EXPORT octave_value_list FSEEK_CUR(const octave_value_list &args, int)
Definition: file-io.cc:3141
OCTAVE_EXPORT octave_value_list FSEEK_SET(const octave_value_list &args, int)
Definition: file-io.cc:3130
OCTAVE_EXPORT octave_value_list FSEEK_END(const octave_value_list &args, int)
Definition: file-io.cc:3152
OCTAVE_EXPORT octave_value_list Ffeof(octave::interpreter &interp, const octave_value_list &args, int)
Definition: file-io.cc:2670
OCTAVE_EXPORT octave_value_list Fpclose(octave::interpreter &interp, const octave_value_list &args, int)
Definition: file-io.cc:2801
static std::string get_scan_string_data(const octave_value &val, const std::string &who)
Definition: file-io.cc:1082
static octave_value_list puts_internal(octave::interpreter &interp, const std::string &who, const octave_value_list &args)
Definition: file-io.cc:872
OCTAVE_EXPORT octave_value_list Fstdin(octave::interpreter &interp, const octave_value_list &args, int)
Definition: file-io.cc:3175
static void normalize_fopen_mode(std::string &mode, bool &use_zlib)
Definition: file-io.cc:88
OCTAVE_EXPORT octave_value_list Fstderr(octave::interpreter &interp, const octave_value_list &args, int)
Definition: file-io.cc:3204
void cleanup_tmp_files(void)
Definition: file-io.cc:3225
static octave_value const_value(const char *, const octave_value_list &args, int val)
Definition: file-io.cc:3094
OCTAVE_EXPORT octave_value_list Fferror(octave::interpreter &interp, const octave_value_list &args, int)
Definition: file-io.cc:2701
static octave_value_list scanf_internal(octave::interpreter &interp, const std::string &who, const octave_value_list &args)
Definition: file-io.cc:988
OCTAVE_EXPORT octave_value_list FP_tmpdir(const octave_value_list &args, int)
Definition: file-io.cc:3113
OCTAVE_EXPORT octave_value_list Fumask(const octave_value_list &args, int)
Definition: file-io.cc:3073
OCTAVE_EXPORT octave_value_list Fpopen(octave::interpreter &interp, const octave_value_list &args, int)
Definition: file-io.cc:2764
static int convert(int x, int ibase, int obase)
Definition: file-io.cc:3032
static std::ios::openmode fopen_mode_to_ios_mode(const std::string &mode)
Definition: file-io.cc:140
static octave_value_list printf_internal(octave::interpreter &interp, const std::string &who, const octave_value_list &args, int nargout)
Definition: file-io.cc:777
ColumnVector transform(const Matrix &m, double x, double y, double z)
Definition: graphics.cc:5814
QString name
iconv_t octave_iconv_open_wrapper(const char *tocode, const char *fromcode)
int octave_iconv_close_wrapper(iconv_t cd)
double lo_ieee_inf_value(void)
Definition: lo-ieee.cc:78
F77_RET_T const F77_INT F77_CMPLX * A
F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE * d
F77_RET_T const F77_DBLE * x
F77_RET_T const F77_DBLE const F77_DBLE * f
const char * octave_locale_charset_wrapper(void)
bool is_true(const std::string &s)
int octave_mkostemp_wrapper(char *tmpl)
float_format string_to_float_format(const std::string &s)
Definition: mach-info.cc:86
std::complex< T > trunc(const std::complex< T > &x)
Definition: lo-mappers.h:111
FloatComplex(* fptr)(const FloatComplex &, float, int, octave_idx_type &)
Definition: lo-specfun.cc:1128
std::string tilde_expand(const std::string &name)
Definition: file-ops.cc:286
std::string tempnam(const std::string &dir, const std::string &pfx)
Definition: file-ops.cc:646
std::FILE * fopen(const std::string &filename, const std::string &mode)
Definition: lo-sysdep.cc:295
int umask(mode_t mode)
Definition: file-ops.cc:621
int unlink(const std::string &name)
Definition: file-ops.cc:626
void flush_stdout(void)
Definition: pager.cc:260
interpreter & __get_interpreter__(const std::string &who)
std::string do_string_escapes(const std::string &s)
Definition: utils.cc:654
std::string get_P_tmpdir(void)
Definition: sysdep.cc:698
std::string find_data_file_in_load_path(const std::string &fcn, const std::string &file, bool require_regular_file)
Definition: utils.cc:553
#define OCTAVE_LOCAL_BUFFER(T, buf, size)
Definition: oct-locbuf.h:44
return octave_value(v1.char_array_value() . concat(v2.char_array_value(), ra_idx),((a1.is_sq_string()||a2.is_sq_string()) ? '\'' :'"'))
octave_value::octave_value(const Array< char > &chm, char type) return retval
Definition: ov.cc:811
octave_value_list ovl(const OV_Args &... args)
Construct an octave_value_list with less typing.
Definition: ovl.h:211
#define octave_stdout
Definition: pager.h:313
DEFMETHODX("quad", Fquad, interp, args,, doc:)
Definition: quad.cc:130
FILE * octave_tmpfile_wrapper(void)