00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifdef HAVE_CONFIG_H
00028 #include <config.h>
00029 #endif
00030
00031 #include <cfloat>
00032 #include <cstring>
00033 #include <cctype>
00034
00035 #include <fstream>
00036 #include <iomanip>
00037 #include <iostream>
00038 #include <sstream>
00039 #include <string>
00040
00041 #include "strftime.h"
00042
00043 #include "byte-swap.h"
00044 #include "data-conv.h"
00045 #include "file-ops.h"
00046 #include "file-stat.h"
00047 #include "glob-match.h"
00048 #include "lo-mappers.h"
00049 #include "mach-info.h"
00050 #include "oct-env.h"
00051 #include "oct-time.h"
00052 #include "quit.h"
00053 #include "str-vec.h"
00054 #include "oct-locbuf.h"
00055
00056 #include "Cell.h"
00057 #include "defun.h"
00058 #include "error.h"
00059 #include "gripes.h"
00060 #include "load-path.h"
00061 #include "load-save.h"
00062 #include "oct-obj.h"
00063 #include "oct-map.h"
00064 #include "ov-cell.h"
00065 #include "pager.h"
00066 #include "pt-exp.h"
00067 #include "symtab.h"
00068 #include "sysdep.h"
00069 #include "unwind-prot.h"
00070 #include "utils.h"
00071 #include "variables.h"
00072 #include "version.h"
00073 #include "dMatrix.h"
00074
00075 #include "ls-hdf5.h"
00076 #include "ls-mat-ascii.h"
00077 #include "ls-mat4.h"
00078 #include "ls-mat5.h"
00079 #include "ls-oct-ascii.h"
00080 #include "ls-oct-binary.h"
00081
00082
00083 #ifdef close
00084 #undef close
00085 #endif
00086 #ifdef open
00087 #undef open
00088 #endif
00089
00090 #ifdef HAVE_ZLIB
00091 #include "zfstream.h"
00092 #endif
00093
00094
00095 static bool Vcrash_dumps_octave_core = true;
00096
00097
00098
00099 static double Voctave_core_file_limit = -1.0;
00100
00101
00102 static std::string Voctave_core_file_name = "octave-core";
00103
00104
00105
00106 static std::string Vdefault_save_options = "-text";
00107
00108
00109 static std::string Voctave_core_file_options = "-binary";
00110
00111 static std::string
00112 default_save_header_format (void)
00113 {
00114 return
00115 std::string ("# Created by Octave " OCTAVE_VERSION
00116 ", %a %b %d %H:%M:%S %Y %Z <")
00117 + octave_env::get_user_name ()
00118 + std::string ("@")
00119 + octave_env::get_host_name ()
00120 + std::string (">");
00121 }
00122
00123
00124
00125
00126 static std::string Vsave_header_format_string = default_save_header_format ();
00127
00128 static void
00129 gripe_file_open (const std::string& fcn, const std::string& file)
00130 {
00131 if (fcn == "load")
00132 error ("%s: unable to open input file '%s'", fcn.c_str (), file.c_str ());
00133 else if (fcn == "save")
00134 error ("%s: unable to open output file '%s'", fcn.c_str (), file.c_str ());
00135 else
00136 error ("%s: unable to open file '%s'", fcn.c_str (), file.c_str ());
00137 }
00138
00139
00140
00141
00142 static void
00143 install_loaded_variable (const std::string& name,
00144 const octave_value& val,
00145 bool global, const std::string& )
00146 {
00147 if (global)
00148 {
00149 symbol_table::symbol_record& sr = symbol_table::insert (name);
00150 sr.clear ();
00151 sr.mark_global ();
00152 sr.varref () = val;
00153 }
00154 else
00155 symbol_table::varref (name) = val;
00156 }
00157
00158
00159
00160 static bool
00161 matches_patterns (const string_vector& patterns, int pat_idx,
00162 int num_pat, const std::string& name)
00163 {
00164 for (int i = pat_idx; i < num_pat; i++)
00165 {
00166 glob_match pattern (patterns[i]);
00167
00168 if (pattern.match (name))
00169 return true;
00170 }
00171
00172 return false;
00173 }
00174
00175 int
00176 read_binary_file_header (std::istream& is, bool& swap,
00177 oct_mach_info::float_format& flt_fmt, bool quiet)
00178 {
00179 const int magic_len = 10;
00180 char magic[magic_len+1];
00181 is.read (magic, magic_len);
00182 magic[magic_len] = '\0';
00183
00184 if (strncmp (magic, "Octave-1-L", magic_len) == 0)
00185 swap = oct_mach_info::words_big_endian ();
00186 else if (strncmp (magic, "Octave-1-B", magic_len) == 0)
00187 swap = ! oct_mach_info::words_big_endian ();
00188 else
00189 {
00190 if (! quiet)
00191 error ("load: unable to read read binary file");
00192 return -1;
00193 }
00194
00195 char tmp = 0;
00196 is.read (&tmp, 1);
00197
00198 flt_fmt = mopt_digit_to_float_format (tmp);
00199
00200 if (flt_fmt == oct_mach_info::flt_fmt_unknown)
00201 {
00202 if (! quiet)
00203 error ("load: unrecognized binary format!");
00204
00205 return -1;
00206 }
00207
00208 return 0;
00209 }
00210
00211 #ifdef HAVE_ZLIB
00212 static bool
00213 check_gzip_magic (const std::string& fname)
00214 {
00215 bool retval = false;
00216 std::ifstream file (fname.c_str ());
00217 OCTAVE_LOCAL_BUFFER (unsigned char, magic, 2);
00218
00219 if (file.read (reinterpret_cast<char *> (magic), 2) && magic[0] == 0x1f &&
00220 magic[1] == 0x8b)
00221 retval = true;
00222
00223 file.close ();
00224 return retval;
00225 }
00226 #endif
00227
00228 static load_save_format
00229 get_file_format (std::istream& file, const std::string& filename)
00230 {
00231 load_save_format retval = LS_UNKNOWN;
00232
00233 oct_mach_info::float_format flt_fmt = oct_mach_info::flt_fmt_unknown;
00234
00235 bool swap = false;
00236
00237 if (read_binary_file_header (file, swap, flt_fmt, true) == 0)
00238 retval = LS_BINARY;
00239 else
00240 {
00241 file.clear ();
00242 file.seekg (0, std::ios::beg);
00243
00244 int32_t mopt, nr, nc, imag, len;
00245
00246 int err = read_mat_file_header (file, swap, mopt, nr, nc, imag, len, 1);
00247
00248 if (! err)
00249 retval = LS_MAT_BINARY;
00250 else
00251 {
00252 file.clear ();
00253 file.seekg (0, std::ios::beg);
00254
00255 err = read_mat5_binary_file_header (file, swap, true, filename);
00256
00257 if (! err)
00258 {
00259 file.clear ();
00260 file.seekg (0, std::ios::beg);
00261 retval = LS_MAT5_BINARY;
00262 }
00263 else
00264 {
00265 file.clear ();
00266 file.seekg (0, std::ios::beg);
00267
00268 std::string tmp = extract_keyword (file, "name");
00269
00270 if (! tmp.empty ())
00271 retval = LS_ASCII;
00272 }
00273 }
00274 }
00275
00276 return retval;
00277 }
00278
00279 static load_save_format
00280 get_file_format (const std::string& fname, const std::string& orig_fname,
00281 bool &use_zlib)
00282 {
00283 load_save_format retval = LS_UNKNOWN;
00284
00285 #ifdef HAVE_HDF5
00286
00287 if (H5Fis_hdf5 (fname.c_str ()) > 0)
00288 return LS_HDF5;
00289 #endif
00290
00291 std::ifstream file (fname.c_str ());
00292 use_zlib = false;
00293
00294 if (file)
00295 {
00296 retval = get_file_format (file, orig_fname);
00297 file.close ();
00298
00299 #ifdef HAVE_ZLIB
00300 if (retval == LS_UNKNOWN && check_gzip_magic (fname))
00301 {
00302 gzifstream gzfile (fname.c_str ());
00303 use_zlib = true;
00304
00305 if (gzfile)
00306 {
00307 retval = get_file_format (gzfile, orig_fname);
00308 gzfile.close ();
00309 }
00310 }
00311 #endif
00312
00313 if (retval == LS_UNKNOWN)
00314 {
00315
00316
00317
00318
00319
00320
00321
00322 retval = LS_MAT_ASCII;
00323 }
00324 }
00325 else
00326 gripe_file_open ("load", orig_fname);
00327
00328 return retval;
00329 }
00330
00331 octave_value
00332 do_load (std::istream& stream, const std::string& orig_fname,
00333 load_save_format format, oct_mach_info::float_format flt_fmt,
00334 bool list_only, bool swap, bool verbose,
00335 const string_vector& argv, int argv_idx, int argc, int nargout)
00336 {
00337 octave_value retval;
00338
00339 octave_scalar_map retstruct;
00340
00341 std::ostringstream output_buf;
00342 std::list<std::string> symbol_names;
00343
00344 octave_idx_type count = 0;
00345
00346 for (;;)
00347 {
00348 bool global = false;
00349 octave_value tc;
00350
00351 std::string name;
00352 std::string doc;
00353
00354 switch (format.type)
00355 {
00356 case LS_ASCII:
00357 name = read_ascii_data (stream, orig_fname, global, tc, count);
00358 break;
00359
00360 case LS_BINARY:
00361 name = read_binary_data (stream, swap, flt_fmt, orig_fname,
00362 global, tc, doc);
00363 break;
00364
00365 case LS_MAT_ASCII:
00366 name = read_mat_ascii_data (stream, orig_fname, tc);
00367 break;
00368
00369 case LS_MAT_BINARY:
00370 name = read_mat_binary_data (stream, orig_fname, tc);
00371 break;
00372
00373 #ifdef HAVE_HDF5
00374 case LS_HDF5:
00375 name = read_hdf5_data (stream, orig_fname, global, tc, doc);
00376 break;
00377 #endif
00378
00379 case LS_MAT5_BINARY:
00380 case LS_MAT7_BINARY:
00381 name = read_mat5_binary_element (stream, orig_fname, swap,
00382 global, tc);
00383 break;
00384
00385 default:
00386 gripe_unrecognized_data_fmt ("load");
00387 break;
00388 }
00389
00390 if (error_state || stream.eof () || name.empty ())
00391 break;
00392 else if (! error_state && ! name.empty ())
00393 {
00394 if (tc.is_defined ())
00395 {
00396 if (format == LS_MAT_ASCII && argv_idx < argc)
00397 warning ("load: loaded ASCII file '%s' -- ignoring extra args",
00398 orig_fname.c_str ());
00399
00400 if (format == LS_MAT_ASCII
00401 || argv_idx == argc
00402 || matches_patterns (argv, argv_idx, argc, name))
00403 {
00404 count++;
00405 if (list_only)
00406 {
00407 if (verbose)
00408 {
00409 if (count == 1)
00410 output_buf
00411 << "type rows cols name\n"
00412 << "==== ==== ==== ====\n";
00413
00414 output_buf
00415 << std::setiosflags (std::ios::left)
00416 << std::setw (16) << tc.type_name () . c_str ()
00417 << std::setiosflags (std::ios::right)
00418 << std::setw (7) << tc.rows ()
00419 << std::setw (7) << tc.columns ()
00420 << " " << name << "\n";
00421 }
00422 else
00423 symbol_names.push_back (name);
00424 }
00425 else
00426 {
00427 if (nargout == 1)
00428 {
00429 if (format == LS_MAT_ASCII)
00430 retval = tc;
00431 else
00432 retstruct.assign (name, tc);
00433 }
00434 else
00435 install_loaded_variable (name, tc, global, doc);
00436 }
00437 }
00438
00439
00440
00441 if (format == LS_MAT_ASCII)
00442 break;
00443 }
00444 else
00445 error ("load: unable to load variable '%s'", name.c_str ());
00446 }
00447 else
00448 {
00449 if (count == 0)
00450 error ("load: are you sure '%s' is an Octave data file?",
00451 orig_fname.c_str ());
00452
00453 break;
00454 }
00455 }
00456
00457 if (list_only && count)
00458 {
00459 if (verbose)
00460 {
00461 std::string msg = output_buf.str ();
00462
00463 if (nargout > 0)
00464 retval = msg;
00465 else
00466 octave_stdout << msg;
00467 }
00468 else
00469 {
00470 if (nargout > 0)
00471 retval = Cell (string_vector (symbol_names));
00472 else
00473 {
00474 string_vector names (symbol_names);
00475
00476 names.list_in_columns (octave_stdout);
00477
00478 octave_stdout << "\n";
00479 }
00480 }
00481 }
00482 else if (retstruct.nfields () != 0)
00483 retval = retstruct;
00484
00485 return retval;
00486 }
00487
00488 std::string
00489 find_file_to_load (const std::string& name, const std::string& orig_name)
00490 {
00491 std::string fname = name;
00492
00493 if (! (octave_env::absolute_pathname (fname)
00494 || octave_env::rooted_relative_pathname (fname)))
00495 {
00496 file_stat fs (fname);
00497
00498 if (! (fs.exists () && fs.is_reg ()))
00499 {
00500 std::string tmp
00501 = octave_env::make_absolute (load_path::find_file (fname));
00502
00503 if (! tmp.empty ())
00504 {
00505 warning_with_id ("Octave:load-file-in-path",
00506 "load: file found in load path");
00507 fname = tmp;
00508 }
00509 }
00510 }
00511
00512 size_t dot_pos = fname.rfind (".");
00513 size_t sep_pos = fname.find_last_of (file_ops::dir_sep_chars ());
00514
00515 if (dot_pos == std::string::npos
00516 || (sep_pos != std::string::npos && dot_pos < sep_pos))
00517 {
00518
00519
00520
00521 file_stat fs (fname);
00522
00523 if (! (fs.exists () && fs.is_reg ()))
00524 fname = find_file_to_load (fname + ".mat", orig_name);
00525 }
00526 else
00527 {
00528 file_stat fs (fname);
00529
00530 if (! (fs.exists () && fs.is_reg ()))
00531 {
00532 fname = "";
00533
00534 error ("load: unable to find file %s", orig_name.c_str ());
00535 }
00536 }
00537
00538 return fname;
00539 }
00540
00541
00542 DEFUN (load, args, nargout,
00543 "-*- texinfo -*-\n\
00544 @deftypefn {Command} {} load file\n\
00545 @deftypefnx {Command} {} load options file\n\
00546 @deftypefnx {Command} {} load options file v1 v2 @dots{}\n\
00547 @deftypefnx {Command} {S =} load (\"options\", \"file\", \"v1\", \"v2\", @dots{})\n\
00548 @deftypefnx {Command} {} load file options\n\
00549 @deftypefnx {Command} {} load file options v1 v2 @dots{}\n\
00550 @deftypefnx {Command} {S =} load (\"file\", \"options\", \"v1\", \"v2\", @dots{})\n\
00551 Load the named variables @var{v1}, @var{v2}, @dots{}, from the file\n\
00552 @var{file}. If no variables are specified then all variables found in the\n\
00553 file will be loaded. As with @code{save}, the list of variables to extract\n\
00554 can be full names or use a pattern syntax. The format of the file is\n\
00555 automatically detected but may be overridden by supplying the appropriate\n\
00556 option.\n\
00557 \n\
00558 If load is invoked using the functional form\n\
00559 \n\
00560 @example\n\
00561 load (\"-option1\", @dots{}, \"file\", \"v1\", @dots{})\n\
00562 @end example\n\
00563 \n\
00564 @noindent\n\
00565 then the @var{options}, @var{file}, and variable name arguments\n\
00566 (@var{v1}, @dots{}) must be specified as character strings.\n\
00567 \n\
00568 If a variable that is not marked as global is loaded from a file when a\n\
00569 global symbol with the same name already exists, it is loaded in the\n\
00570 global symbol table. Also, if a variable is marked as global in a file\n\
00571 and a local symbol exists, the local symbol is moved to the global\n\
00572 symbol table and given the value from the file.\n\
00573 \n\
00574 If invoked with a single output argument, Octave returns data instead\n\
00575 of inserting variables in the symbol table. If the data file contains\n\
00576 only numbers (TAB- or space-delimited columns), a matrix of values is\n\
00577 returned. Otherwise, @code{load} returns a structure with members\n\
00578 corresponding to the names of the variables in the file.\n\
00579 \n\
00580 The @code{load} command can read data stored in Octave's text and\n\
00581 binary formats, and @sc{matlab}'s binary format. If compiled with zlib\n\
00582 support, it can also load gzip-compressed files. It will automatically\n\
00583 detect the type of file and do conversion from different floating point\n\
00584 formats (currently only IEEE big and little endian, though other formats\n\
00585 may be added in the future).\n\
00586 \n\
00587 Valid options for @code{load} are listed in the following table.\n\
00588 \n\
00589 @table @code\n\
00590 @item -force\n\
00591 This option is accepted for backward compatibility but is ignored.\n\
00592 Octave now overwrites variables currently in memory with\n\
00593 those of the same name found in the file.\n\
00594 \n\
00595 @item -ascii\n\
00596 Force Octave to assume the file contains columns of numbers in text format\n\
00597 without any header or other information. Data in the file will be loaded\n\
00598 as a single numeric matrix with the name of the variable derived from the\n\
00599 name of the file.\n\
00600 \n\
00601 @item -binary\n\
00602 Force Octave to assume the file is in Octave's binary format.\n\
00603 \n\
00604 @item -hdf5\n\
00605 Force Octave to assume the file is in @sc{hdf5} format.\n\
00606 (@sc{hdf5} is a free, portable binary format developed by the National\n\
00607 Center for Supercomputing Applications at the University of Illinois.)\n\
00608 Note that Octave can read @sc{hdf5} files not created by itself, but may\n\
00609 skip some datasets in formats that it cannot support. This format is\n\
00610 only available if Octave was built with a link to the @sc{hdf5} libraries.\n\
00611 \n\
00612 @item -import\n\
00613 This option is accepted for backward compatibility but is ignored.\n\
00614 Octave can now support multi-dimensional HDF data and automatically\n\
00615 modifies variable names if they are invalid Octave identifiers.\n\
00616 \n\
00617 @item -mat\n\
00618 @itemx -mat-binary\n\
00619 @itemx -6\n\
00620 @itemx -v6\n\
00621 @itemx -7\n\
00622 @itemx -v7\n\
00623 Force Octave to assume the file is in @sc{matlab}'s version 6 or 7 binary\n\
00624 format.\n\
00625 \n\
00626 @item -mat4-binary\n\
00627 @itemx -4\n\
00628 @itemx -v4\n\
00629 @itemx -V4\n\
00630 Force Octave to assume the file is in the binary format written by\n\
00631 @sc{matlab} version 4.\n\
00632 \n\
00633 @item -text\n\
00634 Force Octave to assume the file is in Octave's text format.\n\
00635 @end table\n\
00636 @seealso{save, dlmwrite, csvwrite, fwrite}\n\
00637 @end deftypefn")
00638 {
00639 octave_value_list retval;
00640
00641 int argc = args.length () + 1;
00642
00643 string_vector argv = args.make_argv ("load");
00644
00645 if (error_state)
00646 return retval;
00647
00648 int i = 1;
00649 std::string orig_fname = "";
00650
00651
00652 if (argc > 1 && ! argv[1].empty () && argv[1].at(0) != '-')
00653 {
00654 orig_fname = argv[1];
00655 i++;
00656 }
00657
00658
00659
00660
00661
00662 load_save_format format = LS_UNKNOWN;
00663
00664 bool list_only = false;
00665 bool verbose = false;
00666
00667
00668 for (; i < argc; i++)
00669 {
00670 if (argv[i] == "-force" || argv[i] == "-f")
00671 {
00672
00673
00674 }
00675 else if (argv[i] == "-list" || argv[i] == "-l")
00676 {
00677 list_only = true;
00678 }
00679 else if (argv[i] == "-verbose" || argv[i] == "-v")
00680 {
00681 verbose = true;
00682 }
00683 else if (argv[i] == "-ascii" || argv[i] == "-a")
00684 {
00685 format = LS_MAT_ASCII;
00686 }
00687 else if (argv[i] == "-binary" || argv[i] == "-b")
00688 {
00689 format = LS_BINARY;
00690 }
00691 else if (argv[i] == "-mat-binary" || argv[i] == "-mat" || argv[i] == "-m"
00692 || argv[i] == "-6" || argv[i] == "-v6")
00693 {
00694 format = LS_MAT5_BINARY;
00695 }
00696 else if (argv[i] == "-7" || argv[i] == "-v7")
00697 {
00698 format = LS_MAT7_BINARY;
00699 }
00700 else if (argv[i] == "-mat4-binary" || argv[i] == "-V4"
00701 || argv[i] == "-v4" || argv[i] == "-4")
00702 {
00703 format = LS_MAT_BINARY;
00704 }
00705 else if (argv[i] == "-hdf5" || argv[i] == "-h")
00706 {
00707 #ifdef HAVE_HDF5
00708 format = LS_HDF5;
00709 #else
00710 error ("load: octave executable was not linked with HDF5 library");
00711 return retval;
00712 #endif
00713 }
00714 else if (argv[i] == "-import" || argv[i] == "-i")
00715 {
00716 warning ("load: -import ignored");
00717 }
00718 else if (argv[i] == "-text" || argv[i] == "-t")
00719 {
00720 format = LS_ASCII;
00721 }
00722 else
00723 break;
00724 }
00725
00726 if (orig_fname == "")
00727 {
00728 if (i == argc)
00729 {
00730 print_usage ();
00731 return retval;
00732 }
00733 else
00734 orig_fname = argv[i];
00735 }
00736 else
00737 i--;
00738
00739 oct_mach_info::float_format flt_fmt = oct_mach_info::flt_fmt_unknown;
00740
00741 bool swap = false;
00742
00743 if (orig_fname == "-")
00744 {
00745 i++;
00746
00747 #ifdef HAVE_HDF5
00748 if (format == LS_HDF5)
00749 error ("load: cannot read HDF5 format from stdin");
00750 else
00751 #endif
00752 if (format != LS_UNKNOWN)
00753 {
00754
00755
00756
00757
00758
00759 retval = do_load (std::cin, orig_fname, format, flt_fmt,
00760 list_only, swap, verbose, argv, i, argc,
00761 nargout);
00762 }
00763 else
00764 error ("load: must specify file format if reading from stdin");
00765 }
00766 else
00767 {
00768 std::string fname = file_ops::tilde_expand (orig_fname);
00769
00770 fname = find_file_to_load (fname, orig_fname);
00771
00772 if (error_state)
00773 return retval;
00774
00775 bool use_zlib = false;
00776
00777 if (format == LS_UNKNOWN)
00778 format = get_file_format (fname, orig_fname, use_zlib);
00779
00780 #ifdef HAVE_HDF5
00781 if (format == LS_HDF5)
00782 {
00783 i++;
00784
00785 hdf5_ifstream hdf5_file (fname.c_str ());
00786
00787 if (hdf5_file.file_id >= 0)
00788 {
00789 retval = do_load (hdf5_file, orig_fname, format,
00790 flt_fmt, list_only, swap, verbose,
00791 argv, i, argc, nargout);
00792
00793 hdf5_file.close ();
00794 }
00795 else
00796 gripe_file_open ("load", orig_fname);
00797 }
00798 else
00799 #endif
00800
00801
00802 if (format != LS_UNKNOWN)
00803 {
00804 i++;
00805
00806
00807
00808 std::ios::openmode mode = std::ios::in | std::ios::binary;
00809
00810 #ifdef HAVE_ZLIB
00811 if (use_zlib)
00812 {
00813 gzifstream file (fname.c_str (), mode);
00814
00815 if (file)
00816 {
00817 if (format == LS_BINARY)
00818 {
00819 if (read_binary_file_header (file, swap, flt_fmt) < 0)
00820 {
00821 if (file) file.close ();
00822 return retval;
00823 }
00824 }
00825 else if (format == LS_MAT5_BINARY
00826 || format == LS_MAT7_BINARY)
00827 {
00828 if (read_mat5_binary_file_header (file, swap, false, orig_fname) < 0)
00829 {
00830 if (file) file.close ();
00831 return retval;
00832 }
00833 }
00834
00835 retval = do_load (file, orig_fname, format,
00836 flt_fmt, list_only, swap, verbose,
00837 argv, i, argc, nargout);
00838
00839 file.close ();
00840 }
00841 else
00842 gripe_file_open ("load", orig_fname);
00843 }
00844 else
00845 #endif
00846 {
00847 std::ifstream file (fname.c_str (), mode);
00848
00849 if (file)
00850 {
00851 if (format == LS_BINARY)
00852 {
00853 if (read_binary_file_header (file, swap, flt_fmt) < 0)
00854 {
00855 if (file) file.close ();
00856 return retval;
00857 }
00858 }
00859 else if (format == LS_MAT5_BINARY
00860 || format == LS_MAT7_BINARY)
00861 {
00862 if (read_mat5_binary_file_header (file, swap, false, orig_fname) < 0)
00863 {
00864 if (file) file.close ();
00865 return retval;
00866 }
00867 }
00868
00869 retval = do_load (file, orig_fname, format,
00870 flt_fmt, list_only, swap, verbose,
00871 argv, i, argc, nargout);
00872
00873 file.close ();
00874 }
00875 else
00876 error ("load: unable to open input file '%s'",
00877 orig_fname.c_str ());
00878 }
00879 }
00880 }
00881
00882 return retval;
00883 }
00884
00885
00886
00887 static bool
00888 glob_pattern_p (const std::string& pattern)
00889 {
00890 int open = 0;
00891
00892 int len = pattern.length ();
00893
00894 for (int i = 0; i < len; i++)
00895 {
00896 char c = pattern[i];
00897
00898 switch (c)
00899 {
00900 case '?':
00901 case '*':
00902 return true;
00903
00904 case '[':
00905 open++;
00906 continue;
00907
00908 case ']':
00909 if (open)
00910 return true;
00911 continue;
00912
00913 case '\\':
00914 if (i == len - 1)
00915 return false;
00916
00917 default:
00918 continue;
00919 }
00920 }
00921
00922 return false;
00923 }
00924
00925 static void
00926 do_save (std::ostream& os, const octave_value& tc,
00927 const std::string& name, const std::string& help,
00928 bool global, load_save_format fmt, bool save_as_floats)
00929 {
00930 switch (fmt.type)
00931 {
00932 case LS_ASCII:
00933 save_ascii_data (os, tc, name, global, 0);
00934 break;
00935
00936 case LS_BINARY:
00937 save_binary_data (os, tc, name, help, global, save_as_floats);
00938 break;
00939
00940 case LS_MAT_ASCII:
00941 if (! save_mat_ascii_data (os, tc, fmt.opts & LS_MAT_ASCII_LONG ? 16 : 8,
00942 fmt.opts & LS_MAT_ASCII_TABS))
00943 warning ("save: unable to save %s in ASCII format", name.c_str ());
00944 break;
00945
00946 case LS_MAT_BINARY:
00947 save_mat_binary_data (os, tc, name);
00948 break;
00949
00950 #ifdef HAVE_HDF5
00951 case LS_HDF5:
00952 save_hdf5_data (os, tc, name, help, global, save_as_floats);
00953 break;
00954 #endif
00955
00956 case LS_MAT5_BINARY:
00957 save_mat5_binary_element (os, tc, name, global, false, save_as_floats);
00958 break;
00959
00960 case LS_MAT7_BINARY:
00961 save_mat5_binary_element (os, tc, name, global, true, save_as_floats);
00962 break;
00963
00964 default:
00965 gripe_unrecognized_data_fmt ("save");
00966 break;
00967 }
00968 }
00969
00970
00971
00972 void
00973 do_save (std::ostream& os, const symbol_table::symbol_record& sr,
00974 load_save_format fmt, bool save_as_floats)
00975 {
00976 octave_value val = sr.varval ();
00977
00978 if (val.is_defined ())
00979 {
00980 std::string name = sr.name ();
00981 std::string help;
00982 bool global = sr.is_global ();
00983
00984 do_save (os, val, name, help, global, fmt, save_as_floats);
00985 }
00986 }
00987
00988
00989
00990
00991 static size_t
00992 save_fields (std::ostream& os, const octave_scalar_map& m,
00993 const std::string& pattern,
00994 load_save_format fmt, bool save_as_floats)
00995 {
00996 glob_match pat (pattern);
00997
00998 size_t saved = 0;
00999
01000 for (octave_scalar_map::const_iterator p = m.begin (); p != m.end (); p++)
01001 {
01002 std::string empty_str;
01003
01004 if (pat.match(m.key (p)))
01005 {
01006 do_save (os, m.contents (p), m.key (p), empty_str,
01007 0, fmt, save_as_floats);
01008
01009 saved++;
01010 }
01011 }
01012
01013 return saved;
01014 }
01015
01016
01017
01018
01019 static size_t
01020 save_vars (std::ostream& os, const std::string& pattern,
01021 load_save_format fmt, bool save_as_floats)
01022 {
01023 std::list<symbol_table::symbol_record> vars = symbol_table::glob (pattern);
01024
01025 size_t saved = 0;
01026
01027 typedef std::list<symbol_table::symbol_record>::const_iterator const_vars_iterator;
01028
01029 for (const_vars_iterator p = vars.begin (); p != vars.end (); p++)
01030 {
01031 do_save (os, *p, fmt, save_as_floats);
01032
01033 if (error_state)
01034 break;
01035
01036 saved++;
01037 }
01038
01039 return saved;
01040 }
01041
01042 static string_vector
01043 parse_save_options (const string_vector &argv,
01044 load_save_format &format, bool &append,
01045 bool &save_as_floats, bool &use_zlib)
01046 {
01047 string_vector retval;
01048 int argc = argv.length ();
01049
01050 bool do_double = false, do_tabs = false;
01051
01052 for (int i = 0; i < argc; i++)
01053 {
01054 if (argv[i] == "-append")
01055 {
01056 append = true;
01057 }
01058 else if (argv[i] == "-ascii" || argv[i] == "-a")
01059 {
01060 format = LS_MAT_ASCII;
01061 }
01062 else if (argv[i] == "-double")
01063 {
01064 do_double = true;
01065 }
01066 else if (argv[i] == "-tabs")
01067 {
01068 do_tabs = true;
01069 }
01070 else if (argv[i] == "-text" || argv[i] == "-t")
01071 {
01072 format = LS_ASCII;
01073 }
01074 else if (argv[i] == "-binary" || argv[i] == "-b")
01075 {
01076 format = LS_BINARY;
01077 }
01078 else if (argv[i] == "-hdf5" || argv[i] == "-h")
01079 {
01080 #ifdef HAVE_HDF5
01081 format = LS_HDF5;
01082 #else
01083 error ("save: octave executable was not linked with HDF5 library");
01084 #endif
01085 }
01086 else if (argv[i] == "-mat-binary" || argv[i] == "-mat"
01087 || argv[i] == "-m" || argv[i] == "-6" || argv[i] == "-v6"
01088 || argv[i] == "-V6")
01089 {
01090 format = LS_MAT5_BINARY;
01091 }
01092 #ifdef HAVE_ZLIB
01093 else if (argv[i] == "-mat7-binary" || argv[i] == "-7"
01094 || argv[i] == "-v7" || argv[i] == "-V7")
01095 {
01096 format = LS_MAT7_BINARY;
01097 }
01098 #endif
01099 else if (argv[i] == "-mat4-binary" || argv[i] == "-V4"
01100 || argv[i] == "-v4" || argv[i] == "-4")
01101 {
01102 format = LS_MAT_BINARY;
01103 }
01104 else if (argv[i] == "-float-binary" || argv[i] == "-f")
01105 {
01106 format = LS_BINARY;
01107 save_as_floats = true;
01108 }
01109 else if (argv[i] == "-float-hdf5")
01110 {
01111 #ifdef HAVE_HDF5
01112 format = LS_HDF5;
01113 save_as_floats = true;
01114 #else
01115 error ("save: octave executable was not linked with HDF5 library");
01116 #endif
01117 }
01118 #ifdef HAVE_ZLIB
01119 else if (argv[i] == "-zip" || argv[i] == "-z")
01120 {
01121 use_zlib = true;
01122 }
01123 #endif
01124 else
01125 retval.append (argv[i]);
01126 }
01127
01128 if (do_double)
01129 {
01130 if (format == LS_MAT_ASCII)
01131 format.opts |= LS_MAT_ASCII_LONG;
01132 else
01133 warning ("save: \"-double\" option only has an effect with \"-ascii\"");
01134 }
01135
01136 if (do_tabs)
01137 {
01138 if (format == LS_MAT_ASCII)
01139 format.opts |= LS_MAT_ASCII_TABS;
01140 else
01141 warning ("save: \"-tabs\" option only has an effect with \"-ascii\"");
01142 }
01143
01144 return retval;
01145 }
01146
01147 static string_vector
01148 parse_save_options (const std::string &arg, load_save_format &format,
01149 bool &append, bool &save_as_floats,
01150 bool &use_zlib)
01151 {
01152 std::istringstream is (arg);
01153 std::string str;
01154 string_vector argv;
01155
01156 while (! is.eof ())
01157 {
01158 is >> str;
01159 argv.append (str);
01160 }
01161
01162 return parse_save_options (argv, format, append, save_as_floats,
01163 use_zlib);
01164 }
01165
01166 void
01167 write_header (std::ostream& os, load_save_format format)
01168 {
01169 switch (format.type)
01170 {
01171 case LS_BINARY:
01172 {
01173 os << (oct_mach_info::words_big_endian ()
01174 ? "Octave-1-B" : "Octave-1-L");
01175
01176 oct_mach_info::float_format flt_fmt =
01177 oct_mach_info::native_float_format ();
01178
01179 char tmp = static_cast<char> (float_format_to_mopt_digit (flt_fmt));
01180
01181 os.write (&tmp, 1);
01182 }
01183 break;
01184
01185 case LS_MAT5_BINARY:
01186 case LS_MAT7_BINARY:
01187 {
01188 char const * versionmagic;
01189 int16_t number = *(reinterpret_cast<const int16_t *>("\x00\x01"));
01190 struct tm bdt;
01191 time_t now;
01192 char headertext[128];
01193
01194 time (&now);
01195 bdt = *gmtime (&now);
01196 memset (headertext, ' ', 124);
01197
01198 nstrftime (headertext, 124, "MATLAB 5.0 MAT-file, written by Octave "
01199 OCTAVE_VERSION ", %Y-%m-%d %T UTC", &bdt, 1, 0);
01200
01201
01202
01203
01204
01205
01206
01207
01208 if (number == 1)
01209 versionmagic = "\x01\x00\x4d\x49";
01210 else
01211 versionmagic = "\x00\x01\x49\x4d";
01212
01213 memcpy (headertext+124, versionmagic, 4);
01214 os.write (headertext, 128);
01215 }
01216
01217 break;
01218
01219 #ifdef HAVE_HDF5
01220 case LS_HDF5:
01221 #endif
01222 case LS_ASCII:
01223 {
01224 octave_localtime now;
01225
01226 std::string comment_string = now.strftime (Vsave_header_format_string);
01227
01228 if (! comment_string.empty ())
01229 {
01230 #ifdef HAVE_HDF5
01231 if (format == LS_HDF5)
01232 {
01233 hdf5_ofstream& hs = dynamic_cast<hdf5_ofstream&> (os);
01234 H5Gset_comment (hs.file_id, "/", comment_string.c_str ());
01235 }
01236 else
01237 #endif
01238 os << comment_string << "\n";
01239 }
01240 }
01241 break;
01242
01243 default:
01244 break;
01245 }
01246 }
01247
01248 static void
01249 save_vars (const string_vector& argv, int argv_idx, int argc,
01250 std::ostream& os, load_save_format fmt,
01251 bool save_as_floats, bool write_header_info)
01252 {
01253 if (write_header_info)
01254 write_header (os, fmt);
01255
01256 if (argv_idx == argc)
01257 {
01258 save_vars (os, "*", fmt, save_as_floats);
01259 }
01260 else if (argv[argv_idx] == "-struct")
01261 {
01262 if (++argv_idx >= argc)
01263 {
01264 error ("save: missing struct name");
01265 return;
01266 }
01267
01268 std::string struct_name = argv[argv_idx];
01269
01270 if (! symbol_table::is_variable (struct_name))
01271 {
01272 error ("save: no such variable: '%s'", struct_name.c_str ());
01273 return;
01274 }
01275
01276 octave_value struct_var = symbol_table::varref (struct_name);
01277
01278 if (! struct_var.is_map () || struct_var.numel () != 1)
01279 {
01280 error ("save: '%s' is not a scalar structure",
01281 struct_name.c_str ());
01282 return;
01283 }
01284 octave_scalar_map struct_var_map = struct_var.scalar_map_value ();
01285
01286 ++argv_idx;
01287
01288 if (argv_idx < argc)
01289 {
01290 for (int i = argv_idx; i < argc; i++)
01291 {
01292 if (! save_fields (os, struct_var_map, argv[i], fmt,
01293 save_as_floats))
01294 {
01295 warning ("save: no such field '%s.%s'",
01296 struct_name.c_str (), argv[i].c_str ());
01297 }
01298 }
01299 }
01300 else
01301 save_fields (os, struct_var_map, "*", fmt, save_as_floats);
01302 }
01303 else
01304 {
01305 for (int i = argv_idx; i < argc; i++)
01306 {
01307 if (! save_vars (os, argv[i], fmt, save_as_floats))
01308 warning ("save: no such variable '%s'", argv[i].c_str ());
01309 }
01310 }
01311 }
01312
01313 static void
01314 dump_octave_core (std::ostream& os, const char *fname, load_save_format fmt,
01315 bool save_as_floats)
01316 {
01317 write_header (os, fmt);
01318
01319 std::list<symbol_table::symbol_record> vars
01320 = symbol_table::all_variables (symbol_table::top_scope (), 0);
01321
01322 double save_mem_size = 0;
01323
01324 typedef std::list<symbol_table::symbol_record>::const_iterator const_vars_iterator;
01325
01326 for (const_vars_iterator p = vars.begin (); p != vars.end (); p++)
01327 {
01328 octave_value val = p->varval ();
01329
01330 if (val.is_defined ())
01331 {
01332 std::string name = p->name ();
01333 std::string help;
01334 bool global = p->is_global ();
01335
01336 double val_size = val.byte_size () / 1024;
01337
01338
01339
01340 if (Voctave_core_file_limit < 0
01341 || save_mem_size + val_size < Voctave_core_file_limit)
01342 {
01343 save_mem_size += val_size;
01344
01345 do_save (os, val, name, help, global, fmt, save_as_floats);
01346
01347 if (error_state)
01348 break;
01349 }
01350 }
01351 }
01352
01353 message (0, "save to '%s' complete", fname);
01354 }
01355
01356 void
01357 dump_octave_core (void)
01358 {
01359 if (Vcrash_dumps_octave_core)
01360 {
01361
01362
01363 const char *fname = Voctave_core_file_name.c_str ();
01364
01365 message (0, "attempting to save variables to '%s'...", fname);
01366
01367 load_save_format format = LS_BINARY;
01368
01369 bool save_as_floats = false;
01370
01371 bool append = false;
01372
01373 bool use_zlib = false;
01374
01375 parse_save_options (Voctave_core_file_options, format, append,
01376 save_as_floats, use_zlib);
01377
01378 std::ios::openmode mode = std::ios::out;
01379
01380
01381 if (format == LS_MAT7_BINARY)
01382 use_zlib = false;
01383
01384 if (format == LS_BINARY
01385 #ifdef HAVE_HDF5
01386 || format == LS_HDF5
01387 #endif
01388 || format == LS_MAT_BINARY
01389 || format == LS_MAT5_BINARY
01390 || format == LS_MAT7_BINARY)
01391 mode |= std::ios::binary;
01392
01393 mode |= append ? std::ios::ate : std::ios::trunc;
01394
01395 #ifdef HAVE_HDF5
01396 if (format == LS_HDF5)
01397 {
01398 hdf5_ofstream file (fname, mode);
01399
01400 if (file.file_id >= 0)
01401 {
01402 dump_octave_core (file, fname, format, save_as_floats);
01403
01404 file.close ();
01405 }
01406 else
01407 warning ("unable to open '%s' for writing...", fname);
01408 }
01409 else
01410 #endif
01411
01412
01413 {
01414 #ifdef HAVE_ZLIB
01415 if (use_zlib)
01416 {
01417 gzofstream file (fname, mode);
01418
01419 if (file)
01420 {
01421 dump_octave_core (file, fname, format, save_as_floats);
01422
01423 file.close ();
01424 }
01425 else
01426 warning ("unable to open '%s' for writing...", fname);
01427 }
01428 else
01429 #endif
01430 {
01431 std::ofstream file (fname, mode);
01432
01433 if (file)
01434 {
01435 dump_octave_core (file, fname, format, save_as_floats);
01436
01437 file.close ();
01438 }
01439 else
01440 warning ("unable to open '%s' for writing...", fname);
01441 }
01442 }
01443 }
01444 }
01445
01446
01447 DEFUN (save, args, ,
01448 "-*- texinfo -*-\n\
01449 @deftypefn {Command} {} save file\n\
01450 @deftypefnx {Command} {} save options file\n\
01451 @deftypefnx {Command} {} save options file @var{v1} @var{v2} @dots{}\n\
01452 @deftypefnx {Command} {} save options file -struct @var{STRUCT} @var{f1} @var{f2} @dots{}\n\
01453 Save the named variables @var{v1}, @var{v2}, @dots{}, in the file\n\
01454 @var{file}. The special filename @samp{-} may be used to write\n\
01455 output to the terminal. If no variable names are listed, Octave saves\n\
01456 all the variables in the current scope. Otherwise, full variable names or\n\
01457 pattern syntax can be used to specify the variables to save.\n\
01458 If the @option{-struct} modifier is used, fields @var{f1} @var{f2} @dots{}\n\
01459 of the scalar structure @var{STRUCT} are saved as if they were variables\n\
01460 with corresponding names.\n\
01461 Valid options for the @code{save} command are listed in the following table.\n\
01462 Options that modify the output format override the format specified by\n\
01463 @code{default_save_options}.\n\
01464 \n\
01465 If save is invoked using the functional form\n\
01466 \n\
01467 @example\n\
01468 save (\"-option1\", @dots{}, \"file\", \"v1\", @dots{})\n\
01469 @end example\n\
01470 \n\
01471 @noindent\n\
01472 then the @var{options}, @var{file}, and variable name arguments\n\
01473 (@var{v1}, @dots{}) must be specified as character strings.\n\
01474 \n\
01475 @table @code\n\
01476 @item -append\n\
01477 Append to the destination instead of overwriting.\n\
01478 \n\
01479 @item -ascii\n\
01480 Save a single matrix in a text file without header or any other information.\n\
01481 \n\
01482 @item -binary\n\
01483 Save the data in Octave's binary data format.\n\
01484 \n\
01485 @item -float-binary\n\
01486 Save the data in Octave's binary data format but only using single\n\
01487 precision. Only use this format if you know that all the\n\
01488 values to be saved can be represented in single precision.\n\
01489 \n\
01490 @item -hdf5\n\
01491 Save the data in @sc{hdf5} format.\n\
01492 (HDF5 is a free, portable binary format developed by the National\n\
01493 Center for Supercomputing Applications at the University of Illinois.)\n\
01494 This format is only available if Octave was built with a link to the\n\
01495 @sc{hdf5} libraries.\n\
01496 \n\
01497 @item -float-hdf5\n\
01498 Save the data in @sc{hdf5} format but only using single precision.\n\
01499 Only use this format if you know that all the\n\
01500 values to be saved can be represented in single precision.\n\
01501 \n\
01502 @item -V7\n\
01503 @itemx -v7\n\
01504 @itemx -7\n\
01505 @itemx -mat7-binary\n\
01506 Save the data in @sc{matlab}'s v7 binary data format.\n\
01507 \n\
01508 @item -V6\n\
01509 @itemx -v6\n\
01510 @itemx -6\n\
01511 @itemx -mat\n\
01512 @itemx -mat-binary\n\
01513 Save the data in @sc{matlab}'s v6 binary data format.\n\
01514 \n\
01515 @item -V4\n\
01516 @itemx -v4\n\
01517 @itemx -4\n\
01518 @itemx -mat4-binary\n\
01519 Save the data in the binary format written by @sc{matlab} version 4.\n\
01520 \n\
01521 @item -text\n\
01522 Save the data in Octave's text data format. (default).\n\
01523 \n\
01524 @item -zip\n\
01525 @itemx -z\n\
01526 Use the gzip algorithm to compress the file. This works equally on files\n\
01527 that are compressed with gzip outside of octave, and gzip can equally be\n\
01528 used to convert the files for backward compatibility.\n\
01529 This option is only available if Octave was built with a link to the zlib\n\
01530 libraries.\n\
01531 @end table\n\
01532 \n\
01533 The list of variables to save may use wildcard patterns containing\n\
01534 the following special characters:\n\
01535 @table @code\n\
01536 @item ?\n\
01537 Match any single character.\n\
01538 \n\
01539 @item *\n\
01540 Match zero or more characters.\n\
01541 \n\
01542 @item [ @var{list} ]\n\
01543 Match the list of characters specified by @var{list}. If the first\n\
01544 character is @code{!} or @code{^}, match all characters except those\n\
01545 specified by @var{list}. For example, the pattern @code{[a-zA-Z]} will\n\
01546 match all lower and uppercase alphabetic characters.\n\
01547 \n\
01548 Wildcards may also be used in the field name specifications when using\n\
01549 the @option{-struct} modifier (but not in the struct name itself).\n\
01550 \n\
01551 @end table\n\
01552 \n\
01553 Except when using the @sc{matlab} binary data file format or the\n\
01554 @samp{-ascii} format, saving global\n\
01555 variables also saves the global status of the variable. If the variable\n\
01556 is restored at a later time using @samp{load}, it will be restored as a\n\
01557 global variable.\n\
01558 \n\
01559 The command\n\
01560 \n\
01561 @example\n\
01562 save -binary data a b*\n\
01563 @end example\n\
01564 \n\
01565 @noindent\n\
01566 saves the variable @samp{a} and all variables beginning with @samp{b} to\n\
01567 the file @file{data} in Octave's binary format.\n\
01568 @seealso{load, default_save_options, save_header_format_string, dlmread, csvread, fread}\n\
01569 @end deftypefn")
01570 {
01571 octave_value_list retval;
01572
01573 int argc = args.length ();
01574
01575 string_vector argv = args.make_argv ();
01576
01577 if (error_state)
01578 return retval;
01579
01580
01581
01582
01583 bool save_as_floats = false;
01584
01585 load_save_format format = LS_ASCII;
01586
01587 bool append = false;
01588
01589 bool use_zlib = false;
01590
01591
01592 parse_save_options (Vdefault_save_options, format, append, save_as_floats,
01593 use_zlib);
01594
01595
01596 argv = parse_save_options (argv, format, append, save_as_floats,
01597 use_zlib);
01598 argc = argv.length ();
01599 int i = 0;
01600
01601 if (error_state)
01602 return retval;
01603
01604 if (i == argc)
01605 {
01606 print_usage ();
01607 return retval;
01608 }
01609
01610 if (save_as_floats && format == LS_ASCII)
01611 {
01612 error ("save: cannot specify both -ascii and -float-binary");
01613 return retval;
01614 }
01615
01616 if (argv[i] == "-")
01617 {
01618 i++;
01619
01620 #ifdef HAVE_HDF5
01621 if (format == LS_HDF5)
01622 error ("save: cannot write HDF5 format to stdout");
01623 else
01624 #endif
01625
01626
01627 {
01628 if (append)
01629 warning ("save: ignoring -append option for output to stdout");
01630
01631
01632
01633
01634 save_vars (argv, i, argc, octave_stdout, format,
01635 save_as_floats, true);
01636 }
01637 }
01638
01639
01640
01641 else if (i == argc - 1 && glob_pattern_p (argv[i]))
01642 {
01643 print_usage ();
01644 return retval;
01645 }
01646 else
01647 {
01648 std::string fname = file_ops::tilde_expand (argv[i]);
01649
01650 i++;
01651
01652
01653 if (format == LS_MAT7_BINARY)
01654 use_zlib = false;
01655
01656 std::ios::openmode mode
01657 = append ? (std::ios::app | std::ios::ate) : std::ios::out;
01658
01659 if (format == LS_BINARY
01660 #ifdef HAVE_HDF5
01661 || format == LS_HDF5
01662 #endif
01663 || format == LS_MAT_BINARY
01664 || format == LS_MAT5_BINARY
01665 || format == LS_MAT7_BINARY)
01666 mode |= std::ios::binary;
01667
01668 #ifdef HAVE_HDF5
01669 if (format == LS_HDF5)
01670 {
01671
01672 if (append)
01673 {
01674 error ("save: appending to HDF5 files is not implemented");
01675 return retval;
01676 }
01677
01678 bool write_header_info = ! (append &&
01679 H5Fis_hdf5 (fname.c_str ()) > 0);
01680
01681 hdf5_ofstream hdf5_file (fname.c_str (), mode);
01682
01683 if (hdf5_file.file_id != -1)
01684 {
01685 save_vars (argv, i, argc, hdf5_file, format,
01686 save_as_floats, write_header_info);
01687
01688 hdf5_file.close ();
01689 }
01690 else
01691 {
01692 gripe_file_open ("save", fname);
01693 return retval;
01694 }
01695 }
01696 else
01697 #endif
01698
01699
01700 {
01701 #ifdef HAVE_ZLIB
01702 if (use_zlib)
01703 {
01704 gzofstream file (fname.c_str (), mode);
01705
01706 if (file)
01707 {
01708 bool write_header_info = ! file.tellp ();
01709
01710 save_vars (argv, i, argc, file, format,
01711 save_as_floats, write_header_info);
01712
01713 file.close ();
01714 }
01715 else
01716 {
01717 gripe_file_open ("save", fname);
01718 return retval;
01719 }
01720 }
01721 else
01722 #endif
01723 {
01724 std::ofstream file (fname.c_str (), mode);
01725
01726 if (file)
01727 {
01728 bool write_header_info = ! file.tellp ();
01729
01730 save_vars (argv, i, argc, file, format,
01731 save_as_floats, write_header_info);
01732
01733 file.close ();
01734 }
01735 else
01736 {
01737 gripe_file_open ("save", fname);
01738 return retval;
01739 }
01740 }
01741 }
01742 }
01743
01744 return retval;
01745 }
01746
01747 DEFUN (crash_dumps_octave_core, args, nargout,
01748 "-*- texinfo -*-\n\
01749 @deftypefn {Built-in Function} {@var{val} =} crash_dumps_octave_core ()\n\
01750 @deftypefnx {Built-in Function} {@var{old_val} =} crash_dumps_octave_core (@var{new_val})\n\
01751 @deftypefnx {Built-in Function} {} crash_dumps_octave_core (@var{new_val}, \"local\")\n\
01752 Query or set the internal variable that controls whether Octave tries\n\
01753 to save all current variables to the file \"octave-core\" if it\n\
01754 crashes or receives a hangup, terminate or similar signal.\n\
01755 \n\
01756 When called from inside a function with the \"local\" option, the variable is\n\
01757 changed locally for the function and any subroutines it calls. The original\n\
01758 variable value is restored when exiting the function.\n\
01759 @seealso{octave_core_file_limit, octave_core_file_name, octave_core_file_options}\n\
01760 @end deftypefn")
01761 {
01762 return SET_INTERNAL_VARIABLE (crash_dumps_octave_core);
01763 }
01764
01765 DEFUN (default_save_options, args, nargout,
01766 "-*- texinfo -*-\n\
01767 @deftypefn {Built-in Function} {@var{val} =} default_save_options ()\n\
01768 @deftypefnx {Built-in Function} {@var{old_val} =} default_save_options (@var{new_val})\n\
01769 @deftypefnx {Built-in Function} {} default_save_options (@var{new_val}, \"local\")\n\
01770 Query or set the internal variable that specifies the default options\n\
01771 for the @code{save} command, and defines the default format.\n\
01772 Typical values include @code{\"-ascii\"}, @code{\"-text -zip\"}.\n\
01773 The default value is @option{-text}.\n\
01774 \n\
01775 When called from inside a function with the \"local\" option, the variable is\n\
01776 changed locally for the function and any subroutines it calls. The original\n\
01777 variable value is restored when exiting the function.\n\
01778 @seealso{save}\n\
01779 @end deftypefn")
01780 {
01781 return SET_NONEMPTY_INTERNAL_STRING_VARIABLE (default_save_options);
01782 }
01783
01784 DEFUN (octave_core_file_limit, args, nargout,
01785 "-*- texinfo -*-\n\
01786 @deftypefn {Built-in Function} {@var{val} =} octave_core_file_limit ()\n\
01787 @deftypefnx {Built-in Function} {@var{old_val} =} octave_core_file_limit (@var{new_val})\n\
01788 @deftypefnx {Built-in Function} {} octave_core_file_limit (@var{new_val}, \"local\")\n\
01789 Query or set the internal variable that specifies the maximum amount\n\
01790 of memory (in kilobytes) of the top-level workspace that Octave will\n\
01791 attempt to save when writing data to the crash dump file (the name of\n\
01792 the file is specified by @var{octave_core_file_name}). If\n\
01793 @var{octave_core_file_options} flags specify a binary format,\n\
01794 then @var{octave_core_file_limit} will be approximately the maximum\n\
01795 size of the file. If a text file format is used, then the file could\n\
01796 be much larger than the limit. The default value is -1 (unlimited)\n\
01797 \n\
01798 When called from inside a function with the \"local\" option, the variable is\n\
01799 changed locally for the function and any subroutines it calls. The original\n\
01800 variable value is restored when exiting the function.\n\
01801 @seealso{crash_dumps_octave_core, octave_core_file_name, octave_core_file_options}\n\
01802 @end deftypefn")
01803 {
01804 return SET_INTERNAL_VARIABLE (octave_core_file_limit);
01805 }
01806
01807 DEFUN (octave_core_file_name, args, nargout,
01808 "-*- texinfo -*-\n\
01809 @deftypefn {Built-in Function} {@var{val} =} octave_core_file_name ()\n\
01810 @deftypefnx {Built-in Function} {@var{old_val} =} octave_core_file_name (@var{new_val})\n\
01811 @deftypefnx {Built-in Function} {} octave_core_file_name (@var{new_val}, \"local\")\n\
01812 Query or set the internal variable that specifies the name of the file\n\
01813 used for saving data from the top-level workspace if Octave aborts.\n\
01814 The default value is @code{\"octave-core\"}\n\
01815 \n\
01816 When called from inside a function with the \"local\" option, the variable is\n\
01817 changed locally for the function and any subroutines it calls. The original\n\
01818 variable value is restored when exiting the function.\n\
01819 @seealso{crash_dumps_octave_core, octave_core_file_name, octave_core_file_options}\n\
01820 @end deftypefn")
01821 {
01822 return SET_NONEMPTY_INTERNAL_STRING_VARIABLE (octave_core_file_name);
01823 }
01824
01825 DEFUN (octave_core_file_options, args, nargout,
01826 "-*- texinfo -*-\n\
01827 @deftypefn {Built-in Function} {@var{val} =} octave_core_file_options ()\n\
01828 @deftypefnx {Built-in Function} {@var{old_val} =} octave_core_file_options (@var{new_val})\n\
01829 @deftypefnx {Built-in Function} {} octave_core_file_options (@var{new_val}, \"local\")\n\
01830 Query or set the internal variable that specifies the options used for\n\
01831 saving the workspace data if Octave aborts. The value of\n\
01832 @code{octave_core_file_options} should follow the same format as the\n\
01833 options for the @code{save} function. The default value is Octave's binary\n\
01834 format.\n\
01835 \n\
01836 When called from inside a function with the \"local\" option, the variable is\n\
01837 changed locally for the function and any subroutines it calls. The original\n\
01838 variable value is restored when exiting the function.\n\
01839 @seealso{crash_dumps_octave_core, octave_core_file_name, octave_core_file_limit}\n\
01840 @end deftypefn")
01841 {
01842 return SET_NONEMPTY_INTERNAL_STRING_VARIABLE (octave_core_file_options);
01843 }
01844
01845 DEFUN (save_header_format_string, args, nargout,
01846 "-*- texinfo -*-\n\
01847 @deftypefn {Built-in Function} {@var{val} =} save_header_format_string ()\n\
01848 @deftypefnx {Built-in Function} {@var{old_val} =} save_header_format_string (@var{new_val})\n\
01849 @deftypefnx {Built-in Function} {} save_header_format_string (@var{new_val}, \"local\")\n\
01850 Query or set the internal variable that specifies the format\n\
01851 string used for the comment line written at the beginning of\n\
01852 text-format data files saved by Octave. The format string is\n\
01853 passed to @code{strftime} and should begin with the character\n\
01854 @samp{#} and contain no newline characters. If the value of\n\
01855 @code{save_header_format_string} is the empty string,\n\
01856 the header comment is omitted from text-format data files. The\n\
01857 default value is\n\
01858 @c Set example in small font to prevent overfull line\n\
01859 \n\
01860 @smallexample\n\
01861 \"# Created by Octave VERSION, %a %b %d %H:%M:%S %Y %Z <USER@@HOST>\"\n\
01862 @end smallexample\n\
01863 \n\
01864 When called from inside a function with the \"local\" option, the variable is\n\
01865 changed locally for the function and any subroutines it calls. The original\n\
01866 variable value is restored when exiting the function.\n\
01867 @seealso{strftime, save}\n\
01868 @end deftypefn")
01869 {
01870 return SET_INTERNAL_VARIABLE (save_header_format_string);
01871 }