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