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