Mercurial > octave
annotate libinterp/corefcn/ls-oct-text.cc @ 28179:bea3f8f96f7a stable
Load structures with arbitrary string fieldnames (bug #50831, bug #46645).
* ls-oct-text.h, ls-oct-text.cc (read_text_data): Consider additional optional
bool argument to skip validation of input name.
* ov-struct.cc (octave_struct::load_ascii, octave_scalar_struct::load_ascii):
Call read_text_data with additional argument (skip_validation), set to true.
* test/bug-50831/bug-50831.tst, test/bug-50831/module.mk: New test files.
author | Olaf Till <i7tiol@t-online.de> |
---|---|
date | Wed, 19 Apr 2017 15:06:31 +0200 |
parents | a4268efb7334 |
children | 7a8c69c4eb55 |
rev | line source |
---|---|
27923
bd51beb6205e
update formatting of copyright notices
John W. Eaton <jwe@octave.org>
parents:
27919
diff
changeset
|
1 //////////////////////////////////////////////////////////////////////// |
bd51beb6205e
update formatting of copyright notices
John W. Eaton <jwe@octave.org>
parents:
27919
diff
changeset
|
2 // |
bd51beb6205e
update formatting of copyright notices
John W. Eaton <jwe@octave.org>
parents:
27919
diff
changeset
|
3 // Copyright (C) 1996-2020 The Octave Project Developers |
bd51beb6205e
update formatting of copyright notices
John W. Eaton <jwe@octave.org>
parents:
27919
diff
changeset
|
4 // |
bd51beb6205e
update formatting of copyright notices
John W. Eaton <jwe@octave.org>
parents:
27919
diff
changeset
|
5 // See the file COPYRIGHT.md in the top-level directory of this |
bd51beb6205e
update formatting of copyright notices
John W. Eaton <jwe@octave.org>
parents:
27919
diff
changeset
|
6 // distribution or <https://octave.org/copyright/>. |
bd51beb6205e
update formatting of copyright notices
John W. Eaton <jwe@octave.org>
parents:
27919
diff
changeset
|
7 // |
bd51beb6205e
update formatting of copyright notices
John W. Eaton <jwe@octave.org>
parents:
27919
diff
changeset
|
8 // This file is part of Octave. |
bd51beb6205e
update formatting of copyright notices
John W. Eaton <jwe@octave.org>
parents:
27919
diff
changeset
|
9 // |
bd51beb6205e
update formatting of copyright notices
John W. Eaton <jwe@octave.org>
parents:
27919
diff
changeset
|
10 // Octave is free software: you can redistribute it and/or modify it |
bd51beb6205e
update formatting of copyright notices
John W. Eaton <jwe@octave.org>
parents:
27919
diff
changeset
|
11 // under the terms of the GNU General Public License as published by |
bd51beb6205e
update formatting of copyright notices
John W. Eaton <jwe@octave.org>
parents:
27919
diff
changeset
|
12 // the Free Software Foundation, either version 3 of the License, or |
bd51beb6205e
update formatting of copyright notices
John W. Eaton <jwe@octave.org>
parents:
27919
diff
changeset
|
13 // (at your option) any later version. |
bd51beb6205e
update formatting of copyright notices
John W. Eaton <jwe@octave.org>
parents:
27919
diff
changeset
|
14 // |
bd51beb6205e
update formatting of copyright notices
John W. Eaton <jwe@octave.org>
parents:
27919
diff
changeset
|
15 // Octave is distributed in the hope that it will be useful, but |
bd51beb6205e
update formatting of copyright notices
John W. Eaton <jwe@octave.org>
parents:
27919
diff
changeset
|
16 // WITHOUT ANY WARRANTY; without even the implied warranty of |
bd51beb6205e
update formatting of copyright notices
John W. Eaton <jwe@octave.org>
parents:
27919
diff
changeset
|
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
bd51beb6205e
update formatting of copyright notices
John W. Eaton <jwe@octave.org>
parents:
27919
diff
changeset
|
18 // GNU General Public License for more details. |
bd51beb6205e
update formatting of copyright notices
John W. Eaton <jwe@octave.org>
parents:
27919
diff
changeset
|
19 // |
bd51beb6205e
update formatting of copyright notices
John W. Eaton <jwe@octave.org>
parents:
27919
diff
changeset
|
20 // You should have received a copy of the GNU General Public License |
bd51beb6205e
update formatting of copyright notices
John W. Eaton <jwe@octave.org>
parents:
27919
diff
changeset
|
21 // along with Octave; see the file COPYING. If not, see |
bd51beb6205e
update formatting of copyright notices
John W. Eaton <jwe@octave.org>
parents:
27919
diff
changeset
|
22 // <https://www.gnu.org/licenses/>. |
bd51beb6205e
update formatting of copyright notices
John W. Eaton <jwe@octave.org>
parents:
27919
diff
changeset
|
23 // |
bd51beb6205e
update formatting of copyright notices
John W. Eaton <jwe@octave.org>
parents:
27919
diff
changeset
|
24 //////////////////////////////////////////////////////////////////////// |
4634 | 25 |
21724
aba2e6293dd8
use "#if ..." consistently instead of "#ifdef" and "#ifndef"
John W. Eaton <jwe@octave.org>
parents:
21301
diff
changeset
|
26 #if defined (HAVE_CONFIG_H) |
21301
40de9f8f23a6
Use '#include "config.h"' rather than <config.h>.
Rik <rik@octave.org>
parents:
21200
diff
changeset
|
27 # include "config.h" |
4634 | 28 #endif |
29 | |
30 #include <cstring> | |
31 #include <cctype> | |
32 | |
33 #include <fstream> | |
34 #include <iomanip> | |
25438
cb1606f78f6b
prefer <istream>, <ostream>, or <iosfwd> to <iostream> where possible
John W. Eaton <jwe@octave.org>
parents:
25392
diff
changeset
|
35 #include <istream> |
cb1606f78f6b
prefer <istream>, <ostream>, or <iosfwd> to <iostream> where possible
John W. Eaton <jwe@octave.org>
parents:
25392
diff
changeset
|
36 #include <ostream> |
5765 | 37 #include <sstream> |
4634 | 38 #include <string> |
39 | |
40 #include "byte-swap.h" | |
41 #include "data-conv.h" | |
42 #include "file-ops.h" | |
43 #include "glob-match.h" | |
44 #include "lo-mappers.h" | |
45 #include "mach-info.h" | |
46 #include "oct-env.h" | |
47 #include "oct-time.h" | |
48 #include "quit.h" | |
49 #include "str-vec.h" | |
50 | |
51 #include "Cell.h" | |
52 #include "defun.h" | |
53 #include "error.h" | |
21100
e39e05d90788
Switch gripe_XXX to either err_XXX or warn_XXX naming scheme.
Rik <rik@octave.org>
parents:
21021
diff
changeset
|
54 #include "errwarn.h" |
24540
46440078d73b
don't use singleton for octave_value_typeinfo
John W. Eaton <jwe@octave.org>
parents:
24534
diff
changeset
|
55 #include "interpreter-private.h" |
4634 | 56 #include "load-save.h" |
8946
e7e928088e90
fix CRLF issues with text-mode reading in windows when loading ascii data
Benjamin Lindner <lindnerb@users.sourceforge.net>
parents:
8920
diff
changeset
|
57 #include "ls-ascii-helper.h" |
20447
c6224b4e7774
maint: Rename instances of LS_ASCII to LS_TEXT for clarity.
Rik <rik@octave.org>
parents:
20428
diff
changeset
|
58 #include "ls-oct-text.h" |
20940
48b2ad5ee801
maint: Rename oct-obj.[cc|h] to ovl.[cc|h] for clarity.
Rik <rik@octave.org>
parents:
20853
diff
changeset
|
59 #include "ovl.h" |
4634 | 60 #include "oct-map.h" |
61 #include "ov-cell.h" | |
62 #include "pager.h" | |
63 #include "unwind-prot.h" | |
64 #include "utils.h" | |
65 #include "variables.h" | |
66 #include "version.h" | |
67 #include "dMatrix.h" | |
68 | |
23556
31b1ef1ee585
Fix Octave's -text format for saving data to make it lossless for IEEE-754 doubles.
Rik <rik@octave.org>
parents:
23470
diff
changeset
|
69 // The number of decimal digits to use when writing ASCII data. |
31b1ef1ee585
Fix Octave's -text format for saving data to make it lossless for IEEE-754 doubles.
Rik <rik@octave.org>
parents:
23470
diff
changeset
|
70 // 17 is the minimum necessary for lossless save/restore of IEEE-754 doubles. |
31b1ef1ee585
Fix Octave's -text format for saving data to make it lossless for IEEE-754 doubles.
Rik <rik@octave.org>
parents:
23470
diff
changeset
|
71 static int Vsave_precision = 17; |
4634 | 72 |
20447
c6224b4e7774
maint: Rename instances of LS_ASCII to LS_TEXT for clarity.
Rik <rik@octave.org>
parents:
20428
diff
changeset
|
73 // Functions for reading octave format text data. |
4634 | 74 |
75 // Extract a KEYWORD and its value from stream IS, returning the | |
76 // associated value in a new string. | |
77 // | |
78 // Input should look something like: | |
79 // | |
80 // [%#][ \t]*keyword[ \t]*:[ \t]*string-value[ \t]*\n | |
81 | |
82 std::string | |
4687 | 83 extract_keyword (std::istream& is, const char *keyword, const bool next_only) |
4634 | 84 { |
85 std::string retval; | |
86 | |
7744
14b841c47a5f
handle load/save for handles to built-in functions
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
87 int ch = is.peek (); |
14b841c47a5f
handle load/save for handles to built-in functions
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
88 if (next_only && ch != '%' && ch != '#') |
14b841c47a5f
handle load/save for handles to built-in functions
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
89 return retval; |
14b841c47a5f
handle load/save for handles to built-in functions
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
90 |
4634 | 91 char c; |
92 while (is.get (c)) | |
93 { | |
94 if (c == '%' || c == '#') | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10160
diff
changeset
|
95 { |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10160
diff
changeset
|
96 std::ostringstream buf; |
11586
12df7854fa7c
strip trailing whitespace from source files
John W. Eaton <jwe@octave.org>
parents:
11523
diff
changeset
|
97 |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10160
diff
changeset
|
98 while (is.get (c) && (c == ' ' || c == '\t' || c == '%' || c == '#')) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10160
diff
changeset
|
99 ; // Skip whitespace and comment characters. |
4634 | 100 |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10160
diff
changeset
|
101 if (isalpha (c)) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10160
diff
changeset
|
102 buf << c; |
4634 | 103 |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10160
diff
changeset
|
104 while (is.get (c) && isalpha (c)) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10160
diff
changeset
|
105 buf << c; |
4634 | 106 |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10160
diff
changeset
|
107 std::string tmp = buf.str (); |
21021
a5b99b09f8fd
maint: Use comparison operators rather than compare() for strings.
Rik <rik@octave.org>
parents:
21017
diff
changeset
|
108 bool match = (tmp.substr (0, strlen (keyword)) == keyword); |
4634 | 109 |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10160
diff
changeset
|
110 if (match) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10160
diff
changeset
|
111 { |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10160
diff
changeset
|
112 std::ostringstream value; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10160
diff
changeset
|
113 while (is.get (c) && (c == ' ' || c == '\t' || c == ':')) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10160
diff
changeset
|
114 ; // Skip whitespace and the colon. |
4634 | 115 |
14861
f7afecdd87ef
maint: Use Octave coding conventions for cuddling parentheses in src/ directory
Rik <octave@nomad.inbox5.com>
parents:
14846
diff
changeset
|
116 is.putback (c); |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10160
diff
changeset
|
117 retval = read_until_newline (is, false); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10160
diff
changeset
|
118 break; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10160
diff
changeset
|
119 } |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10160
diff
changeset
|
120 else if (next_only) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10160
diff
changeset
|
121 break; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10160
diff
changeset
|
122 else |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10160
diff
changeset
|
123 skip_until_newline (is, false); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10160
diff
changeset
|
124 } |
4634 | 125 } |
126 | |
127 int len = retval.length (); | |
128 | |
129 if (len > 0) | |
130 { | |
131 while (len) | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10160
diff
changeset
|
132 { |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10160
diff
changeset
|
133 c = retval[len-1]; |
4634 | 134 |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10160
diff
changeset
|
135 if (c == ' ' || c == '\t') |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10160
diff
changeset
|
136 len--; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10160
diff
changeset
|
137 else |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10160
diff
changeset
|
138 { |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10160
diff
changeset
|
139 retval.resize (len); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10160
diff
changeset
|
140 break; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10160
diff
changeset
|
141 } |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10160
diff
changeset
|
142 } |
4634 | 143 } |
144 | |
145 return retval; | |
146 } | |
147 | |
148 // Extract one value (scalar, matrix, string, etc.) from stream IS and | |
149 // place it in TC, returning the name of the variable. If the value | |
150 // is tagged as global in the file, return TRUE in GLOBAL. | |
151 // | |
4687 | 152 // Each type supplies its own function to load the data, and so this |
153 // function is extensible. | |
154 // | |
4634 | 155 // FILENAME is used for error messages. |
156 // | |
157 // The data is expected to be in the following format: | |
158 // | |
159 // The input file must have a header followed by some data. | |
160 // | |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14138
diff
changeset
|
161 // All lines in the header must begin with a '#' character. |
4634 | 162 // |
163 // The header must contain a list of keyword and value pairs with the | |
164 // keyword and value separated by a colon. | |
165 // | |
166 // Keywords must appear in the following order: | |
167 // | |
168 // # name: <name> | |
169 // # type: <type> | |
170 // # <info> | |
171 // | |
4687 | 172 // Where, for the built in types are: |
4634 | 173 // |
174 // <name> : a valid identifier | |
175 // | |
176 // <type> : <typename> | |
177 // | global <typename> | |
178 // | |
179 // <typename> : scalar | |
180 // | complex scalar | |
181 // | matrix | |
182 // | complex matrix | |
4687 | 183 // | bool |
184 // | bool matrix | |
4634 | 185 // | string |
186 // | range | |
187 // | |
188 // <info> : <matrix info> | |
189 // | <string info> | |
190 // | |
191 // <matrix info> : # rows: <integer> | |
192 // : # columns: <integer> | |
193 // | |
4687 | 194 // <string info> : # elements: <integer> |
195 // : # length: <integer> (once before each string) | |
4634 | 196 // |
21751
b571fc85953f
maint: Use two spaces after period to indicate sentence break.
Rik <rik@octave.org>
parents:
21724
diff
changeset
|
197 // For backward compatibility the type "string array" is treated as a |
b571fc85953f
maint: Use two spaces after period to indicate sentence break.
Rik <rik@octave.org>
parents:
21724
diff
changeset
|
198 // "string" type. Also "string" can have a single element with no elements |
4687 | 199 // line such that |
200 // | |
201 // <string info> : # length: <integer> | |
4634 | 202 // |
203 // Formatted ASCII data follows the header. | |
204 // | |
205 // Example: | |
206 // | |
207 // # name: foo | |
208 // # type: matrix | |
209 // # rows: 2 | |
210 // # columns: 2 | |
211 // 2 4 | |
212 // 1 3 | |
213 // | |
214 // Example: | |
215 // | |
216 // # name: foo | |
4687 | 217 // # type: string |
4634 | 218 // # elements: 5 |
219 // # length: 4 | |
220 // this | |
221 // # length: 2 | |
222 // is | |
223 // # length: 1 | |
224 // a | |
225 // # length: 6 | |
226 // string | |
227 // # length: 5 | |
228 // array | |
229 // | |
20447
c6224b4e7774
maint: Rename instances of LS_ASCII to LS_TEXT for clarity.
Rik <rik@octave.org>
parents:
20428
diff
changeset
|
230 // FIXME: This format is fairly rigid, and doesn't allow for arbitrary comments. |
c6224b4e7774
maint: Rename instances of LS_ASCII to LS_TEXT for clarity.
Rik <rik@octave.org>
parents:
20428
diff
changeset
|
231 // Someone should fix that. It does allow arbitrary types however. |
4634 | 232 |
233 // Ugh. The signature of the compare method is not standard in older | |
234 // versions of the GNU libstdc++. Do this instead: | |
235 | |
26372
2d9ae06f621b
Fix static analyzer detected V1003 issues with expansions in macros (bug #55347).
Rik <rik@octave.org>
parents:
26164
diff
changeset
|
236 #define SUBSTRING_COMPARE_EQ(s, pos, n, t) (s.substr (pos, n) == (t)) |
4634 | 237 |
238 std::string | |
20447
c6224b4e7774
maint: Rename instances of LS_ASCII to LS_TEXT for clarity.
Rik <rik@octave.org>
parents:
20428
diff
changeset
|
239 read_text_data (std::istream& is, const std::string& filename, bool& global, |
28179
bea3f8f96f7a
Load structures with arbitrary string fieldnames (bug #50831, bug #46645).
Olaf Till <i7tiol@t-online.de>
parents:
27978
diff
changeset
|
240 octave_value& tc, octave_idx_type count, |
bea3f8f96f7a
Load structures with arbitrary string fieldnames (bug #50831, bug #46645).
Olaf Till <i7tiol@t-online.de>
parents:
27978
diff
changeset
|
241 const bool do_name_validation) |
4634 | 242 { |
243 // Read name for this entry or break on EOF. | |
244 | |
245 std::string name = extract_keyword (is, "name"); | |
246 | |
247 if (name.empty ()) | |
248 { | |
249 if (count == 0) | |
15466
d174210ce1ec
use ' instead of ` in error messages, warnings and most comments
John W. Eaton <jwe@octave.org>
parents:
14138
diff
changeset
|
250 error ("load: empty name keyword or no data found in file '%s'", |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10160
diff
changeset
|
251 filename.c_str ()); |
4634 | 252 |
21017
93748bcaec17
maint: Replace emtpy 'std::string ()' calls with "".
Rik <rik@octave.org>
parents:
21014
diff
changeset
|
253 return ""; |
4634 | 254 } |
255 | |
28179
bea3f8f96f7a
Load structures with arbitrary string fieldnames (bug #50831, bug #46645).
Olaf Till <i7tiol@t-online.de>
parents:
27978
diff
changeset
|
256 if (name != CELL_ELT_TAG |
bea3f8f96f7a
Load structures with arbitrary string fieldnames (bug #50831, bug #46645).
Olaf Till <i7tiol@t-online.de>
parents:
27978
diff
changeset
|
257 && do_name_validation && ! octave::valid_identifier (name)) |
20835
14cd86258b3d
use 'invalid' instead of 'bogus' in source files
John W. Eaton <jwe@octave.org>
parents:
20831
diff
changeset
|
258 error ("load: invalid identifier '%s' found in file '%s'", |
20741
a5ab31b52ae8
eliminate more uses of error_state
John W. Eaton <jwe@octave.org>
parents:
20447
diff
changeset
|
259 name.c_str (), filename.c_str ()); |
4634 | 260 |
261 // Look for type keyword. | |
262 | |
263 std::string tag = extract_keyword (is, "type"); | |
264 | |
20981
c11cea70b638
maint: invert if/else/error instances.
John W. Eaton <jwe@octave.org>
parents:
20962
diff
changeset
|
265 if (tag.empty ()) |
c11cea70b638
maint: invert if/else/error instances.
John W. Eaton <jwe@octave.org>
parents:
20962
diff
changeset
|
266 error ("load: failed to extract keyword specifying value type"); |
4634 | 267 |
20981
c11cea70b638
maint: invert if/else/error instances.
John W. Eaton <jwe@octave.org>
parents:
20962
diff
changeset
|
268 std::string typ; |
c11cea70b638
maint: invert if/else/error instances.
John W. Eaton <jwe@octave.org>
parents:
20962
diff
changeset
|
269 size_t pos = tag.rfind (' '); |
4634 | 270 |
20981
c11cea70b638
maint: invert if/else/error instances.
John W. Eaton <jwe@octave.org>
parents:
20962
diff
changeset
|
271 if (pos != std::string::npos) |
c11cea70b638
maint: invert if/else/error instances.
John W. Eaton <jwe@octave.org>
parents:
20962
diff
changeset
|
272 { |
c11cea70b638
maint: invert if/else/error instances.
John W. Eaton <jwe@octave.org>
parents:
20962
diff
changeset
|
273 global = SUBSTRING_COMPARE_EQ (tag, 0, 6, "global"); |
4634 | 274 |
23450
855122b993da
maint: Wrap tertiary operator in parentheses "(COND ? x : y)".
Rik <rik@octave.org>
parents:
23220
diff
changeset
|
275 typ = (global ? tag.substr (7) : tag); |
4634 | 276 } |
277 else | |
20981
c11cea70b638
maint: invert if/else/error instances.
John W. Eaton <jwe@octave.org>
parents:
20962
diff
changeset
|
278 typ = tag; |
c11cea70b638
maint: invert if/else/error instances.
John W. Eaton <jwe@octave.org>
parents:
20962
diff
changeset
|
279 |
c11cea70b638
maint: invert if/else/error instances.
John W. Eaton <jwe@octave.org>
parents:
20962
diff
changeset
|
280 // Special case for backward compatibility. A small bit of cruft |
c11cea70b638
maint: invert if/else/error instances.
John W. Eaton <jwe@octave.org>
parents:
20962
diff
changeset
|
281 if (SUBSTRING_COMPARE_EQ (typ, 0, 12, "string array")) |
c11cea70b638
maint: invert if/else/error instances.
John W. Eaton <jwe@octave.org>
parents:
20962
diff
changeset
|
282 tc = charMatrix (); |
c11cea70b638
maint: invert if/else/error instances.
John W. Eaton <jwe@octave.org>
parents:
20962
diff
changeset
|
283 else |
24540
46440078d73b
don't use singleton for octave_value_typeinfo
John W. Eaton <jwe@octave.org>
parents:
24534
diff
changeset
|
284 { |
46440078d73b
don't use singleton for octave_value_typeinfo
John W. Eaton <jwe@octave.org>
parents:
24534
diff
changeset
|
285 octave::type_info& type_info |
46440078d73b
don't use singleton for octave_value_typeinfo
John W. Eaton <jwe@octave.org>
parents:
24534
diff
changeset
|
286 = octave::__get_type_info__ ("read_text_data"); |
46440078d73b
don't use singleton for octave_value_typeinfo
John W. Eaton <jwe@octave.org>
parents:
24534
diff
changeset
|
287 |
46440078d73b
don't use singleton for octave_value_typeinfo
John W. Eaton <jwe@octave.org>
parents:
24534
diff
changeset
|
288 tc = type_info.lookup_type (typ); |
46440078d73b
don't use singleton for octave_value_typeinfo
John W. Eaton <jwe@octave.org>
parents:
24534
diff
changeset
|
289 } |
20981
c11cea70b638
maint: invert if/else/error instances.
John W. Eaton <jwe@octave.org>
parents:
20962
diff
changeset
|
290 |
c11cea70b638
maint: invert if/else/error instances.
John W. Eaton <jwe@octave.org>
parents:
20962
diff
changeset
|
291 if (! tc.load_ascii (is)) |
c11cea70b638
maint: invert if/else/error instances.
John W. Eaton <jwe@octave.org>
parents:
20962
diff
changeset
|
292 error ("load: trouble reading ascii file '%s'", filename.c_str ()); |
4634 | 293 |
294 return name; | |
295 } | |
296 | |
297 // Save the data from TC along with the corresponding NAME, and global | |
298 // flag MARK_AS_GLOBAL on stream OS in the plain text format described | |
20447
c6224b4e7774
maint: Rename instances of LS_ASCII to LS_TEXT for clarity.
Rik <rik@octave.org>
parents:
20428
diff
changeset
|
299 // above for load_text_data. If NAME is empty, the name: line is not |
11586
12df7854fa7c
strip trailing whitespace from source files
John W. Eaton <jwe@octave.org>
parents:
11523
diff
changeset
|
300 // generated. PRECISION specifies the number of decimal digits to print. |
4634 | 301 // |
302 // Assumes ranges and strings cannot contain Inf or NaN values. | |
303 // | |
304 // Returns 1 for success and 0 for failure. | |
305 | |
17787
175b392e91fe
Use GNU style coding conventions for code in libinterp/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
306 // FIXME: should probably write the help string here too. |
4634 | 307 |
308 bool | |
20447
c6224b4e7774
maint: Rename instances of LS_ASCII to LS_TEXT for clarity.
Rik <rik@octave.org>
parents:
20428
diff
changeset
|
309 save_text_data (std::ostream& os, const octave_value& val_arg, |
23470
a41fdb801db6
use mark_global and mark_persistent consistently
John W. Eaton <jwe@octave.org>
parents:
23450
diff
changeset
|
310 const std::string& name, bool mark_global, |
20447
c6224b4e7774
maint: Rename instances of LS_ASCII to LS_TEXT for clarity.
Rik <rik@octave.org>
parents:
20428
diff
changeset
|
311 int precision) |
4634 | 312 { |
313 if (! name.empty ()) | |
314 os << "# name: " << name << "\n"; | |
315 | |
316 octave_value val = val_arg; | |
317 | |
23470
a41fdb801db6
use mark_global and mark_persistent consistently
John W. Eaton <jwe@octave.org>
parents:
23450
diff
changeset
|
318 if (mark_global) |
4687 | 319 os << "# type: global " << val.type_name () << "\n"; |
320 else | |
14846
460a3c6d8bf1
maint: Use Octave coding convention for cuddled parenthis in function calls with empty argument lists.
Rik <octave@nomad.inbox5.com>
parents:
14138
diff
changeset
|
321 os << "# type: " << val.type_name () << "\n"; |
4634 | 322 |
5951 | 323 if (! precision) |
324 precision = Vsave_precision; | |
325 | |
326 long old_precision = os.precision (); | |
327 os.precision (precision); | |
328 | |
26410
d644dec272ea
ls-oct-text.cc: Fix static analyzer detected V519 issue (bug #55347).
Andreas Weber <octave@josoansi.de>
parents:
26376
diff
changeset
|
329 bool success = val.save_ascii (os); |
4634 | 330 |
10417
ad29dbbc3f70
save: make that two newline characters
John W. Eaton <jwe@octave.org>
parents:
10416
diff
changeset
|
331 // Insert an extra pair of newline characters after the data so that |
ad29dbbc3f70
save: make that two newline characters
John W. Eaton <jwe@octave.org>
parents:
10416
diff
changeset
|
332 // multiple data elements may be handled separately by gnuplot (see |
ad29dbbc3f70
save: make that two newline characters
John W. Eaton <jwe@octave.org>
parents:
10416
diff
changeset
|
333 // the description of the index qualifier for the plot command in the |
ad29dbbc3f70
save: make that two newline characters
John W. Eaton <jwe@octave.org>
parents:
10416
diff
changeset
|
334 // gnuplot documentation). |
ad29dbbc3f70
save: make that two newline characters
John W. Eaton <jwe@octave.org>
parents:
10416
diff
changeset
|
335 os << "\n\n"; |
10416
f06ede00fd8f
save: separate variables by blank line in Octave text format files
John W. Eaton <jwe@octave.org>
parents:
10315
diff
changeset
|
336 |
4634 | 337 os.precision (old_precision); |
338 | |
339 return (os && success); | |
340 } | |
341 | |
342 bool | |
20447
c6224b4e7774
maint: Rename instances of LS_ASCII to LS_TEXT for clarity.
Rik <rik@octave.org>
parents:
20428
diff
changeset
|
343 save_text_data_for_plotting (std::ostream& os, const octave_value& t, |
c6224b4e7774
maint: Rename instances of LS_ASCII to LS_TEXT for clarity.
Rik <rik@octave.org>
parents:
20428
diff
changeset
|
344 const std::string& name) |
4634 | 345 { |
20447
c6224b4e7774
maint: Rename instances of LS_ASCII to LS_TEXT for clarity.
Rik <rik@octave.org>
parents:
20428
diff
changeset
|
346 return save_text_data (os, t, name, false, 6); |
4634 | 347 } |
348 | |
349 // Maybe this should be a static function in tree-plot.cc? | |
350 | |
351 // If TC is matrix, save it on stream OS in a format useful for | |
21014
b9d4c3615e89
maint: Capitalize D for dimension in messages and comments.
Rik <rik@octave.org>
parents:
20981
diff
changeset
|
352 // making a 3-D plot with gnuplot. If PARAMETRIC is TRUE, |
b9d4c3615e89
maint: Capitalize D for dimension in messages and comments.
Rik <rik@octave.org>
parents:
20981
diff
changeset
|
353 // assume a parametric 3-D plot will be generated. |
4634 | 354 |
355 bool | |
356 save_three_d (std::ostream& os, const octave_value& tc, bool parametric) | |
357 { | |
5275 | 358 octave_idx_type nr = tc.rows (); |
359 octave_idx_type nc = tc.columns (); | |
4634 | 360 |
20962
3aa293be0e8d
maint: Invert simple conditionals in if/else/error paradigm.
Rik <rik@octave.org>
parents:
20940
diff
changeset
|
361 if (! tc.is_real_matrix ()) |
3aa293be0e8d
maint: Invert simple conditionals in if/else/error paradigm.
Rik <rik@octave.org>
parents:
20940
diff
changeset
|
362 error ("for now, I can only save real matrices in 3-D format"); |
4634 | 363 |
20962
3aa293be0e8d
maint: Invert simple conditionals in if/else/error paradigm.
Rik <rik@octave.org>
parents:
20940
diff
changeset
|
364 os << "# 3-D data...\n" |
3aa293be0e8d
maint: Invert simple conditionals in if/else/error paradigm.
Rik <rik@octave.org>
parents:
20940
diff
changeset
|
365 << "# type: matrix\n" |
3aa293be0e8d
maint: Invert simple conditionals in if/else/error paradigm.
Rik <rik@octave.org>
parents:
20940
diff
changeset
|
366 << "# total rows: " << nr << "\n" |
3aa293be0e8d
maint: Invert simple conditionals in if/else/error paradigm.
Rik <rik@octave.org>
parents:
20940
diff
changeset
|
367 << "# total columns: " << nc << "\n"; |
6171 | 368 |
20962
3aa293be0e8d
maint: Invert simple conditionals in if/else/error paradigm.
Rik <rik@octave.org>
parents:
20940
diff
changeset
|
369 long old_precision = os.precision (); |
3aa293be0e8d
maint: Invert simple conditionals in if/else/error paradigm.
Rik <rik@octave.org>
parents:
20940
diff
changeset
|
370 os.precision (6); |
4634 | 371 |
20962
3aa293be0e8d
maint: Invert simple conditionals in if/else/error paradigm.
Rik <rik@octave.org>
parents:
20940
diff
changeset
|
372 if (parametric) |
3aa293be0e8d
maint: Invert simple conditionals in if/else/error paradigm.
Rik <rik@octave.org>
parents:
20940
diff
changeset
|
373 { |
3aa293be0e8d
maint: Invert simple conditionals in if/else/error paradigm.
Rik <rik@octave.org>
parents:
20940
diff
changeset
|
374 octave_idx_type extras = nc % 3; |
3aa293be0e8d
maint: Invert simple conditionals in if/else/error paradigm.
Rik <rik@octave.org>
parents:
20940
diff
changeset
|
375 if (extras) |
26164
7f6a50f73625
Silence compiler warnings about format identifier for octave_idx_type (bug #55046).
Markus Mützel <markus.muetzel@gmx.de>
parents:
25646
diff
changeset
|
376 warning ("ignoring last %" OCTAVE_IDX_TYPE_FORMAT " columns", extras); |
20962
3aa293be0e8d
maint: Invert simple conditionals in if/else/error paradigm.
Rik <rik@octave.org>
parents:
20940
diff
changeset
|
377 |
3aa293be0e8d
maint: Invert simple conditionals in if/else/error paradigm.
Rik <rik@octave.org>
parents:
20940
diff
changeset
|
378 Matrix tmp = tc.matrix_value (); |
3aa293be0e8d
maint: Invert simple conditionals in if/else/error paradigm.
Rik <rik@octave.org>
parents:
20940
diff
changeset
|
379 nr = tmp.rows (); |
3aa293be0e8d
maint: Invert simple conditionals in if/else/error paradigm.
Rik <rik@octave.org>
parents:
20940
diff
changeset
|
380 |
3aa293be0e8d
maint: Invert simple conditionals in if/else/error paradigm.
Rik <rik@octave.org>
parents:
20940
diff
changeset
|
381 for (octave_idx_type i = 0; i < nc-extras; i += 3) |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10160
diff
changeset
|
382 { |
20962
3aa293be0e8d
maint: Invert simple conditionals in if/else/error paradigm.
Rik <rik@octave.org>
parents:
20940
diff
changeset
|
383 os << tmp.extract (0, i, nr-1, i+2); |
3aa293be0e8d
maint: Invert simple conditionals in if/else/error paradigm.
Rik <rik@octave.org>
parents:
20940
diff
changeset
|
384 if (i+3 < nc-extras) |
3aa293be0e8d
maint: Invert simple conditionals in if/else/error paradigm.
Rik <rik@octave.org>
parents:
20940
diff
changeset
|
385 os << "\n"; |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10160
diff
changeset
|
386 } |
4634 | 387 } |
388 else | |
20962
3aa293be0e8d
maint: Invert simple conditionals in if/else/error paradigm.
Rik <rik@octave.org>
parents:
20940
diff
changeset
|
389 { |
3aa293be0e8d
maint: Invert simple conditionals in if/else/error paradigm.
Rik <rik@octave.org>
parents:
20940
diff
changeset
|
390 Matrix tmp = tc.matrix_value (); |
3aa293be0e8d
maint: Invert simple conditionals in if/else/error paradigm.
Rik <rik@octave.org>
parents:
20940
diff
changeset
|
391 nr = tmp.rows (); |
3aa293be0e8d
maint: Invert simple conditionals in if/else/error paradigm.
Rik <rik@octave.org>
parents:
20940
diff
changeset
|
392 |
3aa293be0e8d
maint: Invert simple conditionals in if/else/error paradigm.
Rik <rik@octave.org>
parents:
20940
diff
changeset
|
393 for (octave_idx_type i = 0; i < nc; i++) |
3aa293be0e8d
maint: Invert simple conditionals in if/else/error paradigm.
Rik <rik@octave.org>
parents:
20940
diff
changeset
|
394 { |
3aa293be0e8d
maint: Invert simple conditionals in if/else/error paradigm.
Rik <rik@octave.org>
parents:
20940
diff
changeset
|
395 os << tmp.extract (0, i, nr-1, i); |
3aa293be0e8d
maint: Invert simple conditionals in if/else/error paradigm.
Rik <rik@octave.org>
parents:
20940
diff
changeset
|
396 if (i+1 < nc) |
3aa293be0e8d
maint: Invert simple conditionals in if/else/error paradigm.
Rik <rik@octave.org>
parents:
20940
diff
changeset
|
397 os << "\n"; |
3aa293be0e8d
maint: Invert simple conditionals in if/else/error paradigm.
Rik <rik@octave.org>
parents:
20940
diff
changeset
|
398 } |
3aa293be0e8d
maint: Invert simple conditionals in if/else/error paradigm.
Rik <rik@octave.org>
parents:
20940
diff
changeset
|
399 } |
3aa293be0e8d
maint: Invert simple conditionals in if/else/error paradigm.
Rik <rik@octave.org>
parents:
20940
diff
changeset
|
400 |
3aa293be0e8d
maint: Invert simple conditionals in if/else/error paradigm.
Rik <rik@octave.org>
parents:
20940
diff
changeset
|
401 os.precision (old_precision); |
4634 | 402 |
26462
88dd00f48522
Fix compilation error in 73ce195bf66e.
Rik <rik@octave.org>
parents:
26460
diff
changeset
|
403 return (static_cast<bool> (os)); |
4634 | 404 } |
405 | |
5794 | 406 DEFUN (save_precision, args, nargout, |
21966
112b20240c87
move docstrings in C++ files out of C strings and into comments
John W. Eaton <jwe@octave.org>
parents:
21751
diff
changeset
|
407 doc: /* -*- texinfo -*- |
112b20240c87
move docstrings in C++ files out of C strings and into comments
John W. Eaton <jwe@octave.org>
parents:
21751
diff
changeset
|
408 @deftypefn {} {@var{val} =} save_precision () |
112b20240c87
move docstrings in C++ files out of C strings and into comments
John W. Eaton <jwe@octave.org>
parents:
21751
diff
changeset
|
409 @deftypefnx {} {@var{old_val} =} save_precision (@var{new_val}) |
112b20240c87
move docstrings in C++ files out of C strings and into comments
John W. Eaton <jwe@octave.org>
parents:
21751
diff
changeset
|
410 @deftypefnx {} {} save_precision (@var{new_val}, "local") |
112b20240c87
move docstrings in C++ files out of C strings and into comments
John W. Eaton <jwe@octave.org>
parents:
21751
diff
changeset
|
411 Query or set the internal variable that specifies the number of digits to |
112b20240c87
move docstrings in C++ files out of C strings and into comments
John W. Eaton <jwe@octave.org>
parents:
21751
diff
changeset
|
412 keep when saving data in text format. |
112b20240c87
move docstrings in C++ files out of C strings and into comments
John W. Eaton <jwe@octave.org>
parents:
21751
diff
changeset
|
413 |
23556
31b1ef1ee585
Fix Octave's -text format for saving data to make it lossless for IEEE-754 doubles.
Rik <rik@octave.org>
parents:
23470
diff
changeset
|
414 The default value is 17 which is the minimum necessary for the lossless saving |
31b1ef1ee585
Fix Octave's -text format for saving data to make it lossless for IEEE-754 doubles.
Rik <rik@octave.org>
parents:
23470
diff
changeset
|
415 and restoring of IEEE-754 double values; For IEEE-754 single values the minimum |
31b1ef1ee585
Fix Octave's -text format for saving data to make it lossless for IEEE-754 doubles.
Rik <rik@octave.org>
parents:
23470
diff
changeset
|
416 value is 9. If file size is a concern, it is probably better to choose a |
31b1ef1ee585
Fix Octave's -text format for saving data to make it lossless for IEEE-754 doubles.
Rik <rik@octave.org>
parents:
23470
diff
changeset
|
417 binary format for saving data rather than to reduce the precision of the saved |
31b1ef1ee585
Fix Octave's -text format for saving data to make it lossless for IEEE-754 doubles.
Rik <rik@octave.org>
parents:
23470
diff
changeset
|
418 values. |
31b1ef1ee585
Fix Octave's -text format for saving data to make it lossless for IEEE-754 doubles.
Rik <rik@octave.org>
parents:
23470
diff
changeset
|
419 |
21966
112b20240c87
move docstrings in C++ files out of C strings and into comments
John W. Eaton <jwe@octave.org>
parents:
21751
diff
changeset
|
420 When called from inside a function with the @qcode{"local"} option, the |
112b20240c87
move docstrings in C++ files out of C strings and into comments
John W. Eaton <jwe@octave.org>
parents:
21751
diff
changeset
|
421 variable is changed locally for the function and any subroutines it calls. |
112b20240c87
move docstrings in C++ files out of C strings and into comments
John W. Eaton <jwe@octave.org>
parents:
21751
diff
changeset
|
422 The original variable value is restored when exiting the function. |
23556
31b1ef1ee585
Fix Octave's -text format for saving data to make it lossless for IEEE-754 doubles.
Rik <rik@octave.org>
parents:
23470
diff
changeset
|
423 |
31b1ef1ee585
Fix Octave's -text format for saving data to make it lossless for IEEE-754 doubles.
Rik <rik@octave.org>
parents:
23470
diff
changeset
|
424 @seealso{save_default_options} |
21966
112b20240c87
move docstrings in C++ files out of C strings and into comments
John W. Eaton <jwe@octave.org>
parents:
21751
diff
changeset
|
425 @end deftypefn */) |
4634 | 426 { |
15215
9020dddc925a
use std::numeric_limits for integer max and min values
John W. Eaton <jwe@octave.org>
parents:
15195
diff
changeset
|
427 return SET_INTERNAL_VARIABLE_WITH_LIMITS (save_precision, -1, |
9020dddc925a
use std::numeric_limits for integer max and min values
John W. Eaton <jwe@octave.org>
parents:
15195
diff
changeset
|
428 std::numeric_limits<int>::max ()); |
4634 | 429 } |