GNU Octave  4.4.1
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-2018 John W. Eaton
4 
5 This file is part of Octave.
6 
7 Octave is free software: you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11 
12 Octave is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with Octave; see the file COPYING. If not, see
19 <https://www.gnu.org/licenses/>.
20 
21 */
22 
23 // Author: John W. Eaton.
24 // HDF5 support by Steven G. Johnson <stevenj@alum.mit.edu>
25 // Matlab v5 support by James R. Van Zandt <jrv@vanzandt.mv.com>
26 
27 #if defined (HAVE_CONFIG_H)
28 # include "config.h"
29 #endif
30 
31 #include <cstring>
32 
33 #include <fstream>
34 #include <iomanip>
35 #include <iostream>
36 #include <list>
37 #include <sstream>
38 #include <string>
39 
40 #include "byte-swap.h"
41 #include "dMatrix.h"
42 #include "data-conv.h"
43 #include "file-ops.h"
44 #include "file-stat.h"
45 #include "glob-match.h"
46 #include "lo-mappers.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-private.h"
60 #include "load-path.h"
61 #include "load-save.h"
62 #include "oct-hdf5.h"
63 #include "ovl.h"
64 #include "oct-map.h"
65 #include "ov-cell.h"
66 #include "pager.h"
67 #include "pt-exp.h"
68 #include "symtab.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 "zfstream.h"
92 #endif
93 
94 // Write octave-workspace file if Octave crashes or is killed by a signal.
95 static bool Vcrash_dumps_octave_core = true;
96 
97 // The maximum amount of memory (in kilobytes) that we will attempt to
98 // write to the Octave core file.
99 static double Voctave_core_file_limit = -1.0;
100 
101 // The name of the Octave core file.
102 static std::string Voctave_core_file_name = "octave-workspace";
103 
104 // The default output format. May be one of "binary", "text",
105 // "mat-binary", or "hdf5".
107 
108 // The output format for Octave core files.
110 
111 static std::string
113 {
114  return
115  std::string ("# Created by Octave " OCTAVE_VERSION
116  ", %a %b %d %H:%M:%S %Y %Z <")
118  + '@'
120  + '>';
121 }
122 
123 // The format string for the comment line at the top of text-format
124 // save files. Passed to strftime. Should begin with '#' and contain
125 // no newline characters.
127 
128 OCTAVE_NORETURN static
129 void
131 {
132  if (fcn == "load")
133  error ("%s: unable to open input file '%s'", fcn.c_str (), file.c_str ());
134  else if (fcn == "save")
135  error ("%s: unable to open output file '%s'", fcn.c_str (), file.c_str ());
136  else
137  error ("%s: unable to open file '%s'", fcn.c_str (), file.c_str ());
138 }
139 
140 // Install a variable with name NAME and the value VAL in the
141 // symbol table. If GLOBAL is TRUE, make the variable global.
142 
143 static void
145  const octave_value& val,
146  bool global, const std::string& /*doc*/)
147 {
148  octave::symbol_table& symtab
149  = octave::__get_symbol_table__ ("install_loaded_variable");
150 
152  = symtab.require_current_scope ("install_loaded_variable");
153 
154  if (global)
155  {
156  octave::symbol_record sym = scope.find_symbol (name);
157 
158  if (! sym.is_global ())
159  {
160  octave::symbol_scope global_scope = symtab.global_scope ();
161  octave::symbol_record global_sym = global_scope.find_symbol (name);
162 
163  sym.bind_fwd_rep (global_scope.get_rep (), global_sym);
164  }
165  }
166 
167  scope.assign (name, val);
168 }
169 
170 // Return TRUE if NAME matches one of the given globbing PATTERNS.
171 
172 static bool
173 matches_patterns (const string_vector& patterns, int pat_idx,
174  int num_pat, const std::string& name)
175 {
176  for (int i = pat_idx; i < num_pat; i++)
177  {
178  glob_match pattern (patterns[i]);
179 
180  if (pattern.match (name))
181  return true;
182  }
183 
184  return false;
185 }
186 
187 int
188 read_binary_file_header (std::istream& is, bool& swap,
190 {
191  const int magic_len = 10;
192  char magic[magic_len+1];
193  is.read (magic, magic_len);
194  magic[magic_len] = '\0';
195 
196  if (strncmp (magic, "Octave-1-L", magic_len) == 0)
198  else if (strncmp (magic, "Octave-1-B", magic_len) == 0)
200  else
201  {
202  if (! quiet)
203  error ("load: unable to read binary file");
204 
205  return -1;
206  }
207 
208  char tmp = 0;
209  is.read (&tmp, 1);
210 
212 
214  {
215  if (! quiet)
216  error ("load: unrecognized binary format!");
217 
218  return -1;
219  }
220 
221  return 0;
222 }
223 
224 #if defined (HAVE_ZLIB)
225 static bool
227 {
228  bool retval = false;
229 
230  std::ifstream file (fname.c_str (), std::ios::in | std::ios::binary);
231 
232  unsigned char magic[2];
233  if (file.read (reinterpret_cast<char *> (&magic[0]), 2)
234  && magic[0] == 0x1f && magic[1] == 0x8b)
235  retval = true;
236 
237  file.close ();
238 
239  return retval;
240 }
241 #endif
242 
243 static load_save_format
244 get_file_format (std::istream& file, const std::string& filename)
245 {
247 
249 
250  bool swap = false;
251 
252  if (read_binary_file_header (file, swap, flt_fmt, true) == 0)
253  retval = LS_BINARY;
254  else
255  {
256  file.clear ();
257  file.seekg (0, std::ios::beg);
258 
259  int32_t mopt, nr, nc, imag, len;
260 
261  int err = read_mat_file_header (file, swap, mopt, nr, nc, imag, len,
262  true);
263 
264  if (! err)
266  else
267  {
268  file.clear ();
269  file.seekg (0, std::ios::beg);
270 
272 
273  if (! err)
274  {
275  file.clear ();
276  file.seekg (0, std::ios::beg);
278  }
279  else
280  {
281  file.clear ();
282  file.seekg (0, std::ios::beg);
283 
284  std::string name_val = extract_keyword (file, "name");
285  std::string type_val = extract_keyword (file, "type");
286 
287  if (name_val.empty () != true && type_val.empty () != true)
288  retval = LS_TEXT;
289  else
290  {
291  file.clear ();
292  file.seekg (0, std::ios::beg);
293 
294  // FIXME: looks_like_mat_ascii_file does not check to see
295  // whether the file contains numbers. It just skips comments
296  // and checks for the same number of words on each line. We
297  // may need a better check here. The best way to do that
298  // might be just to try to read the file and see if it works.
299 
302  }
303  }
304  }
305  }
306 
307  return retval;
308 }
309 
310 static load_save_format
312  bool& use_zlib, bool quiet = false)
313 {
315 
316 #if defined (HAVE_HDF5)
317  // check this before we open the file
318  if (H5Fis_hdf5 (fname.c_str ()) > 0)
319  return LS_HDF5;
320 #endif
321 
322 #if defined (HAVE_ZLIB)
324 #else
325  use_zlib = false;
326 #endif
327 
328  if (! use_zlib)
329  {
330  std::ifstream file (fname.c_str (), std::ios::in | std::ios::binary);
331  if (file)
332  {
334  file.close ();
335  }
336  else if (! quiet)
337  err_file_open ("load", orig_fname);
338  }
339 #if defined (HAVE_ZLIB)
340  else
341  {
342  gzifstream gzfile (fname.c_str (), std::ios::in | std::ios::binary);
343  if (gzfile)
344  {
345  retval = get_file_format (gzfile, orig_fname);
346  gzfile.close ();
347  }
348  else if (! quiet)
349  err_file_open ("load", orig_fname);
350  }
351 #endif
352 
353  return retval;
354 }
355 
357 do_load (std::istream& stream, const std::string& orig_fname,
359  bool list_only, bool swap, bool verbose,
360  const string_vector& argv, int argv_idx, int argc, int nargout)
361 {
363 
364  octave_scalar_map retstruct;
365 
366  std::ostringstream output_buf;
367  std::list<std::string> symbol_names;
368 
369  octave_idx_type count = 0;
370 
371  for (;;)
372  {
373  bool global = false;
374  octave_value tc;
375 
377  std::string doc;
378 
379  switch (format.type)
380  {
381  case LS_TEXT:
382  name = read_text_data (stream, orig_fname, global, tc, count);
383  break;
384 
385  case LS_BINARY:
387  global, tc, doc);
388  break;
389 
390  case LS_MAT_ASCII:
391  name = read_mat_ascii_data (stream, orig_fname, tc);
392  break;
393 
394  case LS_MAT_BINARY:
395  name = read_mat_binary_data (stream, orig_fname, tc);
396  break;
397 
398 #if defined (HAVE_HDF5)
399  case LS_HDF5:
400  name = read_hdf5_data (stream, orig_fname, global, tc, doc,
401  argv, argv_idx, argc);
402  break;
403 #endif
404 
405  case LS_MAT5_BINARY:
406  case LS_MAT7_BINARY:
408  global, tc);
409  break;
410 
411  default:
412  err_unrecognized_data_fmt ("load");
413  break;
414  }
415 
416  if (stream.eof () || name.empty ())
417  break;
418  else
419  {
420  if (! tc.is_defined ())
421  error ("load: unable to load variable '%s'", name.c_str ());
422 
423  if (format == LS_MAT_ASCII && argv_idx < argc)
424  warning ("load: loaded ASCII file '%s' -- ignoring extra args",
425  orig_fname.c_str ());
426 
427  if (format == LS_MAT_ASCII
428  || argv_idx == argc
429  || matches_patterns (argv, argv_idx, argc, name))
430  {
431  count++;
432  if (list_only)
433  {
434  if (verbose)
435  {
436  if (count == 1)
437  output_buf
438  << "type rows cols name\n"
439  << "==== ==== ==== ====\n";
440 
441  output_buf
442  << std::setiosflags (std::ios::left)
443  << std::setw (16) << tc.type_name ().c_str ()
444  << std::setiosflags (std::ios::right)
445  << std::setw (7) << tc.rows ()
446  << std::setw (7) << tc.columns ()
447  << " " << name << "\n";
448  }
449  else
450  symbol_names.push_back (name);
451  }
452  else
453  {
454  if (nargout == 1)
455  {
456  if (format == LS_MAT_ASCII)
457  retval = tc;
458  else
459  retstruct.assign (name, tc);
460  }
461  else
462  install_loaded_variable (name, tc, global, doc);
463  }
464  }
465 
466  // Only attempt to read one item from a headless text file.
467 
468  if (format == LS_MAT_ASCII)
469  break;
470  }
471  }
472 
473  if (list_only && count)
474  {
475  if (verbose)
476  {
477  std::string msg = output_buf.str ();
478 
479  if (nargout > 0)
480  retval = msg;
481  else
482  octave_stdout << msg;
483  }
484  else
485  {
486  if (nargout > 0)
487  retval = Cell (string_vector (symbol_names));
488  else
489  {
490  string_vector names (symbol_names);
491 
493 
494  octave_stdout << "\n";
495  }
496  }
497  }
498  else if (retstruct.nfields () != 0)
499  retval = retstruct;
500 
501  return retval;
502 }
503 
504 static std::string
505 find_file_to_load (const std::string& name, const std::string& orig_name)
506 {
508 
509  size_t dot_pos = fname.rfind ('.');
510  size_t sep_pos = fname.find_last_of (octave::sys::file_ops::dir_sep_chars ());
511 
512  if (dot_pos == std::string::npos
513  || (sep_pos != std::string::npos && dot_pos < sep_pos))
514  {
515  // Either no '.' in name or no '.' appears after last directory
516  // separator.
517 
519 
520  if (! (fs.exists () && fs.is_reg ()))
521  fname = find_file_to_load (fname + ".mat", orig_name);
522  }
523  else
524  {
526 
527  if (! (fs.exists () && fs.is_reg ()))
528  {
529  fname = "";
530 
531  error ("load: unable to find file %s", orig_name.c_str ());
532  }
533  }
534 
535  return fname;
536 }
537 
538 bool
540 {
541  bool use_zlib = false;
542  return get_file_format (fname, fname, use_zlib, true) != LS_UNKNOWN;
543 }
544 
545 DEFUN (load, args, nargout,
546  doc: /* -*- texinfo -*-
547 @deftypefn {} {} load file
548 @deftypefnx {} {} load options file
549 @deftypefnx {} {} load options file v1 v2 @dots{}
550 @deftypefnx {} {S =} load ("options", "file", "v1", "v2", @dots{})
551 @deftypefnx {} {} load file options
552 @deftypefnx {} {} load file options v1 v2 @dots{}
553 @deftypefnx {} {S =} load ("file", "options", "v1", "v2", @dots{})
554 Load the named variables @var{v1}, @var{v2}, @dots{}, from the file
555 @var{file}.
556 
557 If no variables are specified then all variables found in the
558 file will be loaded. As with @code{save}, the list of variables to extract
559 can be full names or use a pattern syntax. The format of the file is
560 automatically detected but may be overridden by supplying the appropriate
561 option.
562 
563 If load is invoked using the functional form
564 
565 @example
566 load ("-option1", @dots{}, "file", "v1", @dots{})
567 @end example
568 
569 @noindent
570 then the @var{options}, @var{file}, and variable name arguments
571 (@var{v1}, @dots{}) must be specified as character strings.
572 
573 If a variable that is not marked as global is loaded from a file when a
574 global symbol with the same name already exists, it is loaded in the
575 global symbol table. Also, if a variable is marked as global in a file
576 and a local symbol exists, the local symbol is moved to the global
577 symbol table and given the value from the file.
578 
579 If invoked with a single output argument, Octave returns data instead
580 of inserting variables in the symbol table. If the data file contains
581 only numbers (TAB- or space-delimited columns), a matrix of values is
582 returned. Otherwise, @code{load} returns a structure with members
583  corresponding to the names of the variables in the file.
584 
585 The @code{load} command can read data stored in Octave's text and
586 binary formats, and @sc{matlab}'s binary format. If compiled with zlib
587 support, it can also load gzip-compressed files. It will automatically
588 detect the type of file and do conversion from different floating point
589 formats (currently only IEEE big and little endian, though other formats
590 may be added in the future).
591 
592 Valid options for @code{load} are listed in the following table.
593 
594 @table @code
595 @item -force
596 This option is accepted for backward compatibility but is ignored.
597 Octave now overwrites variables currently in memory with
598 those of the same name found in the file.
599 
600 @item -ascii
601 Force Octave to assume the file contains columns of numbers in text format
602 without any header or other information. Data in the file will be loaded
603 as a single numeric matrix with the name of the variable derived from the
604 name of the file.
605 
606 @item -binary
607 Force Octave to assume the file is in Octave's binary format.
608 
609 @item -hdf5
610 Force Octave to assume the file is in @sc{hdf5} format.
611 (@sc{hdf5} is a free, portable binary format developed by the National
612 Center for Supercomputing Applications at the University of Illinois.)
613 Note that Octave can read @sc{hdf5} files not created by itself, but may
614 skip some datasets in formats that it cannot support. This format is
615 only available if Octave was built with a link to the @sc{hdf5} libraries.
616 
617 @item -import
618 This option is accepted for backward compatibility but is ignored.
619 Octave can now support multi-dimensional HDF data and automatically
620 modifies variable names if they are invalid Octave identifiers.
621 
622 @item -mat
623 @itemx -mat-binary
624 @itemx -6
625 @itemx -v6
626 @itemx -7
627 @itemx -v7
628 Force Octave to assume the file is in @sc{matlab}'s version 6 or 7 binary
629 format.
630 
631 @item -mat4-binary
632 @itemx -4
633 @itemx -v4
634 @itemx -V4
635 Force Octave to assume the file is in the binary format written by
636 @sc{matlab} version 4.
637 
638 @item -text
639 Force Octave to assume the file is in Octave's text format.
640 @end table
641 @seealso{save, dlmwrite, csvwrite, fwrite}
642 @end deftypefn */)
643 {
645 
646  int argc = args.length () + 1;
647 
648  string_vector argv = args.make_argv ("load");
649 
650  int i = 1;
652 
653  // Function called with Matlab-style ["filename", options] syntax
654  if (argc > 1 && ! argv[1].empty () && argv[1].at (0) != '-')
655  {
656  orig_fname = argv[1];
657  i++;
658  }
659 
660  // It isn't necessary to have the default load format stored in a
661  // user preference variable since we can determine the type of file
662  // as we are reading.
663 
665 
666  bool list_only = false;
667  bool verbose = false;
668 
669  for (; i < argc; i++)
670  {
671  if (argv[i] == "-force" || argv[i] == "-f")
672  {
673  // Silently ignore this
674  // warning ("load: -force ignored");
675  }
676  else if (argv[i] == "-list" || argv[i] == "-l")
677  {
678  list_only = true;
679  }
680  else if (argv[i] == "-verbose" || argv[i] == "-v")
681  {
682  verbose = true;
683  }
684  else if (argv[i] == "-ascii" || argv[i] == "-a")
685  {
687  }
688  else if (argv[i] == "-binary" || argv[i] == "-b")
689  {
690  format = LS_BINARY;
691  }
692  else if (argv[i] == "-mat-binary" || argv[i] == "-mat" || argv[i] == "-m"
693  || argv[i] == "-6" || argv[i] == "-v6")
694  {
696  }
697  else if (argv[i] == "-7" || argv[i] == "-v7")
698  {
700  }
701  else if (argv[i] == "-mat4-binary" || argv[i] == "-V4"
702  || argv[i] == "-v4" || argv[i] == "-4")
703  {
705  }
706  else if (argv[i] == "-hdf5" || argv[i] == "-h")
707  {
708 #if defined (HAVE_HDF5)
709  format = LS_HDF5;
710 #else
711  err_disabled_feature ("load", "HDF5");
712 #endif
713  }
714  else if (argv[i] == "-import" || argv[i] == "-i")
715  {
716  warning ("load: -import ignored");
717  }
718  else if (argv[i] == "-text" || argv[i] == "-t")
719  {
720  format = LS_TEXT;
721  }
722  else
723  break;
724  }
725 
726  if (orig_fname == "")
727  {
728  if (i == argc)
729  print_usage ();
730 
731  orig_fname = argv[i];
732  }
733  else
734  i--;
735 
737 
738  bool swap = false;
739 
740  if (orig_fname == "-")
741  {
742  i++;
743 
744 #if defined (HAVE_HDF5)
745  if (format == LS_HDF5)
746  error ("load: cannot read HDF5 format from stdin");
747  else
748 #endif
749  if (format != LS_UNKNOWN)
750  {
751  // FIXME: if we have already seen EOF on a previous call,
752  // how do we fix up the state of std::cin so that we can get
753  // additional input? I'm afraid that we can't fix this
754  // using std::cin only.
755 
756  retval = do_load (std::cin, orig_fname, format, flt_fmt,
758  nargout);
759  }
760  else
761  error ("load: must specify file format if reading from stdin");
762  }
763  else
764  {
766 
768 
769  bool use_zlib = false;
770 
771  if (format == LS_UNKNOWN)
773 
774 #if defined (HAVE_HDF5)
775  if (format == LS_HDF5)
776  {
777  i++;
778 
779  hdf5_ifstream hdf5_file (fname.c_str ());
780 
781  if (hdf5_file.file_id < 0)
782  err_file_open ("load", orig_fname);
783 
784  retval = do_load (hdf5_file, orig_fname, format,
786  argv, i, argc, nargout);
787 
788  hdf5_file.close ();
789  }
790  else
791 #endif
792  // don't insert any statements here; the "else" above has to
793  // go with the "if" below!!!!!
795  {
796  i++;
797 
798  // Always open in binary mode and handle various
799  // line-endings explicitly.
800  std::ios::openmode mode = std::ios::in | std::ios::binary;
801 
802 #if defined (HAVE_ZLIB)
803  if (use_zlib)
804  {
805  gzifstream file (fname.c_str (), mode);
806 
807  if (! file)
808  err_file_open ("load", orig_fname);
809 
810  if (format == LS_BINARY)
811  {
813  {
814  if (file) file.close ();
815  return retval;
816  }
817  }
818  else if (format == LS_MAT5_BINARY
819  || format == LS_MAT7_BINARY)
820  {
822  orig_fname) < 0)
823  {
824  if (file) file.close ();
825  return retval;
826  }
827  }
828 
831  argv, i, argc, nargout);
832 
833  file.close ();
834  }
835  else
836 #endif
837  {
838  std::ifstream file (fname.c_str (), mode);
839 
840  if (! file)
841  error ("load: unable to open input file '%s'",
842  orig_fname.c_str ());
843 
844  if (format == LS_BINARY)
845  {
847  {
848  if (file) file.close ();
849  return retval;
850  }
851  }
852  else if (format == LS_MAT5_BINARY
853  || format == LS_MAT7_BINARY)
854  {
856  orig_fname) < 0)
857  {
858  if (file) file.close ();
859  return retval;
860  }
861  }
862 
865  argv, i, argc, nargout);
866 
867  file.close ();
868  }
869  }
870  else
871  error ("load: unable to determine file format of '%s'",
872  orig_fname.c_str ());
873 
874  }
875 
876  return retval;
877 }
878 
879 // Return TRUE if PATTERN has any special globbing chars in it.
880 
881 static bool
883 {
884  int open = 0;
885 
886  int len = pattern.length ();
887 
888  for (int i = 0; i < len; i++)
889  {
890  char c = pattern[i];
891 
892  switch (c)
893  {
894  case '?':
895  case '*':
896  return true;
897 
898  case '[': // Only accept an open brace if there is a close
899  open++; // brace to match it. Bracket expressions must be
900  continue; // complete, according to Posix.2
901 
902  case ']':
903  if (open)
904  return true;
905  continue;
906 
907  case '\\':
908  if (i == len - 1)
909  return false;
910  continue;
911 
912  default:
913  continue;
914  }
915  }
916 
917  return false;
918 }
919 
920 static void
921 do_save (std::ostream& os, const octave_value& tc,
922  const std::string& name, const std::string& help,
923  bool global, load_save_format fmt, bool save_as_floats)
924 {
925  switch (fmt.type)
926  {
927  case LS_TEXT:
928  save_text_data (os, tc, name, global, 0);
929  break;
930 
931  case LS_BINARY:
932  save_binary_data (os, tc, name, help, global, save_as_floats);
933  break;
934 
935  case LS_MAT_ASCII:
936  if (! save_mat_ascii_data (os, tc, fmt.opts & LS_MAT_ASCII_LONG ? 16 : 8,
937  fmt.opts & LS_MAT_ASCII_TABS))
938  warning ("save: unable to save %s in ASCII format", name.c_str ());
939  break;
940 
941  case LS_MAT_BINARY:
943  break;
944 
945 #if defined (HAVE_HDF5)
946  case LS_HDF5:
947  save_hdf5_data (os, tc, name, help, global, save_as_floats);
948  break;
949 #endif
950 
951  case LS_MAT5_BINARY:
952  save_mat5_binary_element (os, tc, name, global, false, save_as_floats);
953  break;
954 
955  case LS_MAT7_BINARY:
956  save_mat5_binary_element (os, tc, name, global, true, save_as_floats);
957  break;
958 
959  default:
960  err_unrecognized_data_fmt ("save");
961  break;
962  }
963 }
964 
965 // Save the info from SR on stream OS in the format specified by FMT.
966 
967 void
968 do_save (std::ostream& os, const octave::symbol_record& sr,
971 {
973 
974  if (val.is_defined ())
975  {
976  std::string name = sr.name ();
977  std::string help;
978  bool global = sr.is_global ();
979 
980  do_save (os, val, name, help, global, fmt, save_as_floats);
981  }
982 }
983 
984 // save fields of a scalar structure STR matching PATTERN on stream OS
985 // in the format specified by FMT.
986 
987 static size_t
988 save_fields (std::ostream& os, const octave_scalar_map& m,
989  const std::string& pattern,
991 {
992  glob_match pat (pattern);
993 
994  size_t saved = 0;
995 
996  for (octave_scalar_map::const_iterator it = m.begin (); it != m.end (); it++)
997  {
998  std::string empty_str;
999 
1000  if (pat.match (m.key (it)))
1001  {
1002  do_save (os, m.contents (it), m.key (it), empty_str,
1003  0, fmt, save_as_floats);
1004 
1005  saved++;
1006  }
1007  }
1008 
1009  return saved;
1010 }
1011 
1012 // Save variables with names matching PATTERN on stream OS in the
1013 // format specified by FMT.
1014 
1015 static size_t
1016 save_vars (std::ostream& os, const std::string& pattern,
1017  load_save_format fmt, bool save_as_floats)
1018 {
1020 
1022 
1023  std::list<octave::symbol_record> vars = scope.glob (pattern);
1024 
1025  size_t saved = 0;
1026 
1027  for (const auto& var : vars)
1028  {
1029  do_save (os, var, context, fmt, save_as_floats);
1030 
1031  saved++;
1032  }
1033 
1034  return saved;
1035 }
1036 
1037 static string_vector
1039  load_save_format& format, bool& append,
1040  bool& save_as_floats, bool& use_zlib)
1041 {
1042 #if ! defined (HAVE_ZLIB)
1043  octave_unused_parameter (use_zlib);
1044 #endif
1045 
1047  int argc = argv.numel ();
1048 
1049  bool do_double = false;
1050  bool do_tabs = false;
1051 
1052  for (int i = 0; i < argc; i++)
1053  {
1054  if (argv[i] == "-append")
1055  {
1056  append = true;
1057  }
1058  else if (argv[i] == "-ascii" || argv[i] == "-a")
1059  {
1060  format = LS_MAT_ASCII;
1061  }
1062  else if (argv[i] == "-double")
1063  {
1064  do_double = true;
1065  }
1066  else if (argv[i] == "-tabs")
1067  {
1068  do_tabs = true;
1069  }
1070  else if (argv[i] == "-text" || argv[i] == "-t")
1071  {
1072  format = LS_TEXT;
1073  }
1074  else if (argv[i] == "-binary" || argv[i] == "-b")
1075  {
1076  format = LS_BINARY;
1077  }
1078  else if (argv[i] == "-hdf5" || argv[i] == "-h")
1079  {
1080 #if defined (HAVE_HDF5)
1081  format = LS_HDF5;
1082 #else
1083  err_disabled_feature ("save", "HDF5");
1084 #endif
1085  }
1086  else if (argv[i] == "-mat-binary" || argv[i] == "-mat"
1087  || argv[i] == "-m" || argv[i] == "-6" || argv[i] == "-v6"
1088  || argv[i] == "-V6")
1089  {
1091  }
1092 #if defined (HAVE_ZLIB)
1093  else if (argv[i] == "-mat7-binary" || argv[i] == "-7"
1094  || argv[i] == "-v7" || argv[i] == "-V7")
1095  {
1097  }
1098 #endif
1099  else if (argv[i] == "-mat4-binary" || argv[i] == "-V4"
1100  || argv[i] == "-v4" || argv[i] == "-4")
1101  {
1103  }
1104  else if (argv[i] == "-float-binary" || argv[i] == "-f")
1105  {
1106  format = LS_BINARY;
1107  save_as_floats = true;
1108  }
1109  else if (argv[i] == "-float-hdf5")
1110  {
1111 #if defined (HAVE_HDF5)
1112  format = LS_HDF5;
1113  save_as_floats = true;
1114 #else
1115  err_disabled_feature ("save", "HDF5");
1116 #endif
1117  }
1118 #if defined (HAVE_ZLIB)
1119  else if (argv[i] == "-zip" || argv[i] == "-z")
1120  {
1121  use_zlib = true;
1122  }
1123 #endif
1124  else if (argv[i] == "-struct")
1125  {
1126  retval.append (argv[i]);
1127  }
1128  else if (argv[i][0] == '-' && argv[i] != "-")
1129  {
1130  error ("save: Unrecognized option '%s'", argv[i].c_str ());
1131  }
1132  else
1133  retval.append (argv[i]);
1134  }
1135 
1136  if (do_double)
1137  {
1138  if (format == LS_MAT_ASCII)
1139  format.opts |= LS_MAT_ASCII_LONG;
1140  else
1141  warning (R"(save: "-double" option only has an effect with "-ascii")");
1142  }
1143 
1144  if (do_tabs)
1145  {
1146  if (format == LS_MAT_ASCII)
1147  format.opts |= LS_MAT_ASCII_TABS;
1148  else
1149  warning (R"(save: "-tabs" option only has an effect with "-ascii")");
1150  }
1151 
1152  return retval;
1153 }
1154 
1155 static string_vector
1157  bool& append, bool& save_as_floats, bool& use_zlib)
1158 {
1159  std::istringstream is (arg);
1160  std::string str;
1162 
1163  while (! is.eof ())
1164  {
1165  is >> str;
1166  argv.append (str);
1167  }
1168 
1170 }
1171 
1172 void
1174 {
1175  switch (format.type)
1176  {
1177  case LS_BINARY:
1178  {
1180  ? "Octave-1-B" : "Octave-1-L");
1181 
1184 
1185  char tmp = static_cast<char> (float_format_to_mopt_digit (flt_fmt));
1186 
1187  os.write (&tmp, 1);
1188  }
1189  break;
1190 
1191  case LS_MAT5_BINARY:
1192  case LS_MAT7_BINARY:
1193  {
1194  char const *versionmagic;
1195  char headertext[128];
1197 
1198  // ISO 8601 format date
1199  const char *matlab_format = "MATLAB 5.0 MAT-file, written by Octave "
1200  OCTAVE_VERSION ", %Y-%m-%d %T UTC";
1201  std::string comment_string = now.strftime (matlab_format);
1202 
1203  size_t len = std::min (comment_string.length (), static_cast<size_t> (124));
1204  memset (headertext, ' ', 124);
1205  memcpy (headertext, comment_string.data (), len);
1206 
1207  // The first pair of bytes give the version of the MAT file
1208  // format. The second pair of bytes form a magic number which
1209  // signals a MAT file. MAT file data are always written in
1210  // native byte order. The order of the bytes in the second
1211  // pair indicates whether the file was written by a big- or
1212  // little-endian machine. However, the version number is
1213  // written in the *opposite* byte order from everything else!
1215  versionmagic = "\x01\x00\x4d\x49"; // this machine is big endian
1216  else
1217  versionmagic = "\x00\x01\x49\x4d"; // this machine is little endian
1218 
1219  memcpy (headertext+124, versionmagic, 4);
1220  os.write (headertext, 128);
1221  }
1222 
1223  break;
1224 
1225 #if defined (HAVE_HDF5)
1226  case LS_HDF5:
1227 #endif
1228  case LS_TEXT:
1229  {
1231 
1232  std::string comment_string = now.strftime (Vsave_header_format_string);
1233 
1234  if (! comment_string.empty ())
1235  {
1236 #if defined (HAVE_HDF5)
1237  if (format == LS_HDF5)
1238  {
1239  hdf5_ofstream& hs = dynamic_cast<hdf5_ofstream&> (os);
1240  H5Gset_comment (hs.file_id, "/", comment_string.c_str ());
1241  }
1242  else
1243 #endif
1244  os << comment_string << "\n";
1245  }
1246  }
1247  break;
1248 
1249  default:
1250  break;
1251  }
1252 }
1253 
1254 void
1256 {
1257 #if defined (HAVE_HDF5)
1258  H5dont_atexit ();
1259 #endif
1260 }
1261 
1262 void
1264 {
1265 #if defined (HAVE_HDF5)
1266  H5close ();
1267 #endif
1268 }
1269 
1270 static void
1271 save_vars (const string_vector& argv, int argv_idx, int argc,
1272  std::ostream& os, load_save_format fmt,
1273  bool save_as_floats, bool write_header_info)
1274 {
1275  if (write_header_info)
1276  write_header (os, fmt);
1277 
1278  if (argv_idx == argc)
1279  {
1280  save_vars (os, "*", fmt, save_as_floats);
1281  }
1282  else if (argv[argv_idx] == "-struct")
1283  {
1284  if (++argv_idx >= argc)
1285  error ("save: missing struct name");
1286 
1287  std::string struct_name = argv[argv_idx];
1288 
1290 
1291  octave_value struct_var;
1292 
1293  if (scope)
1294  {
1295  if (! scope.is_variable (struct_name))
1296  error ("save: no such variable: '%s'", struct_name.c_str ());
1297 
1298  struct_var = scope.varval (struct_name);
1299  }
1300 
1301  if (! struct_var.isstruct () || struct_var.numel () != 1)
1302  error ("save: '%s' is not a scalar structure", struct_name.c_str ());
1303 
1304  octave_scalar_map struct_var_map = struct_var.scalar_map_value ();
1305 
1306  ++argv_idx;
1307 
1308  if (argv_idx < argc)
1309  {
1310  for (int i = argv_idx; i < argc; i++)
1311  {
1312  if (! save_fields (os, struct_var_map, argv[i], fmt,
1313  save_as_floats))
1314  {
1315  warning ("save: no such field '%s.%s'",
1316  struct_name.c_str (), argv[i].c_str ());
1317  }
1318  }
1319  }
1320  else
1321  save_fields (os, struct_var_map, "*", fmt, save_as_floats);
1322  }
1323  else
1324  {
1325  for (int i = argv_idx; i < argc; i++)
1326  {
1327  if (argv[i] == "")
1328  continue; // Skip empty vars for Matlab compatibility
1329  if (! save_vars (os, argv[i], fmt, save_as_floats))
1330  warning ("save: no such variable '%s'", argv[i].c_str ());
1331  }
1332  }
1333 }
1334 
1335 static void
1336 dump_octave_core (std::ostream& os, const char *fname, load_save_format fmt,
1337  bool save_as_floats)
1338 {
1339  write_header (os, fmt);
1340 
1341  octave::symbol_table& symtab =
1342  octave::__get_symbol_table__ ("dump_octave_core");
1343 
1344  octave::symbol_scope top_scope = symtab.top_scope ();
1345 
1347 
1348  std::list<octave::symbol_record> vars = top_scope.all_variables ();
1349 
1350  double save_mem_size = 0;
1351 
1352  for (const auto& var : vars)
1353  {
1354  octave_value val = var.varval (context);
1355 
1356  if (val.is_defined ())
1357  {
1358  std::string name = var.name ();
1359  std::string help;
1360  bool global = var.is_global ();
1361 
1362  double val_size = val.byte_size () / 1024;
1363 
1364  // FIXME: maybe we should try to throw out the largest first...
1365 
1366  if (Voctave_core_file_limit < 0
1367  || save_mem_size + val_size < Voctave_core_file_limit)
1368  {
1369  save_mem_size += val_size;
1370 
1371  do_save (os, val, name, help, global, fmt, save_as_floats);
1372  }
1373  }
1374  }
1375 
1376  message (nullptr, "save to '%s' complete", fname);
1377 }
1378 
1379 void
1381 {
1383  {
1384  // FIXME: should choose better filename?
1385 
1386  const char *fname = Voctave_core_file_name.c_str ();
1387 
1388  message (nullptr, "attempting to save variables to '%s'...", fname);
1389 
1391 
1392  bool save_as_floats = false;
1393 
1394  bool append = false;
1395 
1396  bool use_zlib = false;
1397 
1400 
1401  std::ios::openmode mode = std::ios::out;
1402 
1403  // Matlab v7 files are always compressed
1404  if (format == LS_MAT7_BINARY)
1405  use_zlib = false;
1406 
1407  if (format == LS_BINARY
1408 #if defined (HAVE_HDF5)
1409  || format == LS_HDF5
1410 #endif
1411  || format == LS_MAT_BINARY
1412  || format == LS_MAT5_BINARY
1413  || format == LS_MAT7_BINARY)
1414  mode |= std::ios::binary;
1415 
1416  mode |= append ? std::ios::ate : std::ios::trunc;
1417 
1418 #if defined (HAVE_HDF5)
1419  if (format == LS_HDF5)
1420  {
1422 
1423  if (file.file_id >= 0)
1424  {
1426 
1427  file.close ();
1428  }
1429  else
1430  warning ("dump_octave_core: unable to open '%s' for writing...",
1431  fname);
1432  }
1433  else
1434 #endif
1435  // don't insert any commands here! The open brace below must
1436  // go with the else above!
1437  {
1438 #if defined (HAVE_ZLIB)
1439  if (use_zlib)
1440  {
1442 
1443  if (file)
1444  {
1446 
1447  file.close ();
1448  }
1449  else
1450  warning ("dump_octave_core: unable to open '%s' for writing...",
1451  fname);
1452  }
1453  else
1454 #endif
1455  {
1456  std::ofstream file (fname, mode);
1457 
1458  if (file)
1459  {
1461 
1462  file.close ();
1463  }
1464  else
1465  warning ("dump_octave_core: unable to open '%s' for writing...",
1466  fname);
1467  }
1468  }
1469  }
1470 }
1471 
1472 DEFUN (save, args, nargout,
1473  doc: /* -*- texinfo -*-
1474 @deftypefn {} {} save file
1475 @deftypefnx {} {} save options file
1476 @deftypefnx {} {} save options file @var{v1} @var{v2} @dots{}
1477 @deftypefnx {} {} save options file -struct @var{STRUCT}
1478 @deftypefnx {} {} save options file -struct @var{STRUCT} @var{f1} @var{f2} @dots{}
1479 @deftypefnx {} {} save - @var{v1} @var{v2} @dots{}
1480 @deftypefnx {} {@var{str} =} save ("-", @qcode{"@var{v1}"}, @qcode{"@var{v2}"}, @dots{})
1481 Save the named variables @var{v1}, @var{v2}, @dots{}, in the file @var{file}.
1482 
1483 The special filename @samp{-} may be used to return the content of the
1484 variables as a string. If no variable names are listed, Octave saves all the
1485 variables in the current scope. Otherwise, full variable names or pattern
1486 syntax can be used to specify the variables to save. If the @option{-struct}
1487 modifier is used then the fields of the @strong{scalar} struct are saved as if
1488 they were variables with the corresponding field names. The @option{-struct}
1489 option can be combined with specific field names @var{f1}, @var{f2}, @dots{} to
1490 write only certain fields to the file.
1491 
1492 Valid options for the @code{save} command are listed in the following table.
1493 Options that modify the output format override the format specified by
1494 @code{save_default_options}.
1495 
1496 If save is invoked using the functional form
1497 
1498 @example
1499 save ("-option1", @dots{}, "file", "v1", @dots{})
1500 @end example
1501 
1502 @noindent
1503 then the @var{options}, @var{file}, and variable name arguments (@var{v1},
1504 @dots{}) must be specified as character strings.
1505 
1506 If called with a filename of @qcode{"-"}, write the output to stdout if nargout
1507 is 0, otherwise return the output in a character string.
1508 
1509 @table @code
1510 @item -append
1511 Append to the destination instead of overwriting.
1512 
1513 @item -ascii
1514 Save a matrix in a text file without a header or any other information. The
1515 matrix must be 2-D and only the real part of any complex value is written to
1516 the file. Numbers are stored in single-precision format and separated by
1517 spaces. Additional options for the @option{-ascii} format are
1518 
1519 @table @code
1520 @item -double
1521 Store numbers in double-precision format.
1522 
1523 @item -tabs
1524 Separate numbers with tabs.
1525 @end table
1526 
1527 @item -binary
1528 Save the data in Octave's binary data format.
1529 
1530 @item -float-binary
1531 Save the data in Octave's binary data format but using only single precision.
1532 Use this format @strong{only} if you know that all the values to be saved can
1533 be represented in single precision.
1534 
1535 @item -hdf5
1536 Save the data in @sc{hdf5} format.
1537 (HDF5 is a free, portable, binary format developed by the National Center for
1538 Supercomputing Applications at the University of Illinois.) This format is only
1539 available if Octave was built with a link to the @sc{hdf5} libraries.
1540 
1541 @item -float-hdf5
1542 Save the data in @sc{hdf5} format but using only single precision. Use this
1543 format @strong{only} if you know that all the values to be saved can be
1544 represented in single precision.
1545 
1546 @item -V7
1547 @itemx -v7
1548 @itemx -7
1549 @itemx -mat7-binary
1550 Save the data in @sc{matlab}'s v7 binary data format.
1551 
1552 @item -V6
1553 @itemx -v6
1554 @itemx -6
1555 @itemx -mat
1556 @itemx -mat-binary
1557 Save the data in @sc{matlab}'s v6 binary data format.
1558 
1559 @item -V4
1560 @itemx -v4
1561 @itemx -4
1562 @itemx -mat4-binary
1563 Save the data in the binary format written by @sc{matlab} version 4.
1564 
1565 @item -text
1566 Save the data in Octave's text data format. (default).
1567 
1568 @item -zip
1569 @itemx -z
1570 Use the gzip algorithm to compress the file. This works on files that are
1571 compressed with gzip outside of Octave, and gzip can also be used to convert
1572 the files for backward compatibility. This option is only available if Octave
1573 was built with a link to the zlib libraries.
1574 @end table
1575 
1576 The list of variables to save may use wildcard patterns containing the
1577 following special characters:
1578 
1579 @table @code
1580 @item ?
1581 Match any single character.
1582 
1583 @item *
1584 Match zero or more characters.
1585 
1586 @item [ @var{list} ]
1587 Match the list of characters specified by @var{list}. If the first character
1588 is @code{!} or @code{^}, match all characters except those specified by
1589 @var{list}. For example, the pattern @code{[a-zA-Z]} will match all lower and
1590 uppercase alphabetic characters.
1591 
1592 Wildcards may also be used in the field name specifications when using the
1593 @option{-struct} modifier (but not in the struct name itself).
1594 
1595 @end table
1596 
1597 Except when using the @sc{matlab} binary data file format or the @samp{-ascii}
1598 format, saving global variables also saves the global status of the variable.
1599 If the variable is restored at a later time using @samp{load}, it will be
1600 restored as a global variable.
1601 
1602 The command
1603 
1604 @example
1605 save -binary data a b*
1606 @end example
1607 
1608 @noindent
1609 saves the variable @samp{a} and all variables beginning with @samp{b} to the
1610 file @file{data} in Octave's binary format.
1611 @seealso{load, save_default_options, save_header_format_string, save_precision, dlmread, csvread, fread}
1612 @end deftypefn */)
1613 {
1614  // Here is where we would get the default save format if it were
1615  // stored in a user preference variable.
1617  bool save_as_floats = false;
1618  bool append = false;
1619  bool use_zlib = false;
1620 
1621  // get default options
1623  use_zlib);
1624 
1625  // override from command line
1626  string_vector argv = args.make_argv ();
1627 
1629 
1630  int argc = argv.numel ();
1631  int i = 0;
1632 
1633  if (i == argc)
1634  print_usage ();
1635 
1636  if (save_as_floats && format == LS_TEXT)
1637  error ("save: cannot specify both -text and -float-binary");
1638 
1640 
1641  if (argv[i] == "-")
1642  {
1643  i++;
1644 
1645 #if defined (HAVE_HDF5)
1646  if (format == LS_HDF5)
1647  error ("save: cannot write HDF5 format to stdout");
1648  else
1649 #endif
1650  // don't insert any commands here! the brace below must go
1651  // with the "else" above!
1652  {
1653  if (append)
1654  warning ("save: ignoring -append option for output to stdout");
1655 
1656  if (nargout == 0)
1657  save_vars (argv, i, argc, std::cout, format, save_as_floats, true);
1658  else
1659  {
1660  std::ostringstream output_buf;
1661  save_vars (argv, i, argc, output_buf, format, save_as_floats, true);
1662  retval = octave_value (output_buf.str());
1663  }
1664  }
1665  }
1666 
1667  // Guard against things like 'save a*', which are probably mistakes...
1668 
1669  else if (i == argc - 1 && glob_pattern_p (argv[i]))
1670  print_usage ();
1671  else
1672  {
1674 
1675  i++;
1676 
1677  // Matlab v7 files are always compressed
1678  if (format == LS_MAT7_BINARY)
1679  use_zlib = false;
1680 
1681  std::ios::openmode mode
1682  = (append ? (std::ios::app | std::ios::ate) : std::ios::out);
1683 
1684  if (format == LS_BINARY
1685 #if defined (HAVE_HDF5)
1686  || format == LS_HDF5
1687 #endif
1688  || format == LS_MAT_BINARY
1689  || format == LS_MAT5_BINARY
1690  || format == LS_MAT7_BINARY)
1691  mode |= std::ios::binary;
1692 
1693 #if defined (HAVE_HDF5)
1694  if (format == LS_HDF5)
1695  {
1696  // FIXME: It should be possible to append to HDF5 files.
1697  if (append)
1698  error ("save: appending to HDF5 files is not implemented");
1699 
1700  bool write_header_info
1701  = ! (append && H5Fis_hdf5 (fname.c_str ()) > 0);
1702 
1703  hdf5_ofstream hdf5_file (fname.c_str (), mode);
1704 
1705  if (hdf5_file.file_id == -1)
1706  err_file_open ("save", fname);
1707 
1708  save_vars (argv, i, argc, hdf5_file, format,
1709  save_as_floats, write_header_info);
1710 
1711  hdf5_file.close ();
1712  }
1713  else
1714 #endif
1715  // don't insert any statements here! The brace below must go
1716  // with the "else" above!
1717  {
1718 #if defined (HAVE_ZLIB)
1719  if (use_zlib)
1720  {
1721  gzofstream file (fname.c_str (), mode);
1722 
1723  if (! file)
1724  err_file_open ("save", fname);
1725 
1726  bool write_header_info = ! file.tellp ();
1727 
1728  save_vars (argv, i, argc, file, format,
1729  save_as_floats, write_header_info);
1730 
1731  file.close ();
1732  }
1733  else
1734 #endif
1735  {
1736  std::ofstream file (fname.c_str (), mode);
1737 
1738  if (! file)
1739  err_file_open ("save", fname);
1740 
1741  bool write_header_info = ! file.tellp ();
1742 
1743  save_vars (argv, i, argc, file, format,
1744  save_as_floats, write_header_info);
1745 
1746  file.close ();
1747  }
1748  }
1749  }
1750 
1751  return retval;
1752 }
1753 
1754 DEFUN (crash_dumps_octave_core, args, nargout,
1755  doc: /* -*- texinfo -*-
1756 @deftypefn {} {@var{val} =} crash_dumps_octave_core ()
1757 @deftypefnx {} {@var{old_val} =} crash_dumps_octave_core (@var{new_val})
1758 @deftypefnx {} {} crash_dumps_octave_core (@var{new_val}, "local")
1759 Query or set the internal variable that controls whether Octave tries
1760 to save all current variables to the file @file{octave-workspace} if it
1761 crashes or receives a hangup, terminate or similar signal.
1762 
1763 When called from inside a function with the @qcode{"local"} option, the
1764 variable is changed locally for the function and any subroutines it calls.
1765 The original variable value is restored when exiting the function.
1766 @seealso{octave_core_file_limit, octave_core_file_name, octave_core_file_options}
1767 @end deftypefn */)
1768 {
1769  return SET_INTERNAL_VARIABLE (crash_dumps_octave_core);
1770 }
1771 
1772 DEFUN (save_default_options, args, nargout,
1773  doc: /* -*- texinfo -*-
1774 @deftypefn {} {@var{val} =} save_default_options ()
1775 @deftypefnx {} {@var{old_val} =} save_default_options (@var{new_val})
1776 @deftypefnx {} {} save_default_options (@var{new_val}, "local")
1777 Query or set the internal variable that specifies the default options
1778 for the @code{save} command, and defines the default format.
1779 
1780 The default value is @qcode{"-text"} (Octave's own text-based file format).
1781 See the documentation of the @code{save} command for other choices.
1782 
1783 When called from inside a function with the @qcode{"local"} option, the
1784 variable is changed locally for the function and any subroutines it calls.
1785 The original variable value is restored when exiting the function.
1786 @seealso{save, save_header_format_string, save_precision}
1787 @end deftypefn */)
1788 {
1789  return SET_NONEMPTY_INTERNAL_STRING_VARIABLE (save_default_options);
1790 }
1791 
1792 DEFUN (octave_core_file_limit, args, nargout,
1793  doc: /* -*- texinfo -*-
1794 @deftypefn {} {@var{val} =} octave_core_file_limit ()
1795 @deftypefnx {} {@var{old_val} =} octave_core_file_limit (@var{new_val})
1796 @deftypefnx {} {} octave_core_file_limit (@var{new_val}, "local")
1797 Query or set the internal variable that specifies the maximum amount of memory
1798 that Octave will save when writing a crash dump file.
1799 
1800 The limit is measured in kilobytes and is applied to the top-level workspace.
1801 The name of the crash dump file is specified by
1802 @var{octave_core_file_name}.
1803 
1804 If @var{octave_core_file_options} flags specify a binary format, then
1805 @var{octave_core_file_limit} will be approximately the maximum size of the
1806 file. If a text file format is used, then the file could be much larger than
1807 the limit. The default value is -1 (unlimited).
1808 
1809 When called from inside a function with the @qcode{"local"} option, the
1810 variable is changed locally for the function and any subroutines it calls.
1811 The original variable value is restored when exiting the function.
1812 @seealso{crash_dumps_octave_core, octave_core_file_name, octave_core_file_options}
1813 @end deftypefn */)
1814 {
1815  return SET_INTERNAL_VARIABLE (octave_core_file_limit);
1816 }
1817 
1818 DEFUN (octave_core_file_name, args, nargout,
1819  doc: /* -*- texinfo -*-
1820 @deftypefn {} {@var{val} =} octave_core_file_name ()
1821 @deftypefnx {} {@var{old_val} =} octave_core_file_name (@var{new_val})
1822 @deftypefnx {} {} octave_core_file_name (@var{new_val}, "local")
1823 Query or set the internal variable that specifies the name of the file
1824 used for saving data from the top-level workspace if Octave aborts.
1825 
1826 The default value is @qcode{"octave-workspace"}
1827 
1828 When called from inside a function with the @qcode{"local"} option, the
1829 variable is changed locally for the function and any subroutines it calls.
1830 The original variable value is restored when exiting the function.
1831 @seealso{crash_dumps_octave_core, octave_core_file_name, octave_core_file_options}
1832 @end deftypefn */)
1833 {
1834  return SET_NONEMPTY_INTERNAL_STRING_VARIABLE (octave_core_file_name);
1835 }
1836 
1837 DEFUN (octave_core_file_options, args, nargout,
1838  doc: /* -*- texinfo -*-
1839 @deftypefn {} {@var{val} =} octave_core_file_options ()
1840 @deftypefnx {} {@var{old_val} =} octave_core_file_options (@var{new_val})
1841 @deftypefnx {} {} octave_core_file_options (@var{new_val}, "local")
1842 Query or set the internal variable that specifies the options used for
1843 saving the workspace data if Octave aborts.
1844 
1845 The value of @code{octave_core_file_options} should follow the same format
1846 as the options for the @code{save} function. The default value is Octave's
1847 binary format.
1848 
1849 When called from inside a function with the @qcode{"local"} option, the
1850 variable is changed locally for the function and any subroutines it calls.
1851 The original variable value is restored when exiting the function.
1852 @seealso{crash_dumps_octave_core, octave_core_file_name, octave_core_file_limit}
1853 @end deftypefn */)
1854 {
1855  return SET_NONEMPTY_INTERNAL_STRING_VARIABLE (octave_core_file_options);
1856 }
1857 
1858 DEFUN (save_header_format_string, args, nargout,
1859  doc: /* -*- texinfo -*-
1860 @deftypefn {} {@var{val} =} save_header_format_string ()
1861 @deftypefnx {} {@var{old_val} =} save_header_format_string (@var{new_val})
1862 @deftypefnx {} {} save_header_format_string (@var{new_val}, "local")
1863 Query or set the internal variable that specifies the format string used for
1864 the comment line written at the beginning of text-format data files saved by
1865 Octave.
1866 
1867 The format string is passed to @code{strftime} and must begin with the
1868 character @samp{#} and contain no newline characters. If the value of
1869 @code{save_header_format_string} is the empty string, the header comment is
1870 omitted from text-format data files. The default value is
1871 @c Set example in small font to prevent overfull line
1872 
1873 @smallexample
1874 "# Created by Octave VERSION, %a %b %d %H:%M:%S %Y %Z <USER@@HOST>"
1875 @end smallexample
1876 
1877 When called from inside a function with the @qcode{"local"} option, the
1878 variable is changed locally for the function and any subroutines it calls.
1879 The original variable value is restored when exiting the function.
1880 @seealso{strftime, save_default_options}
1881 @end deftypefn */)
1882 {
1883  return SET_INTERNAL_VARIABLE (save_header_format_string);
1884 }
octave_idx_type write(const octave_value &data, octave_idx_type block_size, oct_data_conv::data_type output_type, octave_idx_type skip, mach_info::float_format flt_fmt)
Definition: oct-stream.cc:6704
octave_value do_load(std::istream &stream, const std::string &orig_fname, load_save_format format, octave::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:357
static std::string Voctave_core_file_name
Definition: load-save.cc:102
static std::string default_save_header_format(void)
Definition: load-save.cc:112
static void do_save(std::ostream &os, const octave_value &tc, const std::string &name, const std::string &help, bool global, load_save_format fmt, bool save_as_floats)
Definition: load-save.cc:921
static int left
Definition: randmtzig.cc:184
symbol_scope top_scope(void)
Definition: symtab.h:75
Definition: Cell.h:37
For example cd octave end example noindent changes the current working directory to file
Definition: dirfns.cc:124
bool is_global(void) const
Definition: symrec.h:653
static bool Vcrash_dumps_octave_core
Definition: load-save.cc:95
std::string read_mat_ascii_data(std::istream &is, const std::string &filename, octave_value &tc)
void assign(const std::string &name, const octave_value &value, bool force_add)
Definition: symscope.h:707
int read_binary_file_header(std::istream &is, bool &swap, octave::mach_info::float_format &flt_fmt, bool quiet)
Definition: load-save.cc:188
fname
Definition: load-save.cc:767
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:727
void octave_prepare_hdf5(void)
Definition: load-save.cc:1255
symbol_scope global_scope(void)
Definition: symtab.h:74
bool is_octave_data_file(const std::string &fname)
Definition: load-save.cc:539
OCTINTERP_API void print_usage(void)
Definition: defun.cc:54
std::string dir_sep_chars(void)
Definition: file-ops.cc:242
static OCTAVE_NORETURN void err_file_open(const std::string &fcn, const std::string &file)
Definition: load-save.cc:130
int i
Definition: load-save.cc:650
identity matrix If supplied two scalar respectively For allows like xample val
Definition: data.cc:4986
int argc
Definition: load-save.cc:646
Return the CPU time used by your Octave session The first output is the total time spent executing your process and is equal to the sum of second and third which are the number of CPU seconds spent executing in user mode and the number of CPU seconds spent executing in system mode
Definition: data.cc:6348
symbol_record find_symbol(const std::string &name)
Definition: symscope.h:674
octave::sys::time now
Definition: data.cc:6251
static std::map< std::string, std::string > vars
Definition: mkoctfile.in.cc:52
void err_unrecognized_data_fmt(const char *name)
Definition: errwarn.cc:130
std::string tilde_expand(const std::string &name)
Definition: file-ops.cc:276
bool looks_like_mat_ascii_file(std::istream &is, const std::string &filename)
Gzipped file output stream class.
Definition: zfstream.h:365
std::string orig_fname
Definition: load-save.cc:651
#define DEFUN(name, args_name, nargout_name, doc)
Macro to define a builtin function.
Definition: defun.h:53
#define SET_INTERNAL_VARIABLE(NM)
Definition: variables.h:109
std::ostream & list_in_columns(std::ostream &, int width=0, const std::string &prefix="") const
Definition: str-vec.cc:195
void bind_fwd_rep(const std::shared_ptr< symbol_scope_rep > &fwd_scope, const symbol_record &sr)
Definition: symrec.h:683
static std::string Voctave_core_file_options
Definition: load-save.cc:109
static bool glob_pattern_p(const std::string &pattern)
Definition: load-save.cc:882
std::string filename
Definition: urlwrite.cc:121
octave::mach_info::float_format flt_fmt
Definition: load-save.cc:736
bool is_defined(void) const
Definition: ov.h:523
static llvm::LLVMContext & context
Definition: jit-typeinfo.cc:79
symbol_scope __get_current_scope__(const std::string &who)
bool list_only
Definition: load-save.cc:666
nd example oindent opens the file binary numeric values will be read assuming they are stored in IEEE format with the least significant bit and then converted to the native representation Opening a file that is already open simply opens it again and returns a separate file id It is not an error to open a file several though writing to the same file through several different file ids may produce unexpected results The possible values of text mode reading and writing automatically converts linefeeds to the appropriate line end character for the you may append a you must also open the file in binary mode The parameter conversions are currently only supported for and permissions will be set to and then everything is written in a single operation This is very efficient and improves performance c
Definition: file-io.cc:587
std::string read_mat5_binary_element(std::istream &is, const std::string &filename, bool swap, bool &global, octave_value &tc)
Definition: ls-mat5.cc:476
in this the arguments are accumulated from left to right
Definition: data.cc:390
octave_value arg
Definition: pr-output.cc:3244
octave_function * fcn
Definition: ov-class.cc:1754
else error("load: unable to determine file format of '%s'", orig_fname.c_str())
string_vector argv
Definition: load-save.cc:648
#define OCTAVE_VERSION
Definition: main.in.cc:48
bool swap
Definition: load-save.cc:738
bool verbose
Definition: load-save.cc:667
bool save_mat_ascii_data(std::ostream &os, const octave_value &val, int precision, bool tabs)
std::list< symbol_record > all_variables(bool defined_only=true, unsigned int exclude=symbol_record::hidden) const
Definition: symscope.h:808
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:105
void message(const char *name, const char *fmt,...)
Definition: error.cc:435
symbol_table & __get_symbol_table__(const std::string &who)
create a structure array and initialize its values The dimensions of each cell array of values must match Singleton cells and non cell values are repeated so that they fill the entire array If the cells are empty
Definition: ov-struct.cc:1736
nd deftypefn *std::string name
Definition: sysdep.cc:647
static bool check_gzip_magic(const std::string &fname)
Definition: load-save.cc:226
octave_fields::const_iterator const_iterator
Definition: oct-map.h:181
OCTAVE_EXPORT octave_value_list return the number of command line arguments passed to Octave If called with the optional argument the function xample nargout(@histc)
Definition: ov-usr-fcn.cc:997
static size_t save_fields(std::ostream &os, const octave_scalar_map &m, const std::string &pattern, load_save_format fmt, bool save_as_floats)
Definition: load-save.cc:988
std::string extract_keyword(std::istream &is, const char *keyword, const bool next_only)
Definition: ls-oct-text.cc:82
octave_idx_type numel(const octave_value_list &idx)
Definition: ov.h:412
std::string name(void) const
Definition: symrec.h:576
int float_format_to_mopt_digit(octave::mach_info::float_format flt_fmt)
Definition: ls-mat4.cc:198
std::list< symbol_record > glob(const std::string &pattern, bool vars_only=false) const
Definition: symscope.h:817
symbol_record::context_id current_context(void) const
Definition: symscope.h:669
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:1148
octave_idx_type columns(void) const
Definition: ov.h:474
bool match(const std::string &str) const
Definition: glob-match.cc:32
std::shared_ptr< symbol_scope_rep > get_rep(void) const
Definition: symscope.h:970
float_format native_float_format(void)
Definition: mach-info.cc:62
std::string str
Definition: hash.cc:118
const_iterator end(void) const
Definition: oct-map.h:185
static std::string get_host_name(void)
Definition: oct-env.cc:185
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:2241
bool save_as_floats
Definition: load-save.cc:1617
string_vector & append(const std::string &s)
Definition: str-vec.cc:107
static std::string get_user_name(void)
Definition: oct-env.cc:178
const_iterator begin(void) const
Definition: oct-map.h:184
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)
std::complex< T > trunc(const std::complex< T > &x)
Definition: lo-mappers.h:120
write the output to stdout if nargout otherwise return the output in a character string able ode tem append Append to the destination instead of overwriting tem ascii Save a matrix in a text file without a header or any other information The matrix must be D and only the real part of any complex value is written to the file Numbers are stored in single precision format and separated by spaces Additional options for the and gzip can also be used to convert the files for backward compatibility This option is only available if Octave was built with a link to the zlib libraries end table The list of variables to save may use wildcard patterns containing the following special match all characters except those specified by var
Definition: load-save.cc:1612
octave_idx_type rows(void) const
Definition: ov.h:472
double tmp
Definition: data.cc:6252
bool append
Definition: load-save.cc:1618
static string_vector parse_save_options(const string_vector &argv, load_save_format &format, bool &append, bool &save_as_floats, bool &use_zlib)
Definition: load-save.cc:1038
OCTAVE_EXPORT octave_value_list at
Definition: time.cc:115
int read_mat5_binary_file_header(std::istream &is, bool &swap, bool quiet, const std::string &filename)
Definition: ls-mat5.cc:1484
symbol_scope require_current_scope(const std::string &who)
Definition: symtab.h:79
LS_TEXT format
Definition: load-save.cc:1616
bool isstruct(void) const
Definition: ov.h:589
std::string key(const_iterator p) const
Definition: oct-map.h:189
is longer than or if then or only for unique occurrences of the complete pattern(false). The default is true. If a cell array of strings ar
Definition: strfind.cc:190
bool words_big_endian(void)
Definition: mach-info.cc:69
#define SET_NONEMPTY_INTERNAL_STRING_VARIABLE(NM)
Definition: variables.h:112
octave_value varval(const std::string &name) const
Definition: symscope.h:727
static std::string find_file_to_load(const std::string &name, const std::string &orig_name)
Definition: load-save.cc:505
static double Voctave_core_file_limit
Definition: load-save.cc:99
static void install_loaded_variable(const std::string &name, const octave_value &val, bool global, const std::string &)
Definition: load-save.cc:144
Gzipped file input stream class.
Definition: zfstream.h:278
octave::mach_info::float_format mopt_digit_to_float_format(int mach)
Definition: ls-mat4.cc:172
void warning(const char *fmt,...)
Definition: error.cc:801
return octave_value(v1.char_array_value() . concat(v2.char_array_value(), ra_idx),((a1.is_sq_string()||a2.is_sq_string()) ? '\'' :'"'))
bool is_reg(void) const
Definition: file-stat.cc:75
defaults to zero A value of zero computes the digamma a value the trigamma and so on The digamma function is defined
Definition: psi.cc:68
octave_scalar_map scalar_map_value(void) const
#define octave_stdout
Definition: pager.h:174
const octave_value & contents(const_iterator p) const
Definition: oct-map.h:194
OCTINTERP_API std::string find_data_file_in_load_path(const std::string &fcn, const std::string &file, bool require_regular_file=false)
symbol_scope __require_current_scope__(const std::string &who)
bool is_variable(const std::string &name) const
Definition: symscope.h:732
bool save_mat_binary_data(std::ostream &os, const octave_value &tc, const std::string &name)
Definition: ls-mat4.cc:392
void octave_finalize_hdf5(void)
Definition: load-save.cc:1263
void assign(const std::string &k, const octave_value &val)
Definition: oct-map.h:227
std::string read_text_data(std::istream &is, const std::string &filename, bool &global, octave_value &tc, octave_idx_type count)
Definition: ls-oct-text.cc:238
static void read_mat_binary_data(std::istream &is, double *data, int precision, int len, bool swap, octave::mach_info::float_format flt_fmt)
Definition: ls-mat4.cc:69
octave_hdf5_id file_id
Definition: ls-hdf5.h:44
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:307
bool exists(void) const
Definition: file-stat.h:144
octave::sys::file_stat fs(filename)
ColumnVector imag(const ComplexColumnVector &a)
Definition: dColVector.cc:141
void write_header(std::ostream &os, load_save_format format)
Definition: load-save.cc:1173
OCTAVE_EXPORT octave_value_list error nd deftypefn *const octave_scalar_map err
Definition: error.cc:1049
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.
Definition: oct-string.cc:146
return retval
Definition: load-save.cc:876
octave_value varval(context_id context) const
Definition: symrec.h:624
octave_idx_type numel(void) const
Number of elements in the array.
Definition: Array.h:366
octave_idx_type nfields(void) const
Definition: oct-map.h:207
write the output to stdout if nargout is
Definition: load-save.cc:1612
static load_save_format get_file_format(std::istream &file, const std::string &filename)
Definition: load-save.cc:244
void err_disabled_feature(const std::string &fcn, const std::string &feature, const std::string &pkg)
Definition: errwarn.cc:50
std::string type_name(void) const
Definition: ov.h:1289
If this string is the system will ring the terminal sometimes it is useful to be able to print the original representation of the string
Definition: utils.cc:888
static std::string Vsave_header_format_string
Definition: load-save.cc:126
octave::stream os
Definition: file-io.cc:627
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)
static size_t save_vars(std::ostream &os, const std::string &pattern, load_save_format fmt, bool save_as_floats)
Definition: load-save.cc:1016
static void dump_octave_core(std::ostream &os, const char *fname, load_save_format fmt, bool save_as_floats)
Definition: load-save.cc:1336
charNDArray min(char d, const charNDArray &m)
Definition: chNDArray.cc:204
static bool matches_patterns(const string_vector &patterns, int pat_idx, int num_pat, const std::string &name)
Definition: load-save.cc:173
static std::string Vsave_default_options
Definition: load-save.cc:106
bool use_zlib
Definition: load-save.cc:769