Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifdef HAVE_CONFIG_H
00024 #include <config.h>
00025 #endif
00026
00027 #include <cfloat>
00028 #include <cstring>
00029 #include <cctype>
00030
00031 #include <fstream>
00032 #include <iomanip>
00033 #include <iostream>
00034 #include <sstream>
00035 #include <string>
00036
00037 #include "byte-swap.h"
00038 #include "data-conv.h"
00039 #include "file-ops.h"
00040 #include "glob-match.h"
00041 #include "lo-mappers.h"
00042 #include "mach-info.h"
00043 #include "oct-env.h"
00044 #include "oct-time.h"
00045 #include "quit.h"
00046 #include "str-vec.h"
00047
00048 #include "Cell.h"
00049 #include "defun.h"
00050 #include "error.h"
00051 #include "gripes.h"
00052 #include "lex.h"
00053 #include "load-save.h"
00054 #include "ls-ascii-helper.h"
00055 #include "ls-mat-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 "sysdep.h"
00062 #include "unwind-prot.h"
00063 #include "utils.h"
00064 #include "variables.h"
00065 #include "version.h"
00066 #include "dMatrix.h"
00067
00068 static std::string
00069 get_mat_data_input_line (std::istream& is)
00070 {
00071 std::string retval;
00072
00073 bool have_data = false;
00074
00075 do
00076 {
00077 retval = "";
00078
00079 char c;
00080 while (is.get (c))
00081 {
00082 if (c == '\n' || c == '\r')
00083 {
00084 is.putback (c);
00085 skip_preceeding_newline (is);
00086 break;
00087 }
00088
00089 if (c == '%' || c == '#')
00090 {
00091 skip_until_newline (is, false);
00092 break;
00093 }
00094
00095 if (! is.eof ())
00096 {
00097 if (! have_data && c != ' ' && c != '\t')
00098 have_data = true;
00099
00100 retval += c;
00101 }
00102 }
00103 }
00104 while (! (have_data || is.eof ()));
00105
00106 return retval;
00107 }
00108
00109 static void
00110 get_lines_and_columns (std::istream& is, const std::string& filename, octave_idx_type& nr, octave_idx_type& nc)
00111 {
00112 std::streampos pos = is.tellg ();
00113
00114 int file_line_number = 0;
00115
00116 nr = 0;
00117 nc = 0;
00118
00119 while (is && ! error_state)
00120 {
00121 octave_quit ();
00122
00123 std::string buf = get_mat_data_input_line (is);
00124
00125 file_line_number++;
00126
00127 size_t beg = buf.find_first_not_of (", \t");
00128
00129
00130
00131
00132
00133 if (beg != std::string::npos && buf[beg] == '\r' && beg == buf.length () - 1)
00134 {
00135
00136
00137 beg = std::string::npos;
00138 }
00139
00140 octave_idx_type tmp_nc = 0;
00141
00142 while (beg != std::string::npos)
00143 {
00144 tmp_nc++;
00145
00146 size_t end = buf.find_first_of (", \t", beg);
00147
00148 if (end != std::string::npos)
00149 {
00150 beg = buf.find_first_not_of (", \t", end);
00151
00152 if (beg == std::string::npos || (buf[beg] == '\r' &&
00153 beg == buf.length () - 1))
00154 {
00155
00156
00157
00158 break;
00159 }
00160 }
00161 else
00162 break;
00163 }
00164
00165 if (tmp_nc > 0)
00166 {
00167 if (nc == 0)
00168 {
00169 nc = tmp_nc;
00170 nr++;
00171 }
00172 else if (nc == tmp_nc)
00173 nr++;
00174 else
00175 error ("load: %s: inconsistent number of columns near line %d",
00176 filename.c_str (), file_line_number);
00177 }
00178 }
00179
00180 if (nr == 0 || nc == 0)
00181 error ("load: file '%s' seems to be empty!", filename.c_str ());
00182
00183 is.clear ();
00184 is.seekg (pos);
00185 }
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198 std::string
00199 read_mat_ascii_data (std::istream& is, const std::string& filename,
00200 octave_value& tc)
00201 {
00202 std::string retval;
00203
00204 std::string varname;
00205
00206 size_t pos = filename.rfind ('/');
00207
00208 if (pos != std::string::npos)
00209 varname = filename.substr (pos+1);
00210 else
00211 varname = filename;
00212
00213 pos = varname.rfind ('.');
00214
00215 if (pos != std::string::npos)
00216 varname = varname.substr (0, pos);
00217
00218 size_t len = varname.length ();
00219 for (size_t i = 0; i < len; i++)
00220 {
00221 char c = varname[i];
00222 if (! (isalnum (c) || c == '_'))
00223 varname[i] = '_';
00224 }
00225
00226 if (is_keyword (varname) || ! isalpha (varname[0]))
00227 varname.insert (0, "X");
00228
00229 if (valid_identifier (varname))
00230 {
00231 octave_idx_type nr = 0;
00232 octave_idx_type nc = 0;
00233
00234 int total_count = 0;
00235
00236 get_lines_and_columns (is, filename, nr, nc);
00237
00238 octave_quit ();
00239
00240 if (! error_state && nr > 0 && nc > 0)
00241 {
00242 Matrix tmp (nr, nc);
00243
00244 if (nr < 1 || nc < 1)
00245 is.clear (std::ios::badbit);
00246 else
00247 {
00248 double d;
00249 for (octave_idx_type i = 0; i < nr; i++)
00250 {
00251 std::string buf = get_mat_data_input_line (is);
00252
00253 std::istringstream tmp_stream (buf);
00254
00255 for (octave_idx_type j = 0; j < nc; j++)
00256 {
00257 octave_quit ();
00258
00259 d = octave_read_value<double> (tmp_stream);
00260
00261 if (tmp_stream || tmp_stream.eof ())
00262 {
00263 tmp.elem (i, j) = d;
00264 total_count++;
00265
00266
00267 char c;
00268 while (1)
00269 {
00270 tmp_stream >> c;
00271
00272 if (! tmp_stream)
00273 break;
00274
00275 if (! (c == ' ' || c == '\t' || c == ','))
00276 {
00277 tmp_stream.putback (c);
00278 break;
00279 }
00280 }
00281
00282 if (tmp_stream.eof ())
00283 break;
00284 }
00285 else
00286 {
00287 error ("load: failed to read matrix from file '%s'",
00288 filename.c_str ());
00289
00290 return retval;
00291 }
00292
00293 }
00294 }
00295 }
00296
00297 if (is || is.eof ())
00298 {
00299
00300
00301 if (is.eof ())
00302 is.clear ();
00303
00304 octave_idx_type expected = nr * nc;
00305
00306 if (expected == total_count)
00307 {
00308 tc = tmp;
00309 retval = varname;
00310 }
00311 else
00312 error ("load: expected %d elements, found %d",
00313 expected, total_count);
00314 }
00315 else
00316 error ("load: failed to read matrix from file '%s'",
00317 filename.c_str ());
00318 }
00319 else
00320 error ("load: unable to extract matrix size from file '%s'",
00321 filename.c_str ());
00322 }
00323 else
00324 error ("load: unable to convert filename '%s' to valid identifier",
00325 filename.c_str ());
00326
00327 return retval;
00328 }
00329
00330 bool
00331 save_mat_ascii_data (std::ostream& os, const octave_value& val,
00332 int precision, bool tabs)
00333 {
00334 bool success = true;
00335
00336 if (val.is_complex_type ())
00337 warning ("save: omitting imaginary part for ASCII file");
00338
00339 Matrix m = val.matrix_value (true);
00340
00341 if (error_state)
00342 {
00343 success = false;
00344
00345 error_state = 0;
00346 }
00347 else
00348 {
00349 long old_precision = os.precision ();
00350
00351 os.precision (precision);
00352
00353 std::ios::fmtflags oflags
00354 = os.flags (static_cast<std::ios::fmtflags> (std::ios::scientific));
00355
00356 if (tabs)
00357 {
00358 for (octave_idx_type i = 0; i < m.rows (); i++)
00359 {
00360 for (octave_idx_type j = 0; j < m.cols (); j++)
00361 {
00362
00363 if (j != 0) os << '\t';
00364 octave_write_double (os, m (i, j));
00365 }
00366 os << "\n";
00367 }
00368 }
00369 else
00370 os << m;
00371
00372 os.flags (oflags);
00373
00374 os.precision (old_precision);
00375 }
00376
00377 return (os && success);
00378 }