GNU Octave 11.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 
Loading...
Searching...
No Matches
load-save.cc
Go to the documentation of this file.
1////////////////////////////////////////////////////////////////////////
2//
3// Copyright (C) 1994-2026 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#if defined (HAVE_CONFIG_H)
27# include "config.h"
28#endif
29
30#include <cstring>
31
32#include <fstream>
33#include <iomanip>
34#include <iostream>
35#include <list>
36#include <sstream>
37#include <string>
38
39#include "byte-swap.h"
40#include "dMatrix.h"
41#include "data-conv.h"
42#include "file-ops.h"
43#include "file-stat.h"
44#include "glob-match.h"
45#include "mach-info.h"
46#include "mappers.h"
47#include "oct-env.h"
48#include "oct-locbuf.h"
49#include "oct-sysdep.h"
50#include "oct-time.h"
51#include "quit.h"
52#include "str-vec.h"
53#include "strftime-wrapper.h"
54
55#include "Cell.h"
56#include "defun.h"
57#include "error.h"
58#include "errwarn.h"
59#include "interpreter.h"
60#include "interpreter-private.h"
61#include "load-path.h"
62#include "load-save.h"
63#include "oct-hdf5.h"
64#include "ovl.h"
65#include "oct-map.h"
66#include "ov-cell.h"
67#include "pager.h"
68#include "syminfo.h"
69#include "sysdep.h"
70#include "unwind-prot.h"
71#include "utils.h"
72#include "variables.h"
73#include "version.h"
74
75#include "ls-hdf5.h"
76#include "ls-mat-ascii.h"
77#include "ls-mat4.h"
78#include "ls-mat5.h"
79#include "ls-oct-text.h"
80#include "ls-oct-binary.h"
81#include "ls-mat-subsys.h"
82
83// Remove gnulib definitions, if any.
84#if defined (close)
85# undef close
86#endif
87#if defined (open)
88# undef open
89#endif
90
91#if defined (HAVE_ZLIB)
92# include "gzfstream.h"
93#endif
94
96
97OCTAVE_NORETURN static
98void
99err_file_open (const std::string& fcn, const std::string& file)
100{
101 if (fcn == "load")
102 error ("%s: unable to open input file '%s'", fcn.c_str (), file.c_str ());
103 else if (fcn == "save")
104 error ("%s: unable to open output file '%s'", fcn.c_str (), file.c_str ());
105 else
106 error ("%s: unable to open file '%s'", fcn.c_str (), file.c_str ());
107}
108
109// Return TRUE if NAME matches one of the given globbing PATTERNS.
110
111static bool
112matches_patterns (const string_vector& patterns, int pat_idx,
113 int num_pat, const std::string& name)
114{
115 for (int i = pat_idx; i < num_pat; i++)
116 {
117 symbol_match pattern (patterns[i]);
118
119 if (pattern.match (name))
120 return true;
121 }
122
123 return false;
124}
125
126static int
127read_binary_file_header (std::istream& is, bool& swap,
128 mach_info::float_format& flt_fmt,
129 bool quiet = false)
130{
131 const int magic_len = 10;
132 char magic[magic_len+1];
133 is.read (magic, magic_len);
134 magic[magic_len] = '\0';
135
136 if (strncmp (magic, "Octave-1-L", magic_len) == 0)
137 swap = mach_info::words_big_endian ();
138 else if (strncmp (magic, "Octave-1-B", magic_len) == 0)
139 swap = ! mach_info::words_big_endian ();
140 else
141 {
142 if (! quiet)
143 error ("load: unable to read binary file");
144
145 return -1;
146 }
147
148 char tmp = 0;
149 is.read (&tmp, 1);
150
151 flt_fmt = mopt_digit_to_float_format (tmp);
152
153 if (flt_fmt == mach_info::flt_fmt_unknown)
154 {
155 if (! quiet)
156 error ("load: unrecognized binary format!");
157
158 return -1;
159 }
160
161 return 0;
162}
163
164#if defined (HAVE_ZLIB)
165static bool
166check_gzip_magic (const std::string& fname)
167{
168 bool retval = false;
169
170 std::ifstream file = sys::ifstream (fname.c_str (),
171 std::ios::in | std::ios::binary);
172
173 unsigned char magic[2];
174 if (file.read (reinterpret_cast<char *> (&magic[0]), 2)
175 && magic[0] == 0x1f && magic[1] == 0x8b)
176 retval = true;
177
178 file.close ();
179
180 return retval;
181}
182#endif
183
184static std::string
185find_file_to_load (const std::string& name, const std::string& orig_name)
186{
187 std::string fname = find_data_file_in_load_path ("load", name, true);
188
189 std::size_t dot_pos = fname.rfind ('.');
190 std::size_t sep_pos = fname.find_last_of (sys::file_ops::dir_sep_chars ());
191
192 if (dot_pos == std::string::npos
193 || (sep_pos != std::string::npos && dot_pos < sep_pos))
194 {
195 // Either no '.' in name or no '.' appears after last directory
196 // separator.
197
198 if (! (sys::file_exists (fname, false)))
199 fname = find_file_to_load (fname + ".mat", orig_name);
200 }
201 else
202 {
203 if (! (sys::file_exists (fname, false)))
204 {
205 fname = "";
206
207 error ("load: unable to find file %s", orig_name.c_str ());
208 }
209 }
210
211 return fname;
212}
213
214// Return TRUE if PATTERN has any special globbing chars in it.
215
216static bool
217glob_pattern_p (const std::string& pattern)
218{
219 int open = 0;
220
221 int len = pattern.length ();
222
223 for (int i = 0; i < len; i++)
224 {
225 char c = pattern[i];
226
227 switch (c)
228 {
229 case '?':
230 case '*':
231 return true;
232
233 case '[': // Only accept an open brace if there is a close
234 open++; // brace to match it. Bracket expressions must be
235 continue; // complete, according to Posix.2
236
237 case ']':
238 if (open)
239 return true;
240 continue;
241
242 case '\\':
243 if (i == len - 1)
244 return false;
245 continue;
246
247 default:
248 continue;
249 }
250 }
251
252 return false;
253}
254
256 : m_interpreter (interp),
257 m_crash_dumps_octave_core (true),
258 m_octave_core_file_limit (-1.0),
259 m_octave_core_file_name ("octave-workspace"),
260 m_save_default_options ("-text"),
261 m_octave_core_file_options ("-binary"),
262 m_save_header_format_string (init_save_header_format ())
263{
264#if defined (HAVE_HDF5)
265 H5dont_atexit ();
266#endif
267}
268
270{
271#if defined (HAVE_HDF5)
272 H5close ();
273#endif
274}
275
278 int nargout)
279{
280 return set_internal_variable (m_crash_dumps_octave_core, args, nargout,
281 "crash_dumps_octave_core");
282}
283
286 int nargout)
287{
288 return set_internal_variable (m_octave_core_file_limit, args, nargout,
289 "octave_core_file_limit");
290}
291
294 int nargout)
295{
296 return set_internal_variable (m_octave_core_file_name, args, nargout,
297 "octave_core_file_name", false);
298}
299
302 int nargout)
303{
304 return set_internal_variable (m_save_default_options, args, nargout,
305 "save_default_options", false);
306}
307
310 int nargout)
311{
312 return set_internal_variable (m_octave_core_file_options, args, nargout,
313 "octave_core_file_options", false);
314}
315
318 int nargout)
319{
320 return set_internal_variable (m_save_header_format_string, args, nargout,
321 "save_header_format_string");
322}
323
325load_save_system::get_file_format (const std::string& fname,
326 const std::string& orig_fname,
327 bool& use_zlib, bool quiet)
328{
329 load_save_format retval = UNKNOWN;
330
331#if defined (HAVE_HDF5_UTF8)
332 std::string ascii_fname = fname;
333#else
334 std::string ascii_fname = sys::get_ASCII_filename (fname);
335#endif
336
337#if defined (HAVE_HDF5)
338 // check this before we open the file
339 if (H5Fis_hdf5 (ascii_fname.c_str ()) > 0)
340 return HDF5;
341#endif
342
343#if defined (HAVE_ZLIB)
344 use_zlib = check_gzip_magic (fname);
345#else
346 use_zlib = false;
347#endif
348
349 if (! use_zlib)
350 {
351 std::ifstream file = sys::ifstream (fname.c_str (),
352 std::ios::in | std::ios::binary);
353 if (file)
354 {
355 retval = get_file_format (file, orig_fname);
356 file.close ();
357 }
358 else if (! quiet)
359 err_file_open ("load", orig_fname);
360 }
361#if defined (HAVE_ZLIB)
362 else
363 {
364 gzifstream gzfile (fname.c_str (), std::ios::in | std::ios::binary);
365 if (gzfile)
366 {
367 retval = get_file_format (gzfile, orig_fname);
368 gzfile.close ();
369 }
370 else if (! quiet)
371 err_file_open ("load", orig_fname);
372 }
373#endif
374
375 return retval;
376}
377
380 const std::string& orig_fname,
381 const load_save_format& fmt,
382 mach_info::float_format flt_fmt,
383 bool list_only, bool swap, bool verbose,
384 const string_vector& argv, int argv_idx,
385 int argc, int nargout)
386{
387 octave_value retval;
388
389 octave_scalar_map retstruct;
390
391 std::ostringstream output_buf;
392 std::list<std::string> symbol_names;
393
394 octave_idx_type count = 0;
395
396 for (;;)
397 {
398 bool global = false;
399 octave_value tc;
400
401 std::string name;
402 std::string doc;
403
404 switch (fmt.type ())
405 {
406 case TEXT:
407 name = read_text_data (stream, orig_fname, global, tc, count);
408 break;
409
410 case BINARY:
411 name = read_binary_data (stream, swap, flt_fmt, orig_fname,
412 global, tc, doc);
413 break;
414
415 case MAT_ASCII:
416 name = read_mat_ascii_data (stream, orig_fname, tc);
417 break;
418
419 case MAT_BINARY:
420 name = read_mat_binary_data (stream, orig_fname, tc);
421 break;
422
423#if defined (HAVE_HDF5)
424 case HDF5:
425 name = read_hdf5_data (stream, orig_fname, global, tc, doc,
426 argv, argv_idx, argc);
427 break;
428#endif
429
430 case MAT5_BINARY:
431 case MAT7_BINARY:
432 name = read_mat5_binary_element (stream, orig_fname, swap,
433 global, tc);
434 break;
435
436 default:
438 break;
439 }
440
441 if (stream.eof () || name.empty ())
442 break;
443 else
444 {
445 if (! tc.is_defined ())
446 error ("load: unable to load variable '%s'", name.c_str ());
447
448 if (fmt.type () == MAT_ASCII && argv_idx < argc)
449 warning ("load: loaded ASCII file '%s' -- ignoring extra args",
450 orig_fname.c_str ());
451
452 if (fmt.type () == MAT_ASCII
453 || argv_idx == argc
454 || matches_patterns (argv, argv_idx, argc, name))
455 {
456 count++;
457 if (list_only)
458 {
459 if (verbose)
460 {
461 if (count == 1)
462 output_buf
463 << "type rows cols name\n"
464 << "==== ==== ==== ====\n";
465
466 output_buf
467 << std::setiosflags (std::ios::left)
468 << std::setw (16) << tc.type_name ().c_str ()
469 << std::setiosflags (std::ios::right)
470 << std::setw (7) << tc.rows ()
471 << std::setw (7) << tc.columns ()
472 << " " << name << "\n";
473 }
474 else
475 symbol_names.push_back (name);
476 }
477 else
478 {
479 if (nargout == 1)
480 {
481 if (fmt.type () == MAT_ASCII)
482 retval = tc;
483 else
484 retstruct.assign (name, tc);
485 }
486 else
487 install_loaded_variable (name, tc, global, doc);
488 }
489 }
490
491 // Only attempt to read one item from a headless text file.
492
493 if (fmt.type () == MAT_ASCII)
494 break;
495 }
496 }
497
498 if (list_only && count)
499 {
500 if (verbose)
501 {
502 std::string msg = output_buf.str ();
503
504 if (nargout > 0)
505 retval = msg;
506 else
507 octave_stdout << msg;
508 }
509 else
510 {
511 if (nargout > 0)
512 retval = Cell (string_vector (symbol_names));
513 else
514 {
515 string_vector names (symbol_names);
516
518
519 octave_stdout << "\n";
520 }
521 }
522 }
523 else if (retstruct.nfields () != 0)
524 retval = retstruct;
525
526 return retval;
527}
528
531 load_save_format& fmt, bool& append,
532 bool& save_as_floats, bool& use_zlib)
533{
534#if ! defined (HAVE_ZLIB)
535 octave_unused_parameter (use_zlib);
536#endif
537
538 string_vector retval;
539 int argc = argv.numel ();
540
541 bool do_double = false;
542 bool do_tabs = false;
543
544 for (int i = 0; i < argc; i++)
545 {
546 if (argv[i] == "-append")
547 {
548 append = true;
549 }
550 else if (argv[i] == "-ascii" || argv[i] == "-a")
551 {
552 fmt.set_type (MAT_ASCII);
553 }
554 else if (argv[i] == "-double")
555 {
556 do_double = true;
557 }
558 else if (argv[i] == "-tabs")
559 {
560 do_tabs = true;
561 }
562 else if (argv[i] == "-text" || argv[i] == "-t")
563 {
564 fmt.set_type (TEXT);
565 }
566 else if (argv[i] == "-binary" || argv[i] == "-b")
567 {
568 fmt.set_type (BINARY);
569 }
570 else if (argv[i] == "-hdf5" || argv[i] == "-h")
571 {
572#if defined (HAVE_HDF5)
573 fmt.set_type (HDF5);
574#else
575 err_disabled_feature ("save", "HDF5");
576#endif
577 }
578 else if (argv[i] == "-v7.3" || argv[i] == "-V7.3" || argv[i] == "-7.3")
579 {
580 error ("save: Matlab file format -v7.3 is not yet implemented");
581 }
582#if defined (HAVE_ZLIB)
583 else if (argv[i] == "-v7" || argv[i] == "-V7" || argv[i] == "-7"
584 || argv[i] == "-mat7-binary")
585 {
586 fmt.set_type (MAT7_BINARY);
587 }
588#endif
589 else if (argv[i] == "-mat" || argv[i] == "-m"
590 || argv[i] == "-v6" || argv[i] == "-V6" || argv[i] == "-6"
591 || argv[i] == "-mat-binary")
592 {
593 fmt.set_type (MAT5_BINARY);
594 }
595 else if (argv[i] == "-v4" || argv[i] == "-V4" || argv[i] == "-4"
596 || argv[i] == "-mat4-binary")
597 {
598 fmt.set_type (MAT_BINARY);
599 }
600 else if (argv[i] == "-float-binary" || argv[i] == "-f")
601 {
602 fmt.set_type (BINARY);
603 save_as_floats = true;
604 }
605 else if (argv[i] == "-float-hdf5")
606 {
607#if defined (HAVE_HDF5)
608 fmt.set_type (HDF5);
609 save_as_floats = true;
610#else
611 err_disabled_feature ("save", "HDF5");
612#endif
613 }
614#if defined (HAVE_ZLIB)
615 else if (argv[i] == "-zip" || argv[i] == "-z")
616 {
617 use_zlib = true;
618 }
619#endif
620 else if (argv[i] == "-struct")
621 {
622 retval.append (argv[i]);
623 }
624 else if (argv[i][0] == '-' && argv[i] != "-")
625 {
626 error ("save: Unrecognized option '%s'", argv[i].c_str ());
627 }
628 else
629 retval.append (argv[i]);
630 }
631
632 if (do_double)
633 {
634 if (fmt.type () == MAT_ASCII)
636 else
637 warning (R"(save: "-double" option only has an effect with "-ascii")");
638 }
639
640 if (do_tabs)
641 {
642 if (fmt.type () == MAT_ASCII)
644 else
645 warning (R"(save: "-tabs" option only has an effect with "-ascii")");
646 }
647
648 if (append && use_zlib
649 && (fmt.type () != TEXT && fmt.type () != MAT_ASCII))
650 error ("save: -append and -zip options can only be used together with a text format (-text or -ascii)");
651
652 return retval;
653}
654
657 load_save_format& fmt,
658 bool& append, bool& save_as_floats,
659 bool& use_zlib)
660{
661 std::istringstream is (arg);
662 std::string str;
663 string_vector argv;
664
665 while (! is.eof ())
666 {
667 is >> str;
668 argv.append (str);
669 }
670
671 return parse_save_options (argv, fmt, append, save_as_floats, use_zlib);
672}
673
674void
676 int argc, std::ostream& os,
677 const load_save_format& fmt,
678 bool save_as_floats,
679 bool write_header_info)
680{
681 if (write_header_info)
682 write_header (os, fmt);
683
684 create_subsystem_handler (); // for MAT file formats
685
686 octave::unwind_action
687 clear_obj_cache ([this] ()
688 {
691 });
692
693 if (argv_idx == argc)
694 {
695 save_vars (os, "*", fmt, save_as_floats);
696 }
697 else if (argv[argv_idx] == "-struct")
698 {
699 if (++argv_idx >= argc)
700 error ("save: missing struct name");
701
702 std::string struct_name = argv[argv_idx];
703
704 if (! m_interpreter.is_variable (struct_name))
705 error ("save: no such variable: '%s'", struct_name.c_str ());
706
707 octave_value struct_var = m_interpreter.varval (struct_name);
708
709 if (! struct_var.isstruct () || struct_var.numel () != 1)
710 error ("save: '%s' is not a scalar structure", struct_name.c_str ());
711
712 octave_scalar_map struct_var_map = struct_var.scalar_map_value ();
713
714 ++argv_idx;
715
716 if (argv_idx < argc)
717 {
718 for (int i = argv_idx; i < argc; i++)
719 {
720 if (! save_fields (os, struct_var_map, argv[i], fmt,
721 save_as_floats))
722 {
723 warning ("save: no such field '%s.%s'",
724 struct_name.c_str (), argv[i].c_str ());
725 }
726 }
727 }
728 else
729 save_fields (os, struct_var_map, "*", fmt, save_as_floats);
730 }
731 else
732 {
733 for (int i = argv_idx; i < argc; i++)
734 {
735 if (argv[i] == "")
736 continue; // Skip empty vars for Matlab compatibility
737 if (! save_vars (os, argv[i], fmt, save_as_floats))
738 warning ("save: no such variable '%s'", argv[i].c_str ());
739 }
740 }
741}
742
743void
745{
746 if (m_crash_dumps_octave_core)
747 {
748 // FIXME: should choose better filename?
749
750 const char *fname = m_octave_core_file_name.c_str ();
751
752 message (nullptr, "attempting to save variables to '%s'...", fname);
753
755
756 bool save_as_floats = false;
757
758 bool append = false;
759
760 bool use_zlib = false;
761
762 load_save_system::parse_save_options (m_octave_core_file_options,
763 fmt, append, save_as_floats,
764 use_zlib);
765
766 std::ios::openmode mode = std::ios::out;
767
768 // Matlab v7 files are always compressed
769 if (fmt.type () == MAT7_BINARY)
770 use_zlib = false;
771
772 if (fmt.type () == BINARY
773#if defined (HAVE_HDF5)
774 || fmt.type () == HDF5
775#endif
776 || fmt.type () == MAT_BINARY
777 || fmt.type () == MAT5_BINARY
778 || fmt.type () == MAT7_BINARY)
779 mode |= std::ios::binary;
780
781 mode |= append ? std::ios::ate : std::ios::trunc;
782
783#if defined (HAVE_HDF5)
784 if (fmt.type () == HDF5)
785 {
786 hdf5_ofstream file (fname, mode);
787
788 if (file.file_id >= 0)
789 {
790 dump_octave_core (file, fname, fmt, save_as_floats);
791
792 file.close ();
793 }
794 else
795 warning ("dump_octave_core: unable to open '%s' for writing...",
796 fname);
797 }
798 else
799#endif
800 // don't insert any commands here! The open brace below must
801 // go with the else above!
802 {
803#if defined (HAVE_ZLIB)
804 if (use_zlib)
805 {
806 gzofstream file (fname, mode);
807
808 if (file)
809 {
810 dump_octave_core (file, fname, fmt, save_as_floats);
811
812 file.close ();
813 }
814 else
815 warning ("dump_octave_core: unable to open '%s' for writing...",
816 fname);
817 }
818 else
819#endif
820 {
821 std::ofstream file = sys::ofstream (fname, mode);
822
823 if (file)
824 {
825 dump_octave_core (file, fname, fmt, save_as_floats);
826
827 file.close ();
828 }
829 else
830 warning ("dump_octave_core: unable to open '%s' for writing...",
831 fname);
832 }
833 }
834 }
835}
836
837void
838load_save_system::write_header (std::ostream& os,
839 const load_save_format& fmt)
840{
841 switch (fmt.type ())
842 {
843 case BINARY:
844 {
845 os << (mach_info::words_big_endian ()
846 ? "Octave-1-B" : "Octave-1-L");
847
848 mach_info::float_format flt_fmt = mach_info::native_float_format ();
849
850 char tmp = static_cast<char> (float_format_to_mopt_digit (flt_fmt));
851
852 os.write (&tmp, 1);
853 }
854 break;
855
856 case MAT5_BINARY:
857 case MAT7_BINARY:
858 {
859 char const *versionmagic;
860 char headertext[128];
861 sys::gmtime now;
862
863 // ISO 8601 format date
864 const char *matlab_format = "MATLAB 5.0 MAT-file, written by Octave "
865 OCTAVE_VERSION ", %Y-%m-%d %T UTC";
866 std::string comment_string = now.strftime (matlab_format);
867
868 std::size_t len = std::min (comment_string.length (),
869 static_cast<std::size_t> (124));
870 memset (headertext, '\0', 124);
871 memcpy (headertext, comment_string.data (), len);
872
873 // The first pair of bytes give the version of the MAT file
874 // format. The second pair of bytes form a magic number which
875 // signals a MAT file. MAT file data are always written in
876 // native byte order. The order of the bytes in the second
877 // pair indicates whether the file was written by a big- or
878 // little-endian machine. However, the version number is
879 // written in the *opposite* byte order from everything else!
880 if (mach_info::words_big_endian ())
881 versionmagic = "\x01\x00\x4d\x49"; // this machine is big endian
882 else
883 versionmagic = "\x00\x01\x49\x4d"; // this machine is little endian
884
885 memcpy (headertext+124, versionmagic, 4);
886 os.write (headertext, 128);
887 }
888
889 break;
890
891#if defined (HAVE_HDF5)
892 case HDF5:
893#endif
894 case TEXT:
895 {
896 sys::localtime now;
897
898 std::string comment_string = now.strftime (m_save_header_format_string);
899
900 if (! comment_string.empty ())
901 {
902#if defined (HAVE_HDF5)
903 if (fmt.type () == HDF5)
904 {
905 hdf5_ofstream& hs = dynamic_cast<hdf5_ofstream&> (os);
906 H5Gset_comment (hs.file_id, "/", comment_string.c_str ());
907 }
908 else
909#endif
910 os << comment_string << "\n";
911 }
912 }
913 break;
914
915 default:
916 break;
917 }
918}
919
920// Save variables with names matching PATTERN on stream OS in the
921// format specified by FMT.
922
923std::size_t
924load_save_system::save_vars (std::ostream& os,
925 const std::string& pattern,
926 const load_save_format& fmt,
927 bool save_as_floats)
928{
929 tree_evaluator& tw = m_interpreter.get_evaluator ();
930
931 symbol_info_list syminfo_list = tw.glob_symbol_info (pattern);
932
933 std::size_t saved = 0;
934
935 for (const auto& syminfo : syminfo_list)
936 {
937 do_save (os, syminfo, fmt, save_as_floats);
938
939 saved++;
940 }
941
942 return saved;
943}
944
945void
946load_save_system::do_save (std::ostream& os, const octave_value& tc,
947 const std::string& name,
948 const std::string& help,
949 bool global, const load_save_format& fmt,
950 bool save_as_floats)
951{
952 switch (fmt.type ())
953 {
954 case TEXT:
955 save_text_data (os, tc, name, global, 0);
956 break;
957
958 case BINARY:
959 save_binary_data (os, tc, name, help, global, save_as_floats);
960 break;
961
962 case MAT_ASCII:
963 if (! save_mat_ascii_data (os, tc,
964 fmt.options () & MAT_ASCII_LONG ? 16 : 8,
965 fmt.options () & MAT_ASCII_TABS))
966 warning ("save: unable to save %s in ASCII format", name.c_str ());
967 break;
968
969 case MAT_BINARY:
970 save_mat_binary_data (os, tc, name);
971 break;
972
973#if defined (HAVE_HDF5)
974 case HDF5:
975 save_hdf5_data (os, tc, name, help, global, save_as_floats);
976 break;
977#endif
978
979 case MAT5_BINARY:
980 save_mat5_binary_element (os, tc, name, global, false, save_as_floats);
981 break;
982
983 case MAT7_BINARY:
984 save_mat5_binary_element (os, tc, name, global, true, save_as_floats);
985 break;
986
987 default:
989 break;
990 }
991}
992
993// Save the info from SR on stream OS in the format specified by FMT.
994
995void
996load_save_system::do_save (std::ostream& os,
997 const symbol_info& syminfo,
998 const load_save_format& fmt,
999 bool save_as_floats)
1000{
1001 octave_value val = syminfo.value ();
1002
1003 if (val.is_defined ())
1004 {
1005 std::string name = syminfo.name ();
1006 std::string help;
1007 bool global = syminfo.is_global ();
1008
1009 do_save (os, val, name, help, global, fmt, save_as_floats);
1010 }
1011}
1012
1013// save fields of a scalar structure STR matching PATTERN on stream OS
1014// in the format specified by FMT.
1015
1016std::size_t
1017load_save_system::save_fields (std::ostream& os,
1018 const octave_scalar_map& m,
1019 const std::string& pattern,
1020 const load_save_format& fmt,
1021 bool save_as_floats)
1022{
1023 symbol_match pat (pattern);
1024
1025 std::size_t saved = 0;
1026
1027 for (auto it = m.begin (); it != m.end (); it++)
1028 {
1029 std::string empty_str;
1030
1031 if (pat.match (m.key (it)))
1032 {
1033 do_save (os, m.contents (it), m.key (it), empty_str,
1034 0, fmt, save_as_floats);
1035
1036 saved++;
1037 }
1038 }
1039
1040 return saved;
1041}
1042
1043void
1044load_save_system::dump_octave_core (std::ostream& os,
1045 const char *fname,
1046 const load_save_format& fmt,
1047 bool save_as_floats)
1048{
1049 write_header (os, fmt);
1050
1051 tree_evaluator& tw = m_interpreter.get_evaluator ();
1052
1053 symbol_info_list syminfo_list = tw.top_scope_symbol_info ();
1054
1055 double save_mem_size = 0;
1056
1057 for (const auto& syminfo : syminfo_list)
1058 {
1059 octave_value val = syminfo.value ();
1060
1061 std::string name = syminfo.name ();
1062 std::string help;
1063 bool global = syminfo.is_global ();
1064
1065 double val_size = val.byte_size () / 1024;
1066
1067 // FIXME: maybe we should try to throw out the largest first...
1068
1069 if (m_octave_core_file_limit < 0
1070 || save_mem_size + val_size < m_octave_core_file_limit)
1071 {
1072 save_mem_size += val_size;
1073
1074 do_save (os, val, name, help, global, fmt, save_as_floats);
1075 }
1076 }
1077
1078 message (nullptr, "save to '%s' complete", fname);
1079}
1080
1081// Install a variable with name NAME and the value VAL in the
1082// symbol table. If GLOBAL is TRUE, make the variable global.
1083
1084void
1085load_save_system::install_loaded_variable (const std::string& name,
1086 const octave_value& val,
1087 bool global,
1088 const std::string& /*doc*/)
1089{
1090 m_interpreter.install_variable (name, val, global);
1091}
1092
1093std::string
1094load_save_system::init_save_header_format ()
1095{
1096 return "# Created by Octave " OCTAVE_VERSION ", %a %b %d %H:%M:%S %Y %Z";
1097}
1098
1100load_save_system::get_file_format (std::istream& file,
1101 const std::string& filename)
1102{
1104
1105 mach_info::float_format flt_fmt
1106 = mach_info::flt_fmt_unknown;
1107
1108 bool swap = false;
1109
1110 if (read_binary_file_header (file, swap, flt_fmt, true) == 0)
1111 retval = BINARY;
1112 else
1113 {
1114 file.clear ();
1115 file.seekg (0, std::ios::beg);
1116
1117 int32_t mopt, nr, nc, imag, len;
1118
1119 int err = read_mat_file_header (file, swap, mopt, nr, nc, imag, len,
1120 true);
1121
1122 if (! err)
1123 retval = MAT_BINARY;
1124 else
1125 {
1126 file.clear ();
1127 file.seekg (0, std::ios::beg);
1128
1129 err = read_mat5_binary_file_header (file, swap, true, filename);
1130
1131 if (! err)
1132 {
1133 file.clear ();
1134 file.seekg (0, std::ios::beg);
1135 retval = MAT5_BINARY;
1136 }
1137 else
1138 {
1139 file.clear ();
1140 file.seekg (0, std::ios::beg);
1141
1142 std::string name_val = extract_keyword (file, "name");
1143 std::string type_val = extract_keyword (file, "type");
1144
1145 if (name_val.empty () != true && type_val.empty () != true)
1146 retval = TEXT;
1147 else
1148 {
1149 file.clear ();
1150 file.seekg (0, std::ios::beg);
1151
1152 // FIXME: looks_like_mat_ascii_file does not check
1153 // to see whether the file contains numbers. It
1154 // just skips comments and checks for the same
1155 // number of words on each line. We may need a
1156 // better check here. The best way to do that might
1157 // be just to try to read the file and see if it
1158 // works.
1159
1160 if (looks_like_mat_ascii_file (file, filename))
1161 retval = MAT_ASCII;
1162 }
1163 }
1164 }
1165 }
1166
1167 return retval;
1168}
1169
1172{
1173 octave_value_list retval;
1174
1175 int argc = args.length () + 1;
1176
1177 string_vector argv = args.make_argv ("load");
1178
1179 int i = 1;
1180 std::string orig_fname = "";
1181
1182 // Function called with Matlab-style ["filename", options] syntax
1183 if (argc > 1 && ! argv[1].empty () && argv[1].at (0) != '-')
1184 {
1185 orig_fname = argv[1];
1186 i++;
1187 }
1188
1189 // It isn't necessary to have the default load format stored in a
1190 // user preference variable since we can determine the type of file
1191 // as we are reading.
1192
1194
1195 bool list_only = false;
1196 bool verbose = false;
1197
1198 create_subsystem_handler (); // for MAT file formats
1199
1200 octave::unwind_action
1201 clear_obj_cache ([this] ()
1202 {
1205 });
1206
1207 for (; i < argc; i++)
1208 {
1209 if (argv[i] == "-text" || argv[i] == "-t")
1210 {
1211 format = TEXT;
1212 }
1213 else if (argv[i] == "-binary" || argv[i] == "-b")
1214 {
1215 format = BINARY;
1216 }
1217 else if (argv[i] == "-hdf5" || argv[i] == "-h")
1218 {
1219#if defined (HAVE_HDF5)
1220 format = HDF5;
1221#else
1222 err_disabled_feature ("load", "HDF5");
1223#endif
1224 }
1225 else if (argv[i] == "-ascii" || argv[i] == "-a")
1226 {
1227 format = MAT_ASCII;
1228 }
1229 else if (argv[i] == "-v7.3" || argv[i] == "-V7.3" || argv[i] == "-7.3")
1230 {
1231 error ("load: Matlab file format -v7.3 is not yet implemented");
1232 }
1233 else if (argv[i] == "-v7" || argv[i] == "-V7" || argv[i] == "-7"
1234 || argv[i] == "-mat7-binary")
1235 {
1237 }
1238 else if (argv[i] == "-mat" || argv[i] == "-m"
1239 || argv[i] == "-v6" || argv[i] == "-V6" || argv[i] == "-6"
1240 || argv[i] == "-mat-binary")
1241 {
1243 }
1244 else if (argv[i] == "-v4" || argv[i] == "-V4" || argv[i] == "-4"
1245 || argv[i] == "-mat4-binary")
1246 {
1248 }
1249 else if (argv[i] == "-list" || argv[i] == "-l")
1250 {
1251 list_only = true;
1252 }
1253 else if (argv[i] == "-verbose" || argv[i] == "-v")
1254 {
1255 verbose = true;
1256 }
1257 else
1258 break;
1259 }
1260
1261 if (orig_fname == "")
1262 {
1263 if (i == argc)
1264 print_usage ();
1265
1266 orig_fname = argv[i];
1267 }
1268 else
1269 i--;
1270
1271 mach_info::float_format flt_fmt = mach_info::flt_fmt_unknown;
1272
1273 bool swap = false;
1274
1275 if (orig_fname == "-")
1276 {
1277 i++;
1278
1279#if defined (HAVE_HDF5)
1280 if (format.type () == HDF5)
1281 error ("load: cannot read HDF5 format from stdin");
1282 else
1283#endif
1284 if (format.type () != UNKNOWN)
1285 {
1286 // FIXME: if we have already seen EOF on a previous call,
1287 // how do we fix up the state of std::cin so that we can get
1288 // additional input? I'm afraid that we can't fix this
1289 // using std::cin only.
1290
1291 retval = load_vars (std::cin, orig_fname, format, flt_fmt,
1292 list_only, swap, verbose, argv, i,
1293 argc, nargout);
1294 }
1295 else
1296 error ("load: must specify file format if reading from stdin");
1297 }
1298 else
1299 {
1300 std::string fname = sys::file_ops::tilde_expand (orig_fname);
1301
1302 fname = find_file_to_load (fname, orig_fname);
1303
1304 bool use_zlib = false;
1305
1306 if (format.type () == UNKNOWN)
1307 format = get_file_format (fname, orig_fname, use_zlib);
1308
1309#if defined (HAVE_HDF5)
1310 if (format.type () == HDF5)
1311 {
1312 i++;
1313
1314 hdf5_ifstream hdf5_file (fname.c_str ());
1315
1316 if (hdf5_file.file_id < 0)
1317 err_file_open ("load", orig_fname);
1318
1319 retval = load_vars (hdf5_file, orig_fname, format, flt_fmt,
1320 list_only, swap, verbose, argv, i,
1321 argc, nargout);
1322
1323 hdf5_file.close ();
1324 }
1325 else
1326#endif
1327 // don't insert any statements here; the "else" above has to
1328 // go with the "if" below!!!!!
1329 if (format.type () != UNKNOWN)
1330 {
1331 i++;
1332
1333 // Always open in binary mode and handle various
1334 // line-endings explicitly.
1335 std::ios::openmode mode = std::ios::in | std::ios::binary;
1336
1337#if defined (HAVE_ZLIB)
1338 if (use_zlib)
1339 {
1340 gzifstream file (fname.c_str (), mode);
1341
1342 if (! file)
1343 err_file_open ("load", orig_fname);
1344
1345 if (format.type () == BINARY)
1346 {
1347 if (read_binary_file_header (file, swap, flt_fmt) < 0)
1348 {
1349 if (file) file.close ();
1350 return retval;
1351 }
1352 }
1353 else if (format.type () == MAT5_BINARY
1354 || format.type () == MAT7_BINARY)
1355 {
1356 if (read_mat5_binary_file_header (file, swap, false,
1357 orig_fname) < 0)
1358 {
1359 if (file) file.close ();
1360 return retval;
1361 }
1362 }
1363
1364 retval = load_vars (file, orig_fname, format, flt_fmt,
1365 list_only, swap, verbose, argv, i,
1366 argc, nargout);
1367
1368 file.close ();
1369 }
1370 else
1371#endif
1372 {
1373 std::ifstream file = sys::ifstream (fname.c_str (), mode);
1374
1375 if (! file)
1376 error ("load: unable to open input file '%s'",
1377 orig_fname.c_str ());
1378
1379 if (format.type () == BINARY)
1380 {
1381 if (read_binary_file_header (file, swap, flt_fmt) < 0)
1382 {
1383 if (file) file.close ();
1384 return retval;
1385 }
1386 }
1387 else if (format.type () == MAT5_BINARY
1388 || format.type () == MAT7_BINARY)
1389 {
1390 if (read_mat5_binary_file_header (file, swap, false,
1391 orig_fname) < 0)
1392 {
1393 if (file) file.close ();
1394 return retval;
1395 }
1396 }
1397
1398 retval = load_vars (file, orig_fname, format, flt_fmt,
1399 list_only, swap, verbose, argv, i,
1400 argc, nargout);
1401
1402 file.close ();
1403 }
1404 }
1405 else
1406 error ("load: unable to determine file format of '%s'",
1407 orig_fname.c_str ());
1408
1409 }
1410
1411 return retval;
1412}
1413
1416{
1417 // Here is where we would get the default save format if it were
1418 // stored in a user preference variable.
1420 bool save_as_floats = false;
1421 bool append = false;
1422 bool use_zlib = false;
1423
1424
1425 // get default options
1427 save_as_floats, use_zlib);
1428
1429 // override from command line
1430 string_vector argv = args.make_argv ();
1431
1432 argv = parse_save_options (argv, format, append, save_as_floats, use_zlib);
1433
1434 int argc = argv.numel ();
1435 int i = 0;
1436
1437 if (i == argc)
1438 print_usage ();
1439
1440 if (save_as_floats && format.type () == TEXT)
1441 error ("save: cannot specify both -text and -float-binary");
1442
1443 octave_value_list retval;
1444
1445 if (argv[i] == "-")
1446 {
1447 i++;
1448
1449#if defined (HAVE_HDF5)
1450 if (format.type () == HDF5)
1451 error ("save: cannot write HDF5 format to stdout");
1452 else
1453#endif
1454 // don't insert any commands here! the brace below must go
1455 // with the "else" above!
1456 {
1457 if (append)
1458 warning ("save: ignoring -append option for output to stdout");
1459
1460 if (nargout == 0)
1461 save_vars (argv, i, argc, octave_stdout, format,
1462 save_as_floats, true);
1463 else
1464 {
1465 std::ostringstream output_buf;
1466 save_vars (argv, i, argc, output_buf, format,
1467 save_as_floats, true);
1468 retval = octave_value (output_buf.str());
1469 }
1470 }
1471 }
1472
1473 // Guard against things like 'save a*', which are probably mistakes...
1474
1475 else if (i == argc - 1 && glob_pattern_p (argv[i]))
1476 print_usage ();
1477 else
1478 {
1479 // For non-append mode, we make a new temporary filename, write to that
1480 // instead of the file specified, then rename it at the end.
1481 // That way, if something goes wrong during the save like OOM,
1482 // we won't overwrite already-saved data in a file.
1483 // See bug #63803 for context.
1484 // In append mode, this kind of guard is counterproductive so we write
1485 // directly to the specified file.
1486
1487 std::string desiredname = sys::file_ops::tilde_expand (argv[i]);
1488 std::string fname = desiredname + (append ? "" : ".saving_in_progress");
1489
1490 i++;
1491
1492 // Matlab v7 files are always compressed
1493 if (format.type () == MAT7_BINARY)
1494 use_zlib = false;
1495
1496 // Matlab v6 and v4 files are never compressed
1497 if (use_zlib && (format.type () == MAT5_BINARY
1498 || format.type () == MAT_BINARY))
1499 {
1500 use_zlib = false;
1501 warning ("save: MATLAB compatible formats '-v4' and '-v6' are uncompressed");
1502 }
1503
1504 std::ios::openmode mode
1505 = (append ? (std::ios::app | std::ios::ate) : std::ios::out);
1506
1507 // Always open in binary mode to save line endings as is.
1508 mode |= std::ios::binary;
1509
1510#if defined (HAVE_HDF5)
1511 if (format.type () == HDF5)
1512 {
1513 // FIXME: It should be possible to append to HDF5 files.
1514 if (append)
1515 error ("save: appending to HDF5 files is not implemented");
1516
1517# if defined (HAVE_HDF5_UTF8)
1518 bool write_header_info
1519 = ! (append && H5Fis_hdf5 (fname.c_str ()) > 0);
1520# else
1521 std::string ascii_fname = sys::get_ASCII_filename (fname);
1522
1523 bool write_header_info
1524 = ! (append && H5Fis_hdf5 (ascii_fname.c_str ()) > 0);
1525# endif
1526
1527 hdf5_ofstream hdf5_file (fname.c_str (), mode);
1528
1529 if (hdf5_file.file_id == -1)
1530 err_file_open ("save", fname);
1531
1532 save_vars (argv, i, argc, hdf5_file, format, save_as_floats,
1533 write_header_info);
1534
1535 hdf5_file.close ();
1536 }
1537 else
1538#endif
1539 // don't insert any statements here! The brace below must go
1540 // with the "else" above!
1541 {
1542#if defined (HAVE_ZLIB)
1543 if (use_zlib)
1544 {
1545 gzofstream file (fname.c_str (), mode);
1546
1547 if (! file)
1548 err_file_open ("save", fname);
1549
1550 bool write_header_info = ! file.tellp ();
1551
1552 save_vars (argv, i, argc, file, format, save_as_floats,
1553 write_header_info);
1554
1555 file.close ();
1556 }
1557 else
1558#endif
1559 {
1560 std::ofstream file = sys::ofstream (fname.c_str (), mode);
1561
1562 if (! file)
1563 err_file_open ("save", fname);
1564
1565 bool write_header_info = ! file.tellp ();
1566
1567 save_vars (argv, i, argc, file, format, save_as_floats,
1568 write_header_info);
1569
1570 file.close ();
1571 }
1572 }
1573
1574 // If we are all the way here without Octave crashing or running
1575 // out of memory etc, then we can say that writing to the
1576 // temporary file was successful. So now we try to rename it to
1577 // the actual file that was specified, unless we were in append mode
1578 // in which case we take no action.
1579
1580 if (! append)
1581 {
1582 std::string msg;
1583 if (octave::sys::rename (fname, desiredname, msg) < 0)
1584 error ("save: unable to save to %s %s",
1585 desiredname.c_str (), msg.c_str ());
1586 }
1587 }
1588
1589 return retval;
1590}
1591
1592void
1594{
1595 m_mcos_object_load_cache.clear ();
1596 m_mcos_object_save_cache.clear ();
1597}
1598
1599void
1601 octave_value& obj)
1602{
1603 m_mcos_object_load_cache[object_id] = obj;
1604}
1605
1608{
1609 return m_mcos_object_load_cache[object_id];
1610}
1611
1612bool
1614{
1615 // FIXME: Consider replacing this with std::unordered_map<>::contains when we
1616 // allow C++20.
1617 return m_mcos_object_load_cache.find (object_id)
1618 != m_mcos_object_load_cache.end ();
1619}
1620
1621uint32_t
1622load_save_system::get_mcos_object_cache_id (const void *obj, bool& new_entry)
1623{
1624 // identify objects by their address in memory
1625 uint32_t id = m_mcos_object_save_cache[obj];
1626 if (id == 0)
1627 {
1628 // The object hasn't been present in the cache yet.
1629 // Assign and return a new id (starting at 1).
1630 id = m_mcos_object_save_cache.size ();
1631 m_mcos_object_save_cache[obj] = id;
1632 new_entry = true;
1633 }
1634 else
1635 new_entry = false;
1636
1637 return id;
1638}
1639
1640void
1642{
1643 m_subsystem_handler = std::make_unique<subsystem_handler> ();
1644}
1645
1648{
1649 return m_subsystem_handler.get ();
1650}
1651
1652void
1654{
1655 m_subsystem_handler.reset ();
1656}
1657
1658DEFMETHOD (load, interp, args, nargout,
1659 doc: /* -*- texinfo -*-
1660@deftypefn {} {} load file
1661@deftypefnx {} {} load options file
1662@deftypefnx {} {} load options file v1 v2 @dots{}
1663@deftypefnx {} {S =} load ("options", "file", "v1", "v2", @dots{})
1664@deftypefnx {} {} load file options
1665@deftypefnx {} {} load file options v1 v2 @dots{}
1666@deftypefnx {} {S =} load ("file", "options", "v1", "v2", @dots{})
1667Load the named variables @var{v1}, @var{v2}, @dots{}, from the file @var{file}.
1668
1669If no variables are specified then all variables found in the file will be
1670loaded. Otherwise, full variable names or pattern syntax can be used to
1671specify the variables to save. The format of the file is automatically
1672detected but may be overridden by supplying the appropriate option.
1673
1674The @code{load} command may also be invoked using the functional form
1675
1676@example
1677load ("-option1", @dots{}, "file", "v1", @dots{})
1678@end example
1679
1680@noindent
1681where the @var{options}, @var{file}, and variable name arguments (@var{v1},
1682@dots{}) must be specified as character strings.
1683
1684Valid options for @code{load} are listed in the following table.
1685
1686@table @code
1687
1688@item -ascii
1689Force Octave to assume the file contains columns of numbers in text format
1690without any header or other information. Data in the file will be loaded
1691as a single numeric matrix with the name of the variable derived from the
1692name of the file.
1693
1694@item -binary
1695Force Octave to assume the file is in Octave's binary format.
1696
1697@item -hdf5
1698Force Octave to assume the file is in @sc{hdf5} format. (@sc{hdf5} is a free,
1699portable binary format developed by the National Center for Supercomputing
1700Applications at the University of Illinois.) Note that @code{load} is only
1701designed to read @sc{hdf5} files that were created by Octave with @code{save},
1702and attempts to read other @sc{hdf5} files may fail or produce unpredictable
1703results. The @option{-hdf5} option provides a limited ability to read files
1704created using @sc{matlab}'s @option{-v7.3} option (which saves in @sc{hdf5}
1705format) although many data types are not yet supported. This format is only
1706available if Octave was built with a link to the @sc{hdf5} libraries.
1707
1708@item -text
1709Force Octave to assume the file is in Octave's text format.
1710
1711@item -v7.3
1712@itemx -V7.3
1713@itemx -7.3
1714Octave does @strong{not} yet implement @sc{matlab}'s v7.3 binary data format.
1715As the v7.3 format is an @sc{hdf5} based format, the @qcode{"-hdf5"} option
1716may be used to attempt to open a v7.3 format file, although most non-numeric
1717data types are not yet supported. Note that Octave @strong{can not} currently
1718save in this format.
1719
1720@item -v7
1721@itemx -V7
1722@itemx -7
1723@itemx -mat7-binary
1724Force Octave to assume the file is in @sc{matlab}'s version 7 binary format.
1725
1726@item -v6
1727@itemx -V6
1728@itemx -6
1729@itemx -mat
1730@itemx -mat-binary
1731Force Octave to assume the file is in @sc{matlab}'s version 6 binary format.
1732
1733@item -v4
1734@itemx -V4
1735@itemx -4
1736@itemx -mat4-binary
1737Force Octave to assume the file is in @sc{matlab}'s version 4 binary format.
1738
1739@end table
1740
1741The list of variables to load may use wildcard patterns (glob patterns)
1742containing the following special characters:
1743
1744@table @code
1745@item ?
1746Match any single character.
1747
1748@item *
1749Match zero or more characters.
1750
1751@item [ @var{list} ]
1752Match the list of characters specified by @var{list}. If the first character
1753is @code{!} or @code{^}, match all characters except those specified by
1754@var{list}. For example, the pattern @code{[a-zA-Z]} will match all lower and
1755uppercase alphabetic characters.
1756
1757@end table
1758
1759If invoked with a single output argument, Octave assigns loaded data to the
1760output instead of inserting variables in the symbol table. If the data file
1761contains only numbers (TAB- or space-delimited columns), a matrix of values is
1762returned. Otherwise, @code{load} returns a structure with members
1763corresponding to the names of the variables in the file.
1764
1765The @code{load} command can read data stored in Octave's text and binary
1766formats, @sc{matlab}'s binary format, and many simple formats such as
1767comma-separated-values (CSV). If compiled with zlib support, it can also load
1768gzip-compressed files. It will automatically detect the type of file and do
1769conversion from different floating point formats (currently only IEEE big and
1770little endian, though other formats may be added in the future).
1771
1772Programming Note: If a variable that is not marked as global is loaded from a
1773file when a global symbol with the same name already exists, it is loaded in
1774the global symbol table. Also, if a variable is marked as global in a file and
1775a local symbol exists, the local symbol is moved to the global symbol table and
1776given the value from the file.
1777
1778@seealso{save, csvread, dlmread, fread, textscan}
1779@end deftypefn */)
1780{
1781 load_save_system& load_save_sys = interp.get_load_save_system ();
1782
1783 return load_save_sys.load (args, nargout);
1784}
1785
1786DEFMETHOD (save, interp, args, nargout,
1787 doc: /* -*- texinfo -*-
1788@deftypefn {} {} save file
1789@deftypefnx {} {} save options file
1790@deftypefnx {} {} save options file @var{v1} @var{v2} @dots{}
1791@deftypefnx {} {} save options file -struct @var{STRUCT}
1792@deftypefnx {} {} save options file -struct @var{STRUCT} @var{f1} @var{f2} @dots{}
1793@deftypefnx {} {} save - @var{v1} @var{v2} @dots{}
1794@deftypefnx {} {@var{str} =} save ("-", @qcode{"@var{v1}"}, @qcode{"@var{v2}"}, @dots{})
1795Save the named variables @var{v1}, @var{v2}, @dots{}, in the file @var{file}.
1796
1797If no variable names are listed, Octave saves all the variables in the current
1798scope. Otherwise, full variable names or pattern syntax can be used to specify
1799the variables to save. If the @option{-struct} modifier is used then the
1800fields of the @strong{scalar} struct are saved as if they were variables with
1801the corresponding field names. The @option{-struct} option can be combined
1802with specific field names @var{f1}, @var{f2}, @dots{} to write only certain
1803fields to the file.
1804
1805The @code{save} command may also be invoked using the functional form
1806
1807@example
1808save ("-option1", @dots{}, "file", "v1", @dots{})
1809@end example
1810
1811@noindent
1812where the @var{options}, @var{file}, and variable name arguments (@var{v1},
1813@dots{}) must be specified as character strings.
1814
1815Valid options for the @code{save} command are listed in the following table.
1816Options that modify the output format override the format specified by
1817@code{save_default_options}.
1818
1819@table @code
1820@item -append
1821Append to the file instead of overwriting.
1822
1823@item -ascii
1824Save a matrix in a text file without a header or any other information. The
1825matrix must be 2-D and only the real part of any complex value is written to
1826the file. Numbers are stored in single-precision format and separated by
1827spaces. Additional options for the @option{-ascii} format are
1828
1829@table @code
1830@item -double
1831Store numbers in double-precision format.
1832
1833@item -tabs
1834Separate numbers with tabs.
1835@end table
1836
1837@item -binary
1838Save the data in Octave's binary data format.
1839
1840@item -float-binary
1841Save the data in Octave's binary data format using just single precision.
1842Use this format @strong{only} if you know that all the values to be saved can
1843be represented in single precision.
1844
1845@item -hdf5
1846Save the data in @sc{hdf5} format. (@sc{hdf5} is a free, portable, binary
1847format developed by the National Center for Supercomputing Applications at the
1848University of Illinois.) This format is only available if Octave was built
1849with a link to the @sc{hdf5} libraries.
1850
1851@item -float-hdf5
1852Save the data in @sc{hdf5} format using just single precision. Use this
1853format @strong{only} if you know that all the values to be saved can be
1854represented in single precision.
1855
1856@item -text (default)
1857Save the data in Octave's text data format. The
1858@ref{XREFsave_precision,,@code{save_precision}} function specifies the number
1859of significant figures to use when saving data (default: 17). The header of
1860the text data file can be configure with
1861@ref{XREFsave_header_format_string,,save_header_format_string}.
1862
1863@item -v7.3
1864@itemx -V7.3
1865@itemx -7.3
1866Octave does @strong{not} yet implement saving in @sc{matlab}'s v7.3 binary
1867data format.
1868
1869@item -v7
1870@itemx -V7
1871@itemx -7
1872@itemx -mat7-binary
1873Save the data in @sc{matlab}'s v7 binary data format.
1874
1875@item -v6
1876@itemx -V6
1877@itemx -6
1878@itemx -mat
1879@itemx -mat-binary
1880Save the data in @sc{matlab}'s v6 binary data format.
1881
1882@item -v4
1883@itemx -V4
1884@itemx -4
1885@itemx -mat4-binary
1886Save the data in @sc{matlab}'s v4 binary data format.
1887
1888@item -zip
1889@itemx -z
1890Use the gzip algorithm to compress the file. This works on files that are
1891compressed with gzip outside of Octave, and gzip can also be used to convert
1892the files for backward compatibility. This option is only available if Octave
1893was built with a link to the zlib libraries.
1894@end table
1895
1896The list of variables to save may use wildcard patterns (glob patterns)
1897containing the following special characters:
1898
1899@table @code
1900@item ?
1901Match any single character.
1902
1903@item *
1904Match zero or more characters.
1905
1906@item [ @var{list} ]
1907Match the list of characters specified by @var{list}. If the first character
1908is @code{!} or @code{^}, match all characters except those specified by
1909@var{list}. For example, the pattern @code{[a-zA-Z]} will match all lower and
1910uppercase alphabetic characters.
1911
1912Wildcards may also be used in the field name specifications when using the
1913@option{-struct} modifier (but not in the struct name itself).
1914
1915@end table
1916
1917Programming Notes: If called with the special filename @qcode{"-"} the data to
1918be saved is returned as a string rather than writing it to an actual file.
1919
1920When saving global variables the global status of the variable is also stored.
1921If the variable is restored at a later time using @code{load}, it will be
1922restored as a global variable. Global status is @emph{not} preserved if
1923using a @sc{matlab} binary data file format or the @option{-ascii} format.
1924
1925Note that @code{classdef} objects will be saved as @code{struct} in file
1926formats that support saving @code{struct}. That means they will not be loaded
1927as @code{classdef} objects when loading the variables from the save file at a
1928later point.
1929
1930Example:
1931
1932The command
1933
1934@example
1935save -binary data a b*
1936@end example
1937
1938@noindent
1939saves the variable @samp{a} and all variables beginning with @samp{b} to the
1940file @file{data} in Octave's binary format.
1941
1942@seealso{load, save_default_options, save_header_format_string, save_precision,
1943csvwrite, dlmwrite, fwrite}
1944@end deftypefn */)
1945{
1946 load_save_system& load_save_sys = interp.get_load_save_system ();
1947
1948 return load_save_sys.save (args, nargout);
1949}
1950
1951/*
1952## Save and load strings with "-v6"
1953%!test
1954%! A = A2 = "foobar"; # normal string
1955%! B = B2 = "a"; # short string
1956%! C = C2 = ["foo"; "bar"]; # character matrix
1957%! D = D2 = "ab".'; # short character matrix
1958%! E = E2 = {"foo", "bar"}; # cell string
1959%! F = F2 = {"Saint Barthélemy", "Saint Kitts and Nevis"}; % non-ASCII
1960%! mat_file = [tempname(), ".mat"];
1961%! unwind_protect
1962%! save (mat_file, "A", "B", "C", "D", "E", "F", "-v6");
1963%! clear ("A", "B", "C", "D", "E", "F");
1964%! load (mat_file);
1965%! unwind_protect_cleanup
1966%! delete ([mat_file, '*']);
1967%! end_unwind_protect
1968%! assert (A, A2);
1969%! assert (B, B2);
1970%! assert (C, C2);
1971%! assert (D, D2);
1972%! assert (E, E2);
1973%! assert (F, F2);
1974
1975## Save and load strings with "-v7"
1976%!testif HAVE_ZLIB
1977%! A = A2 = "foobar"; # normal string
1978%! B = B2 = "a"; # short string
1979%! C = C2 = ["foo"; "bar"]; # character matrix
1980%! D = D2 = "ab".'; # short character matrix
1981%! E = E2 = {"foo", "bar"}; # cell string
1982%! F = F2 = {"Saint Barthélemy", "Saint Kitts and Nevis"}; # non-ASCII
1983%! mat_file = [tempname(), ".mat"];
1984%! unwind_protect
1985%! save (mat_file, "A", "B", "C", "D", "E", "F", "-v7");
1986%! clear ("A", "B", "C", "D", "E", "F");
1987%! load (mat_file);
1988%! unwind_protect_cleanup
1989%! delete ([mat_file, '*']);
1990%! end_unwind_protect
1991%! assert (A, A2);
1992%! assert (B, B2);
1993%! assert (C, C2);
1994%! assert (D, D2);
1995%! assert (E, E2);
1996%! assert (F, F2);
1997
1998## Save and load struct with "-v6"
1999%!test
2000%! struc.a = "foobar"; # normal string
2001%! struc.b = "a"; # short string
2002%! struc.c = ["foo"; "bar"]; # character matrix
2003%! struc.d = "ab".'; # short character matrix
2004%! struc.e = {"foo", "bar"}; # cell string
2005%! struc.f = {"Saint Barthélemy", "Saint Kitts and Nevis"}; # non-ASCII
2006%! struc.g = [1 2 3]; # double vector
2007%! struc.h = 1:5; # range
2008%! struc2 = struc;
2009%! mat_file = [tempname(), ".mat"];
2010%! unwind_protect
2011%! save (mat_file, "struc", "-v6");
2012%! clear ("struc");
2013%! load (mat_file);
2014%! unwind_protect_cleanup
2015%! delete ([mat_file, '*']);
2016%! end_unwind_protect
2017%! assert (struc, struc2);
2018
2019## Save and load struct with "-v7"
2020%!testif HAVE_ZLIB
2021%! struc.a = "foobar"; # normal string
2022%! struc.b = "a"; # short string
2023%! struc.c = ["foo"; "bar"]; # character matrix
2024%! struc.d = "ab".'; # short character matrix
2025%! struc.e = {"foo", "bar"}; # cell string
2026%! struc.f = {"Saint Barthélemy", "Saint Kitts and Nevis"}; # non-ASCII
2027%! struc.g = [1 2 3]; # double vector
2028%! struc.h = 1:5; # range
2029%! struc2 = struc;
2030%! mat_file = [tempname(), ".mat"];
2031%! unwind_protect
2032%! save (mat_file, "struc", "-v7");
2033%! clear ("struc");
2034%! load (mat_file);
2035%! unwind_protect_cleanup
2036%! delete ([mat_file, '*']);
2037%! end_unwind_protect
2038%! assert (struc, struc2);
2039
2040## Save and load double and single matrix in "-binary"
2041%!test <*67699>
2042%! x = [1, 1+eps()];
2043%! y = single (x); # i.e., [1, 1]
2044%! mat_file = [tempname(), ".bin"];
2045%! unwind_protect
2046%! save (mat_file, "x", "y", "-binary");
2047%! clear ("x", "y");
2048%! load (mat_file);
2049%! unwind_protect_cleanup
2050%! delete ([mat_file, '*']);
2051%! end_unwind_protect
2052%! assert (x, [1, 1+eps()]);
2053%! assert (y, single ([1, 1+eps()]));
2054
2055## Save and load double and single matrix in "-float-binary"
2056%!test <*67699>
2057%! x = [1, 1+eps()]; # truncates to [1, 1] when saving as "-float-binary"
2058%! y = single (x); # i.e., [1, 1]
2059%! mat_file = [tempname(), ".bin"];
2060%! unwind_protect
2061%! save (mat_file, "x", "y", "-float-binary");
2062%! clear ("x", "y");
2063%! load (mat_file);
2064%! unwind_protect_cleanup
2065%! delete ([mat_file, '*']);
2066%! end_unwind_protect
2067%! assert (x, double (single ([1, 1+eps()])));
2068%! assert (y, single ([1, 1+eps()]));
2069
2070## Test input validation
2071%!testif HAVE_ZLIB <*59225>
2072%! fname = tempname ();
2073%! x = 1;
2074%! fail ('save ("-append", "-zip", "-binary", fname, "x")',
2075%! "-append and -zip options .* with a text format");
2076*/
2077
2078DEFMETHOD (crash_dumps_octave_core, interp, args, nargout,
2079 doc: /* -*- texinfo -*-
2080@deftypefn {} {@var{val} =} crash_dumps_octave_core ()
2081@deftypefnx {} {@var{old_val} =} crash_dumps_octave_core (@var{new_val})
2082@deftypefnx {} {@var{old_val} =} crash_dumps_octave_core (@var{new_val}, "local")
2083Query or set the internal variable that controls whether Octave tries
2084to save all current variables to the file @file{octave-workspace} if it
2085crashes or receives a hangup, terminate or similar signal.
2086
2087When called from inside a function with the @qcode{"local"} option, the
2088variable is changed locally for the function and any subroutines it calls.
2089The original variable value is restored when exiting the function.
2090@seealso{octave_core_file_limit, octave_core_file_name,
2091octave_core_file_options}
2092@end deftypefn */)
2093{
2094 load_save_system& load_save_sys = interp.get_load_save_system ();
2095
2096 return load_save_sys.crash_dumps_octave_core (args, nargout);
2097}
2098
2099DEFMETHOD (save_default_options, interp, args, nargout,
2100 doc: /* -*- texinfo -*-
2101@deftypefn {} {@var{val} =} save_default_options ()
2102@deftypefnx {} {@var{old_val} =} save_default_options (@var{new_val})
2103@deftypefnx {} {@var{old_val} =} save_default_options (@var{new_val}, "local")
2104Query or set the internal variable that specifies the default options
2105for the @code{save} command, and defines the default format.
2106
2107The default value is @qcode{"-text"} (Octave's own text-based file format).
2108See the documentation of the @code{save} command for other choices.
2109
2110When called from inside a function with the @qcode{"local"} option, the
2111variable is changed locally for the function and any subroutines it calls.
2112The original variable value is restored when exiting the function.
2113@seealso{save, save_header_format_string, save_precision}
2114@end deftypefn */)
2115{
2116 load_save_system& load_save_sys = interp.get_load_save_system ();
2117
2118 return load_save_sys.save_default_options (args, nargout);
2119}
2120
2121DEFMETHOD (octave_core_file_limit, interp, args, nargout,
2122 doc: /* -*- texinfo -*-
2123@deftypefn {} {@var{val} =} octave_core_file_limit ()
2124@deftypefnx {} {@var{old_val} =} octave_core_file_limit (@var{new_val})
2125@deftypefnx {} {@var{old_val} =} octave_core_file_limit (@var{new_val}, "local")
2126Query or set the internal variable that specifies the maximum amount of memory
2127that Octave will save when writing a crash dump file.
2128
2129The limit is measured in kilobytes and is applied to the top-level workspace.
2130The name of the crash dump file is specified by
2131@var{octave_core_file_name}.
2132
2133If @var{octave_core_file_options} flags specify a binary format, then
2134@var{octave_core_file_limit} will be approximately the maximum size of the
2135file. If a text file format is used, then the file could be much larger than
2136the limit. The default value is -1 (unlimited).
2137
2138When called from inside a function with the @qcode{"local"} option, the
2139variable is changed locally for the function and any subroutines it calls.
2140The original variable value is restored when exiting the function.
2141@seealso{crash_dumps_octave_core, octave_core_file_name,
2142octave_core_file_options}
2143@end deftypefn */)
2144{
2145 load_save_system& load_save_sys = interp.get_load_save_system ();
2146
2147 return load_save_sys.octave_core_file_limit (args, nargout);
2148}
2149
2150DEFMETHOD (octave_core_file_name, interp, args, nargout,
2151 doc: /* -*- texinfo -*-
2152@deftypefn {} {@var{val} =} octave_core_file_name ()
2153@deftypefnx {} {@var{old_val} =} octave_core_file_name (@var{new_val})
2154@deftypefnx {} {@var{old_val} =} octave_core_file_name (@var{new_val}, "local")
2155Query or set the internal variable that specifies the name of the file
2156used for saving data from the top-level workspace if Octave aborts.
2157
2158The default value is @qcode{"octave-workspace"}
2159
2160When called from inside a function with the @qcode{"local"} option, the
2161variable is changed locally for the function and any subroutines it calls.
2162The original variable value is restored when exiting the function.
2163@seealso{crash_dumps_octave_core, octave_core_file_name,
2164octave_core_file_options}
2165@end deftypefn */)
2166{
2167 load_save_system& load_save_sys = interp.get_load_save_system ();
2168
2169 return load_save_sys.octave_core_file_name (args, nargout);
2170}
2171
2172DEFMETHOD (octave_core_file_options, interp, args, nargout,
2173 doc: /* -*- texinfo -*-
2174@deftypefn {} {@var{val} =} octave_core_file_options ()
2175@deftypefnx {} {@var{old_val} =} octave_core_file_options (@var{new_val})
2176@deftypefnx {} {@var{old_val} =} octave_core_file_options (@var{new_val}, "local")
2177Query or set the internal variable that specifies the options used for
2178saving the workspace data if Octave aborts.
2179
2180The value of @code{octave_core_file_options} should follow the same format
2181as the options for the @code{save} function. The default value is Octave's
2182binary format.
2183
2184When called from inside a function with the @qcode{"local"} option, the
2185variable is changed locally for the function and any subroutines it calls.
2186The original variable value is restored when exiting the function.
2187@seealso{crash_dumps_octave_core, octave_core_file_name, octave_core_file_limit}
2188@end deftypefn */)
2189{
2190 load_save_system& load_save_sys = interp.get_load_save_system ();
2191
2192 return load_save_sys.octave_core_file_options (args, nargout);
2193}
2194
2195DEFMETHOD (save_header_format_string, interp, args, nargout,
2196 doc: /* -*- texinfo -*-
2197@deftypefn {} {@var{val} =} save_header_format_string ()
2198@deftypefnx {} {@var{old_val} =} save_header_format_string (@var{new_val})
2199@deftypefnx {} {@var{old_val} =} save_header_format_string (@var{new_val}, "local")
2200Query or set the internal variable that specifies the format string used for
2201the comment line written at the beginning of text-format data files saved by
2202Octave.
2203
2204The format string is passed to @code{strftime} and must begin with the
2205character @samp{#} and contain no newline characters. If the value of
2206@code{save_header_format_string} is the empty string, the header comment is
2207omitted from text-format data files. The default value is
2208@c Set example in small font to prevent overfull line
2209
2210@smallexample
2211"# Created by Octave VERSION, %a %b %d %H:%M:%S %Y %Z"
2212@end smallexample
2213
2214When called from inside a function with the @qcode{"local"} option, the
2215variable is changed locally for the function and any subroutines it calls.
2216The original variable value is restored when exiting the function.
2217@seealso{strftime, save_default_options}
2218@end deftypefn */)
2219{
2220 load_save_system& load_save_sys = interp.get_load_save_system ();
2221
2222 return load_save_sys.save_header_format_string (args, nargout);
2223}
2224
2225OCTAVE_END_NAMESPACE(octave)
Definition Cell.h:41
Gzipped file input stream class.
Definition gzfstream.h:278
void close()
Close gzipped file.
Definition gzfstream.cc:584
Gzipped file output stream class.
Definition gzfstream.h:365
void close()
Close gzipped file.
Definition gzfstream.cc:633
octave_hdf5_id file_id
Definition ls-hdf5.h:47
octave_value varval(const std::string &name) const
void install_variable(const std::string &name, const octave_value &value, bool global)
bool is_variable(const std::string &name) const
tree_evaluator & get_evaluator()
int options() const
Definition load-save.h:315
void set_option(load_save_system::format_options option)
Definition load-save.h:310
void set_type(load_save_system::format_type type)
Definition load-save.h:306
load_save_system::format_type type() const
Definition load-save.h:308
octave_value save_header_format_string(const octave_value_list &args, int nargout)
Definition load-save.cc:317
octave_value_list save(const octave_value_list &args=octave_value_list(), int nargout=0)
std::string save_header_format_string() const
Definition load-save.h:152
subsystem_handler * get_subsystem_handler()
octave_value octave_core_file_name(const octave_value_list &args, int nargout)
Definition load-save.cc:293
void save_vars(const string_vector &argv, int argv_idx, int argc, std::ostream &os, const load_save_format &fmt, bool save_as_floats, bool write_header_info)
Definition load-save.cc:675
octave_value & get_mcos_object_cache_entry(uint32_t object_id)
void create_subsystem_handler()
octave_value octave_core_file_options(const octave_value_list &args, int nargout)
Definition load-save.cc:309
bool crash_dumps_octave_core() const
Definition load-save.h:87
void clear_mcos_object_cache()
octave_value save_default_options(const octave_value_list &args, int nargout)
Definition load-save.cc:301
void dump_octave_core()
Definition load-save.cc:744
octave_value crash_dumps_octave_core(const octave_value_list &args, int nargout)
Definition load-save.cc:277
std::string octave_core_file_name() const
Definition load-save.h:113
bool is_mcos_object_cache_entry(uint32_t object_id)
octave_value load_vars(std::istream &stream, const std::string &orig_fname, const load_save_format &fmt, mach_info::float_format flt_fmt, bool list_only, bool swap, bool verbose, const string_vector &argv, int argv_idx, int argc, int nargout)
Definition load-save.cc:379
std::string octave_core_file_options() const
Definition load-save.h:139
double octave_core_file_limit() const
Definition load-save.h:100
octave_value_list load(const octave_value_list &args=octave_value_list(), int nargout=0)
static load_save_format get_file_format(const std::string &fname, const std::string &orig_fname, bool &use_zlib, bool quiet=false)
Definition load-save.cc:325
void clear_subsystem_handler()
load_save_system(interpreter &interp)
Definition load-save.cc:255
std::string save_default_options() const
Definition load-save.h:126
octave_value octave_core_file_limit(const octave_value_list &args, int nargout)
Definition load-save.cc:285
void set_mcos_object_cache_entry(uint32_t object_id, octave_value &obj)
uint32_t get_mcos_object_cache_id(const void *obj, bool &new_entry)
static string_vector parse_save_options(const string_vector &argv, load_save_format &fmt, bool &append, bool &save_as_floats, bool &use_zlib)
Definition load-save.cc:530
const octave_value & contents(const_iterator p) const
Definition oct-map.h:197
const_iterator end() const
Definition oct-map.h:185
const_iterator begin() const
Definition oct-map.h:184
void assign(const std::string &k, const octave_value &val)
Definition oct-map.h:230
octave_idx_type nfields() const
Definition oct-map.h:210
std::string key(const_iterator p) const
Definition oct-map.h:192
string_vector make_argv(const std::string &="") const
Definition ovl.cc:227
octave_idx_type length() const
Definition ovl.h:111
octave_idx_type rows() const
Definition ov.h:543
octave_scalar_map scalar_map_value() const
bool is_defined() const
Definition ov.h:590
octave_idx_type numel() const
Definition ov.h:557
std::string type_name() const
Definition ov.h:1358
std::size_t byte_size() const
Definition ov.h:560
bool isstruct() const
Definition ov.h:647
octave_idx_type columns() const
Definition ov.h:545
bool eof() const
string_vector & append(const std::string &s)
Definition str-vec.cc:110
std::ostream & list_in_columns(std::ostream &, int width=0, const std::string &prefix="") const
Definition str-vec.cc:201
octave_idx_type numel() const
Definition str-vec.h:98
bool is_global() const
Definition syminfo.h:73
std::string name() const
Definition syminfo.h:63
octave_value value() const
Definition syminfo.h:65
symbol_info_list top_scope_symbol_info() const
Definition pt-eval.cc:4716
symbol_info_list glob_symbol_info(const std::string &pattern) const
Definition pt-eval.cc:4698
ColumnVector imag(const ComplexColumnVector &a)
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
void print_usage()
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
void warning(const char *fmt,...)
Definition error.cc:1083
void error(const char *fmt,...)
Definition error.cc:1008
void message(const char *name, const char *fmt,...)
Definition error.cc:976
void err_unrecognized_data_fmt(const char *name)
Definition errwarn.cc:134
void err_disabled_feature(const std::string &fcn, const std::string &feature, const std::string &pkg)
Definition errwarn.cc:53
bool save_hdf5_data(std::ostream &os, const octave_value &tc, const std::string &name, const std::string &doc, bool mark_global, bool save_as_floats)
Definition ls-hdf5.cc:1520
std::string read_hdf5_data(std::istream &is, const std::string &, bool &global, octave_value &tc, std::string &doc, const string_vector &argv, int argv_idx, int argc)
Definition ls-hdf5.cc:1085
bool save_mat_ascii_data(std::ostream &os, const octave_value &val, int precision, bool tabs)
std::string read_mat_ascii_data(std::istream &is, const std::string &filename, octave_value &tc)
bool looks_like_mat_ascii_file(std::istream &is, const std::string &filename)
octave::mach_info::float_format mopt_digit_to_float_format(int mach)
Definition ls-mat4.cc:174
bool save_mat_binary_data(std::ostream &os, const octave_value &tc, const std::string &name)
Definition ls-mat4.cc:394
int read_mat_file_header(std::istream &is, bool &swap, int32_t &mopt, int32_t &nr, int32_t &nc, int32_t &imag, int32_t &len, int quiet)
Definition ls-mat4.cc:107
std::string read_mat_binary_data(std::istream &is, const std::string &filename, octave_value &tc)
Definition ls-mat4.cc:232
int float_format_to_mopt_digit(octave::mach_info::float_format flt_fmt)
Definition ls-mat4.cc:200
bool save_mat5_binary_element(std::ostream &os, const octave_value &tc_in, const std::string &name, bool mark_global, bool mat7_format, bool save_as_floats, bool compressing)
Definition ls-mat5.cc:2379
int read_mat5_binary_file_header(std::istream &is, bool &swap, bool quiet, const std::string &filename)
Definition ls-mat5.cc:1548
std::string read_mat5_binary_element(std::istream &is, const std::string &filename, bool swap, bool &global, octave_value &tc)
Definition ls-mat5.cc:478
std::string read_binary_data(std::istream &is, bool swap, octave::mach_info::float_format fmt, const std::string &filename, bool &global, octave_value &tc, std::string &doc)
bool save_binary_data(std::ostream &os, const octave_value &tc_in, const std::string &name, const std::string &doc, bool mark_global, bool save_as_floats)
std::string read_text_data(std::istream &is, const std::string &filename, bool &global, octave_value &tc, octave_idx_type count, const bool do_name_validation)
std::string extract_keyword(std::istream &is, const char *keyword, const bool next_only)
bool save_text_data(std::ostream &os, const octave_value &val_arg, const std::string &name, bool mark_global, int precision)
#define OCTAVE_VERSION
Definition main.in.cc:63
bool strncmp(const T &str_a, const T &str_b, const typename T::size_type n)
True if the first N characters are the same.
#define octave_stdout
Definition pager.h:301
std::string find_data_file_in_load_path(const std::string &fcn, const std::string &file, bool require_regular_file)
Definition utils.cc:711
std::size_t format(std::ostream &os, const char *fmt,...)
Definition utils.cc:1514
octave_value set_internal_variable(bool &var, const octave_value_list &args, int nargout, const char *nm)
Definition variables.cc:583
F77_RET_T len
Definition xerbla.cc:61