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