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 #ifdef HAVE_CONFIG_H
00026 #include <config.h>
00027 #endif
00028
00029 #include <cstring>
00030 #include <cctype>
00031
00032 #include <fstream>
00033 #include <iomanip>
00034 #include <iostream>
00035 #include <sstream>
00036 #include <string>
00037
00038 #include "byte-swap.h"
00039 #include "data-conv.h"
00040 #include "file-ops.h"
00041 #include "glob-match.h"
00042 #include "lo-mappers.h"
00043 #include "mach-info.h"
00044 #include "oct-env.h"
00045 #include "oct-time.h"
00046 #include "quit.h"
00047 #include "str-vec.h"
00048
00049 #include "Cell.h"
00050 #include "defun.h"
00051 #include "error.h"
00052 #include "gripes.h"
00053 #include "load-save.h"
00054 #include "ls-ascii-helper.h"
00055 #include "ls-oct-ascii.h"
00056 #include "oct-obj.h"
00057 #include "oct-map.h"
00058 #include "ov-cell.h"
00059 #include "pager.h"
00060 #include "pt-exp.h"
00061 #include "unwind-prot.h"
00062 #include "utils.h"
00063 #include "variables.h"
00064 #include "version.h"
00065 #include "dMatrix.h"
00066
00067
00068 static int Vsave_precision = 16;
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079 std::string
00080 extract_keyword (std::istream& is, const char *keyword, const bool next_only)
00081 {
00082 std::string retval;
00083
00084 int ch = is.peek ();
00085 if (next_only && ch != '%' && ch != '#')
00086 return retval;
00087
00088 char c;
00089 while (is.get (c))
00090 {
00091 if (c == '%' || c == '#')
00092 {
00093 std::ostringstream buf;
00094
00095 while (is.get (c) && (c == ' ' || c == '\t' || c == '%' || c == '#'))
00096 ;
00097
00098 if (isalpha (c))
00099 buf << c;
00100
00101 while (is.get (c) && isalpha (c))
00102 buf << c;
00103
00104 std::string tmp = buf.str ();
00105 bool match = (tmp.compare (0, strlen (keyword), keyword) == 0);
00106
00107 if (match)
00108 {
00109 std::ostringstream value;
00110 while (is.get (c) && (c == ' ' || c == '\t' || c == ':'))
00111 ;
00112
00113 is.putback(c);
00114 retval = read_until_newline (is, false);
00115 break;
00116 }
00117 else if (next_only)
00118 break;
00119 else
00120 skip_until_newline (is, false);
00121 }
00122 }
00123
00124 int len = retval.length ();
00125
00126 if (len > 0)
00127 {
00128 while (len)
00129 {
00130 c = retval[len-1];
00131
00132 if (c == ' ' || c == '\t')
00133 len--;
00134 else
00135 {
00136 retval.resize (len);
00137 break;
00138 }
00139 }
00140 }
00141
00142 return retval;
00143 }
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234 #define SUBSTRING_COMPARE_EQ(s, pos, n, t) (s.substr (pos, n) == t)
00235
00236 std::string
00237 read_ascii_data (std::istream& is, const std::string& filename, bool& global,
00238 octave_value& tc, octave_idx_type count)
00239 {
00240
00241
00242 std::string name = extract_keyword (is, "name");
00243
00244 if (name.empty ())
00245 {
00246 if (count == 0)
00247 error ("load: empty name keyword or no data found in file '%s'",
00248 filename.c_str ());
00249
00250 return std::string ();
00251 }
00252
00253 if (! (name == ".nargin." || name == ".nargout."
00254 || name == CELL_ELT_TAG || valid_identifier (name)))
00255 {
00256 error ("load: bogus identifier '%s' found in file '%s'",
00257 name.c_str (), filename.c_str ());
00258 return std::string ();
00259 }
00260
00261
00262
00263 std::string tag = extract_keyword (is, "type");
00264
00265 if (! tag.empty ())
00266 {
00267 std::string typ;
00268 size_t pos = tag.rfind (' ');
00269
00270 if (pos != std::string::npos)
00271 {
00272 global = SUBSTRING_COMPARE_EQ (tag, 0, 6, "global");
00273
00274 typ = global ? tag.substr (7) : tag;
00275 }
00276 else
00277 typ = tag;
00278
00279
00280 if (SUBSTRING_COMPARE_EQ (typ, 0, 12, "string array"))
00281 tc = charMatrix ();
00282 else
00283 tc = octave_value_typeinfo::lookup_type (typ);
00284
00285 if (! tc.load_ascii (is))
00286 error ("load: trouble reading ascii file '%s'", filename.c_str ());
00287 }
00288 else
00289 error ("load: failed to extract keyword specifying value type");
00290
00291 if (error_state)
00292 {
00293 error ("load: reading file %s", filename.c_str ());
00294 return std::string ();
00295 }
00296
00297 return name;
00298 }
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311 bool
00312 save_ascii_data (std::ostream& os, const octave_value& val_arg,
00313 const std::string& name, bool mark_as_global,
00314 int precision)
00315 {
00316 bool success = true;
00317
00318 if (! name.empty ())
00319 os << "# name: " << name << "\n";
00320
00321 octave_value val = val_arg;
00322
00323 if (mark_as_global)
00324 os << "# type: global " << val.type_name () << "\n";
00325 else
00326 os << "# type: " << val.type_name() << "\n";
00327
00328 if (! precision)
00329 precision = Vsave_precision;
00330
00331 long old_precision = os.precision ();
00332 os.precision (precision);
00333
00334 success = val.save_ascii (os);
00335
00336
00337
00338
00339
00340 os << "\n\n";
00341
00342 os.precision (old_precision);
00343
00344 return (os && success);
00345 }
00346
00347 bool
00348 save_ascii_data_for_plotting (std::ostream& os, const octave_value& t,
00349 const std::string& name)
00350 {
00351 return save_ascii_data (os, t, name, false, 6);
00352 }
00353
00354
00355
00356
00357
00358
00359
00360 bool
00361 save_three_d (std::ostream& os, const octave_value& tc, bool parametric)
00362 {
00363 bool fail = false;
00364
00365 octave_idx_type nr = tc.rows ();
00366 octave_idx_type nc = tc.columns ();
00367
00368 if (tc.is_real_matrix ())
00369 {
00370 os << "# 3D data...\n"
00371 << "# type: matrix\n"
00372 << "# total rows: " << nr << "\n"
00373 << "# total columns: " << nc << "\n";
00374
00375 long old_precision = os.precision ();
00376 os.precision (6);
00377
00378 if (parametric)
00379 {
00380 octave_idx_type extras = nc % 3;
00381 if (extras)
00382 warning ("ignoring last %d columns", extras);
00383
00384 Matrix tmp = tc.matrix_value ();
00385 nr = tmp.rows ();
00386
00387 for (octave_idx_type i = 0; i < nc-extras; i += 3)
00388 {
00389 os << tmp.extract (0, i, nr-1, i+2);
00390 if (i+3 < nc-extras)
00391 os << "\n";
00392 }
00393 }
00394 else
00395 {
00396 Matrix tmp = tc.matrix_value ();
00397 nr = tmp.rows ();
00398
00399 for (octave_idx_type i = 0; i < nc; i++)
00400 {
00401 os << tmp.extract (0, i, nr-1, i);
00402 if (i+1 < nc)
00403 os << "\n";
00404 }
00405 }
00406
00407 os.precision (old_precision);
00408 }
00409 else
00410 {
00411 ::error ("for now, I can only save real matrices in 3D format");
00412 fail = true;
00413 }
00414
00415 return (os && ! fail);
00416 }
00417
00418 DEFUN (save_precision, args, nargout,
00419 "-*- texinfo -*-\n\
00420 @deftypefn {Built-in Function} {@var{val} =} save_precision ()\n\
00421 @deftypefnx {Built-in Function} {@var{old_val} =} save_precision (@var{new_val})\n\
00422 @deftypefnx {Built-in Function} {} save_precision (@var{new_val}, \"local\")\n\
00423 Query or set the internal variable that specifies the number of\n\
00424 digits to keep when saving data in text format.\n\
00425 \n\
00426 When called from inside a function with the \"local\" option, the variable is\n\
00427 changed locally for the function and any subroutines it calls. The original\n\
00428 variable value is restored when exiting the function.\n\
00429 @end deftypefn")
00430 {
00431 return SET_INTERNAL_VARIABLE_WITH_LIMITS (save_precision, -1, INT_MAX);
00432 }