|
jwe@2376
|
1 |
/*
|
|
jwe@2376
|
2 |
|
|
jwe@7017
|
3 |
Copyright (C) 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005,
|
|
jwe@7017
|
4 |
2006, 2007 John W. Eaton
|
|
jwe@2376
|
5 |
|
|
jwe@2376
|
6 |
This file is part of Octave.
|
|
jwe@2376
|
7 |
|
|
jwe@2376
|
8 |
Octave is free software; you can redistribute it and/or modify it
|
|
jwe@2376
|
9 |
under the terms of the GNU General Public License as published by the
|
|
jwe@7016
|
10 |
Free Software Foundation; either version 3 of the License, or (at your
|
|
jwe@7016
|
11 |
option) any later version.
|
|
jwe@2376
|
12 |
|
|
jwe@2376
|
13 |
Octave is distributed in the hope that it will be useful, but WITHOUT
|
|
jwe@2376
|
14 |
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
jwe@2376
|
15 |
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
jwe@2376
|
16 |
for more details.
|
|
jwe@2376
|
17 |
|
|
jwe@2376
|
18 |
You should have received a copy of the GNU General Public License
|
|
jwe@7016
|
19 |
along with Octave; see the file COPYING. If not, see
|
|
jwe@7016
|
20 |
<http://www.gnu.org/licenses/>.
|
|
jwe@2376
|
21 |
|
|
jwe@2376
|
22 |
*/
|
|
jwe@2376
|
23 |
|
|
jwe@2376
|
24 |
#ifdef HAVE_CONFIG_H
|
|
jwe@2376
|
25 |
#include <config.h>
|
|
jwe@2376
|
26 |
#endif
|
|
jwe@2376
|
27 |
|
|
jwe@3503
|
28 |
#include <iostream>
|
|
jwe@4726
|
29 |
#include <vector>
|
|
jwe@2901
|
30 |
|
|
jwe@4944
|
31 |
#include "data-conv.h"
|
|
jwe@2376
|
32 |
#include "lo-ieee.h"
|
|
jwe@4944
|
33 |
#include "mach-info.h"
|
|
jwe@2376
|
34 |
#include "mx-base.h"
|
|
jwe@2376
|
35 |
|
|
jwe@5758
|
36 |
#include "defun.h"
|
|
jwe@5758
|
37 |
#include "byte-swap.h"
|
|
jwe@5758
|
38 |
#include "gripes.h"
|
|
jwe@5758
|
39 |
#include "ls-oct-ascii.h"
|
|
jwe@5758
|
40 |
#include "ls-hdf5.h"
|
|
jwe@5758
|
41 |
#include "ls-utils.h"
|
|
jwe@2407
|
42 |
#include "oct-obj.h"
|
|
jwe@4944
|
43 |
#include "oct-stream.h"
|
|
jwe@2376
|
44 |
#include "ops.h"
|
|
jwe@5033
|
45 |
#include "ov-scalar.h"
|
|
jwe@2376
|
46 |
#include "ov-re-mat.h"
|
|
jwe@2376
|
47 |
#include "ov-str-mat.h"
|
|
jwe@2376
|
48 |
#include "pr-output.h"
|
|
jwe@3836
|
49 |
#include "pt-mat.h"
|
|
jwe@5758
|
50 |
#include "utils.h"
|
|
lindnerb@7685
|
51 |
#include "ls-ascii-helper.h"
|
|
jwe@4687
|
52 |
|
|
jwe@3219
|
53 |
DEFINE_OCTAVE_ALLOCATOR (octave_char_matrix_str);
|
|
jwe@5279
|
54 |
DEFINE_OCTAVE_ALLOCATOR (octave_char_matrix_sq_str);
|
|
jwe@2376
|
55 |
|
|
jwe@4612
|
56 |
DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_char_matrix_str, "string", "char");
|
|
jwe@5279
|
57 |
DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_char_matrix_sq_str, "sq_string", "char");
|
|
jwe@2376
|
58 |
|
|
jwe@5759
|
59 |
static octave_base_value *
|
|
jwe@5759
|
60 |
default_numeric_conversion_function (const octave_base_value& a)
|
|
jwe@2376
|
61 |
{
|
|
jwe@5759
|
62 |
octave_base_value *retval = 0;
|
|
jwe@5033
|
63 |
|
|
jwe@2376
|
64 |
CAST_CONV_ARG (const octave_char_matrix_str&);
|
|
jwe@2376
|
65 |
|
|
jwe@4668
|
66 |
NDArray nda = v.array_value (true);
|
|
jwe@3203
|
67 |
|
|
jwe@5033
|
68 |
if (! error_state)
|
|
jwe@5033
|
69 |
{
|
|
jwe@5033
|
70 |
if (nda.numel () == 1)
|
|
jwe@5033
|
71 |
retval = new octave_scalar (nda(0));
|
|
jwe@5033
|
72 |
else
|
|
jwe@5033
|
73 |
retval = new octave_matrix (nda);
|
|
jwe@5033
|
74 |
}
|
|
jwe@5033
|
75 |
|
|
jwe@5033
|
76 |
return retval;
|
|
jwe@2376
|
77 |
}
|
|
jwe@2376
|
78 |
|
|
jwe@5759
|
79 |
octave_base_value::type_conv_fcn
|
|
jwe@2376
|
80 |
octave_char_matrix_str::numeric_conversion_function (void) const
|
|
jwe@2376
|
81 |
{
|
|
jwe@2376
|
82 |
return default_numeric_conversion_function;
|
|
jwe@2376
|
83 |
}
|
|
jwe@2376
|
84 |
|
|
jwe@2376
|
85 |
octave_value
|
|
jwe@5400
|
86 |
octave_char_matrix_str::do_index_op_internal (const octave_value_list& idx,
|
|
jwe@5885
|
87 |
bool resize_ok, char type)
|
|
jwe@2407
|
88 |
{
|
|
jwe@2407
|
89 |
octave_value retval;
|
|
jwe@2407
|
90 |
|
|
jwe@5275
|
91 |
octave_idx_type len = idx.length ();
|
|
jwe@2407
|
92 |
|
|
jwe@2407
|
93 |
switch (len)
|
|
jwe@2407
|
94 |
{
|
|
jwe@5539
|
95 |
case 0:
|
|
jwe@5539
|
96 |
retval = octave_value (matrix, true, type);
|
|
jwe@2407
|
97 |
break;
|
|
jwe@2407
|
98 |
|
|
jwe@2407
|
99 |
case 1:
|
|
jwe@2407
|
100 |
{
|
|
jwe@2407
|
101 |
idx_vector i = idx (0).index_vector ();
|
|
jwe@2407
|
102 |
|
|
jwe@5086
|
103 |
if (! error_state)
|
|
jwe@5086
|
104 |
retval = octave_value (charNDArray (matrix.index (i, resize_ok)),
|
|
jwe@5400
|
105 |
true, type);
|
|
jwe@2407
|
106 |
}
|
|
jwe@2407
|
107 |
break;
|
|
jwe@2407
|
108 |
|
|
jwe@5539
|
109 |
case 2:
|
|
jwe@5539
|
110 |
{
|
|
jwe@5539
|
111 |
idx_vector i = idx (0).index_vector ();
|
|
jwe@5539
|
112 |
idx_vector j = idx (1).index_vector ();
|
|
jwe@5539
|
113 |
|
|
jwe@5539
|
114 |
if (! error_state)
|
|
jwe@5539
|
115 |
retval = octave_value (charNDArray (matrix.index (i, j, resize_ok)),
|
|
jwe@5539
|
116 |
true, type);
|
|
jwe@5539
|
117 |
}
|
|
jwe@5435
|
118 |
break;
|
|
jwe@5435
|
119 |
|
|
jwe@2407
|
120 |
default:
|
|
jwe@4513
|
121 |
{
|
|
jwe@4513
|
122 |
Array<idx_vector> idx_vec (len);
|
|
jwe@4513
|
123 |
|
|
jwe@5275
|
124 |
for (octave_idx_type i = 0; i < len; i++)
|
|
jwe@4513
|
125 |
idx_vec(i) = idx(i).index_vector ();
|
|
jwe@4513
|
126 |
|
|
jwe@5086
|
127 |
if (! error_state)
|
|
jwe@5086
|
128 |
retval = octave_value (charNDArray (matrix.index (idx_vec, resize_ok)),
|
|
jwe@5400
|
129 |
true, type);
|
|
jwe@4513
|
130 |
}
|
|
jwe@2407
|
131 |
break;
|
|
jwe@2407
|
132 |
}
|
|
jwe@2407
|
133 |
|
|
jwe@2407
|
134 |
return retval;
|
|
jwe@2407
|
135 |
}
|
|
jwe@2407
|
136 |
|
|
jwe@2407
|
137 |
void
|
|
jwe@2407
|
138 |
octave_char_matrix_str::assign (const octave_value_list& idx,
|
|
jwe@2407
|
139 |
const charMatrix& rhs)
|
|
jwe@2407
|
140 |
{
|
|
jwe@5275
|
141 |
octave_idx_type len = idx.length ();
|
|
jwe@2407
|
142 |
|
|
jwe@5775
|
143 |
// FIXME
|
|
jwe@2571
|
144 |
charMatrix tmp = rhs;
|
|
jwe@2571
|
145 |
if (tmp.rows () == 1 && tmp.columns () == 0)
|
|
jwe@2571
|
146 |
tmp.resize (0, 0);
|
|
jwe@2571
|
147 |
|
|
jwe@5275
|
148 |
for (octave_idx_type i = 0; i < len; i++)
|
|
jwe@4513
|
149 |
matrix.set_index (idx(i).index_vector ());
|
|
jwe@2407
|
150 |
|
|
jwe@4513
|
151 |
::assign (matrix, tmp, Vstring_fill_char);
|
|
jwe@2407
|
152 |
}
|
|
jwe@2407
|
153 |
|
|
jwe@5731
|
154 |
octave_value
|
|
jwe@5731
|
155 |
octave_char_matrix_str::resize (const dim_vector& dv, bool fill) const
|
|
jwe@5731
|
156 |
{
|
|
jwe@5731
|
157 |
charNDArray retval (matrix);
|
|
jwe@5731
|
158 |
if (fill)
|
|
jwe@5731
|
159 |
retval.resize (dv, charNDArray::resize_fill_value());
|
|
jwe@5731
|
160 |
else
|
|
jwe@5731
|
161 |
retval.resize (dv);
|
|
jwe@5731
|
162 |
return octave_value (retval, true);
|
|
jwe@5731
|
163 |
}
|
|
jwe@5731
|
164 |
|
|
jwe@2376
|
165 |
bool
|
|
jwe@2376
|
166 |
octave_char_matrix_str::valid_as_scalar_index (void) const
|
|
jwe@2376
|
167 |
{
|
|
jwe@2376
|
168 |
bool retval = false;
|
|
jwe@2376
|
169 |
error ("octave_char_matrix_str::valid_as_scalar_index(): not implemented");
|
|
jwe@2376
|
170 |
return retval;
|
|
jwe@2376
|
171 |
}
|
|
jwe@2376
|
172 |
|
|
jwe@4668
|
173 |
#define CHAR_MATRIX_CONV(T, INIT, TNAME, FCN) \
|
|
jwe@4668
|
174 |
T retval INIT; \
|
|
jwe@4668
|
175 |
\
|
|
jwe@4668
|
176 |
if (! force_string_conv) \
|
|
jwe@4668
|
177 |
gripe_invalid_conversion ("string", TNAME); \
|
|
jwe@4668
|
178 |
else \
|
|
jwe@4668
|
179 |
{ \
|
|
jwe@5878
|
180 |
warning_with_id ("Octave:str-to-num", \
|
|
jwe@5781
|
181 |
"implicit conversion from %s to %s", \
|
|
jwe@5781
|
182 |
"string", TNAME); \
|
|
jwe@4668
|
183 |
\
|
|
jwe@4668
|
184 |
retval = octave_char_matrix::FCN (); \
|
|
jwe@4668
|
185 |
} \
|
|
jwe@4668
|
186 |
\
|
|
jwe@4668
|
187 |
return retval
|
|
jwe@4668
|
188 |
|
|
jwe@4643
|
189 |
double
|
|
jwe@4643
|
190 |
octave_char_matrix_str::double_value (bool force_string_conv) const
|
|
jwe@4643
|
191 |
{
|
|
jwe@4668
|
192 |
CHAR_MATRIX_CONV (double, = 0, "real scalar", double_value);
|
|
jwe@4668
|
193 |
}
|
|
jwe@4643
|
194 |
|
|
jwe@4668
|
195 |
Complex
|
|
jwe@4668
|
196 |
octave_char_matrix_str::complex_value (bool force_string_conv) const
|
|
jwe@4668
|
197 |
{
|
|
jwe@4668
|
198 |
CHAR_MATRIX_CONV (Complex, = 0, "complex scalar", complex_value);
|
|
jwe@4643
|
199 |
}
|
|
jwe@4643
|
200 |
|
|
jwe@2376
|
201 |
Matrix
|
|
jwe@2376
|
202 |
octave_char_matrix_str::matrix_value (bool force_string_conv) const
|
|
jwe@2376
|
203 |
{
|
|
jwe@4668
|
204 |
CHAR_MATRIX_CONV (Matrix, , "real matrix", matrix_value);
|
|
jwe@4668
|
205 |
}
|
|
jwe@2376
|
206 |
|
|
jwe@4668
|
207 |
ComplexMatrix
|
|
jwe@4668
|
208 |
octave_char_matrix_str::complex_matrix_value (bool force_string_conv) const
|
|
jwe@4668
|
209 |
{
|
|
jwe@4668
|
210 |
CHAR_MATRIX_CONV (ComplexMatrix, , "complex matrix", complex_matrix_value);
|
|
jwe@4668
|
211 |
}
|
|
jwe@2376
|
212 |
|
|
jwe@4668
|
213 |
NDArray
|
|
jwe@4668
|
214 |
octave_char_matrix_str::array_value (bool force_string_conv) const
|
|
jwe@4668
|
215 |
{
|
|
jwe@4668
|
216 |
CHAR_MATRIX_CONV (NDArray, , "real N-d array", array_value);
|
|
jwe@4668
|
217 |
}
|
|
jwe@2376
|
218 |
|
|
jwe@4668
|
219 |
ComplexNDArray
|
|
jwe@4668
|
220 |
octave_char_matrix_str::complex_array_value (bool force_string_conv) const
|
|
jwe@4668
|
221 |
{
|
|
jwe@4668
|
222 |
CHAR_MATRIX_CONV (ComplexNDArray, , "complex N-d array",
|
|
jwe@4668
|
223 |
complex_array_value);
|
|
jwe@2376
|
224 |
}
|
|
jwe@2376
|
225 |
|
|
jwe@2493
|
226 |
string_vector
|
|
jwe@5715
|
227 |
octave_char_matrix_str::all_strings (bool) const
|
|
jwe@2376
|
228 |
{
|
|
jwe@4513
|
229 |
string_vector retval;
|
|
jwe@2493
|
230 |
|
|
jwe@4513
|
231 |
if (matrix.ndims () == 2)
|
|
jwe@4513
|
232 |
{
|
|
jwe@6816
|
233 |
charMatrix chm = matrix.matrix_value ();
|
|
jwe@2493
|
234 |
|
|
jwe@6816
|
235 |
octave_idx_type n = chm.rows ();
|
|
jwe@4513
|
236 |
|
|
jwe@6816
|
237 |
retval.resize (n);
|
|
jwe@4513
|
238 |
|
|
jwe@6816
|
239 |
for (octave_idx_type i = 0; i < n; i++)
|
|
jwe@6816
|
240 |
retval[i] = chm.row_as_string (i);
|
|
jwe@4513
|
241 |
}
|
|
jwe@4513
|
242 |
else
|
|
jwe@4513
|
243 |
error ("invalid conversion of charNDArray to string_vector");
|
|
jwe@2493
|
244 |
|
|
jwe@2493
|
245 |
return retval;
|
|
jwe@2376
|
246 |
}
|
|
jwe@2376
|
247 |
|
|
jwe@3536
|
248 |
std::string
|
|
jwe@4457
|
249 |
octave_char_matrix_str::string_value (bool) const
|
|
jwe@2376
|
250 |
{
|
|
jwe@4513
|
251 |
std::string retval;
|
|
jwe@4513
|
252 |
|
|
jwe@4513
|
253 |
if (matrix.ndims () == 2)
|
|
jwe@4513
|
254 |
{
|
|
jwe@4513
|
255 |
charMatrix chm = matrix.matrix_value ();
|
|
jwe@4513
|
256 |
|
|
jwe@5775
|
257 |
retval = chm.row_as_string (0); // FIXME???
|
|
jwe@4513
|
258 |
}
|
|
jwe@4513
|
259 |
else
|
|
jwe@4513
|
260 |
error ("invalid conversion of charNDArray to string");
|
|
jwe@4513
|
261 |
|
|
jwe@4513
|
262 |
return retval;
|
|
jwe@2376
|
263 |
}
|
|
jwe@2376
|
264 |
|
|
jwe@2376
|
265 |
void
|
|
jwe@3523
|
266 |
octave_char_matrix_str::print_raw (std::ostream& os, bool pr_as_read_syntax) const
|
|
jwe@2376
|
267 |
{
|
|
jwe@3219
|
268 |
octave_print_internal (os, matrix, pr_as_read_syntax,
|
|
jwe@3219
|
269 |
current_print_indent_level (), true);
|
|
jwe@2376
|
270 |
}
|
|
jwe@2376
|
271 |
|
|
jwe@4687
|
272 |
bool
|
|
jwe@6974
|
273 |
octave_char_matrix_str::save_ascii (std::ostream& os)
|
|
jwe@4687
|
274 |
{
|
|
jwe@4805
|
275 |
dim_vector d = dims ();
|
|
jwe@4805
|
276 |
if (d.length () > 2)
|
|
jwe@4687
|
277 |
{
|
|
jwe@4805
|
278 |
charNDArray tmp = char_array_value ();
|
|
jwe@4805
|
279 |
os << "# ndims: " << d.length () << "\n";
|
|
jwe@4805
|
280 |
for (int i=0; i < d.length (); i++)
|
|
jwe@4805
|
281 |
os << " " << d (i);
|
|
jwe@4687
|
282 |
os << "\n";
|
|
jwe@5760
|
283 |
os.write (tmp.fortran_vec (), d.numel ());
|
|
jwe@4805
|
284 |
os << "\n";
|
|
jwe@4805
|
285 |
}
|
|
jwe@4805
|
286 |
else
|
|
jwe@4805
|
287 |
{
|
|
jwe@4805
|
288 |
// Keep this case, rather than use generic code above for
|
|
jwe@4805
|
289 |
// backward compatiability. Makes load_ascii much more complex!!
|
|
jwe@4805
|
290 |
charMatrix chm = char_matrix_value ();
|
|
jwe@5275
|
291 |
octave_idx_type elements = chm.rows ();
|
|
jwe@4805
|
292 |
os << "# elements: " << elements << "\n";
|
|
jwe@5275
|
293 |
for (octave_idx_type i = 0; i < elements; i++)
|
|
jwe@4805
|
294 |
{
|
|
jwe@4805
|
295 |
unsigned len = chm.cols ();
|
|
jwe@4805
|
296 |
os << "# length: " << len << "\n";
|
|
jwe@4805
|
297 |
std::string tstr = chm.row_as_string (i, false, true);
|
|
jwe@4805
|
298 |
const char *tmp = tstr.data ();
|
|
jwe@4805
|
299 |
if (tstr.length () > len)
|
|
jwe@4805
|
300 |
panic_impossible ();
|
|
jwe@5760
|
301 |
os.write (tmp, len);
|
|
jwe@4805
|
302 |
os << "\n";
|
|
jwe@4805
|
303 |
}
|
|
jwe@4687
|
304 |
}
|
|
jwe@4687
|
305 |
|
|
jwe@4687
|
306 |
return true;
|
|
jwe@4687
|
307 |
}
|
|
jwe@4687
|
308 |
|
|
jwe@4687
|
309 |
bool
|
|
jwe@4687
|
310 |
octave_char_matrix_str::load_ascii (std::istream& is)
|
|
jwe@4687
|
311 |
{
|
|
jwe@4687
|
312 |
bool success = true;
|
|
jwe@4687
|
313 |
|
|
jwe@5099
|
314 |
string_vector keywords(3);
|
|
jwe@5099
|
315 |
|
|
jwe@5099
|
316 |
keywords[0] = "ndims";
|
|
jwe@5099
|
317 |
keywords[1] = "elements";
|
|
jwe@5099
|
318 |
keywords[2] = "length";
|
|
jwe@5099
|
319 |
|
|
jwe@5099
|
320 |
std::string kw;
|
|
jwe@5099
|
321 |
int val = 0;
|
|
jwe@5099
|
322 |
|
|
jwe@5099
|
323 |
if (extract_keyword (is, keywords, kw, val, true))
|
|
jwe@4687
|
324 |
{
|
|
jwe@5099
|
325 |
if (kw == "ndims")
|
|
jwe@4805
|
326 |
{
|
|
jwe@5099
|
327 |
int mdims = val;
|
|
jwe@4687
|
328 |
|
|
jwe@5099
|
329 |
if (mdims >= 0)
|
|
jwe@5099
|
330 |
{
|
|
jwe@5099
|
331 |
dim_vector dv;
|
|
jwe@5099
|
332 |
dv.resize (mdims);
|
|
jwe@4687
|
333 |
|
|
jwe@5099
|
334 |
for (int i = 0; i < mdims; i++)
|
|
jwe@5099
|
335 |
is >> dv(i);
|
|
jwe@4805
|
336 |
|
|
jwe@6717
|
337 |
if (is)
|
|
jwe@6717
|
338 |
{
|
|
jwe@6717
|
339 |
charNDArray tmp(dv);
|
|
jwe@4805
|
340 |
|
|
jwe@6717
|
341 |
if (tmp.is_empty ())
|
|
jwe@6717
|
342 |
matrix = tmp;
|
|
jwe@6717
|
343 |
else
|
|
jwe@6717
|
344 |
{
|
|
jwe@6717
|
345 |
char *ftmp = tmp.fortran_vec ();
|
|
jwe@5099
|
346 |
|
|
jwe@6717
|
347 |
// Skip the return line
|
|
lindnerb@7685
|
348 |
skip_preceeding_newline (is);
|
|
jwe@6717
|
349 |
|
|
jwe@6717
|
350 |
if (! is.read (ftmp, dv.numel ()) || !is)
|
|
jwe@6717
|
351 |
{
|
|
jwe@6717
|
352 |
error ("load: failed to load string constant");
|
|
jwe@6717
|
353 |
success = false;
|
|
jwe@6717
|
354 |
}
|
|
jwe@6717
|
355 |
else
|
|
jwe@6717
|
356 |
matrix = tmp;
|
|
jwe@6717
|
357 |
}
|
|
jwe@6717
|
358 |
}
|
|
jwe@6717
|
359 |
else
|
|
jwe@5099
|
360 |
{
|
|
jwe@6717
|
361 |
error ("load: failed to read dimensions");
|
|
jwe@5099
|
362 |
success = false;
|
|
jwe@5099
|
363 |
}
|
|
jwe@5099
|
364 |
}
|
|
jwe@5099
|
365 |
else
|
|
jwe@4687
|
366 |
{
|
|
jwe@5099
|
367 |
error ("load: failed to extract matrix size");
|
|
jwe@4805
|
368 |
success = false;
|
|
jwe@4687
|
369 |
}
|
|
jwe@4687
|
370 |
}
|
|
jwe@5099
|
371 |
else if (kw == "elements")
|
|
jwe@4687
|
372 |
{
|
|
jwe@5099
|
373 |
int elements = val;
|
|
jwe@4687
|
374 |
|
|
jwe@4805
|
375 |
if (elements >= 0)
|
|
jwe@4805
|
376 |
{
|
|
jwe@5775
|
377 |
// FIXME -- need to be able to get max length
|
|
jwe@4805
|
378 |
// before doing anything.
|
|
jwe@4687
|
379 |
|
|
jwe@4805
|
380 |
charMatrix chm (elements, 0);
|
|
jwe@4805
|
381 |
int max_len = 0;
|
|
jwe@4805
|
382 |
for (int i = 0; i < elements; i++)
|
|
jwe@4805
|
383 |
{
|
|
jwe@4805
|
384 |
int len;
|
|
jwe@4805
|
385 |
if (extract_keyword (is, "length", len) && len >= 0)
|
|
jwe@4805
|
386 |
{
|
|
jwe@6151
|
387 |
// Use this instead of a C-style character
|
|
jwe@6151
|
388 |
// buffer so that we can properly handle
|
|
jwe@6151
|
389 |
// embedded NUL characters.
|
|
jwe@6151
|
390 |
charMatrix tmp (1, len);
|
|
jwe@6151
|
391 |
char *ptmp = tmp.fortran_vec ();
|
|
jwe@6151
|
392 |
|
|
jwe@6151
|
393 |
if (len > 0 && ! is.read (ptmp, len))
|
|
jwe@4805
|
394 |
{
|
|
jwe@4805
|
395 |
error ("load: failed to load string constant");
|
|
jwe@4805
|
396 |
success = false;
|
|
jwe@4805
|
397 |
break;
|
|
jwe@4805
|
398 |
}
|
|
jwe@4805
|
399 |
else
|
|
jwe@4805
|
400 |
{
|
|
jwe@4805
|
401 |
if (len > max_len)
|
|
jwe@4805
|
402 |
{
|
|
jwe@4805
|
403 |
max_len = len;
|
|
jwe@4805
|
404 |
chm.resize (elements, max_len, 0);
|
|
jwe@4805
|
405 |
}
|
|
jwe@6151
|
406 |
|
|
jwe@4805
|
407 |
chm.insert (tmp, i, 0);
|
|
jwe@4805
|
408 |
}
|
|
jwe@4805
|
409 |
}
|
|
jwe@4805
|
410 |
else
|
|
jwe@4805
|
411 |
{
|
|
jwe@4805
|
412 |
error ("load: failed to extract string length for element %d",
|
|
jwe@4805
|
413 |
i+1);
|
|
jwe@4805
|
414 |
success = false;
|
|
jwe@4805
|
415 |
}
|
|
jwe@4805
|
416 |
}
|
|
jwe@4805
|
417 |
|
|
jwe@4805
|
418 |
if (! error_state)
|
|
jwe@4805
|
419 |
matrix = chm;
|
|
jwe@4687
|
420 |
}
|
|
jwe@4687
|
421 |
else
|
|
jwe@4687
|
422 |
{
|
|
jwe@4805
|
423 |
error ("load: failed to extract number of string elements");
|
|
jwe@4805
|
424 |
success = false;
|
|
jwe@4805
|
425 |
}
|
|
jwe@4805
|
426 |
}
|
|
jwe@5099
|
427 |
else if (kw == "length")
|
|
jwe@4805
|
428 |
{
|
|
jwe@5099
|
429 |
int len = val;
|
|
jwe@4805
|
430 |
|
|
jwe@5099
|
431 |
if (len >= 0)
|
|
jwe@4805
|
432 |
{
|
|
jwe@4805
|
433 |
// This is cruft for backward compatiability,
|
|
jwe@4805
|
434 |
// but relatively harmless.
|
|
jwe@4805
|
435 |
|
|
jwe@6151
|
436 |
// Use this instead of a C-style character buffer so
|
|
jwe@6151
|
437 |
// that we can properly handle embedded NUL characters.
|
|
jwe@6151
|
438 |
charMatrix tmp (1, len);
|
|
jwe@6151
|
439 |
char *ptmp = tmp.fortran_vec ();
|
|
jwe@4805
|
440 |
|
|
jwe@6151
|
441 |
if (len > 0 && ! is.read (ptmp, len))
|
|
jwe@4805
|
442 |
{
|
|
jwe@4805
|
443 |
error ("load: failed to load string constant");
|
|
jwe@4805
|
444 |
}
|
|
jwe@4687
|
445 |
else
|
|
jwe@4805
|
446 |
{
|
|
jwe@4805
|
447 |
if (is)
|
|
jwe@6151
|
448 |
matrix = tmp;
|
|
jwe@4805
|
449 |
else
|
|
jwe@4805
|
450 |
error ("load: failed to load string constant");
|
|
jwe@4805
|
451 |
}
|
|
jwe@4687
|
452 |
}
|
|
jwe@4687
|
453 |
}
|
|
jwe@5099
|
454 |
else
|
|
jwe@5099
|
455 |
panic_impossible ();
|
|
jwe@5099
|
456 |
}
|
|
jwe@5099
|
457 |
else
|
|
jwe@5099
|
458 |
{
|
|
jwe@5099
|
459 |
error ("load: failed to extract number of rows and columns");
|
|
jwe@5099
|
460 |
success = false;
|
|
jwe@4687
|
461 |
}
|
|
jwe@4687
|
462 |
|
|
jwe@4687
|
463 |
return success;
|
|
jwe@4687
|
464 |
}
|
|
jwe@4687
|
465 |
|
|
jwe@4687
|
466 |
bool
|
|
jwe@4687
|
467 |
octave_char_matrix_str::save_binary (std::ostream& os,
|
|
jwe@4687
|
468 |
bool& /* save_as_floats */)
|
|
jwe@4687
|
469 |
{
|
|
jwe@4805
|
470 |
dim_vector d = dims ();
|
|
jwe@4805
|
471 |
if (d.length() < 1)
|
|
jwe@4805
|
472 |
return false;
|
|
jwe@4805
|
473 |
|
|
jwe@4805
|
474 |
// Use negative value for ndims to differentiate with old format!!
|
|
jwe@5828
|
475 |
int32_t tmp = - d.length();
|
|
jwe@5760
|
476 |
os.write (reinterpret_cast<char *> (&tmp), 4);
|
|
jwe@4805
|
477 |
for (int i=0; i < d.length (); i++)
|
|
jwe@4687
|
478 |
{
|
|
jwe@4805
|
479 |
tmp = d(i);
|
|
jwe@5760
|
480 |
os.write (reinterpret_cast<char *> (&tmp), 4);
|
|
jwe@4687
|
481 |
}
|
|
jwe@4805
|
482 |
|
|
jwe@4805
|
483 |
charNDArray m = char_array_value ();
|
|
jwe@4805
|
484 |
os.write (m.fortran_vec (), d.numel ());
|
|
jwe@4687
|
485 |
return true;
|
|
jwe@4687
|
486 |
}
|
|
jwe@4687
|
487 |
|
|
jwe@4687
|
488 |
bool
|
|
jwe@4687
|
489 |
octave_char_matrix_str::load_binary (std::istream& is, bool swap,
|
|
jwe@4687
|
490 |
oct_mach_info::float_format /* fmt */)
|
|
jwe@4687
|
491 |
{
|
|
jwe@5828
|
492 |
int32_t elements;
|
|
jwe@5760
|
493 |
if (! is.read (reinterpret_cast<char *> (&elements), 4))
|
|
jwe@4687
|
494 |
return false;
|
|
jwe@4687
|
495 |
if (swap)
|
|
jwe@4944
|
496 |
swap_bytes<4> (&elements);
|
|
jwe@4805
|
497 |
|
|
jwe@4805
|
498 |
if (elements < 0)
|
|
jwe@4687
|
499 |
{
|
|
jwe@5828
|
500 |
int32_t mdims = - elements;
|
|
jwe@5828
|
501 |
int32_t di;
|
|
jwe@4805
|
502 |
dim_vector dv;
|
|
jwe@4805
|
503 |
dv.resize (mdims);
|
|
jwe@4805
|
504 |
|
|
jwe@4805
|
505 |
for (int i = 0; i < mdims; i++)
|
|
jwe@4805
|
506 |
{
|
|
jwe@5760
|
507 |
if (! is.read (reinterpret_cast<char *> (&di), 4))
|
|
jwe@4805
|
508 |
return false;
|
|
jwe@4805
|
509 |
if (swap)
|
|
jwe@4944
|
510 |
swap_bytes<4> (&di);
|
|
jwe@4805
|
511 |
dv(i) = di;
|
|
jwe@4805
|
512 |
}
|
|
jwe@4805
|
513 |
|
|
jwe@5157
|
514 |
// Convert an array with a single dimension to be a row vector.
|
|
jwe@5157
|
515 |
// Octave should never write files like this, other software
|
|
jwe@5157
|
516 |
// might.
|
|
jwe@5157
|
517 |
|
|
jwe@5157
|
518 |
if (mdims == 1)
|
|
jwe@5157
|
519 |
{
|
|
jwe@5157
|
520 |
mdims = 2;
|
|
jwe@5157
|
521 |
dv.resize (mdims);
|
|
jwe@5157
|
522 |
dv(1) = dv(0);
|
|
jwe@5157
|
523 |
dv(0) = 1;
|
|
jwe@5157
|
524 |
}
|
|
jwe@5157
|
525 |
|
|
jwe@4805
|
526 |
charNDArray m(dv);
|
|
jwe@4805
|
527 |
char *tmp = m.fortran_vec ();
|
|
jwe@4805
|
528 |
is.read (tmp, dv.numel ());
|
|
jwe@4805
|
529 |
|
|
jwe@4805
|
530 |
if (error_state || ! is)
|
|
jwe@4687
|
531 |
return false;
|
|
jwe@4805
|
532 |
matrix = m;
|
|
jwe@4805
|
533 |
}
|
|
jwe@4805
|
534 |
else
|
|
jwe@4805
|
535 |
{
|
|
jwe@4805
|
536 |
charMatrix chm (elements, 0);
|
|
jwe@4805
|
537 |
int max_len = 0;
|
|
jwe@4805
|
538 |
for (int i = 0; i < elements; i++)
|
|
jwe@4687
|
539 |
{
|
|
jwe@5828
|
540 |
int32_t len;
|
|
jwe@5760
|
541 |
if (! is.read (reinterpret_cast<char *> (&len), 4))
|
|
jwe@4805
|
542 |
return false;
|
|
jwe@4805
|
543 |
if (swap)
|
|
jwe@4944
|
544 |
swap_bytes<4> (&len);
|
|
jwe@6151
|
545 |
charMatrix btmp (1, len);
|
|
jwe@6151
|
546 |
char *pbtmp = btmp.fortran_vec ();
|
|
jwe@6151
|
547 |
if (! is.read (pbtmp, len))
|
|
jwe@4805
|
548 |
return false;
|
|
jwe@4805
|
549 |
if (len > max_len)
|
|
jwe@4805
|
550 |
{
|
|
jwe@4805
|
551 |
max_len = len;
|
|
jwe@4805
|
552 |
chm.resize (elements, max_len, 0);
|
|
jwe@4805
|
553 |
}
|
|
jwe@4805
|
554 |
chm.insert (btmp, i, 0);
|
|
jwe@4687
|
555 |
}
|
|
jwe@4805
|
556 |
matrix = chm;
|
|
jwe@4687
|
557 |
}
|
|
jwe@4687
|
558 |
return true;
|
|
jwe@4687
|
559 |
}
|
|
jwe@4687
|
560 |
|
|
jwe@4687
|
561 |
#if defined (HAVE_HDF5)
|
|
jwe@4944
|
562 |
|
|
jwe@4687
|
563 |
bool
|
|
jwe@4687
|
564 |
octave_char_matrix_str::save_hdf5 (hid_t loc_id, const char *name,
|
|
jwe@4687
|
565 |
bool /* save_as_floats */)
|
|
jwe@4687
|
566 |
{
|
|
jwe@4837
|
567 |
dim_vector dv = dims ();
|
|
jwe@4837
|
568 |
int empty = save_hdf5_empty (loc_id, name, dv);
|
|
jwe@4837
|
569 |
if (empty)
|
|
jwe@4805
|
570 |
return (empty > 0);
|
|
jwe@4805
|
571 |
|
|
jwe@4837
|
572 |
int rank = dv.length ();
|
|
jwe@4805
|
573 |
hid_t space_hid = -1, data_hid = -1;
|
|
jwe@4687
|
574 |
bool retval = true;
|
|
jwe@4805
|
575 |
charNDArray m = char_array_value ();
|
|
jwe@4687
|
576 |
|
|
jwe@4805
|
577 |
OCTAVE_LOCAL_BUFFER (hsize_t, hdims, rank);
|
|
jwe@4687
|
578 |
|
|
jwe@4805
|
579 |
// Octave uses column-major, while HDF5 uses row-major ordering
|
|
jwe@4805
|
580 |
for (int i = 0; i < rank; i++)
|
|
jwe@4837
|
581 |
hdims[i] = dv (rank-i-1);
|
|
jwe@4805
|
582 |
|
|
jwe@4815
|
583 |
space_hid = H5Screate_simple (rank, hdims, 0);
|
|
jwe@4805
|
584 |
if (space_hid < 0)
|
|
jwe@4805
|
585 |
return false;
|
|
jwe@4687
|
586 |
|
|
jwe@4805
|
587 |
data_hid = H5Dcreate (loc_id, name, H5T_NATIVE_CHAR, space_hid,
|
|
jwe@4805
|
588 |
H5P_DEFAULT);
|
|
jwe@4805
|
589 |
if (data_hid < 0)
|
|
jwe@4687
|
590 |
{
|
|
jwe@4805
|
591 |
H5Sclose (space_hid);
|
|
jwe@4687
|
592 |
return false;
|
|
jwe@4687
|
593 |
}
|
|
jwe@4687
|
594 |
|
|
jwe@4837
|
595 |
OCTAVE_LOCAL_BUFFER (char, s, dv.numel ());
|
|
jwe@4687
|
596 |
|
|
jwe@4837
|
597 |
for (int i = 0; i < dv.numel (); ++i)
|
|
jwe@4805
|
598 |
s[i] = m(i);
|
|
jwe@4687
|
599 |
|
|
jwe@4805
|
600 |
retval = H5Dwrite (data_hid, H5T_NATIVE_CHAR, H5S_ALL, H5S_ALL,
|
|
jwe@4815
|
601 |
H5P_DEFAULT, s) >= 0;
|
|
jwe@4687
|
602 |
|
|
jwe@4687
|
603 |
H5Dclose (data_hid);
|
|
jwe@4687
|
604 |
H5Sclose (space_hid);
|
|
jwe@4837
|
605 |
|
|
jwe@4687
|
606 |
return retval;
|
|
jwe@4687
|
607 |
}
|
|
jwe@4687
|
608 |
|
|
jwe@4687
|
609 |
bool
|
|
jwe@4687
|
610 |
octave_char_matrix_str::load_hdf5 (hid_t loc_id, const char *name,
|
|
jwe@4687
|
611 |
bool /* have_h5giterate_bug */)
|
|
jwe@4687
|
612 |
{
|
|
jwe@4837
|
613 |
bool retval = false;
|
|
jwe@4837
|
614 |
|
|
jwe@4805
|
615 |
dim_vector dv;
|
|
jwe@4805
|
616 |
int empty = load_hdf5_empty (loc_id, name, dv);
|
|
jwe@4805
|
617 |
if (empty > 0)
|
|
jwe@4805
|
618 |
matrix.resize(dv);
|
|
jwe@4837
|
619 |
if (empty)
|
|
jwe@4837
|
620 |
return (empty > 0);
|
|
jwe@4805
|
621 |
|
|
jwe@4687
|
622 |
hid_t data_hid = H5Dopen (loc_id, name);
|
|
jwe@4687
|
623 |
hid_t space_hid = H5Dget_space (data_hid);
|
|
jwe@4687
|
624 |
hsize_t rank = H5Sget_simple_extent_ndims (space_hid);
|
|
jwe@4687
|
625 |
hid_t type_hid = H5Dget_type (data_hid);
|
|
jwe@4805
|
626 |
hid_t type_class_hid = H5Tget_class (type_hid);
|
|
jwe@4687
|
627 |
|
|
jwe@4805
|
628 |
if (type_class_hid == H5T_INTEGER)
|
|
jwe@4687
|
629 |
{
|
|
jwe@4805
|
630 |
if (rank < 1)
|
|
jwe@4687
|
631 |
{
|
|
jwe@4687
|
632 |
H5Tclose (type_hid);
|
|
jwe@4687
|
633 |
H5Sclose (space_hid);
|
|
jwe@4687
|
634 |
H5Dclose (data_hid);
|
|
jwe@4687
|
635 |
return false;
|
|
jwe@4687
|
636 |
}
|
|
jwe@4805
|
637 |
|
|
jwe@4805
|
638 |
OCTAVE_LOCAL_BUFFER (hsize_t, hdims, rank);
|
|
jwe@4805
|
639 |
OCTAVE_LOCAL_BUFFER (hsize_t, maxdims, rank);
|
|
jwe@4805
|
640 |
|
|
jwe@4805
|
641 |
H5Sget_simple_extent_dims (space_hid, hdims, maxdims);
|
|
jwe@4805
|
642 |
|
|
jwe@4805
|
643 |
// Octave uses column-major, while HDF5 uses row-major ordering
|
|
jwe@4805
|
644 |
if (rank == 1)
|
|
jwe@4805
|
645 |
{
|
|
jwe@4805
|
646 |
dv.resize (2);
|
|
jwe@4805
|
647 |
dv(0) = 1;
|
|
jwe@4805
|
648 |
dv(1) = hdims[0];
|
|
jwe@4805
|
649 |
}
|
|
jwe@4687
|
650 |
else
|
|
jwe@4687
|
651 |
{
|
|
jwe@4805
|
652 |
dv.resize (rank);
|
|
jwe@4815
|
653 |
for (hsize_t i = 0, j = rank - 1; i < rank; i++, j--)
|
|
jwe@4805
|
654 |
dv(j) = hdims[i];
|
|
jwe@4805
|
655 |
}
|
|
jwe@4805
|
656 |
|
|
jwe@4805
|
657 |
charNDArray m (dv);
|
|
jwe@4805
|
658 |
char *str = m.fortran_vec ();
|
|
jwe@4805
|
659 |
if (H5Dread (data_hid, H5T_NATIVE_CHAR, H5S_ALL, H5S_ALL,
|
|
jwe@4815
|
660 |
H5P_DEFAULT, str) >= 0)
|
|
jwe@4805
|
661 |
{
|
|
jwe@4805
|
662 |
retval = true;
|
|
jwe@4805
|
663 |
matrix = m;
|
|
jwe@4805
|
664 |
}
|
|
jwe@4805
|
665 |
|
|
jwe@4805
|
666 |
H5Tclose (type_hid);
|
|
jwe@4805
|
667 |
H5Sclose (space_hid);
|
|
jwe@4805
|
668 |
H5Dclose (data_hid);
|
|
jwe@4805
|
669 |
return true;
|
|
jwe@4805
|
670 |
}
|
|
jwe@4805
|
671 |
else
|
|
jwe@4805
|
672 |
{
|
|
jwe@4805
|
673 |
// This is cruft for backward compatiability and easy data
|
|
jwe@4805
|
674 |
// importation
|
|
jwe@4805
|
675 |
if (rank == 0)
|
|
jwe@4805
|
676 |
{
|
|
jwe@4805
|
677 |
// a single string:
|
|
jwe@4805
|
678 |
int slen = H5Tget_size (type_hid);
|
|
jwe@4805
|
679 |
if (slen < 0)
|
|
jwe@4687
|
680 |
{
|
|
jwe@4687
|
681 |
H5Tclose (type_hid);
|
|
jwe@4687
|
682 |
H5Sclose (space_hid);
|
|
jwe@4687
|
683 |
H5Dclose (data_hid);
|
|
jwe@4687
|
684 |
return false;
|
|
jwe@4687
|
685 |
}
|
|
jwe@4805
|
686 |
else
|
|
jwe@4805
|
687 |
{
|
|
jwe@4805
|
688 |
OCTAVE_LOCAL_BUFFER (char, s, slen);
|
|
jwe@4805
|
689 |
// create datatype for (null-terminated) string
|
|
jwe@4805
|
690 |
// to read into:
|
|
jwe@4805
|
691 |
hid_t st_id = H5Tcopy (H5T_C_S1);
|
|
jwe@4805
|
692 |
H5Tset_size (st_id, slen);
|
|
jwe@5760
|
693 |
if (H5Dread (data_hid, st_id, H5S_ALL, H5S_ALL, H5P_DEFAULT, s) < 0)
|
|
jwe@4805
|
694 |
{
|
|
jwe@4805
|
695 |
H5Tclose (st_id);
|
|
jwe@4805
|
696 |
H5Tclose (type_hid);
|
|
jwe@4805
|
697 |
H5Sclose (space_hid);
|
|
jwe@4805
|
698 |
H5Dclose (data_hid);
|
|
jwe@4805
|
699 |
return false;
|
|
jwe@4805
|
700 |
}
|
|
jwe@4687
|
701 |
|
|
jwe@4805
|
702 |
matrix = charMatrix (s);
|
|
jwe@4687
|
703 |
|
|
jwe@4805
|
704 |
H5Tclose (st_id);
|
|
jwe@4805
|
705 |
H5Tclose (type_hid);
|
|
jwe@4805
|
706 |
H5Sclose (space_hid);
|
|
jwe@4805
|
707 |
H5Dclose (data_hid);
|
|
jwe@4805
|
708 |
return true;
|
|
jwe@4805
|
709 |
}
|
|
jwe@4687
|
710 |
}
|
|
jwe@4805
|
711 |
else if (rank == 1)
|
|
jwe@4805
|
712 |
{
|
|
jwe@4805
|
713 |
// string vector
|
|
jwe@4805
|
714 |
hsize_t elements, maxdim;
|
|
jwe@4805
|
715 |
H5Sget_simple_extent_dims (space_hid, &elements, &maxdim);
|
|
jwe@4805
|
716 |
int slen = H5Tget_size (type_hid);
|
|
jwe@4805
|
717 |
if (slen < 0)
|
|
jwe@4805
|
718 |
{
|
|
jwe@4805
|
719 |
H5Tclose (type_hid);
|
|
jwe@4805
|
720 |
H5Sclose (space_hid);
|
|
jwe@4805
|
721 |
H5Dclose (data_hid);
|
|
jwe@4805
|
722 |
return false;
|
|
jwe@4805
|
723 |
}
|
|
jwe@4805
|
724 |
else
|
|
jwe@4805
|
725 |
{
|
|
jwe@4805
|
726 |
// hdf5 string arrays store strings of all the
|
|
jwe@4805
|
727 |
// same physical length (I think), which is
|
|
jwe@4805
|
728 |
// slightly wasteful, but oh well.
|
|
jwe@4805
|
729 |
|
|
jwe@4805
|
730 |
OCTAVE_LOCAL_BUFFER (char, s, elements * slen);
|
|
jwe@4805
|
731 |
|
|
jwe@4805
|
732 |
// create datatype for (null-terminated) string
|
|
jwe@4805
|
733 |
// to read into:
|
|
jwe@4805
|
734 |
hid_t st_id = H5Tcopy (H5T_C_S1);
|
|
jwe@4805
|
735 |
H5Tset_size (st_id, slen);
|
|
jwe@4805
|
736 |
|
|
jwe@5760
|
737 |
if (H5Dread (data_hid, st_id, H5S_ALL, H5S_ALL, H5P_DEFAULT, s) < 0)
|
|
jwe@4805
|
738 |
{
|
|
jwe@4805
|
739 |
H5Tclose (st_id);
|
|
jwe@4805
|
740 |
H5Tclose (type_hid);
|
|
jwe@4805
|
741 |
H5Sclose (space_hid);
|
|
jwe@4805
|
742 |
H5Dclose (data_hid);
|
|
jwe@4805
|
743 |
return false;
|
|
jwe@4805
|
744 |
}
|
|
jwe@4805
|
745 |
|
|
jwe@4805
|
746 |
charMatrix chm (elements, slen - 1);
|
|
jwe@4805
|
747 |
for (hsize_t i = 0; i < elements; ++i)
|
|
jwe@4805
|
748 |
{
|
|
jwe@4805
|
749 |
chm.insert (s + i*slen, i, 0);
|
|
jwe@4805
|
750 |
}
|
|
jwe@4805
|
751 |
|
|
jwe@4805
|
752 |
matrix = chm;
|
|
jwe@4805
|
753 |
|
|
jwe@4805
|
754 |
H5Tclose (st_id);
|
|
jwe@4805
|
755 |
H5Tclose (type_hid);
|
|
jwe@4805
|
756 |
H5Sclose (space_hid);
|
|
jwe@4805
|
757 |
H5Dclose (data_hid);
|
|
jwe@4805
|
758 |
return true;
|
|
jwe@4805
|
759 |
}
|
|
jwe@4805
|
760 |
}
|
|
jwe@4805
|
761 |
else
|
|
jwe@4687
|
762 |
{
|
|
jwe@4687
|
763 |
H5Tclose (type_hid);
|
|
jwe@4687
|
764 |
H5Sclose (space_hid);
|
|
jwe@4687
|
765 |
H5Dclose (data_hid);
|
|
jwe@4687
|
766 |
return false;
|
|
jwe@4687
|
767 |
}
|
|
jwe@4687
|
768 |
}
|
|
jwe@4837
|
769 |
|
|
jwe@4837
|
770 |
return retval;
|
|
jwe@4687
|
771 |
}
|
|
jwe@4944
|
772 |
|
|
jwe@4687
|
773 |
#endif
|
|
jwe@4687
|
774 |
|
|
jwe@2376
|
775 |
/*
|
|
jwe@2376
|
776 |
;;; Local Variables: ***
|
|
jwe@2376
|
777 |
;;; mode: C++ ***
|
|
jwe@2376
|
778 |
;;; End: ***
|
|
jwe@2376
|
779 |
*/
|