Mercurial > octave-nkf
annotate src/mex.cc @ 10853:c3813056f94f
mxArray_number (const char *): create empty string if given NULL arg
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Wed, 04 Aug 2010 19:44:27 -0400 |
parents | bbe99b2a5ba7 |
children | a22f3a673f33 |
rev | line source |
---|---|
7016 | 1 /* |
2 | |
8920 | 3 Copyright (C) 2006, 2007, 2008, 2009 John W. Eaton |
7016 | 4 |
5 This file is part of Octave. | |
6 | |
7 Octave is free software; you can redistribute it and/or modify it | |
8 under the terms of the GNU General Public License as published by the | |
9 Free Software Foundation; either version 3 of the License, or (at your | |
10 option) any later version. | |
11 | |
12 Octave is distributed in the hope that it will be useful, but WITHOUT | |
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
15 for more details. | |
16 | |
17 You should have received a copy of the GNU General Public License | |
18 along with Octave; see the file COPYING. If not, see | |
19 <http://www.gnu.org/licenses/>. | |
20 | |
21 */ | |
22 | |
5900 | 23 #include <config.h> |
5864 | 24 |
25 #include <cfloat> | |
26 #include <csetjmp> | |
5900 | 27 #include <cstdarg> |
10463
bbe99b2a5ba7
undo recent gnulib-related changes
John W. Eaton <jwe@octave.org>
parents:
10447
diff
changeset
|
28 #include <cstdlib> |
5900 | 29 #include <cstring> |
30 #include <cctype> | |
31 | |
5864 | 32 #include <set> |
5900 | 33 |
34 #include "f77-fcn.h" | |
35 #include "lo-ieee.h" | |
8377
25bc2d31e1bf
improve OCTAVE_LOCAL_BUFFER
Jaroslav Hajek <highegg@gmail.com>
parents:
7901
diff
changeset
|
36 #include "oct-locbuf.h" |
5900 | 37 |
38 // mxArray must be declared as a class before including mexproto.h. | |
39 class mxArray; | |
40 #include "Cell.h" | |
41 #include "mexproto.h" | |
42 #include "oct-map.h" | |
43 #include "oct-obj.h" | |
44 #include "ov.h" | |
6068 | 45 #include "ov-mex-fcn.h" |
5900 | 46 #include "ov-usr-fcn.h" |
5864 | 47 #include "pager.h" |
48 #include "parse.h" | |
49 #include "toplev.h" | |
5900 | 50 #include "unwind-prot.h" |
51 #include "utils.h" | |
5864 | 52 #include "variables.h" |
6595 | 53 #include "graphics.h" |
5900 | 54 |
55 // #define DEBUG 1 | |
56 | |
5905 | 57 static void |
58 xfree (void *ptr) | |
59 { | |
60 ::free (ptr); | |
61 } | |
62 | |
6806 | 63 static mwSize |
64 max_str_len (mwSize m, const char **str) | |
5900 | 65 { |
66 int max_len = 0; | |
67 | |
6806 | 68 for (mwSize i = 0; i < m; i++) |
5900 | 69 { |
6806 | 70 mwSize tmp = strlen (str[i]); |
5900 | 71 |
72 if (tmp > max_len) | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
73 max_len = tmp; |
5900 | 74 } |
75 | |
76 return max_len; | |
77 } | |
78 | |
79 static int | |
80 valid_key (const char *key) | |
81 { | |
82 int retval = 0; | |
83 | |
84 int nel = strlen (key); | |
85 | |
86 if (nel > 0) | |
87 { | |
88 if (isalpha (key[0])) | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
89 { |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
90 for (int i = 1; i < nel; i++) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
91 { |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
92 if (! (isalnum (key[i]) || key[i] == '_')) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
93 goto done; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
94 } |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
95 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
96 retval = 1; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
97 } |
5900 | 98 } |
99 | |
100 done: | |
101 | |
102 return retval; | |
103 } | |
104 | |
105 // ------------------------------------------------------------------ | |
106 | |
107 // A class to provide the default implemenation of some of the virtual | |
108 // functions declared in the mxArray class. | |
109 | |
110 class mxArray_base : public mxArray | |
111 { | |
112 protected: | |
113 | |
114 mxArray_base (void) : mxArray (xmxArray ()) { } | |
115 | |
116 public: | |
117 | |
118 mxArray *clone (void) const = 0; | |
119 | |
120 ~mxArray_base (void) { } | |
121 | |
122 bool is_octave_value (void) const { return false; } | |
123 | |
124 int is_cell (void) const = 0; | |
125 | |
126 int is_char (void) const = 0; | |
127 | |
128 int is_class (const char *name_arg) const | |
129 { | |
130 int retval = 0; | |
131 | |
132 const char *cname = get_class_name (); | |
133 | |
134 if (cname && name_arg) | |
135 retval = ! strcmp (cname, name_arg); | |
136 | |
137 return retval; | |
138 } | |
139 | |
140 int is_complex (void) const = 0; | |
141 | |
142 int is_double (void) const = 0; | |
143 | |
144 int is_int16 (void) const = 0; | |
145 | |
146 int is_int32 (void) const = 0; | |
147 | |
148 int is_int64 (void) const = 0; | |
149 | |
150 int is_int8 (void) const = 0; | |
151 | |
152 int is_logical (void) const = 0; | |
153 | |
154 int is_numeric (void) const = 0; | |
155 | |
156 int is_single (void) const = 0; | |
157 | |
158 int is_sparse (void) const = 0; | |
159 | |
160 int is_struct (void) const = 0; | |
161 | |
162 int is_uint16 (void) const = 0; | |
163 | |
164 int is_uint32 (void) const = 0; | |
165 | |
166 int is_uint64 (void) const = 0; | |
167 | |
168 int is_uint8 (void) const = 0; | |
169 | |
170 int is_logical_scalar (void) const | |
171 { | |
172 return is_logical () && get_number_of_elements () == 1; | |
173 } | |
174 | |
175 int is_logical_scalar_true (void) const = 0; | |
176 | |
6686 | 177 mwSize get_m (void) const = 0; |
178 | |
179 mwSize get_n (void) const = 0; | |
180 | |
181 mwSize *get_dimensions (void) const = 0; | |
182 | |
183 mwSize get_number_of_dimensions (void) const = 0; | |
184 | |
185 void set_m (mwSize m) = 0; | |
186 | |
187 void set_n (mwSize n) = 0; | |
188 | |
189 void set_dimensions (mwSize *dims_arg, mwSize ndims_arg) = 0; | |
190 | |
191 mwSize get_number_of_elements (void) const = 0; | |
5900 | 192 |
193 int is_empty (void) const = 0; | |
194 | |
195 mxClassID get_class_id (void) const = 0; | |
196 | |
197 const char *get_class_name (void) const = 0; | |
198 | |
199 void set_class_name (const char *name_arg) = 0; | |
200 | |
6686 | 201 mxArray *get_cell (mwIndex /*idx*/) const |
5900 | 202 { |
203 invalid_type_error (); | |
204 return 0; | |
205 } | |
206 | |
6686 | 207 void set_cell (mwIndex idx, mxArray *val) = 0; |
5900 | 208 |
6332 | 209 double get_scalar (void) const = 0; |
210 | |
5900 | 211 void *get_data (void) const = 0; |
212 | |
213 void *get_imag_data (void) const = 0; | |
214 | |
215 void set_data (void *pr) = 0; | |
216 | |
217 void set_imag_data (void *pi) = 0; | |
218 | |
6686 | 219 mwIndex *get_ir (void) const = 0; |
220 | |
221 mwIndex *get_jc (void) const = 0; | |
222 | |
223 mwSize get_nzmax (void) const = 0; | |
224 | |
225 void set_ir (mwIndex *ir) = 0; | |
226 | |
227 void set_jc (mwIndex *jc) = 0; | |
228 | |
229 void set_nzmax (mwSize nzmax) = 0; | |
5900 | 230 |
231 int add_field (const char *key) = 0; | |
232 | |
233 void remove_field (int key_num) = 0; | |
234 | |
6686 | 235 mxArray *get_field_by_number (mwIndex index, int key_num) const = 0; |
236 | |
237 void set_field_by_number (mwIndex index, int key_num, mxArray *val) = 0; | |
5900 | 238 |
239 int get_number_of_fields (void) const = 0; | |
240 | |
241 const char *get_field_name_by_number (int key_num) const = 0; | |
242 | |
243 int get_field_number (const char *key) const = 0; | |
244 | |
6686 | 245 int get_string (char *buf, mwSize buflen) const = 0; |
5900 | 246 |
247 char *array_to_string (void) const = 0; | |
248 | |
6686 | 249 mwIndex calc_single_subscript (mwSize nsubs, mwIndex *subs) const = 0; |
250 | |
251 size_t get_element_size (void) const = 0; | |
5900 | 252 |
253 bool mutation_needed (void) const { return false; } | |
254 | |
255 mxArray *mutate (void) const { return 0; } | |
256 | |
257 protected: | |
258 | |
5907 | 259 octave_value as_octave_value (void) const = 0; |
260 | |
5900 | 261 mxArray_base (const mxArray_base&) : mxArray (xmxArray ()) { } |
262 | |
263 void invalid_type_error (void) const | |
264 { | |
265 error ("invalid type for operation"); | |
266 } | |
267 | |
268 void error (const char *msg) const | |
269 { | |
270 // FIXME | |
271 ::error ("%s", msg); | |
272 } | |
273 }; | |
274 | |
7357 | 275 static mwIndex |
276 calc_single_subscript_internal (mwSize ndims, const mwSize *dims, | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
277 mwSize nsubs, const mwIndex *subs) |
7357 | 278 { |
279 mwIndex retval = 0; | |
280 | |
281 switch (nsubs) | |
282 { | |
283 case 0: | |
284 break; | |
285 | |
286 case 1: | |
287 retval = subs[0]; | |
288 break; | |
289 | |
290 default: | |
291 { | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
292 // Both nsubs and ndims should be at least 2 here. |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
293 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
294 mwSize n = nsubs <= ndims ? nsubs : ndims; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
295 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
296 retval = subs[--n]; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
297 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
298 while (--n >= 0) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
299 retval = dims[n] * retval + subs[n]; |
7357 | 300 } |
301 break; | |
302 } | |
303 | |
304 return retval; | |
305 } | |
306 | |
5900 | 307 // The object that handles values pass to MEX files from Octave. Some |
308 // methods in this class may set mutate_flag to TRUE to tell the | |
309 // mxArray class to convert to the Matlab-style representation and | |
310 // then invoke the method on that object instead (for example, getting | |
311 // a pointer to real or imaginary data from a complex object requires | |
312 // a mutation but getting a pointer to real data from a real object | |
313 // does not). Changing the representation causes a copy so we try to | |
314 // avoid it unless it is really necessary. Once the conversion | |
315 // happens, we delete this representation, so the conversion can only | |
316 // happen once per call to a MEX file. | |
317 | |
7179 | 318 static inline void *maybe_mark_foreign (void *ptr); |
319 | |
5900 | 320 class mxArray_octave_value : public mxArray_base |
321 { | |
322 public: | |
323 | |
324 mxArray_octave_value (const octave_value& ov) | |
325 : mxArray_base (), val (ov), mutate_flag (false), | |
326 id (mxUNKNOWN_CLASS), class_name (0), ndims (-1), dims (0) { } | |
327 | |
328 mxArray *clone (void) const { return new mxArray_octave_value (*this); } | |
329 | |
330 ~mxArray_octave_value (void) | |
331 { | |
332 mxFree (class_name); | |
333 mxFree (dims); | |
334 } | |
335 | |
336 bool is_octave_value (void) const { return true; } | |
337 | |
338 int is_cell (void) const { return val.is_cell (); } | |
339 | |
340 int is_char (void) const { return val.is_string (); } | |
341 | |
342 int is_complex (void) const { return val.is_complex_type (); } | |
343 | |
344 int is_double (void) const { return val.is_double_type (); } | |
345 | |
346 int is_int16 (void) const { return val.is_int16_type (); } | |
347 | |
348 int is_int32 (void) const { return val.is_int32_type (); } | |
349 | |
350 int is_int64 (void) const { return val.is_int64_type (); } | |
351 | |
352 int is_int8 (void) const { return val.is_int8_type (); } | |
353 | |
354 int is_logical (void) const { return val.is_bool_type (); } | |
355 | |
356 int is_numeric (void) const { return val.is_numeric_type (); } | |
357 | |
358 int is_single (void) const { return val.is_single_type (); } | |
359 | |
360 int is_sparse (void) const { return val.is_sparse_type (); } | |
361 | |
362 int is_struct (void) const { return val.is_map (); } | |
363 | |
364 int is_uint16 (void) const { return val.is_uint16_type (); } | |
365 | |
6069 | 366 int is_uint32 (void) const { return val.is_uint32_type (); } |
367 | |
368 int is_uint64 (void) const { return val.is_uint64_type (); } | |
369 | |
370 int is_uint8 (void) const { return val.is_uint8_type (); } | |
5900 | 371 |
372 int is_range (void) const { return val.is_range (); } | |
373 | |
374 int is_real_type (void) const { return val.is_real_type (); } | |
375 | |
376 int is_logical_scalar_true (void) const | |
377 { | |
378 return (is_logical_scalar () && val.is_true ()); | |
379 } | |
380 | |
6686 | 381 mwSize get_m (void) const { return val.rows (); } |
382 | |
383 mwSize get_n (void) const | |
6187 | 384 { |
6686 | 385 mwSize n = 1; |
6187 | 386 |
387 // Force dims and ndims to be cached. | |
388 get_dimensions(); | |
389 | |
6686 | 390 for (mwIndex i = ndims - 1; i > 0; i--) |
6187 | 391 n *= dims[i]; |
392 | |
393 return n; | |
394 } | |
5900 | 395 |
6686 | 396 mwSize *get_dimensions (void) const |
5900 | 397 { |
398 if (! dims) | |
399 { | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
400 ndims = val.ndims (); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
401 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
402 dims = static_cast<mwSize *> (malloc (ndims * sizeof (mwSize))); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
403 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
404 dim_vector dv = val.dims (); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
405 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
406 for (mwIndex i = 0; i < ndims; i++) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
407 dims[i] = dv(i); |
5900 | 408 } |
409 | |
410 return dims; | |
411 } | |
412 | |
6686 | 413 mwSize get_number_of_dimensions (void) const |
5900 | 414 { |
6332 | 415 // Force dims and ndims to be cached. |
416 get_dimensions (); | |
5900 | 417 |
418 return ndims; | |
419 } | |
420 | |
6686 | 421 void set_m (mwSize /*m*/) { request_mutation (); } |
422 | |
423 void set_n (mwSize /*n*/) { request_mutation (); } | |
424 | |
425 void set_dimensions (mwSize */*dims_arg*/, mwSize /*ndims_arg*/) | |
5900 | 426 { |
6400 | 427 request_mutation (); |
5900 | 428 } |
429 | |
6686 | 430 mwSize get_number_of_elements (void) const { return val.numel (); } |
5900 | 431 |
432 int is_empty (void) const { return val.is_empty (); } | |
433 | |
434 mxClassID get_class_id (void) const | |
435 { | |
436 id = mxUNKNOWN_CLASS; | |
437 | |
438 std::string cn = val.class_name (); | |
439 | |
440 if (cn == "cell") | |
441 id = mxCELL_CLASS; | |
442 else if (cn == "struct") | |
443 id = mxSTRUCT_CLASS; | |
444 else if (cn == "logical") | |
445 id = mxLOGICAL_CLASS; | |
446 else if (cn == "char") | |
447 id = mxCHAR_CLASS; | |
448 else if (cn == "double") | |
449 id = mxDOUBLE_CLASS; | |
450 else if (cn == "single") | |
451 id = mxSINGLE_CLASS; | |
452 else if (cn == "int8") | |
453 id = mxINT8_CLASS; | |
454 else if (cn == "uint8") | |
455 id = mxUINT8_CLASS; | |
456 else if (cn == "int16") | |
457 id = mxINT16_CLASS; | |
458 else if (cn == "uint16") | |
459 id = mxUINT16_CLASS; | |
460 else if (cn == "int32") | |
461 id = mxINT32_CLASS; | |
462 else if (cn == "uint32") | |
463 id = mxUINT32_CLASS; | |
464 else if (cn == "int64") | |
465 id = mxINT64_CLASS; | |
466 else if (cn == "uint64") | |
467 id = mxUINT64_CLASS; | |
6218 | 468 else if (cn == "function_handle") |
5900 | 469 id = mxFUNCTION_CLASS; |
470 | |
471 return id; | |
472 } | |
473 | |
474 const char *get_class_name (void) const | |
475 { | |
476 if (! class_name) | |
477 { | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
478 std::string s = val.class_name (); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
479 class_name = strsave (s.c_str ()); |
5900 | 480 } |
481 | |
482 return class_name; | |
483 } | |
484 | |
485 // Not allowed. | |
6400 | 486 void set_class_name (const char */*name_arg*/) { request_mutation (); } |
5900 | 487 |
6686 | 488 mxArray *get_cell (mwIndex /*idx*/) const |
5900 | 489 { |
490 request_mutation (); | |
491 return 0; | |
492 } | |
493 | |
494 // Not allowed. | |
6686 | 495 void set_cell (mwIndex /*idx*/, mxArray */*val*/) { request_mutation (); } |
5900 | 496 |
6332 | 497 double get_scalar (void) const { return val.scalar_value (true); } |
498 | |
5900 | 499 void *get_data (void) const |
500 { | |
9358
d4b1314a7c31
mex.cc (mxArray_octave_value::get_data): avoid enumerating types that can be handled as foreign
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
501 void *retval = val.mex_get_data (); |
d4b1314a7c31
mex.cc (mxArray_octave_value::get_data): avoid enumerating types that can be handled as foreign
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
502 |
d4b1314a7c31
mex.cc (mxArray_octave_value::get_data): avoid enumerating types that can be handled as foreign
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
503 if (retval) |
d4b1314a7c31
mex.cc (mxArray_octave_value::get_data): avoid enumerating types that can be handled as foreign
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
504 maybe_mark_foreign (retval); |
5900 | 505 else |
506 request_mutation (); | |
507 | |
508 return retval; | |
509 } | |
510 | |
511 void *get_imag_data (void) const | |
512 { | |
513 void *retval = 0; | |
514 | |
515 if (is_numeric () && is_real_type ()) | |
516 retval = 0; | |
517 else | |
518 request_mutation (); | |
519 | |
520 return retval; | |
521 } | |
522 | |
523 // Not allowed. | |
6400 | 524 void set_data (void */*pr*/) { request_mutation (); } |
5900 | 525 |
526 // Not allowed. | |
6400 | 527 void set_imag_data (void */*pi*/) { request_mutation (); } |
5900 | 528 |
6686 | 529 mwIndex *get_ir (void) const |
5900 | 530 { |
7179 | 531 return static_cast<mwIndex *> (maybe_mark_foreign (val.mex_get_ir ())); |
5900 | 532 } |
533 | |
6686 | 534 mwIndex *get_jc (void) const |
5900 | 535 { |
7179 | 536 return static_cast<mwIndex *> (maybe_mark_foreign (val.mex_get_jc ())); |
5900 | 537 } |
538 | |
6686 | 539 mwSize get_nzmax (void) const { return val.nzmax (); } |
5900 | 540 |
541 // Not allowed. | |
6686 | 542 void set_ir (mwIndex */*ir*/) { request_mutation (); } |
5900 | 543 |
544 // Not allowed. | |
6686 | 545 void set_jc (mwIndex */*jc*/) { request_mutation (); } |
5900 | 546 |
547 // Not allowed. | |
6686 | 548 void set_nzmax (mwSize /*nzmax*/) { request_mutation (); } |
5900 | 549 |
550 // Not allowed. | |
551 int add_field (const char */*key*/) | |
552 { | |
6400 | 553 request_mutation (); |
554 return 0; | |
5900 | 555 } |
556 | |
557 // Not allowed. | |
6400 | 558 void remove_field (int /*key_num*/) { request_mutation (); } |
5900 | 559 |
6686 | 560 mxArray *get_field_by_number (mwIndex /*index*/, int /*key_num*/) const |
5900 | 561 { |
562 request_mutation (); | |
563 return 0; | |
564 } | |
565 | |
566 // Not allowed. | |
6686 | 567 void set_field_by_number (mwIndex /*index*/, int /*key_num*/, mxArray */*val*/) |
5900 | 568 { |
6400 | 569 request_mutation (); |
5900 | 570 } |
571 | |
572 int get_number_of_fields (void) const { return val.nfields (); } | |
573 | |
574 const char *get_field_name_by_number (int /*key_num*/) const | |
575 { | |
576 request_mutation (); | |
577 return 0; | |
578 } | |
579 | |
580 int get_field_number (const char */*key*/) const | |
581 { | |
582 request_mutation (); | |
583 return 0; | |
584 } | |
585 | |
6686 | 586 int get_string (char *buf, mwSize buflen) const |
5900 | 587 { |
588 int retval = 1; | |
589 | |
6686 | 590 mwSize nel = get_number_of_elements (); |
5900 | 591 |
592 if (val.is_string () && nel < buflen) | |
593 { | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
594 charNDArray tmp = val.char_array_value (); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
595 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
596 const char *p = tmp.data (); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
597 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
598 for (mwIndex i = 0; i < nel; i++) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
599 buf[i] = p[i]; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
600 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
601 buf[nel] = 0; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
602 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
603 retval = 0; |
5900 | 604 } |
605 | |
606 return retval; | |
607 } | |
608 | |
609 char *array_to_string (void) const | |
610 { | |
611 // FIXME -- this is suposed to handle multi-byte character | |
612 // strings. | |
613 | |
614 char *buf = 0; | |
615 | |
616 if (val.is_string ()) | |
617 { | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
618 mwSize nel = get_number_of_elements (); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
619 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
620 buf = static_cast<char *> (malloc (nel + 1)); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
621 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
622 if (buf) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
623 { |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
624 charNDArray tmp = val.char_array_value (); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
625 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
626 const char *p = tmp.data (); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
627 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
628 for (mwIndex i = 0; i < nel; i++) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
629 buf[i] = p[i]; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
630 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
631 buf[nel] = '\0'; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
632 } |
5900 | 633 } |
634 | |
635 return buf; | |
636 } | |
637 | |
6686 | 638 mwIndex calc_single_subscript (mwSize nsubs, mwIndex *subs) const |
5900 | 639 { |
640 // Force ndims, dims to be cached. | |
641 get_dimensions (); | |
642 | |
7357 | 643 return calc_single_subscript_internal (ndims, dims, nsubs, subs); |
5900 | 644 } |
645 | |
6686 | 646 size_t get_element_size (void) const |
5900 | 647 { |
648 // Force id to be cached. | |
649 get_class_id (); | |
650 | |
651 switch (id) | |
652 { | |
653 case mxCELL_CLASS: return sizeof (mxArray *); | |
654 case mxSTRUCT_CLASS: return sizeof (mxArray *); | |
655 case mxLOGICAL_CLASS: return sizeof (mxLogical); | |
656 case mxCHAR_CLASS: return sizeof (mxChar); | |
657 case mxDOUBLE_CLASS: return sizeof (double); | |
658 case mxSINGLE_CLASS: return sizeof (float); | |
659 case mxINT8_CLASS: return 1; | |
660 case mxUINT8_CLASS: return 1; | |
661 case mxINT16_CLASS: return 2; | |
662 case mxUINT16_CLASS: return 2; | |
663 case mxINT32_CLASS: return 4; | |
664 case mxUINT32_CLASS: return 4; | |
665 case mxINT64_CLASS: return 8; | |
666 case mxUINT64_CLASS: return 8; | |
667 case mxFUNCTION_CLASS: return 0; | |
668 default: return 0; | |
669 } | |
670 } | |
671 | |
672 bool mutation_needed (void) const { return mutate_flag; } | |
673 | |
674 void request_mutation (void) const | |
675 { | |
676 if (mutate_flag) | |
677 panic_impossible (); | |
678 | |
679 mutate_flag = true; | |
680 } | |
681 | |
682 mxArray *mutate (void) const { return val.as_mxArray (); } | |
683 | |
684 protected: | |
685 | |
5907 | 686 octave_value as_octave_value (void) const { return val; } |
687 | |
5900 | 688 mxArray_octave_value (const mxArray_octave_value& arg) |
689 : mxArray_base (arg), val (arg.val), mutate_flag (arg.mutate_flag), | |
690 id (arg.id), class_name (strsave (arg.class_name)), ndims (arg.ndims), | |
6686 | 691 dims (ndims > 0 ? static_cast<mwSize *> (malloc (ndims * sizeof (mwSize))) : 0) |
5900 | 692 { |
693 if (dims) | |
694 { | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
695 for (mwIndex i = 0; i < ndims; i++) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
696 dims[i] = arg.dims[i]; |
5900 | 697 } |
698 } | |
699 | |
700 private: | |
701 | |
702 octave_value val; | |
703 | |
704 mutable bool mutate_flag; | |
705 | |
706 // Caching these does not cost much or lead to much duplicated | |
707 // code. For other things, we just request mutation to a | |
708 // Matlab-style mxArray object. | |
709 | |
710 mutable mxClassID id; | |
711 mutable char *class_name; | |
6686 | 712 mutable mwSize ndims; |
713 mutable mwSize *dims; | |
5900 | 714 }; |
715 | |
716 // The base class for the Matlab-style representation, used to handle | |
717 // things that are common to all Matlab-style objects. | |
718 | |
719 class mxArray_matlab : public mxArray_base | |
720 { | |
721 protected: | |
722 | |
723 mxArray_matlab (mxClassID id_arg = mxUNKNOWN_CLASS) | |
724 : mxArray_base (), class_name (0), id (id_arg), ndims (0), dims (0) { } | |
725 | |
6686 | 726 mxArray_matlab (mxClassID id_arg, mwSize ndims_arg, const mwSize *dims_arg) |
5900 | 727 : mxArray_base (), class_name (0), id (id_arg), |
728 ndims (ndims_arg < 2 ? 2 : ndims_arg), | |
6686 | 729 dims (static_cast<mwSize *> (malloc (ndims * sizeof (mwSize)))) |
5900 | 730 { |
731 if (ndims_arg < 2) | |
732 { | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
733 dims[0] = 1; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
734 dims[1] = 1; |
5900 | 735 } |
736 | |
6686 | 737 for (mwIndex i = 0; i < ndims_arg; i++) |
5900 | 738 dims[i] = dims_arg[i]; |
739 | |
6686 | 740 for (mwIndex i = ndims - 1; i > 1; i--) |
5900 | 741 { |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
742 if (dims[i] == 1) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
743 ndims--; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
744 else |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
745 break; |
5900 | 746 } |
747 } | |
748 | |
749 mxArray_matlab (mxClassID id_arg, const dim_vector& dv) | |
750 : mxArray_base (), class_name (0), id (id_arg), | |
751 ndims (dv.length ()), | |
6686 | 752 dims (static_cast<mwSize *> (malloc (ndims * sizeof (mwSize)))) |
5900 | 753 { |
6686 | 754 for (mwIndex i = 0; i < ndims; i++) |
5900 | 755 dims[i] = dv(i); |
756 | |
6686 | 757 for (mwIndex i = ndims - 1; i > 1; i--) |
5900 | 758 { |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
759 if (dims[i] == 1) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
760 ndims--; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
761 else |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
762 break; |
5900 | 763 } |
764 } | |
765 | |
6686 | 766 mxArray_matlab (mxClassID id_arg, mwSize m, mwSize n) |
5900 | 767 : mxArray_base (), class_name (0), id (id_arg), ndims (2), |
6686 | 768 dims (static_cast<mwSize *> (malloc (ndims * sizeof (mwSize)))) |
5900 | 769 { |
770 dims[0] = m; | |
771 dims[1] = n; | |
772 } | |
773 | |
774 public: | |
775 | |
776 ~mxArray_matlab (void) | |
777 { | |
778 mxFree (class_name); | |
779 mxFree (dims); | |
780 } | |
781 | |
782 int is_cell (void) const { return id == mxCELL_CLASS; } | |
783 | |
784 int is_char (void) const { return id == mxCHAR_CLASS; } | |
785 | |
786 int is_complex (void) const { return 0; } | |
787 | |
788 int is_double (void) const { return id == mxDOUBLE_CLASS; } | |
789 | |
790 int is_int16 (void) const { return id == mxINT16_CLASS; } | |
791 | |
792 int is_int32 (void) const { return id == mxINT32_CLASS; } | |
793 | |
794 int is_int64 (void) const { return id == mxINT64_CLASS; } | |
795 | |
796 int is_int8 (void) const { return id == mxINT8_CLASS; } | |
797 | |
798 int is_logical (void) const { return id == mxLOGICAL_CLASS; } | |
799 | |
800 int is_numeric (void) const | |
801 { | |
802 return (id == mxDOUBLE_CLASS || id == mxSINGLE_CLASS | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
803 || id == mxINT8_CLASS || id == mxUINT8_CLASS |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
804 || id == mxINT16_CLASS || id == mxUINT16_CLASS |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
805 || id == mxINT32_CLASS || id == mxUINT32_CLASS |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
806 || id == mxINT64_CLASS || id == mxUINT64_CLASS); |
5900 | 807 } |
808 | |
809 int is_single (void) const { return id == mxSINGLE_CLASS; } | |
810 | |
811 int is_sparse (void) const { return 0; } | |
812 | |
813 int is_struct (void) const { return id == mxSTRUCT_CLASS; } | |
814 | |
815 int is_uint16 (void) const { return id == mxUINT16_CLASS; } | |
816 | |
817 int is_uint32 (void) const { return id == mxUINT32_CLASS; } | |
818 | |
819 int is_uint64 (void) const { return id == mxUINT64_CLASS; } | |
820 | |
821 int is_uint8 (void) const { return id == mxUINT8_CLASS; } | |
822 | |
823 int is_logical_scalar_true (void) const | |
824 { | |
825 return (is_logical_scalar () | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
826 && static_cast<mxLogical *> (get_data ())[0] != 0); |
5900 | 827 } |
828 | |
6686 | 829 mwSize get_m (void) const { return dims[0]; } |
830 | |
831 mwSize get_n (void) const | |
6187 | 832 { |
6686 | 833 mwSize n = 1; |
834 | |
835 for (mwSize i = ndims - 1 ; i > 0 ; i--) | |
6187 | 836 n *= dims[i]; |
837 | |
838 return n; | |
839 } | |
5900 | 840 |
6686 | 841 mwSize *get_dimensions (void) const { return dims; } |
842 | |
843 mwSize get_number_of_dimensions (void) const { return ndims; } | |
844 | |
845 void set_m (mwSize m) { dims[0] = m; } | |
846 | |
847 void set_n (mwSize n) { dims[1] = n; } | |
848 | |
849 void set_dimensions (mwSize *dims_arg, mwSize ndims_arg) | |
5900 | 850 { |
851 dims = dims_arg; | |
852 ndims = ndims_arg; | |
853 } | |
854 | |
6686 | 855 mwSize get_number_of_elements (void) const |
5900 | 856 { |
6686 | 857 mwSize retval = dims[0]; |
858 | |
859 for (mwIndex i = 1; i < ndims; i++) | |
5900 | 860 retval *= dims[i]; |
861 | |
862 return retval; | |
863 } | |
864 | |
865 int is_empty (void) const { return get_number_of_elements () == 0; } | |
866 | |
867 mxClassID get_class_id (void) const { return id; } | |
868 | |
869 const char *get_class_name (void) const | |
870 { | |
871 switch (id) | |
872 { | |
873 case mxCELL_CLASS: return "cell"; | |
874 case mxSTRUCT_CLASS: return "struct"; | |
875 case mxLOGICAL_CLASS: return "logical"; | |
876 case mxCHAR_CLASS: return "char"; | |
877 case mxDOUBLE_CLASS: return "double"; | |
878 case mxSINGLE_CLASS: return "single"; | |
879 case mxINT8_CLASS: return "int8"; | |
880 case mxUINT8_CLASS: return "uint8"; | |
881 case mxINT16_CLASS: return "int16"; | |
882 case mxUINT16_CLASS: return "uint16"; | |
883 case mxINT32_CLASS: return "int32"; | |
884 case mxUINT32_CLASS: return "uint32"; | |
885 case mxINT64_CLASS: return "int64"; | |
886 case mxUINT64_CLASS: return "uint64"; | |
6218 | 887 case mxFUNCTION_CLASS: return "function_handle"; |
5900 | 888 default: return "unknown"; |
889 } | |
890 } | |
891 | |
892 void set_class_name (const char *name_arg) | |
893 { | |
894 mxFree (class_name); | |
895 class_name = static_cast<char *> (malloc (strlen (name_arg) + 1)); | |
896 strcpy (class_name, name_arg); | |
897 } | |
898 | |
6686 | 899 mxArray *get_cell (mwIndex /*idx*/) const |
5900 | 900 { |
901 invalid_type_error (); | |
902 return 0; | |
903 } | |
904 | |
6686 | 905 void set_cell (mwIndex /*idx*/, mxArray */*val*/) |
5900 | 906 { |
907 invalid_type_error (); | |
908 } | |
909 | |
6332 | 910 double get_scalar (void) const |
911 { | |
912 invalid_type_error (); | |
913 return 0; | |
914 } | |
915 | |
5900 | 916 void *get_data (void) const |
917 { | |
918 invalid_type_error (); | |
919 return 0; | |
920 } | |
921 | |
922 void *get_imag_data (void) const | |
923 { | |
924 invalid_type_error (); | |
925 return 0; | |
926 } | |
927 | |
928 void set_data (void */*pr*/) | |
929 { | |
930 invalid_type_error (); | |
931 } | |
932 | |
933 void set_imag_data (void */*pi*/) | |
934 { | |
935 invalid_type_error (); | |
936 } | |
937 | |
6686 | 938 mwIndex *get_ir (void) const |
5900 | 939 { |
940 invalid_type_error (); | |
941 return 0; | |
942 } | |
943 | |
6686 | 944 mwIndex *get_jc (void) const |
5900 | 945 { |
946 invalid_type_error (); | |
947 return 0; | |
948 } | |
949 | |
6686 | 950 mwSize get_nzmax (void) const |
5900 | 951 { |
952 invalid_type_error (); | |
953 return 0; | |
954 } | |
955 | |
6686 | 956 void set_ir (mwIndex */*ir*/) |
5900 | 957 { |
958 invalid_type_error (); | |
959 } | |
960 | |
6686 | 961 void set_jc (mwIndex */*jc*/) |
5900 | 962 { |
963 invalid_type_error (); | |
964 } | |
965 | |
6686 | 966 void set_nzmax (mwSize /*nzmax*/) |
5900 | 967 { |
968 invalid_type_error (); | |
969 } | |
970 | |
971 int add_field (const char */*key*/) | |
972 { | |
973 invalid_type_error (); | |
974 return -1; | |
975 } | |
976 | |
977 void remove_field (int /*key_num*/) | |
978 { | |
979 invalid_type_error (); | |
980 } | |
981 | |
6686 | 982 mxArray *get_field_by_number (mwIndex /*index*/, int /*key_num*/) const |
5900 | 983 { |
984 invalid_type_error (); | |
985 return 0; | |
986 } | |
987 | |
6686 | 988 void set_field_by_number (mwIndex /*index*/, int /*key_num*/, mxArray */*val*/) |
5900 | 989 { |
990 invalid_type_error (); | |
991 } | |
992 | |
993 int get_number_of_fields (void) const | |
994 { | |
995 invalid_type_error (); | |
996 return 0; | |
997 } | |
998 | |
999 const char *get_field_name_by_number (int /*key_num*/) const | |
1000 { | |
1001 invalid_type_error (); | |
1002 return 0; | |
1003 } | |
1004 | |
1005 int get_field_number (const char */*key*/) const | |
1006 { | |
1007 return -1; | |
1008 } | |
1009 | |
6686 | 1010 int get_string (char */*buf*/, mwSize /*buflen*/) const |
5900 | 1011 { |
1012 invalid_type_error (); | |
1013 return 0; | |
1014 } | |
1015 | |
1016 char *array_to_string (void) const | |
1017 { | |
1018 invalid_type_error (); | |
1019 return 0; | |
1020 } | |
1021 | |
6686 | 1022 mwIndex calc_single_subscript (mwSize nsubs, mwIndex *subs) const |
5900 | 1023 { |
7357 | 1024 return calc_single_subscript_internal (ndims, dims, nsubs, subs); |
5900 | 1025 } |
1026 | |
6686 | 1027 size_t get_element_size (void) const |
5900 | 1028 { |
1029 switch (id) | |
1030 { | |
1031 case mxCELL_CLASS: return sizeof (mxArray *); | |
1032 case mxSTRUCT_CLASS: return sizeof (mxArray *); | |
1033 case mxLOGICAL_CLASS: return sizeof (mxLogical); | |
1034 case mxCHAR_CLASS: return sizeof (mxChar); | |
1035 case mxDOUBLE_CLASS: return sizeof (double); | |
1036 case mxSINGLE_CLASS: return sizeof (float); | |
1037 case mxINT8_CLASS: return 1; | |
1038 case mxUINT8_CLASS: return 1; | |
1039 case mxINT16_CLASS: return 2; | |
1040 case mxUINT16_CLASS: return 2; | |
1041 case mxINT32_CLASS: return 4; | |
1042 case mxUINT32_CLASS: return 4; | |
1043 case mxINT64_CLASS: return 8; | |
1044 case mxUINT64_CLASS: return 8; | |
1045 case mxFUNCTION_CLASS: return 0; | |
1046 default: return 0; | |
1047 } | |
1048 } | |
1049 | |
1050 protected: | |
1051 | |
1052 mxArray_matlab (const mxArray_matlab& val) | |
1053 : mxArray_base (val), class_name (strsave (val.class_name)), | |
1054 id (val.id), ndims (val.ndims), | |
6686 | 1055 dims (static_cast<mwSize *> (malloc (ndims * sizeof (mwSize)))) |
5900 | 1056 { |
6686 | 1057 for (mwIndex i = 0; i < ndims; i++) |
5900 | 1058 dims[i] = val.dims[i]; |
1059 } | |
1060 | |
1061 dim_vector | |
1062 dims_to_dim_vector (void) const | |
1063 { | |
6686 | 1064 mwSize nd = get_number_of_dimensions (); |
1065 | |
1066 mwSize *d = get_dimensions (); | |
5900 | 1067 |
1068 dim_vector dv; | |
1069 dv.resize (nd); | |
1070 | |
6686 | 1071 for (mwIndex i = 0; i < nd; i++) |
5900 | 1072 dv(i) = d[i]; |
1073 | |
1074 return dv; | |
1075 } | |
1076 | |
1077 private: | |
1078 | |
1079 char *class_name; | |
1080 | |
1081 mxClassID id; | |
1082 | |
6686 | 1083 mwSize ndims; |
1084 mwSize *dims; | |
5900 | 1085 |
1086 void invalid_type_error (void) const | |
1087 { | |
1088 error ("invalid type for operation"); | |
1089 } | |
1090 }; | |
1091 | |
1092 // Matlab-style numeric, character, and logical data. | |
1093 | |
1094 class mxArray_number : public mxArray_matlab | |
1095 { | |
1096 public: | |
1097 | |
6686 | 1098 mxArray_number (mxClassID id_arg, mwSize ndims_arg, const mwSize *dims_arg, |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1099 mxComplexity flag = mxREAL) |
5900 | 1100 : mxArray_matlab (id_arg, ndims_arg, dims_arg), |
1101 pr (calloc (get_number_of_elements (), get_element_size ())), | |
1102 pi (flag == mxCOMPLEX ? calloc (get_number_of_elements (), get_element_size ()) : 0) { } | |
1103 | |
1104 mxArray_number (mxClassID id_arg, const dim_vector& dv, | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1105 mxComplexity flag = mxREAL) |
5900 | 1106 : mxArray_matlab (id_arg, dv), |
1107 pr (calloc (get_number_of_elements (), get_element_size ())), | |
1108 pi (flag == mxCOMPLEX ? calloc (get_number_of_elements (), get_element_size ()) : 0) { } | |
1109 | |
6686 | 1110 mxArray_number (mxClassID id_arg, mwSize m, mwSize n, mxComplexity flag = mxREAL) |
5900 | 1111 : mxArray_matlab (id_arg, m, n), |
1112 pr (calloc (get_number_of_elements (), get_element_size ())), | |
1113 pi (flag == mxCOMPLEX ? calloc (get_number_of_elements (), get_element_size ()) : 0) { } | |
1114 | |
1115 mxArray_number (mxClassID id_arg, double val) | |
1116 : mxArray_matlab (id_arg, 1, 1), | |
1117 pr (calloc (get_number_of_elements (), get_element_size ())), | |
1118 pi (0) | |
1119 { | |
1120 double *dpr = static_cast<double *> (pr); | |
1121 dpr[0] = val; | |
1122 } | |
1123 | |
1124 mxArray_number (mxClassID id_arg, mxLogical val) | |
1125 : mxArray_matlab (id_arg, 1, 1), | |
1126 pr (calloc (get_number_of_elements (), get_element_size ())), | |
1127 pi (0) | |
1128 { | |
1129 mxLogical *lpr = static_cast<mxLogical *> (pr); | |
1130 lpr[0] = val; | |
1131 } | |
1132 | |
1133 mxArray_number (const char *str) | |
10853
c3813056f94f
mxArray_number (const char *): create empty string if given NULL arg
John W. Eaton <jwe@octave.org>
parents:
10463
diff
changeset
|
1134 : mxArray_matlab (mxCHAR_CLASS, |
c3813056f94f
mxArray_number (const char *): create empty string if given NULL arg
John W. Eaton <jwe@octave.org>
parents:
10463
diff
changeset
|
1135 str ? (strlen (str) ? 1 : 0) : 0, |
c3813056f94f
mxArray_number (const char *): create empty string if given NULL arg
John W. Eaton <jwe@octave.org>
parents:
10463
diff
changeset
|
1136 str ? strlen (str) : 0), |
5900 | 1137 pr (calloc (get_number_of_elements (), get_element_size ())), |
1138 pi (0) | |
1139 { | |
1140 mxChar *cpr = static_cast<mxChar *> (pr); | |
6686 | 1141 mwSize nel = get_number_of_elements (); |
1142 for (mwIndex i = 0; i < nel; i++) | |
5900 | 1143 cpr[i] = str[i]; |
1144 } | |
1145 | |
6686 | 1146 // FIXME?? |
6806 | 1147 mxArray_number (mwSize m, const char **str) |
5900 | 1148 : mxArray_matlab (mxCHAR_CLASS, m, max_str_len (m, str)), |
1149 pr (calloc (get_number_of_elements (), get_element_size ())), | |
1150 pi (0) | |
1151 { | |
1152 mxChar *cpr = static_cast<mxChar *> (pr); | |
1153 | |
6686 | 1154 mwSize *dv = get_dimensions (); |
1155 | |
1156 mwSize nc = dv[1]; | |
1157 | |
1158 for (mwIndex j = 0; j < m; j++) | |
5900 | 1159 { |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1160 const char *ptr = str[j]; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1161 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1162 size_t tmp_len = strlen (ptr); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1163 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1164 for (size_t i = 0; i < tmp_len; i++) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1165 cpr[m*i+j] = static_cast<mxChar> (ptr[i]); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1166 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1167 for (size_t i = tmp_len; i < nc; i++) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1168 cpr[m*i+j] = static_cast<mxChar> (' '); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1169 } |
5900 | 1170 } |
1171 | |
1172 mxArray_number *clone (void) const { return new mxArray_number (*this); } | |
1173 | |
1174 ~mxArray_number (void) | |
1175 { | |
1176 mxFree (pr); | |
1177 mxFree (pi); | |
1178 } | |
1179 | |
5907 | 1180 int is_complex (void) const { return pi != 0; } |
1181 | |
6332 | 1182 double get_scalar (void) const |
1183 { | |
1184 double retval = 0; | |
1185 | |
1186 switch (get_class_id ()) | |
1187 { | |
1188 case mxLOGICAL_CLASS: | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1189 retval = *(static_cast<bool *> (pr)); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1190 break; |
6332 | 1191 |
1192 case mxCHAR_CLASS: | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1193 retval = *(static_cast<mxChar *> (pr)); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1194 break; |
6332 | 1195 |
1196 case mxSINGLE_CLASS: | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1197 retval = *(static_cast<float *> (pr)); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1198 break; |
6332 | 1199 |
1200 case mxDOUBLE_CLASS: | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1201 retval = *(static_cast<double *> (pr)); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1202 break; |
6332 | 1203 |
1204 case mxINT8_CLASS: | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1205 retval = *(static_cast<int8_t *> (pr)); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1206 break; |
6332 | 1207 |
1208 case mxUINT8_CLASS: | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1209 retval = *(static_cast<uint8_t *> (pr)); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1210 break; |
6332 | 1211 |
1212 case mxINT16_CLASS: | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1213 retval = *(static_cast<int16_t *> (pr)); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1214 break; |
6332 | 1215 |
1216 case mxUINT16_CLASS: | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1217 retval = *(static_cast<uint16_t *> (pr)); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1218 break; |
6332 | 1219 |
1220 case mxINT32_CLASS: | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1221 retval = *(static_cast<int32_t *> (pr)); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1222 break; |
6332 | 1223 |
1224 case mxUINT32_CLASS: | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1225 retval = *(static_cast<uint32_t *> (pr)); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1226 break; |
6332 | 1227 |
1228 case mxINT64_CLASS: | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1229 retval = *(static_cast<int64_t *> (pr)); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1230 break; |
6332 | 1231 |
1232 case mxUINT64_CLASS: | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1233 retval = *(static_cast<uint64_t *> (pr)); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1234 break; |
6332 | 1235 |
1236 default: | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1237 panic_impossible (); |
6332 | 1238 } |
1239 | |
1240 return retval; | |
1241 } | |
1242 | |
5907 | 1243 void *get_data (void) const { return pr; } |
1244 | |
1245 void *get_imag_data (void) const { return pi; } | |
1246 | |
1247 void set_data (void *pr_arg) { pr = pr_arg; } | |
1248 | |
1249 void set_imag_data (void *pi_arg) { pi = pi_arg; } | |
1250 | |
6686 | 1251 int get_string (char *buf, mwSize buflen) const |
5907 | 1252 { |
1253 int retval = 1; | |
1254 | |
6686 | 1255 mwSize nel = get_number_of_elements (); |
6493 | 1256 |
1257 if (nel < buflen) | |
5907 | 1258 { |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1259 mxChar *ptr = static_cast<mxChar *> (pr); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1260 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1261 for (mwIndex i = 0; i < nel; i++) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1262 buf[i] = static_cast<char> (ptr[i]); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1263 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1264 buf[nel] = 0; |
5907 | 1265 } |
1266 | |
1267 return retval; | |
1268 } | |
1269 | |
1270 char *array_to_string (void) const | |
1271 { | |
1272 // FIXME -- this is suposed to handle multi-byte character | |
1273 // strings. | |
1274 | |
6686 | 1275 mwSize nel = get_number_of_elements (); |
5907 | 1276 |
1277 char *buf = static_cast<char *> (malloc (nel + 1)); | |
1278 | |
1279 if (buf) | |
1280 { | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1281 mxChar *ptr = static_cast<mxChar *> (pr); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1282 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1283 for (mwIndex i = 0; i < nel; i++) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1284 buf[i] = static_cast<char> (ptr[i]); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1285 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1286 buf[nel] = '\0'; |
5907 | 1287 } |
1288 | |
1289 return buf; | |
1290 } | |
1291 | |
1292 protected: | |
1293 | |
5900 | 1294 template <typename ELT_T, typename ARRAY_T, typename ARRAY_ELT_T> |
1295 octave_value | |
1296 int_to_ov (const dim_vector& dv) const | |
1297 { | |
1298 octave_value retval; | |
1299 | |
6686 | 1300 mwSize nel = get_number_of_elements (); |
5900 | 1301 |
1302 ELT_T *ppr = static_cast<ELT_T *> (pr); | |
1303 | |
1304 if (pi) | |
1305 error ("complex integer types are not supported"); | |
1306 else | |
1307 { | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1308 ARRAY_T val (dv); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1309 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1310 ARRAY_ELT_T *ptr = val.fortran_vec (); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1311 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1312 for (mwIndex i = 0; i < nel; i++) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1313 ptr[i] = ppr[i]; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1314 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1315 retval = val; |
5900 | 1316 } |
1317 | |
1318 return retval; | |
1319 } | |
1320 | |
1321 octave_value as_octave_value (void) const | |
1322 { | |
1323 octave_value retval; | |
1324 | |
1325 dim_vector dv = dims_to_dim_vector (); | |
1326 | |
1327 switch (get_class_id ()) | |
1328 { | |
1329 case mxLOGICAL_CLASS: | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1330 retval = int_to_ov<bool, boolNDArray, bool> (dv); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1331 break; |
5900 | 1332 |
1333 case mxCHAR_CLASS: | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1334 { |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1335 mwSize nel = get_number_of_elements (); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1336 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1337 mxChar *ppr = static_cast<mxChar *> (pr); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1338 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1339 charNDArray val (dv); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1340 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1341 char *ptr = val.fortran_vec (); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1342 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1343 for (mwIndex i = 0; i < nel; i++) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1344 ptr[i] = static_cast<char> (ppr[i]); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1345 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1346 retval = val; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1347 } |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1348 break; |
5900 | 1349 |
1350 case mxSINGLE_CLASS: | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1351 { |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1352 mwSize nel = get_number_of_elements (); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1353 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1354 float *ppr = static_cast<float *> (pr); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1355 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1356 if (pi) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1357 { |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1358 ComplexNDArray val (dv); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1359 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1360 Complex *ptr = val.fortran_vec (); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1361 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1362 float *ppi = static_cast<float *> (pi); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1363 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1364 for (mwIndex i = 0; i < nel; i++) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1365 ptr[i] = Complex (ppr[i], ppi[i]); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1366 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1367 retval = val; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1368 } |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1369 else |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1370 { |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1371 NDArray val (dv); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1372 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1373 double *ptr = val.fortran_vec (); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1374 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1375 for (mwIndex i = 0; i < nel; i++) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1376 ptr[i] = ppr[i]; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1377 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1378 retval = val; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1379 } |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1380 } |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1381 break; |
5900 | 1382 |
1383 case mxDOUBLE_CLASS: | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1384 { |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1385 mwSize nel = get_number_of_elements (); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1386 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1387 double *ppr = static_cast<double *> (pr); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1388 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1389 if (pi) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1390 { |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1391 ComplexNDArray val (dv); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1392 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1393 Complex *ptr = val.fortran_vec (); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1394 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1395 double *ppi = static_cast<double *> (pi); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1396 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1397 for (mwIndex i = 0; i < nel; i++) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1398 ptr[i] = Complex (ppr[i], ppi[i]); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1399 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1400 retval = val; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1401 } |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1402 else |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1403 { |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1404 NDArray val (dv); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1405 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1406 double *ptr = val.fortran_vec (); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1407 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1408 for (mwIndex i = 0; i < nel; i++) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1409 ptr[i] = ppr[i]; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1410 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1411 retval = val; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1412 } |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1413 } |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1414 break; |
5900 | 1415 |
1416 case mxINT8_CLASS: | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1417 retval = int_to_ov<int8_t, int8NDArray, octave_int8> (dv); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1418 break; |
5900 | 1419 |
1420 case mxUINT8_CLASS: | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1421 retval = int_to_ov<uint8_t, uint8NDArray, octave_uint8> (dv); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1422 break; |
5900 | 1423 |
1424 case mxINT16_CLASS: | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1425 retval = int_to_ov<int16_t, int16NDArray, octave_int16> (dv); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1426 break; |
5900 | 1427 |
1428 case mxUINT16_CLASS: | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1429 retval = int_to_ov<uint16_t, uint16NDArray, octave_uint16> (dv); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1430 break; |
5900 | 1431 |
1432 case mxINT32_CLASS: | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1433 retval = int_to_ov<int32_t, int32NDArray, octave_int32> (dv); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1434 break; |
5900 | 1435 |
1436 case mxUINT32_CLASS: | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1437 retval = int_to_ov<uint32_t, uint32NDArray, octave_uint32> (dv); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1438 break; |
5900 | 1439 |
1440 case mxINT64_CLASS: | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1441 retval = int_to_ov<int64_t, int64NDArray, octave_int64> (dv); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1442 break; |
5900 | 1443 |
1444 case mxUINT64_CLASS: | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1445 retval = int_to_ov<uint64_t, uint64NDArray, octave_uint64> (dv); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1446 break; |
5900 | 1447 |
1448 default: | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1449 panic_impossible (); |
5900 | 1450 } |
1451 | |
1452 return retval; | |
1453 } | |
1454 | |
1455 mxArray_number (const mxArray_number& val) | |
1456 : mxArray_matlab (val), | |
1457 pr (malloc (get_number_of_elements () * get_element_size ())), | |
1458 pi (val.pi ? malloc (get_number_of_elements () * get_element_size ()) : 0) | |
1459 { | |
5907 | 1460 size_t nbytes = get_number_of_elements () * get_element_size (); |
1461 | |
1462 if (pr) | |
1463 memcpy (pr, val.pr, nbytes); | |
5900 | 1464 |
1465 if (pi) | |
5907 | 1466 memcpy (pi, val.pi, nbytes); |
5900 | 1467 } |
1468 | |
1469 private: | |
1470 | |
1471 void *pr; | |
1472 void *pi; | |
1473 }; | |
1474 | |
1475 // Matlab-style sparse arrays. | |
1476 | |
5903 | 1477 class mxArray_sparse : public mxArray_matlab |
5900 | 1478 { |
1479 public: | |
1480 | |
1481 mxArray_sparse (mxClassID id_arg, int m, int n, int nzmax_arg, | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1482 mxComplexity flag = mxREAL) |
5903 | 1483 : mxArray_matlab (id_arg, m, n), nzmax (nzmax_arg) |
5900 | 1484 { |
5903 | 1485 pr = (calloc (nzmax, get_element_size ())); |
1486 pi = (flag == mxCOMPLEX ? calloc (nzmax, get_element_size ()) : 0); | |
6686 | 1487 ir = static_cast<mwIndex *> (calloc (nzmax, sizeof (mwIndex))); |
1488 jc = static_cast<mwIndex *> (calloc (n + 1, sizeof (mwIndex))); | |
5900 | 1489 } |
1490 | |
1491 mxArray_sparse *clone (void) const { return new mxArray_sparse (*this); } | |
1492 | |
1493 ~mxArray_sparse (void) | |
1494 { | |
5903 | 1495 mxFree (pr); |
1496 mxFree (pi); | |
5900 | 1497 mxFree (ir); |
1498 mxFree (jc); | |
1499 } | |
1500 | |
5907 | 1501 int is_complex (void) const { return pi != 0; } |
1502 | |
1503 int is_sparse (void) const { return 1; } | |
1504 | |
1505 void *get_data (void) const { return pr; } | |
1506 | |
1507 void *get_imag_data (void) const { return pi; } | |
1508 | |
1509 void set_data (void *pr_arg) { pr = pr_arg; } | |
1510 | |
1511 void set_imag_data (void *pi_arg) { pi = pi_arg; } | |
1512 | |
6686 | 1513 mwIndex *get_ir (void) const { return ir; } |
1514 | |
1515 mwIndex *get_jc (void) const { return jc; } | |
1516 | |
1517 mwSize get_nzmax (void) const { return nzmax; } | |
1518 | |
1519 void set_ir (mwIndex *ir_arg) { ir = ir_arg; } | |
1520 | |
1521 void set_jc (mwIndex *jc_arg) { jc = jc_arg; } | |
1522 | |
1523 void set_nzmax (mwSize nzmax_arg) { nzmax = nzmax_arg; } | |
5907 | 1524 |
1525 protected: | |
1526 | |
5900 | 1527 octave_value as_octave_value (void) const |
1528 { | |
5903 | 1529 octave_value retval; |
1530 | |
1531 dim_vector dv = dims_to_dim_vector (); | |
1532 | |
1533 switch (get_class_id ()) | |
1534 { | |
1535 case mxLOGICAL_CLASS: | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1536 { |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1537 bool *ppr = static_cast<bool *> (pr); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1538 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1539 SparseBoolMatrix val (get_m (), get_n (), |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1540 static_cast<octave_idx_type> (nzmax)); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1541 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1542 for (mwIndex i = 0; i < nzmax; i++) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1543 { |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1544 val.xdata(i) = ppr[i]; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1545 val.xridx(i) = ir[i]; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1546 } |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1547 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1548 for (mwIndex i = 0; i < get_n () + 1; i++) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1549 val.xcidx(i) = jc[i]; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1550 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1551 retval = val; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1552 } |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1553 break; |
5903 | 1554 |
1555 case mxSINGLE_CLASS: | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1556 error ("single precision sparse data type not supported"); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1557 break; |
5903 | 1558 |
1559 case mxDOUBLE_CLASS: | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1560 { |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1561 if (pi) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1562 { |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1563 double *ppr = static_cast<double *> (pr); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1564 double *ppi = static_cast<double *> (pi); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1565 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1566 SparseComplexMatrix val (get_m (), get_n (), |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1567 static_cast<octave_idx_type> (nzmax)); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1568 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1569 for (mwIndex i = 0; i < nzmax; i++) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1570 { |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1571 val.xdata(i) = Complex (ppr[i], ppi[i]); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1572 val.xridx(i) = ir[i]; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1573 } |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1574 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1575 for (mwIndex i = 0; i < get_n () + 1; i++) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1576 val.xcidx(i) = jc[i]; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1577 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1578 retval = val; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1579 } |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1580 else |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1581 { |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1582 double *ppr = static_cast<double *> (pr); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1583 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1584 SparseMatrix val (get_m (), get_n (), |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1585 static_cast<octave_idx_type> (nzmax)); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1586 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1587 for (mwIndex i = 0; i < nzmax; i++) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1588 { |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1589 val.xdata(i) = ppr[i]; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1590 val.xridx(i) = ir[i]; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1591 } |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1592 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1593 for (mwIndex i = 0; i < get_n () + 1; i++) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1594 val.xcidx(i) = jc[i]; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1595 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1596 retval = val; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1597 } |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1598 } |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1599 break; |
5903 | 1600 |
1601 default: | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1602 panic_impossible (); |
5903 | 1603 } |
1604 | |
1605 return retval; | |
5900 | 1606 } |
1607 | |
1608 private: | |
1609 | |
6686 | 1610 mwSize nzmax; |
5900 | 1611 |
5903 | 1612 void *pr; |
1613 void *pi; | |
6686 | 1614 mwIndex *ir; |
1615 mwIndex *jc; | |
5900 | 1616 |
1617 mxArray_sparse (const mxArray_sparse& val) | |
5903 | 1618 : mxArray_matlab (val), nzmax (val.nzmax), |
7177 | 1619 pr (malloc (nzmax * get_element_size ())), |
1620 pi (val.pi ? malloc (nzmax * get_element_size ()) : 0), | |
6686 | 1621 ir (static_cast<mwIndex *> (malloc (nzmax * sizeof (mwIndex)))), |
1622 jc (static_cast<mwIndex *> (malloc (nzmax * sizeof (mwIndex)))) | |
5900 | 1623 { |
5907 | 1624 size_t nbytes = nzmax * get_element_size (); |
1625 | |
1626 if (pr) | |
1627 memcpy (pr, val.pr, nbytes); | |
1628 | |
5903 | 1629 if (pi) |
5907 | 1630 memcpy (pi, val.pi, nbytes); |
1631 | |
1632 if (ir) | |
6686 | 1633 memcpy (ir, val.ir, nzmax * sizeof (mwIndex)); |
5907 | 1634 |
1635 if (jc) | |
6686 | 1636 memcpy (jc, val.jc, (val.get_n () + 1) * sizeof (mwIndex)); |
5900 | 1637 } |
1638 }; | |
1639 | |
1640 // Matlab-style struct arrays. | |
1641 | |
1642 class mxArray_struct : public mxArray_matlab | |
1643 { | |
1644 public: | |
1645 | |
6686 | 1646 mxArray_struct (mwSize ndims_arg, const mwSize *dims_arg, int num_keys_arg, |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1647 const char **keys) |
5900 | 1648 : mxArray_matlab (mxSTRUCT_CLASS, ndims_arg, dims_arg), nfields (num_keys_arg), |
1649 fields (static_cast<char **> (calloc (nfields, sizeof (char *)))), | |
1650 data (static_cast<mxArray **> (calloc (nfields * get_number_of_elements (), sizeof (mxArray *)))) | |
1651 { | |
1652 init (keys); | |
1653 } | |
1654 | |
1655 mxArray_struct (const dim_vector& dv, int num_keys_arg, const char **keys) | |
1656 : mxArray_matlab (mxSTRUCT_CLASS, dv), nfields (num_keys_arg), | |
1657 fields (static_cast<char **> (calloc (nfields, sizeof (char *)))), | |
1658 data (static_cast<mxArray **> (calloc (nfields * get_number_of_elements (), sizeof (mxArray *)))) | |
1659 { | |
1660 init (keys); | |
1661 } | |
1662 | |
6686 | 1663 mxArray_struct (mwSize m, mwSize n, int num_keys_arg, const char **keys) |
5900 | 1664 : mxArray_matlab (mxSTRUCT_CLASS, m, n), nfields (num_keys_arg), |
1665 fields (static_cast<char **> (calloc (nfields, sizeof (char *)))), | |
1666 data (static_cast<mxArray **> (calloc (nfields * get_number_of_elements (), sizeof (mxArray *)))) | |
1667 { | |
1668 init (keys); | |
1669 } | |
1670 | |
1671 void init (const char **keys) | |
1672 { | |
1673 for (int i = 0; i < nfields; i++) | |
1674 fields[i] = strsave (keys[i]); | |
1675 } | |
1676 | |
1677 mxArray_struct *clone (void) const { return new mxArray_struct (*this); } | |
1678 | |
1679 ~mxArray_struct (void) | |
1680 { | |
1681 for (int i = 0; i < nfields; i++) | |
1682 mxFree (fields[i]); | |
1683 | |
1684 mxFree (fields); | |
1685 | |
6686 | 1686 mwSize ntot = nfields * get_number_of_elements (); |
1687 | |
1688 for (mwIndex i = 0; i < ntot; i++) | |
5905 | 1689 delete data[i]; |
5900 | 1690 |
1691 mxFree (data); | |
1692 } | |
1693 | |
1694 int add_field (const char *key) | |
1695 { | |
1696 int retval = -1; | |
1697 | |
1698 if (valid_key (key)) | |
1699 { | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1700 nfields++; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1701 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1702 fields = static_cast<char **> (mxRealloc (fields, nfields * sizeof (char *))); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1703 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1704 if (fields) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1705 { |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1706 fields[nfields-1] = strsave (key); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1707 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1708 mwSize nel = get_number_of_elements (); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1709 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1710 mwSize ntot = nfields * nel; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1711 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1712 mxArray **new_data = static_cast<mxArray **> (malloc (ntot * sizeof (mxArray *))); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1713 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1714 if (new_data) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1715 { |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1716 mwIndex j = 0; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1717 mwIndex k = 0; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1718 mwIndex n = 0; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1719 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1720 for (mwIndex i = 0; i < ntot; i++) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1721 { |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1722 if (++n == nfields) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1723 { |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1724 new_data[j++] = 0; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1725 n = 0; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1726 } |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1727 else |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1728 new_data[j++] = data[k++]; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1729 } |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1730 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1731 mxFree (data); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1732 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1733 data = new_data; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1734 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1735 retval = nfields - 1; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1736 } |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1737 } |
5900 | 1738 } |
1739 | |
1740 return retval; | |
1741 } | |
1742 | |
1743 void remove_field (int key_num) | |
1744 { | |
1745 if (key_num >= 0 && key_num < nfields) | |
1746 { | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1747 mwSize nel = get_number_of_elements (); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1748 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1749 mwSize ntot = nfields * nel; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1750 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1751 int new_nfields = nfields - 1; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1752 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1753 char **new_fields = static_cast<char **> (malloc (new_nfields * sizeof (char *))); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1754 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1755 mxArray **new_data = static_cast<mxArray **> (malloc (new_nfields * nel * sizeof (mxArray *))); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1756 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1757 for (int i = 0; i < key_num; i++) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1758 new_fields[i] = fields[i]; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1759 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1760 for (int i = key_num + 1; i < nfields; i++) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1761 new_fields[i-1] = fields[i]; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1762 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1763 if (new_nfields > 0) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1764 { |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1765 mwIndex j = 0; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1766 mwIndex k = 0; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1767 mwIndex n = 0; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1768 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1769 for (mwIndex i = 0; i < ntot; i++) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1770 { |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1771 if (n == key_num) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1772 k++; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1773 else |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1774 new_data[j++] = data[k++]; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1775 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1776 if (++n == nfields) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1777 n = 0; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1778 } |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1779 } |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1780 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1781 nfields = new_nfields; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1782 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1783 mxFree (fields); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1784 mxFree (data); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1785 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1786 fields = new_fields; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1787 data = new_data; |
5900 | 1788 } |
1789 } | |
1790 | |
6686 | 1791 mxArray *get_field_by_number (mwIndex index, int key_num) const |
5900 | 1792 { |
6187 | 1793 return key_num >= 0 && key_num < nfields |
6188 | 1794 ? data[nfields * index + key_num] : 0; |
5900 | 1795 } |
1796 | |
6686 | 1797 void set_field_by_number (mwIndex index, int key_num, mxArray *val); |
5900 | 1798 |
1799 int get_number_of_fields (void) const { return nfields; } | |
1800 | |
1801 const char *get_field_name_by_number (int key_num) const | |
1802 { | |
1803 return key_num >= 0 && key_num < nfields ? fields[key_num] : 0; | |
1804 } | |
1805 | |
1806 int get_field_number (const char *key) const | |
1807 { | |
1808 int retval = -1; | |
1809 | |
1810 for (int i = 0; i < nfields; i++) | |
1811 { | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1812 if (! strcmp (key, fields[i])) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1813 { |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1814 retval = i; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1815 break; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1816 } |
5900 | 1817 } |
1818 | |
1819 return retval; | |
1820 } | |
1821 | |
1822 void *get_data (void) const { return data; } | |
1823 | |
1824 void set_data (void *data_arg) { data = static_cast<mxArray **> (data_arg); } | |
1825 | |
5907 | 1826 protected: |
1827 | |
1828 octave_value as_octave_value (void) const | |
1829 { | |
1830 dim_vector dv = dims_to_dim_vector (); | |
1831 | |
1832 string_vector keys (fields, nfields); | |
1833 | |
1834 Octave_map m; | |
1835 | |
6686 | 1836 mwSize ntot = nfields * get_number_of_elements (); |
5907 | 1837 |
1838 for (int i = 0; i < nfields; i++) | |
1839 { | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1840 Cell c (dv); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1841 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1842 octave_value *p = c.fortran_vec (); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1843 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1844 mwIndex k = 0; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1845 for (mwIndex j = i; j < ntot; j += nfields) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1846 p[k++] = mxArray::as_octave_value (data[j]); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1847 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1848 m.assign (keys[i], c); |
5907 | 1849 } |
1850 | |
1851 return m; | |
1852 } | |
1853 | |
5900 | 1854 private: |
1855 | |
1856 int nfields; | |
1857 | |
1858 char **fields; | |
1859 | |
1860 mxArray **data; | |
1861 | |
1862 mxArray_struct (const mxArray_struct& val) | |
1863 : mxArray_matlab (val), nfields (val.nfields), | |
1864 fields (static_cast<char **> (malloc (nfields * sizeof (char *)))), | |
1865 data (static_cast<mxArray **> (malloc (nfields * get_number_of_elements () * sizeof (mxArray *)))) | |
1866 { | |
1867 for (int i = 0; i < nfields; i++) | |
1868 fields[i] = strsave (val.fields[i]); | |
1869 | |
6686 | 1870 mwSize nel = get_number_of_elements (); |
1871 | |
1872 for (mwIndex i = 0; i < nel * nfields; i++) | |
6347 | 1873 { |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1874 mxArray *ptr = val.data[i]; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1875 data[i] = ptr ? ptr->clone () : 0; |
6347 | 1876 } |
5900 | 1877 } |
1878 }; | |
1879 | |
1880 // Matlab-style cell arrays. | |
1881 | |
1882 class mxArray_cell : public mxArray_matlab | |
1883 { | |
1884 public: | |
1885 | |
6686 | 1886 mxArray_cell (mwSize ndims_arg, const mwSize *dims_arg) |
5900 | 1887 : mxArray_matlab (mxCELL_CLASS, ndims_arg, dims_arg), |
1888 data (static_cast<mxArray **> (calloc (get_number_of_elements (), sizeof (mxArray *)))) { } | |
1889 | |
1890 mxArray_cell (const dim_vector& dv) | |
1891 : mxArray_matlab (mxCELL_CLASS, dv), | |
1892 data (static_cast<mxArray **> (calloc (get_number_of_elements (), sizeof (mxArray *)))) { } | |
1893 | |
6686 | 1894 mxArray_cell (mwSize m, mwSize n) |
5900 | 1895 : mxArray_matlab (mxCELL_CLASS, m, n), |
1896 data (static_cast<mxArray **> (calloc (get_number_of_elements (), sizeof (mxArray *)))) { } | |
1897 | |
1898 mxArray_cell *clone (void) const { return new mxArray_cell (*this); } | |
1899 | |
1900 ~mxArray_cell (void) | |
1901 { | |
6686 | 1902 mwSize nel = get_number_of_elements (); |
1903 | |
1904 for (mwIndex i = 0; i < nel; i++) | |
5905 | 1905 delete data[i]; |
5900 | 1906 |
1907 mxFree (data); | |
1908 } | |
1909 | |
6686 | 1910 mxArray *get_cell (mwIndex idx) const |
6187 | 1911 { |
1912 return idx >= 0 && idx < get_number_of_elements () ? data[idx] : 0; | |
1913 } | |
5907 | 1914 |
6686 | 1915 void set_cell (mwIndex idx, mxArray *val); |
5907 | 1916 |
1917 void *get_data (void) const { return data; } | |
1918 | |
1919 void set_data (void *data_arg) { data = static_cast<mxArray **> (data_arg); } | |
1920 | |
1921 protected: | |
1922 | |
5900 | 1923 octave_value as_octave_value (void) const |
1924 { | |
1925 dim_vector dv = dims_to_dim_vector (); | |
1926 | |
1927 Cell c (dv); | |
1928 | |
6686 | 1929 mwSize nel = get_number_of_elements (); |
5900 | 1930 |
1931 octave_value *p = c.fortran_vec (); | |
1932 | |
6686 | 1933 for (mwIndex i = 0; i < nel; i++) |
5907 | 1934 p[i] = mxArray::as_octave_value (data[i]); |
5900 | 1935 |
1936 return c; | |
1937 } | |
1938 | |
1939 private: | |
1940 | |
1941 mxArray **data; | |
1942 | |
1943 mxArray_cell (const mxArray_cell& val) | |
1944 : mxArray_matlab (val), | |
1945 data (static_cast<mxArray **> (malloc (get_number_of_elements () * sizeof (mxArray *)))) | |
1946 { | |
6686 | 1947 mwSize nel = get_number_of_elements (); |
1948 | |
1949 for (mwIndex i = 0; i < nel; i++) | |
6347 | 1950 { |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1951 mxArray *ptr = val.data[i]; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
1952 data[i] = ptr ? ptr->clone () : 0; |
6347 | 1953 } |
5900 | 1954 } |
1955 }; | |
1956 | |
1957 // ------------------------------------------------------------------ | |
1958 | |
1959 mxArray::mxArray (const octave_value& ov) | |
6065 | 1960 : rep (new mxArray_octave_value (ov)), name (0) { } |
5900 | 1961 |
6686 | 1962 mxArray::mxArray (mxClassID id, mwSize ndims, const mwSize *dims, mxComplexity flag) |
6065 | 1963 : rep (new mxArray_number (id, ndims, dims, flag)), name (0) { } |
5900 | 1964 |
1965 mxArray::mxArray (mxClassID id, const dim_vector& dv, mxComplexity flag) | |
6065 | 1966 : rep (new mxArray_number (id, dv, flag)), name (0) { } |
5900 | 1967 |
6686 | 1968 mxArray::mxArray (mxClassID id, mwSize m, mwSize n, mxComplexity flag) |
6065 | 1969 : rep (new mxArray_number (id, m, n, flag)), name (0) { } |
5900 | 1970 |
1971 mxArray::mxArray (mxClassID id, double val) | |
6065 | 1972 : rep (new mxArray_number (id, val)), name (0) { } |
5900 | 1973 |
1974 mxArray::mxArray (mxClassID id, mxLogical val) | |
6065 | 1975 : rep (new mxArray_number (id, val)), name (0) { } |
5900 | 1976 |
1977 mxArray::mxArray (const char *str) | |
6065 | 1978 : rep (new mxArray_number (str)), name (0) { } |
5900 | 1979 |
6686 | 1980 mxArray::mxArray (mwSize m, const char **str) |
6065 | 1981 : rep (new mxArray_number (m, str)), name (0) { } |
5900 | 1982 |
6686 | 1983 mxArray::mxArray (mxClassID id, mwSize m, mwSize n, mwSize nzmax, mxComplexity flag) |
6065 | 1984 : rep (new mxArray_sparse (id, m, n, nzmax, flag)), name (0) { } |
5900 | 1985 |
6686 | 1986 mxArray::mxArray (mwSize ndims, const mwSize *dims, int num_keys, const char **keys) |
6065 | 1987 : rep (new mxArray_struct (ndims, dims, num_keys, keys)), name (0) { } |
5900 | 1988 |
1989 mxArray::mxArray (const dim_vector& dv, int num_keys, const char **keys) | |
6065 | 1990 : rep (new mxArray_struct (dv, num_keys, keys)), name (0) { } |
5900 | 1991 |
6686 | 1992 mxArray::mxArray (mwSize m, mwSize n, int num_keys, const char **keys) |
6065 | 1993 : rep (new mxArray_struct (m, n, num_keys, keys)), name (0) { } |
5900 | 1994 |
6686 | 1995 mxArray::mxArray (mwSize ndims, const mwSize *dims) |
6065 | 1996 : rep (new mxArray_cell (ndims, dims)), name (0) { } |
5900 | 1997 |
1998 mxArray::mxArray (const dim_vector& dv) | |
6065 | 1999 : rep (new mxArray_cell (dv)), name (0) { } |
5900 | 2000 |
6686 | 2001 mxArray::mxArray (mwSize m, mwSize n) |
6065 | 2002 : rep (new mxArray_cell (m, n)), name (0) { } |
5900 | 2003 |
2004 mxArray::~mxArray (void) | |
2005 { | |
2006 mxFree (name); | |
2007 | |
2008 delete rep; | |
2009 } | |
2010 | |
2011 void | |
2012 mxArray::set_name (const char *name_arg) | |
2013 { | |
2014 mxFree (name); | |
2015 name = strsave (name_arg); | |
2016 } | |
2017 | |
5907 | 2018 octave_value |
2019 mxArray::as_octave_value (mxArray *ptr) | |
2020 { | |
2021 return ptr ? ptr->as_octave_value () : octave_value (Matrix ()); | |
2022 } | |
2023 | |
2024 octave_value | |
2025 mxArray::as_octave_value (void) const | |
2026 { | |
2027 return rep->as_octave_value (); | |
2028 } | |
2029 | |
5900 | 2030 void |
2031 mxArray::maybe_mutate (void) const | |
2032 { | |
2033 if (rep->is_octave_value ()) | |
2034 { | |
2035 // The mutate function returns a pointer to a complete new | |
2036 // mxArray object (or 0, if no mutation happened). We just want | |
2037 // to replace the existing rep with the rep from the new object. | |
2038 | |
2039 mxArray *new_val = rep->mutate (); | |
2040 | |
2041 if (new_val) | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2042 { |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2043 delete rep; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2044 rep = new_val->rep; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2045 new_val->rep = 0; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2046 delete new_val; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2047 } |
5900 | 2048 } |
2049 } | |
2050 | |
2051 // ------------------------------------------------------------------ | |
2052 | |
6686 | 2053 // A class to manage calls to MEX functions. Mostly deals with memory |
5900 | 2054 // management. |
5864 | 2055 |
2056 class mex | |
2057 { | |
2058 public: | |
2059 | |
6068 | 2060 mex (octave_mex_function *f) |
2061 : curr_mex_fcn (f), memlist (), arraylist (), fname (0) { } | |
5864 | 2062 |
2063 ~mex (void) | |
2064 { | |
2065 if (! memlist.empty ()) | |
5905 | 2066 error ("mex: %s: cleanup failed", function_name ()); |
5900 | 2067 |
2068 mxFree (fname); | |
5864 | 2069 } |
2070 | |
5900 | 2071 const char *function_name (void) const |
2072 { | |
2073 if (! fname) | |
2074 { | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2075 octave_function *fcn = octave_call_stack::current (); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2076 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2077 if (fcn) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2078 { |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2079 std::string nm = fcn->name (); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2080 fname = mxArray::strsave (nm.c_str ()); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2081 } |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2082 else |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2083 fname = mxArray::strsave ("unknown"); |
5900 | 2084 } |
2085 | |
2086 return fname; | |
2087 } | |
2088 | |
2089 // Free all unmarked pointers obtained from malloc and calloc. | |
2090 static void cleanup (void *ptr) | |
2091 { | |
2092 mex *context = static_cast<mex *> (ptr); | |
2093 | |
5905 | 2094 // We can't use mex::free here because it modifies memlist. |
5900 | 2095 for (std::set<void *>::iterator p = context->memlist.begin (); |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2096 p != context->memlist.end (); p++) |
6601 | 2097 xfree (*p); |
5905 | 2098 |
2099 context->memlist.clear (); | |
2100 | |
2101 // We can't use mex::free_value here because it modifies arraylist. | |
5900 | 2102 for (std::set<mxArray *>::iterator p = context->arraylist.begin (); |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2103 p != context->arraylist.end (); p++) |
5905 | 2104 delete *p; |
2105 | |
2106 context->arraylist.clear (); | |
5900 | 2107 } |
5864 | 2108 |
6071 | 2109 // Allocate memory. |
5900 | 2110 void *malloc_unmarked (size_t n) |
2111 { | |
10411 | 2112 void *ptr = gnulib::malloc (n); |
5900 | 2113 |
2114 if (! ptr) | |
2115 { | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2116 // FIXME -- could use "octave_new_handler();" instead |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2117 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2118 error ("%s: failed to allocate %d bytes of memory", |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2119 function_name (), n); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2120 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2121 abort (); |
5900 | 2122 } |
2123 | |
2124 global_mark (ptr); | |
2125 | |
2126 return ptr; | |
2127 } | |
2128 | |
6071 | 2129 // Allocate memory to be freed on exit. |
5900 | 2130 void *malloc (size_t n) |
2131 { | |
2132 void *ptr = malloc_unmarked (n); | |
2133 | |
2134 mark (ptr); | |
2135 | |
2136 return ptr; | |
2137 } | |
2138 | |
6071 | 2139 // Allocate memory and initialize to 0. |
5900 | 2140 void *calloc_unmarked (size_t n, size_t t) |
2141 { | |
2142 void *ptr = malloc_unmarked (n*t); | |
2143 | |
2144 memset (ptr, 0, n*t); | |
2145 | |
2146 return ptr; | |
2147 } | |
2148 | |
6071 | 2149 // Allocate memory to be freed on exit and initialize to 0. |
5900 | 2150 void *calloc (size_t n, size_t t) |
2151 { | |
2152 void *ptr = calloc_unmarked (n, t); | |
2153 | |
2154 mark (ptr); | |
2155 | |
2156 return ptr; | |
2157 } | |
2158 | |
10225
477d05b0a739
mxRealloc: Allocate new memory on NULL argument
David Grundberg <davidg@cs.umu.se>
parents:
10127
diff
changeset
|
2159 // Reallocate a pointer obtained from malloc or calloc. If the |
477d05b0a739
mxRealloc: Allocate new memory on NULL argument
David Grundberg <davidg@cs.umu.se>
parents:
10127
diff
changeset
|
2160 // pointer is NULL, allocate using malloc. We don't need an |
477d05b0a739
mxRealloc: Allocate new memory on NULL argument
David Grundberg <davidg@cs.umu.se>
parents:
10127
diff
changeset
|
2161 // "unmarked" version of this. |
5900 | 2162 void *realloc (void *ptr, size_t n) |
2163 { | |
10225
477d05b0a739
mxRealloc: Allocate new memory on NULL argument
David Grundberg <davidg@cs.umu.se>
parents:
10127
diff
changeset
|
2164 void *v; |
477d05b0a739
mxRealloc: Allocate new memory on NULL argument
David Grundberg <davidg@cs.umu.se>
parents:
10127
diff
changeset
|
2165 |
477d05b0a739
mxRealloc: Allocate new memory on NULL argument
David Grundberg <davidg@cs.umu.se>
parents:
10127
diff
changeset
|
2166 if (ptr) |
5900 | 2167 { |
10411 | 2168 v = gnulib::realloc (ptr, n); |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2169 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2170 std::set<void *>::iterator p = memlist.find (ptr); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2171 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2172 if (v && p != memlist.end ()) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2173 { |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2174 memlist.erase (p); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2175 memlist.insert (v); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2176 } |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2177 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2178 p = global_memlist.find (ptr); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2179 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2180 if (v && p != global_memlist.end ()) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2181 { |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2182 global_memlist.erase (p); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2183 global_memlist.insert (v); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2184 } |
5900 | 2185 } |
10225
477d05b0a739
mxRealloc: Allocate new memory on NULL argument
David Grundberg <davidg@cs.umu.se>
parents:
10127
diff
changeset
|
2186 else |
477d05b0a739
mxRealloc: Allocate new memory on NULL argument
David Grundberg <davidg@cs.umu.se>
parents:
10127
diff
changeset
|
2187 v = malloc (n); |
5900 | 2188 |
2189 return v; | |
2190 } | |
2191 | |
2192 // Free a pointer obtained from malloc or calloc. | |
2193 void free (void *ptr) | |
2194 { | |
2195 if (ptr) | |
2196 { | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2197 unmark (ptr); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2198 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2199 std::set<void *>::iterator p = global_memlist.find (ptr); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2200 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2201 if (p != global_memlist.end ()) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2202 { |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2203 global_memlist.erase (p); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2204 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2205 xfree (ptr); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2206 } |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2207 else |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2208 { |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2209 p = foreign_memlist.find (ptr); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2210 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2211 if (p != foreign_memlist.end ()) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2212 foreign_memlist.erase (p); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2213 else |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2214 warning ("mxFree: skipping memory not allocated by mxMalloc, mxCalloc, or mxRealloc"); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2215 } |
5900 | 2216 } |
2217 } | |
2218 | |
7172 | 2219 // Mark a pointer to be freed on exit. |
2220 void mark (void *ptr) | |
2221 { | |
2222 #ifdef DEBUG | |
2223 if (memlist.find (ptr) != memlist.end ()) | |
2224 warning ("%s: double registration ignored", function_name ()); | |
2225 #endif | |
2226 | |
2227 memlist.insert (ptr); | |
2228 } | |
2229 | |
2230 // Unmark a pointer to be freed on exit, either because it was | |
2231 // made persistent, or because it was already freed. | |
2232 void unmark (void *ptr) | |
2233 { | |
2234 std::set<void *>::iterator p = memlist.find (ptr); | |
2235 | |
2236 if (p != memlist.end ()) | |
2237 memlist.erase (p); | |
2238 #ifdef DEBUG | |
2239 else | |
2240 warning ("%s: value not marked", function_name ()); | |
2241 #endif | |
2242 } | |
5900 | 2243 |
6065 | 2244 mxArray *mark_array (mxArray *ptr) |
2245 { | |
2246 arraylist.insert (ptr); | |
2247 return ptr; | |
2248 } | |
2249 | |
6071 | 2250 void unmark_array (mxArray *ptr) |
2251 { | |
2252 std::set<mxArray *>::iterator p = arraylist.find (ptr); | |
2253 | |
2254 if (p != arraylist.end ()) | |
2255 arraylist.erase (p); | |
2256 } | |
2257 | |
7179 | 2258 // Mark a pointer as one we allocated. |
2259 void mark_foreign (void *ptr) | |
2260 { | |
2261 #ifdef DEBUG | |
2262 if (foreign_memlist.find (ptr) != foreign_memlist.end ()) | |
2263 warning ("%s: double registration ignored", function_name ()); | |
2264 #endif | |
2265 | |
2266 foreign_memlist.insert (ptr); | |
2267 } | |
2268 | |
2269 // Unmark a pointer as one we allocated. | |
2270 void unmark_foreign (void *ptr) | |
2271 { | |
2272 std::set<void *>::iterator p = foreign_memlist.find (ptr); | |
2273 | |
2274 if (p != foreign_memlist.end ()) | |
2275 foreign_memlist.erase (p); | |
2276 #ifdef DEBUG | |
2277 else | |
2278 warning ("%s: value not marked", function_name ()); | |
2279 #endif | |
2280 | |
2281 } | |
2282 | |
5900 | 2283 // Make a new array value and initialize from an octave value; it will be |
2284 // freed on exit unless marked as persistent. | |
2285 mxArray *make_value (const octave_value& ov) | |
2286 { | |
6065 | 2287 return mark_array (new mxArray (ov)); |
5900 | 2288 } |
2289 | |
2290 // Free an array and its contents. | |
6065 | 2291 bool free_value (mxArray *ptr) |
5900 | 2292 { |
6065 | 2293 bool inlist = false; |
2294 | |
5905 | 2295 std::set<mxArray *>::iterator p = arraylist.find (ptr); |
2296 | |
2297 if (p != arraylist.end ()) | |
2298 { | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2299 inlist = true; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2300 arraylist.erase (p); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2301 delete ptr; |
5905 | 2302 } |
2303 #ifdef DEBUG | |
2304 else | |
2305 warning ("mex::free_value: skipping memory not allocated by mex::make_value"); | |
2306 #endif | |
6065 | 2307 |
2308 return inlist; | |
5900 | 2309 } |
2310 | |
6068 | 2311 octave_mex_function *current_mex_function (void) const |
2312 { | |
2313 return curr_mex_fcn; | |
2314 } | |
2315 | |
5900 | 2316 // 1 if error should be returned to MEX file, 0 if abort. |
5864 | 2317 int trap_feval_error; |
2318 | |
5900 | 2319 // longjmp return point if mexErrMsgTxt or error. |
5864 | 2320 jmp_buf jump; |
2321 | |
5900 | 2322 // Trigger a long jump back to the mex calling function. |
5864 | 2323 void abort (void) { longjmp (jump, 1); } |
2324 | |
2325 private: | |
2326 | |
6068 | 2327 // Pointer to the mex function that corresponds to this mex context. |
2328 octave_mex_function *curr_mex_fcn; | |
2329 | |
5900 | 2330 // List of memory resources that need to be freed upon exit. |
2331 std::set<void *> memlist; | |
2332 | |
7179 | 2333 // List of mxArray objects that need to be freed upon exit. |
5900 | 2334 std::set<mxArray *> arraylist; |
2335 | |
7179 | 2336 // List of memory resources we know about, but that were allocated |
2337 // elsewhere. | |
2338 std::set<void *> foreign_memlist; | |
2339 | |
5900 | 2340 // The name of the currently executing function. |
2341 mutable char *fname; | |
2342 | |
2343 // List of memory resources we allocated. | |
2344 static std::set<void *> global_memlist; | |
2345 | |
2346 // Mark a pointer as one we allocated. | |
5905 | 2347 void global_mark (void *ptr) |
5900 | 2348 { |
2349 #ifdef DEBUG | |
5905 | 2350 if (global_memlist.find (ptr) != global_memlist.end ()) |
2351 warning ("%s: double registration ignored", function_name ()); | |
5864 | 2352 #endif |
5900 | 2353 |
5905 | 2354 global_memlist.insert (ptr); |
5864 | 2355 } |
2356 | |
5900 | 2357 // Unmark a pointer as one we allocated. |
5905 | 2358 void global_unmark (void *ptr) |
5864 | 2359 { |
5905 | 2360 std::set<void *>::iterator p = global_memlist.find (ptr); |
2361 | |
2362 if (p != global_memlist.end ()) | |
2363 global_memlist.erase (p); | |
5900 | 2364 #ifdef DEBUG |
5905 | 2365 else |
2366 warning ("%s: value not marked", function_name ()); | |
5900 | 2367 #endif |
2368 | |
5864 | 2369 } |
2370 }; | |
2371 | |
5900 | 2372 // List of memory resources we allocated. |
2373 std::set<void *> mex::global_memlist; | |
2374 | |
2375 // Current context. | |
2376 mex *mex_context = 0; | |
2377 | |
2378 void * | |
2379 mxArray::malloc (size_t n) | |
2380 { | |
10411 | 2381 return mex_context ? mex_context->malloc_unmarked (n) : gnulib::malloc (n); |
5900 | 2382 } |
2383 | |
2384 void * | |
2385 mxArray::calloc (size_t n, size_t t) | |
2386 { | |
6065 | 2387 return mex_context ? mex_context->calloc_unmarked (n, t) : ::calloc (n, t); |
5900 | 2388 } |
2389 | |
7179 | 2390 static inline void * |
2391 maybe_mark_foreign (void *ptr) | |
2392 { | |
2393 if (mex_context) | |
2394 mex_context->mark_foreign (ptr); | |
2395 | |
2396 return ptr; | |
2397 } | |
2398 | |
6071 | 2399 static inline mxArray * |
2400 maybe_unmark_array (mxArray *ptr) | |
2401 { | |
2402 if (mex_context) | |
2403 mex_context->unmark_array (ptr); | |
2404 | |
2405 return ptr; | |
2406 } | |
2407 | |
7172 | 2408 static inline void * |
2409 maybe_unmark (void *ptr) | |
2410 { | |
2411 if (mex_context) | |
2412 mex_context->unmark (ptr); | |
2413 | |
2414 return ptr; | |
2415 } | |
2416 | |
6071 | 2417 void |
6686 | 2418 mxArray_struct::set_field_by_number (mwIndex index, int key_num, mxArray *val) |
6071 | 2419 { |
6187 | 2420 if (key_num >= 0 && key_num < nfields) |
2421 data[nfields * index + key_num] = maybe_unmark_array (val); | |
6071 | 2422 } |
2423 | |
2424 void | |
6686 | 2425 mxArray_cell::set_cell (mwIndex idx, mxArray *val) |
6071 | 2426 { |
6187 | 2427 if (idx >= 0 && idx < get_number_of_elements ()) |
2428 data[idx] = maybe_unmark_array (val); | |
6071 | 2429 } |
2430 | |
5900 | 2431 // ------------------------------------------------------------------ |
2432 | |
2433 // C interface to mxArray objects: | |
2434 | |
2435 // Floating point predicates. | |
2436 | |
2437 int | |
2438 mxIsFinite (const double v) | |
2439 { | |
2440 return lo_ieee_finite (v) != 0; | |
2441 } | |
2442 | |
2443 int | |
2444 mxIsInf (const double v) | |
2445 { | |
2446 return lo_ieee_isinf (v) != 0; | |
2447 } | |
2448 | |
2449 int | |
2450 mxIsNaN (const double v) | |
2451 { | |
2452 return lo_ieee_isnan (v) != 0; | |
2453 } | |
2454 | |
2455 double | |
2456 mxGetEps (void) | |
2457 { | |
2458 return DBL_EPSILON; | |
2459 } | |
2460 | |
2461 double | |
2462 mxGetInf (void) | |
2463 { | |
2464 return lo_ieee_inf_value (); | |
2465 } | |
2466 | |
2467 double | |
2468 mxGetNaN (void) | |
2469 { | |
2470 return lo_ieee_nan_value (); | |
2471 } | |
2472 | |
2473 // Memory management. | |
2474 void * | |
2475 mxCalloc (size_t n, size_t size) | |
2476 { | |
2477 return mex_context ? mex_context->calloc (n, size) : calloc (n, size); | |
2478 } | |
2479 | |
2480 void * | |
2481 mxMalloc (size_t n) | |
2482 { | |
10411 | 2483 return mex_context ? mex_context->malloc (n) : gnulib::malloc (n); |
5900 | 2484 } |
2485 | |
2486 void * | |
2487 mxRealloc (void *ptr, size_t size) | |
2488 { | |
10411 | 2489 return mex_context ? mex_context->realloc (ptr, size) : gnulib::realloc (ptr, size); |
5900 | 2490 } |
2491 | |
2492 void | |
2493 mxFree (void *ptr) | |
5864 | 2494 { |
5900 | 2495 if (mex_context) |
2496 mex_context->free (ptr); | |
5864 | 2497 else |
6071 | 2498 xfree (ptr); |
5900 | 2499 } |
6065 | 2500 |
2501 static inline mxArray * | |
2502 maybe_mark_array (mxArray *ptr) | |
2503 { | |
2504 return mex_context ? mex_context->mark_array (ptr) : ptr; | |
2505 } | |
5900 | 2506 |
2507 // Constructors. | |
2508 mxArray * | |
6686 | 2509 mxCreateCellArray (mwSize ndims, const mwSize *dims) |
5900 | 2510 { |
6065 | 2511 return maybe_mark_array (new mxArray (ndims, dims)); |
5900 | 2512 } |
2513 | |
2514 mxArray * | |
6686 | 2515 mxCreateCellMatrix (mwSize m, mwSize n) |
5900 | 2516 { |
6065 | 2517 return maybe_mark_array (new mxArray (m, n)); |
5900 | 2518 } |
2519 | |
2520 mxArray * | |
6686 | 2521 mxCreateCharArray (mwSize ndims, const mwSize *dims) |
5900 | 2522 { |
6065 | 2523 return maybe_mark_array (new mxArray (mxCHAR_CLASS, ndims, dims)); |
5864 | 2524 } |
2525 | |
5900 | 2526 mxArray * |
6686 | 2527 mxCreateCharMatrixFromStrings (mwSize m, const char **str) |
5900 | 2528 { |
6065 | 2529 return maybe_mark_array (new mxArray (m, str)); |
5900 | 2530 } |
2531 | |
2532 mxArray * | |
6686 | 2533 mxCreateDoubleMatrix (mwSize m, mwSize n, mxComplexity flag) |
5900 | 2534 { |
6065 | 2535 return maybe_mark_array (new mxArray (mxDOUBLE_CLASS, m, n, flag)); |
5900 | 2536 } |
2537 | |
2538 mxArray * | |
2539 mxCreateDoubleScalar (double val) | |
2540 { | |
6065 | 2541 return maybe_mark_array (new mxArray (mxDOUBLE_CLASS, val)); |
5900 | 2542 } |
2543 | |
2544 mxArray * | |
6686 | 2545 mxCreateLogicalArray (mwSize ndims, const mwSize *dims) |
5864 | 2546 { |
6065 | 2547 return maybe_mark_array (new mxArray (mxLOGICAL_CLASS, ndims, dims)); |
5900 | 2548 } |
2549 | |
2550 mxArray * | |
6686 | 2551 mxCreateLogicalMatrix (mwSize m, mwSize n) |
5900 | 2552 { |
6065 | 2553 return maybe_mark_array (new mxArray (mxLOGICAL_CLASS, m, n)); |
5900 | 2554 } |
2555 | |
2556 mxArray * | |
7577
ba8fcc115fee
mex.cc: arg to mxCreateLogicalScalar is now mxLogical
John W. Eaton <jwe@octave.org>
parents:
7357
diff
changeset
|
2557 mxCreateLogicalScalar (mxLogical val) |
5900 | 2558 { |
6065 | 2559 return maybe_mark_array (new mxArray (mxLOGICAL_CLASS, val)); |
5900 | 2560 } |
2561 | |
2562 mxArray * | |
6686 | 2563 mxCreateNumericArray (mwSize ndims, const mwSize *dims, mxClassID class_id, |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2564 mxComplexity flag) |
5900 | 2565 { |
6065 | 2566 return maybe_mark_array (new mxArray (class_id, ndims, dims, flag)); |
5864 | 2567 } |
2568 | |
5900 | 2569 mxArray * |
6686 | 2570 mxCreateNumericMatrix (mwSize m, mwSize n, mxClassID class_id, mxComplexity flag) |
5900 | 2571 { |
6065 | 2572 return maybe_mark_array (new mxArray (class_id, m, n, flag)); |
5900 | 2573 } |
2574 | |
2575 mxArray * | |
6686 | 2576 mxCreateSparse (mwSize m, mwSize n, mwSize nzmax, mxComplexity flag) |
5900 | 2577 { |
6065 | 2578 return maybe_mark_array (new mxArray (mxDOUBLE_CLASS, m, n, nzmax, flag)); |
5900 | 2579 } |
2580 | |
2581 mxArray * | |
6686 | 2582 mxCreateSparseLogicalMatrix (mwSize m, mwSize n, mwSize nzmax) |
5900 | 2583 { |
6065 | 2584 return maybe_mark_array (new mxArray (mxLOGICAL_CLASS, m, n, nzmax)); |
5900 | 2585 } |
2586 | |
2587 mxArray * | |
2588 mxCreateString (const char *str) | |
2589 { | |
6065 | 2590 return maybe_mark_array (new mxArray (str)); |
5900 | 2591 } |
2592 | |
2593 mxArray * | |
6787 | 2594 mxCreateStructArray (mwSize ndims, const mwSize *dims, int num_keys, const char **keys) |
5900 | 2595 { |
6065 | 2596 return maybe_mark_array (new mxArray (ndims, dims, num_keys, keys)); |
5900 | 2597 } |
5864 | 2598 |
2599 mxArray * | |
6686 | 2600 mxCreateStructMatrix (mwSize m, mwSize n, int num_keys, const char **keys) |
5900 | 2601 { |
6065 | 2602 return maybe_mark_array (new mxArray (m, n, num_keys, keys)); |
5900 | 2603 } |
2604 | |
2605 // Copy constructor. | |
2606 mxArray * | |
2607 mxDuplicateArray (const mxArray *ptr) | |
2608 { | |
6065 | 2609 return maybe_mark_array (ptr->clone ()); |
5900 | 2610 } |
2611 | |
2612 // Destructor. | |
2613 void | |
2614 mxDestroyArray (mxArray *ptr) | |
2615 { | |
6065 | 2616 if (! (mex_context && mex_context->free_value (ptr))) |
2617 delete ptr; | |
5900 | 2618 } |
2619 | |
2620 // Type Predicates. | |
2621 int | |
2622 mxIsCell (const mxArray *ptr) | |
2623 { | |
2624 return ptr->is_cell (); | |
2625 } | |
2626 | |
2627 int | |
2628 mxIsChar (const mxArray *ptr) | |
2629 { | |
2630 return ptr->is_char (); | |
2631 } | |
2632 | |
2633 int | |
2634 mxIsClass (const mxArray *ptr, const char *name) | |
2635 { | |
2636 return ptr->is_class (name); | |
2637 } | |
2638 | |
2639 int | |
2640 mxIsComplex (const mxArray *ptr) | |
2641 { | |
2642 return ptr->is_complex (); | |
2643 } | |
2644 | |
2645 int | |
2646 mxIsDouble (const mxArray *ptr) | |
2647 { | |
2648 return ptr->is_double (); | |
2649 } | |
2650 | |
2651 int | |
2652 mxIsInt16 (const mxArray *ptr) | |
2653 { | |
2654 return ptr->is_int16 (); | |
2655 } | |
2656 | |
2657 int | |
2658 mxIsInt32 (const mxArray *ptr) | |
2659 { | |
2660 return ptr->is_int32 (); | |
2661 } | |
2662 | |
2663 int | |
2664 mxIsInt64 (const mxArray *ptr) | |
2665 { | |
2666 return ptr->is_int64 (); | |
2667 } | |
2668 | |
2669 int | |
2670 mxIsInt8 (const mxArray *ptr) | |
2671 { | |
2672 return ptr->is_int8 (); | |
2673 } | |
2674 | |
2675 int | |
2676 mxIsLogical (const mxArray *ptr) | |
2677 { | |
2678 return ptr->is_logical (); | |
2679 } | |
2680 | |
2681 int | |
2682 mxIsNumeric (const mxArray *ptr) | |
2683 { | |
2684 return ptr->is_numeric (); | |
2685 } | |
2686 | |
2687 int | |
2688 mxIsSingle (const mxArray *ptr) | |
2689 { | |
2690 return ptr->is_single (); | |
2691 } | |
2692 | |
2693 int | |
2694 mxIsSparse (const mxArray *ptr) | |
2695 { | |
2696 return ptr->is_sparse (); | |
2697 } | |
2698 | |
2699 int | |
2700 mxIsStruct (const mxArray *ptr) | |
2701 { | |
2702 return ptr->is_struct (); | |
2703 } | |
2704 | |
2705 int | |
2706 mxIsUint16 (const mxArray *ptr) | |
2707 { | |
2708 return ptr->is_uint16 (); | |
2709 } | |
2710 | |
2711 int | |
2712 mxIsUint32 (const mxArray *ptr) | |
2713 { | |
2714 return ptr->is_uint32 (); | |
2715 } | |
2716 | |
2717 int | |
2718 mxIsUint64 (const mxArray *ptr) | |
2719 { | |
2720 return ptr->is_uint64 (); | |
2721 } | |
2722 | |
2723 int | |
2724 mxIsUint8 (const mxArray *ptr) | |
2725 { | |
2726 return ptr->is_uint8 (); | |
2727 } | |
2728 | |
2729 // Odd type+size predicate. | |
2730 int | |
2731 mxIsLogicalScalar (const mxArray *ptr) | |
2732 { | |
2733 return ptr->is_logical_scalar (); | |
2734 } | |
2735 | |
2736 // Odd type+size+value predicate. | |
2737 int | |
2738 mxIsLogicalScalarTrue (const mxArray *ptr) | |
2739 { | |
2740 return ptr->is_logical_scalar_true (); | |
2741 } | |
2742 | |
2743 // Size predicate. | |
2744 int | |
2745 mxIsEmpty (const mxArray *ptr) | |
2746 { | |
2747 return ptr->is_empty (); | |
2748 } | |
2749 | |
2750 // Just plain odd thing to ask of a value. | |
2751 int | |
2752 mxIsFromGlobalWS (const mxArray */*ptr*/) | |
2753 { | |
2754 // FIXME | |
2755 abort (); | |
2756 return 0; | |
2757 } | |
2758 | |
2759 // Dimension extractors. | |
6686 | 2760 size_t |
5900 | 2761 mxGetM (const mxArray *ptr) |
2762 { | |
2763 return ptr->get_m (); | |
2764 } | |
2765 | |
6686 | 2766 size_t |
5900 | 2767 mxGetN (const mxArray *ptr) |
2768 { | |
2769 return ptr->get_n (); | |
2770 } | |
2771 | |
6686 | 2772 mwSize * |
5900 | 2773 mxGetDimensions (const mxArray *ptr) |
5864 | 2774 { |
5900 | 2775 return ptr->get_dimensions (); |
2776 } | |
2777 | |
6686 | 2778 mwSize |
5900 | 2779 mxGetNumberOfDimensions (const mxArray *ptr) |
2780 { | |
2781 return ptr->get_number_of_dimensions (); | |
2782 } | |
2783 | |
6686 | 2784 size_t |
5900 | 2785 mxGetNumberOfElements (const mxArray *ptr) |
2786 { | |
2787 return ptr->get_number_of_elements (); | |
2788 } | |
2789 | |
2790 // Dimension setters. | |
2791 void | |
6686 | 2792 mxSetM (mxArray *ptr, mwSize m) |
5900 | 2793 { |
2794 ptr->set_m (m); | |
2795 } | |
2796 | |
2797 void | |
6686 | 2798 mxSetN (mxArray *ptr, mwSize n) |
5900 | 2799 { |
2800 ptr->set_n (n); | |
2801 } | |
2802 | |
2803 void | |
10126
8687ce1c56da
Change signature of mxSetDimensions.
David Grundberg <davidg@cs.umu.se>
parents:
10066
diff
changeset
|
2804 mxSetDimensions (mxArray *ptr, const mwSize *dims, mwSize ndims) |
5900 | 2805 { |
10126
8687ce1c56da
Change signature of mxSetDimensions.
David Grundberg <davidg@cs.umu.se>
parents:
10066
diff
changeset
|
2806 ptr->set_dimensions (static_cast<mwSize *> ( |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2807 maybe_unmark (const_cast<mwSize *> (dims))), |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
2808 ndims); |
5900 | 2809 } |
2810 | |
2811 // Data extractors. | |
2812 double * | |
2813 mxGetPr (const mxArray *ptr) | |
2814 { | |
2815 return static_cast<double *> (ptr->get_data ()); | |
2816 } | |
2817 | |
2818 double * | |
2819 mxGetPi (const mxArray *ptr) | |
2820 { | |
2821 return static_cast<double *> (ptr->get_imag_data ()); | |
2822 } | |
2823 | |
2824 double | |
2825 mxGetScalar (const mxArray *ptr) | |
2826 { | |
6332 | 2827 return ptr->get_scalar (); |
5900 | 2828 } |
2829 | |
2830 mxChar * | |
2831 mxGetChars (const mxArray *ptr) | |
2832 { | |
2833 return static_cast<mxChar *> (ptr->get_data ()); | |
2834 } | |
2835 | |
2836 mxLogical * | |
2837 mxGetLogicals (const mxArray *ptr) | |
2838 { | |
2839 return static_cast<mxLogical *> (ptr->get_data ()); | |
2840 } | |
2841 | |
2842 void * | |
2843 mxGetData (const mxArray *ptr) | |
2844 { | |
2845 return ptr->get_data (); | |
2846 } | |
2847 | |
2848 void * | |
2849 mxGetImagData (const mxArray *ptr) | |
2850 { | |
2851 return ptr->get_imag_data (); | |
2852 } | |
2853 | |
2854 // Data setters. | |
2855 void | |
2856 mxSetPr (mxArray *ptr, double *pr) | |
2857 { | |
7172 | 2858 ptr->set_data (maybe_unmark (pr)); |
5900 | 2859 } |
2860 | |
2861 void | |
2862 mxSetPi (mxArray *ptr, double *pi) | |
2863 { | |
7172 | 2864 ptr->set_imag_data (maybe_unmark (pi)); |
5864 | 2865 } |
2866 | |
5900 | 2867 void |
2868 mxSetData (mxArray *ptr, void *pr) | |
2869 { | |
7172 | 2870 ptr->set_data (maybe_unmark (pr)); |
5900 | 2871 } |
2872 | |
2873 void | |
2874 mxSetImagData (mxArray *ptr, void *pi) | |
2875 { | |
7172 | 2876 ptr->set_imag_data (maybe_unmark (pi)); |
5900 | 2877 } |
2878 | |
2879 // Classes. | |
2880 mxClassID | |
2881 mxGetClassID (const mxArray *ptr) | |
2882 { | |
2883 return ptr->get_class_id (); | |
2884 } | |
2885 | |
2886 const char * | |
2887 mxGetClassName (const mxArray *ptr) | |
2888 { | |
2889 return ptr->get_class_name (); | |
2890 } | |
2891 | |
2892 void | |
2893 mxSetClassName (mxArray *ptr, const char *name) | |
2894 { | |
2895 ptr->set_class_name (name); | |
2896 } | |
2897 | |
2898 // Cell support. | |
2899 mxArray * | |
6686 | 2900 mxGetCell (const mxArray *ptr, mwIndex idx) |
5900 | 2901 { |
2902 return ptr->get_cell (idx); | |
2903 } | |
2904 | |
2905 void | |
6686 | 2906 mxSetCell (mxArray *ptr, mwIndex idx, mxArray *val) |
5900 | 2907 { |
2908 ptr->set_cell (idx, val); | |
2909 } | |
2910 | |
2911 // Sparse support. | |
6686 | 2912 mwIndex * |
5900 | 2913 mxGetIr (const mxArray *ptr) |
2914 { | |
2915 return ptr->get_ir (); | |
2916 } | |
2917 | |
6686 | 2918 mwIndex * |
5900 | 2919 mxGetJc (const mxArray *ptr) |
2920 { | |
2921 return ptr->get_jc (); | |
2922 } | |
2923 | |
6686 | 2924 mwSize |
5900 | 2925 mxGetNzmax (const mxArray *ptr) |
2926 { | |
2927 return ptr->get_nzmax (); | |
2928 } | |
2929 | |
2930 void | |
6686 | 2931 mxSetIr (mxArray *ptr, mwIndex *ir) |
5900 | 2932 { |
7172 | 2933 ptr->set_ir (static_cast <mwIndex *> (maybe_unmark (ir))); |
5900 | 2934 } |
2935 | |
2936 void | |
6686 | 2937 mxSetJc (mxArray *ptr, mwIndex *jc) |
5900 | 2938 { |
7172 | 2939 ptr->set_jc (static_cast<mwIndex *> (maybe_unmark (jc))); |
5900 | 2940 } |
2941 | |
2942 void | |
6686 | 2943 mxSetNzmax (mxArray *ptr, mwSize nzmax) |
5900 | 2944 { |
2945 ptr->set_nzmax (nzmax); | |
2946 } | |
2947 | |
2948 // Structure support. | |
2949 int | |
2950 mxAddField (mxArray *ptr, const char *key) | |
2951 { | |
2952 return ptr->add_field (key); | |
2953 } | |
2954 | |
2955 void | |
2956 mxRemoveField (mxArray *ptr, int key_num) | |
2957 { | |
2958 ptr->remove_field (key_num); | |
2959 } | |
5864 | 2960 |
2961 mxArray * | |
6686 | 2962 mxGetField (const mxArray *ptr, mwIndex index, const char *key) |
5900 | 2963 { |
2964 int key_num = mxGetFieldNumber (ptr, key); | |
2965 return mxGetFieldByNumber (ptr, index, key_num); | |
2966 } | |
2967 | |
2968 mxArray * | |
6686 | 2969 mxGetFieldByNumber (const mxArray *ptr, mwIndex index, int key_num) |
5864 | 2970 { |
5900 | 2971 return ptr->get_field_by_number (index, key_num); |
5864 | 2972 } |
2973 | |
5900 | 2974 void |
6686 | 2975 mxSetField (mxArray *ptr, mwIndex index, const char *key, mxArray *val) |
5900 | 2976 { |
2977 int key_num = mxGetFieldNumber (ptr, key); | |
2978 mxSetFieldByNumber (ptr, index, key_num, val); | |
2979 } | |
5864 | 2980 |
2981 void | |
6686 | 2982 mxSetFieldByNumber (mxArray *ptr, mwIndex index, int key_num, mxArray *val) |
5864 | 2983 { |
5900 | 2984 ptr->set_field_by_number (index, key_num, val); |
2985 } | |
2986 | |
2987 int | |
2988 mxGetNumberOfFields (const mxArray *ptr) | |
2989 { | |
2990 return ptr->get_number_of_fields (); | |
5864 | 2991 } |
2992 | |
5900 | 2993 const char * |
2994 mxGetFieldNameByNumber (const mxArray *ptr, int key_num) | |
5864 | 2995 { |
5900 | 2996 return ptr->get_field_name_by_number (key_num); |
2997 } | |
2998 | |
2999 int | |
3000 mxGetFieldNumber (const mxArray *ptr, const char *key) | |
3001 { | |
3002 return ptr->get_field_number (key); | |
5864 | 3003 } |
3004 | |
5900 | 3005 int |
6686 | 3006 mxGetString (const mxArray *ptr, char *buf, mwSize buflen) |
5900 | 3007 { |
3008 return ptr->get_string (buf, buflen); | |
3009 } | |
3010 | |
3011 char * | |
3012 mxArrayToString (const mxArray *ptr) | |
5864 | 3013 { |
5900 | 3014 return ptr->array_to_string (); |
3015 } | |
3016 | |
6686 | 3017 mwIndex |
3018 mxCalcSingleSubscript (const mxArray *ptr, mwSize nsubs, mwIndex *subs) | |
5900 | 3019 { |
3020 return ptr->calc_single_subscript (nsubs, subs); | |
5864 | 3021 } |
5900 | 3022 |
6686 | 3023 size_t |
5900 | 3024 mxGetElementSize (const mxArray *ptr) |
3025 { | |
3026 return ptr->get_element_size (); | |
3027 } | |
3028 | |
3029 // ------------------------------------------------------------------ | |
5864 | 3030 |
3031 typedef void (*cmex_fptr) (int nlhs, mxArray **plhs, int nrhs, mxArray **prhs); | |
3032 typedef F77_RET_T (*fmex_fptr) (int& nlhs, mxArray **plhs, int& nrhs, mxArray **prhs); | |
3033 | |
3034 octave_value_list | |
6068 | 3035 call_mex (bool have_fmex, void *f, const octave_value_list& args, |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
3036 int nargout_arg, octave_mex_function *curr_mex_fcn) |
5864 | 3037 { |
5900 | 3038 // Use at least 1 for nargout since even for zero specified args, |
3039 // still want to be able to return an ans. | |
5864 | 3040 |
8806 | 3041 volatile int nargout = nargout_arg; |
3042 | |
5864 | 3043 int nargin = args.length (); |
5900 | 3044 OCTAVE_LOCAL_BUFFER (mxArray *, argin, nargin); |
5864 | 3045 for (int i = 0; i < nargin; i++) |
3046 argin[i] = 0; | |
3047 | |
3048 int nout = nargout == 0 ? 1 : nargout; | |
5900 | 3049 OCTAVE_LOCAL_BUFFER (mxArray *, argout, nout); |
5864 | 3050 for (int i = 0; i < nout; i++) |
3051 argout[i] = 0; | |
3052 | |
10066
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
3053 unwind_protect_safe frame; |
5905 | 3054 |
3055 // Save old mex pointer. | |
10066
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
3056 frame.protect_var (mex_context); |
5905 | 3057 |
6068 | 3058 mex context (curr_mex_fcn); |
5900 | 3059 |
10066
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
3060 frame.add (mex::cleanup, static_cast<void *> (&context)); |
5864 | 3061 |
3062 for (int i = 0; i < nargin; i++) | |
3063 argin[i] = context.make_value (args(i)); | |
3064 | |
3065 if (setjmp (context.jump) == 0) | |
3066 { | |
5900 | 3067 mex_context = &context; |
5864 | 3068 |
6068 | 3069 if (have_fmex) |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
3070 { |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
3071 fmex_fptr fcn = FCN_PTR_CAST (fmex_fptr, f); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
3072 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
3073 int tmp_nargout = nargout; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
3074 int tmp_nargin = nargin; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
3075 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
3076 fcn (tmp_nargout, argout, tmp_nargin, argin); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
3077 } |
5864 | 3078 else |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
3079 { |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
3080 cmex_fptr fcn = FCN_PTR_CAST (cmex_fptr, f); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
3081 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
3082 fcn (nargout, argout, nargin, argin); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
3083 } |
5864 | 3084 } |
3085 | |
3086 // Convert returned array entries back into octave values. | |
3087 | |
3088 octave_value_list retval; | |
3089 | |
3090 if (! error_state) | |
3091 { | |
3092 if (nargout == 0 && argout[0]) | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
3093 { |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
3094 // We have something for ans. |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
3095 nargout = 1; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
3096 } |
5900 | 3097 |
3098 retval.resize (nargout); | |
3099 | |
3100 for (int i = 0; i < nargout; i++) | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
3101 retval(i) = mxArray::as_octave_value (argout[i]); |
5864 | 3102 } |
3103 | |
3104 // Clean up mex resources. | |
10066
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
3105 frame.run (); |
5864 | 3106 |
3107 return retval; | |
3108 } | |
3109 | |
3110 // C interface to mex functions: | |
3111 | |
3112 const char * | |
3113 mexFunctionName (void) | |
3114 { | |
5900 | 3115 return mex_context ? mex_context->function_name () : "unknown"; |
3116 } | |
3117 | |
3118 int | |
3119 mexCallMATLAB (int nargout, mxArray *argout[], int nargin, mxArray *argin[], | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
3120 const char *fname) |
5900 | 3121 { |
3122 octave_value_list args; | |
3123 | |
3124 // FIXME -- do we need unwind protect to clean up args? Off hand, I | |
3125 // would say that this problem is endemic to Octave and we will | |
3126 // continue to have memory leaks after Ctrl-C until proper exception | |
3127 // handling is implemented. longjmp() only clears the stack, so any | |
3128 // class which allocates data on the heap is going to leak. | |
3129 | |
3130 args.resize (nargin); | |
3131 | |
3132 for (int i = 0; i < nargin; i++) | |
5907 | 3133 args(i) = mxArray::as_octave_value (argin[i]); |
5900 | 3134 |
3135 octave_value_list retval = feval (fname, args, nargout); | |
3136 | |
3137 if (error_state && mex_context->trap_feval_error == 0) | |
5864 | 3138 { |
5900 | 3139 // FIXME -- is this the correct way to clean up? abort() is |
3140 // going to trigger a long jump, so the normal class destructors | |
3141 // will not be called. Hopefully this will reduce things to a | |
3142 // tiny leak. Maybe create a new octave memory tracer type | |
3143 // which prints a friendly message every time it is | |
3144 // created/copied/deleted to check this. | |
3145 | |
3146 args.resize (0); | |
3147 retval.resize (0); | |
3148 mex_context->abort (); | |
3149 } | |
3150 | |
3151 int num_to_copy = retval.length (); | |
3152 | |
3153 if (nargout < retval.length ()) | |
3154 num_to_copy = nargout; | |
3155 | |
3156 for (int i = 0; i < num_to_copy; i++) | |
3157 { | |
3158 // FIXME -- it would be nice to avoid copying the value here, | |
3159 // but there is no way to steal memory from a matrix, never mind | |
3160 // that matrix memory is allocated by new[] and mxArray memory | |
3161 // is allocated by malloc(). | |
3162 argout[i] = mex_context->make_value (retval (i)); | |
3163 } | |
3164 | |
3165 while (num_to_copy < nargout) | |
3166 argout[num_to_copy++] = 0; | |
3167 | |
3168 if (error_state) | |
3169 { | |
3170 error_state = 0; | |
3171 return 1; | |
5864 | 3172 } |
3173 else | |
5900 | 3174 return 0; |
3175 } | |
3176 | |
3177 void | |
3178 mexSetTrapFlag (int flag) | |
3179 { | |
3180 if (mex_context) | |
3181 mex_context->trap_feval_error = flag; | |
3182 } | |
3183 | |
3184 int | |
3185 mexEvalString (const char *s) | |
3186 { | |
3187 int retval = 0; | |
3188 | |
3189 int parse_status; | |
3190 | |
3191 octave_value_list ret; | |
3192 | |
3193 ret = eval_string (s, false, parse_status, 0); | |
3194 | |
3195 if (parse_status || error_state) | |
3196 { | |
3197 error_state = 0; | |
3198 | |
3199 retval = 1; | |
3200 } | |
5864 | 3201 |
3202 return retval; | |
3203 } | |
3204 | |
3205 void | |
3206 mexErrMsgTxt (const char *s) | |
3207 { | |
3208 if (s && strlen (s) > 0) | |
5879 | 3209 error ("%s: %s", mexFunctionName (), s); |
5864 | 3210 else |
3211 // Just set the error state; don't print msg. | |
3212 error (""); | |
3213 | |
5900 | 3214 mex_context->abort (); |
5864 | 3215 } |
3216 | |
5879 | 3217 void |
6338 | 3218 mexErrMsgIdAndTxt (const char *id, const char *fmt, ...) |
5879 | 3219 { |
6338 | 3220 if (fmt && strlen (fmt) > 0) |
3221 { | |
3222 const char *fname = mexFunctionName (); | |
3223 size_t len = strlen (fname) + 2 + strlen (fmt) + 1; | |
3224 OCTAVE_LOCAL_BUFFER (char, tmpfmt, len); | |
3225 sprintf (tmpfmt, "%s: %s", fname, fmt); | |
3226 va_list args; | |
3227 va_start (args, fmt); | |
3228 verror_with_id (id, tmpfmt, args); | |
3229 va_end (args); | |
3230 } | |
5879 | 3231 else |
3232 // Just set the error state; don't print msg. | |
3233 error (""); | |
3234 | |
5900 | 3235 mex_context->abort (); |
5879 | 3236 } |
3237 | |
3238 void | |
3239 mexWarnMsgTxt (const char *s) | |
3240 { | |
3241 warning ("%s", s); | |
3242 } | |
3243 | |
3244 void | |
6338 | 3245 mexWarnMsgIdAndTxt (const char *id, const char *fmt, ...) |
5879 | 3246 { |
6338 | 3247 // FIXME -- is this right? What does Matlab do if fmt is NULL or |
3248 // an empty string? | |
3249 | |
3250 if (fmt && strlen (fmt) > 0) | |
3251 { | |
3252 const char *fname = mexFunctionName (); | |
3253 size_t len = strlen (fname) + 2 + strlen (fmt) + 1; | |
3254 OCTAVE_LOCAL_BUFFER (char, tmpfmt, len); | |
3255 sprintf (tmpfmt, "%s: %s", fname, fmt); | |
3256 va_list args; | |
3257 va_start (args, fmt); | |
3258 vwarning_with_id (id, tmpfmt, args); | |
3259 va_end (args); | |
3260 } | |
5879 | 3261 } |
5864 | 3262 |
10127
f21fdff5c906
Change signature of mexPrintf.
David Grundberg <davidg@cs.umu.se>
parents:
10126
diff
changeset
|
3263 int |
5864 | 3264 mexPrintf (const char *fmt, ...) |
3265 { | |
10127
f21fdff5c906
Change signature of mexPrintf.
David Grundberg <davidg@cs.umu.se>
parents:
10126
diff
changeset
|
3266 int retval; |
5864 | 3267 va_list args; |
3268 va_start (args, fmt); | |
10127
f21fdff5c906
Change signature of mexPrintf.
David Grundberg <davidg@cs.umu.se>
parents:
10126
diff
changeset
|
3269 retval = octave_vformat (octave_stdout, fmt, args); |
5864 | 3270 va_end (args); |
10127
f21fdff5c906
Change signature of mexPrintf.
David Grundberg <davidg@cs.umu.se>
parents:
10126
diff
changeset
|
3271 return retval; |
5864 | 3272 } |
3273 | |
3274 mxArray * | |
5879 | 3275 mexGetVariable (const char *space, const char *name) |
5864 | 3276 { |
3277 mxArray *retval = 0; | |
3278 | |
7752
40c428ea3408
initial implementation of dbup and dbdown
John W. Eaton <jwe@octave.org>
parents:
7577
diff
changeset
|
3279 octave_value val; |
5864 | 3280 |
3281 if (! strcmp (space, "global")) | |
7752
40c428ea3408
initial implementation of dbup and dbdown
John W. Eaton <jwe@octave.org>
parents:
7577
diff
changeset
|
3282 val = get_global_value (name); |
5864 | 3283 else |
7752
40c428ea3408
initial implementation of dbup and dbdown
John W. Eaton <jwe@octave.org>
parents:
7577
diff
changeset
|
3284 { |
9144
c6463412aebb
eliminate symbol_table::scope_stack; fix scoping issue with evalin
John W. Eaton <jwe@octave.org>
parents:
8920
diff
changeset
|
3285 // FIXME -- should this be in variables.cc? |
c6463412aebb
eliminate symbol_table::scope_stack; fix scoping issue with evalin
John W. Eaton <jwe@octave.org>
parents:
8920
diff
changeset
|
3286 |
10066
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
3287 unwind_protect frame; |
9144
c6463412aebb
eliminate symbol_table::scope_stack; fix scoping issue with evalin
John W. Eaton <jwe@octave.org>
parents:
8920
diff
changeset
|
3288 |
7901 | 3289 bool caller = ! strcmp (space, "caller"); |
3290 bool base = ! strcmp (space, "base"); | |
3291 | |
3292 if (caller || base) | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
3293 { |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
3294 if (caller) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
3295 octave_call_stack::goto_caller_frame (); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
3296 else |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
3297 octave_call_stack::goto_base_frame (); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
3298 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
3299 if (! error_state) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
3300 frame.add_fcn (octave_call_stack::pop); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
3301 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
3302 val = symbol_table::varval (name); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
3303 } |
7752
40c428ea3408
initial implementation of dbup and dbdown
John W. Eaton <jwe@octave.org>
parents:
7577
diff
changeset
|
3304 else |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
3305 mexErrMsgTxt ("mexGetVariable: symbol table does not exist"); |
7752
40c428ea3408
initial implementation of dbup and dbdown
John W. Eaton <jwe@octave.org>
parents:
7577
diff
changeset
|
3306 } |
7336 | 3307 |
3308 if (val.is_defined ()) | |
5864 | 3309 { |
7336 | 3310 retval = mex_context->make_value (val); |
3311 | |
3312 retval->set_name (name); | |
5864 | 3313 } |
3314 | |
3315 return retval; | |
3316 } | |
3317 | |
5879 | 3318 const mxArray * |
3319 mexGetVariablePtr (const char *space, const char *name) | |
5864 | 3320 { |
5879 | 3321 return mexGetVariable (space, name); |
5864 | 3322 } |
3323 | |
5900 | 3324 int |
3325 mexPutVariable (const char *space, const char *name, mxArray *ptr) | |
5864 | 3326 { |
5900 | 3327 if (! ptr) |
3328 return 1; | |
3329 | |
3330 if (! name) | |
3331 return 1; | |
3332 | |
3333 if (name[0] == '\0') | |
3334 name = ptr->get_name (); | |
3335 | |
3336 if (! name || name[0] == '\0') | |
3337 return 1; | |
3338 | |
3339 if (! strcmp (space, "global")) | |
5907 | 3340 set_global_value (name, mxArray::as_octave_value (ptr)); |
5900 | 3341 else |
3342 { | |
7336 | 3343 // FIXME -- should this be in variables.cc? |
3344 | |
10066
2cd940306a06
make unwind_protect frames local
Jaroslav Hajek <highegg@gmail.com>
parents:
9689
diff
changeset
|
3345 unwind_protect frame; |
9144
c6463412aebb
eliminate symbol_table::scope_stack; fix scoping issue with evalin
John W. Eaton <jwe@octave.org>
parents:
8920
diff
changeset
|
3346 |
7901 | 3347 bool caller = ! strcmp (space, "caller"); |
3348 bool base = ! strcmp (space, "base"); | |
3349 | |
3350 if (caller || base) | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
3351 { |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
3352 if (caller) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
3353 octave_call_stack::goto_caller_frame (); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
3354 else |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
3355 octave_call_stack::goto_base_frame (); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
3356 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
3357 if (! error_state) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
3358 frame.add_fcn (octave_call_stack::pop); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
3359 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
3360 symbol_table::varref (name) = mxArray::as_octave_value (ptr); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
3361 } |
5900 | 3362 else |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
3363 mexErrMsgTxt ("mexPutVariable: symbol table does not exist"); |
5900 | 3364 } |
3365 | |
3366 return 0; | |
5864 | 3367 } |
3368 | |
3369 void | |
5900 | 3370 mexMakeArrayPersistent (mxArray *ptr) |
5864 | 3371 { |
7172 | 3372 maybe_unmark_array (ptr); |
5864 | 3373 } |
5879 | 3374 |
5864 | 3375 void |
5900 | 3376 mexMakeMemoryPersistent (void *ptr) |
5864 | 3377 { |
7172 | 3378 maybe_unmark (ptr); |
5864 | 3379 } |
3380 | |
5900 | 3381 int |
6068 | 3382 mexAtExit (void (*f) (void)) |
5864 | 3383 { |
6068 | 3384 if (mex_context) |
3385 { | |
3386 octave_mex_function *curr_mex_fcn = mex_context->current_mex_function (); | |
3387 | |
3388 assert (curr_mex_fcn); | |
3389 | |
3390 curr_mex_fcn->atexit (f); | |
3391 } | |
3392 | |
5900 | 3393 return 0; |
5864 | 3394 } |
3395 | |
5900 | 3396 const mxArray * |
6595 | 3397 mexGet (double handle, const char *property) |
5864 | 3398 { |
6595 | 3399 mxArray *m = 0; |
3400 octave_value ret = get_property_from_handle (handle, property, "mexGet"); | |
3401 | |
3402 if (!error_state && ret.is_defined()) | |
3403 m = ret.as_mxArray (); | |
3404 return m; | |
5864 | 3405 } |
3406 | |
5900 | 3407 int |
3408 mexIsGlobal (const mxArray *ptr) | |
5864 | 3409 { |
5900 | 3410 return mxIsFromGlobalWS (ptr); |
5864 | 3411 } |
3412 | |
5900 | 3413 int |
3414 mexIsLocked (void) | |
5864 | 3415 { |
5900 | 3416 int retval = 0; |
3417 | |
3418 if (mex_context) | |
3419 { | |
3420 const char *fname = mexFunctionName (); | |
3421 | |
3422 retval = mislocked (fname); | |
3423 } | |
3424 | |
3425 return retval; | |
5864 | 3426 } |
3427 | |
5900 | 3428 std::map<std::string,int> mex_lock_count; |
3429 | |
3430 void | |
3431 mexLock (void) | |
5864 | 3432 { |
5900 | 3433 if (mex_context) |
5864 | 3434 { |
5900 | 3435 const char *fname = mexFunctionName (); |
3436 | |
3437 if (mex_lock_count.find (fname) == mex_lock_count.end ()) | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
3438 mex_lock_count[fname] = 1; |
5900 | 3439 else |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
3440 mex_lock_count[fname]++; |
5900 | 3441 |
7336 | 3442 mlock (); |
5864 | 3443 } |
3444 } | |
3445 | |
5900 | 3446 int |
6595 | 3447 mexSet (double handle, const char *property, mxArray *val) |
5900 | 3448 { |
6595 | 3449 bool ret = |
3450 set_property_in_handle (handle, property, mxArray::as_octave_value (val), | |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
3451 "mexSet"); |
6595 | 3452 return (ret ? 0 : 1); |
5900 | 3453 } |
3454 | |
3455 void | |
3456 mexUnlock (void) | |
5864 | 3457 { |
5900 | 3458 if (mex_context) |
5864 | 3459 { |
5900 | 3460 const char *fname = mexFunctionName (); |
3461 | |
5905 | 3462 std::map<std::string,int>::iterator p = mex_lock_count.find (fname); |
3463 | |
6062 | 3464 if (p != mex_lock_count.end ()) |
10315
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
3465 { |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
3466 int count = --mex_lock_count[fname]; |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
3467 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
3468 if (count == 0) |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
3469 { |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
3470 munlock (fname); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
3471 |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
3472 mex_lock_count.erase (p); |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
3473 } |
57a59eae83cc
untabify src C++ source files
John W. Eaton <jwe@octave.org>
parents:
10225
diff
changeset
|
3474 } |
5864 | 3475 } |
3476 } |