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