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