Mercurial > octave
changeset 22471:667d353d1ab8
Clean up MEX API prototypes to match Matlab.
Return int, rather than void, from mxSetDimensions.
Return const mwSize *, rather than unconst version, from mxGetDimensions.
Re-order switch statements to have most probable cases first.
* mexproto.h (mxGetDimensions): Change prototype to return const mwSize *.
* mexproto.h (mxSetDimensions): Change prototype to return int.
* mxarray.in.h: Expand comment on why Octave uses OCTAVE_IDX_TYPE for all size
and pointer types.
* mxarray.in.h (mxArray_base::set_dimensions): Return int rather than void.
* mxarray.in.h (mxArray::set_dimensions): Return int rather than void. Use
DO_MUTABLE_METHOD, not DO_VOID_MUTABLE_METHOD, due to prototype change.
* mex.cc (mxArray_octave_value::set_dimensions): Return int rather than void.
Always return 0, success.
* mex.cc (mxArray_octave_value::get_classid): Re-order if/else if tree to put
more probable cases first.
* mex.cc (mxArray_octave_value::get_element_size): Reorder switch statement
to have most probable cases first.
* mex.cc (mxArray_matlab::set_dimensions): Return int rather than void.
Return failure (1) if malloc does not succeed.
* mex.cc (mxArray_matlab::get_class_name): Reorder switch statement to have
most probable cases first.
* mex.cc (mxArray_number::get_double): Reorder switch statement to have
most probable cases first.
* mex.cc (mxArray_number::as_octave_value): Reorder switch statement to have
most probable cases first.
* mex.cc (mxGetDimensions): Return const mwSize *.
* mex.cc (mxSetDimensions): Return int rather than void.
* mex.cc (mxGetChars): Return NULL if input mxArray is not of type mxChar (done
for Matlab compatibility.).
author | Rik <rik@octave.org> |
---|---|
date | Mon, 12 Sep 2016 13:39:32 -0700 |
parents | 9d4cb0cf9cd2 |
children | 76f2b0436423 |
files | libinterp/corefcn/mex.cc libinterp/corefcn/mexproto.h libinterp/corefcn/mxarray.in.h |
diffstat | 3 files changed, 160 insertions(+), 129 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/corefcn/mex.cc Sun Sep 11 21:08:56 2016 -0700 +++ b/libinterp/corefcn/mex.cc Mon Sep 12 13:39:32 2016 -0700 @@ -296,9 +296,11 @@ void set_n (mwSize /*n*/) { request_mutation (); } - void set_dimensions (mwSize * /*dims_arg*/, mwSize /*ndims_arg*/) + int set_dimensions (mwSize * /*dims_arg*/, mwSize /*ndims_arg*/) { request_mutation (); + + return 0; } mwSize get_number_of_elements (void) const { return val.numel (); } @@ -319,18 +321,20 @@ std::string cn = val.class_name (); - if (cn == "cell") + if (cn == "double") + id = mxDOUBLE_CLASS; + else if (cn == "single") + id = mxSINGLE_CLASS; + else if (cn == "char") + id = mxCHAR_CLASS; + else if (cn == "logical") + id = mxLOGICAL_CLASS; + else if (cn == "cell") id = mxCELL_CLASS; else if (cn == "struct") id = mxSTRUCT_CLASS; - else if (cn == "logical") - id = mxLOGICAL_CLASS; - else if (cn == "char") - id = mxCHAR_CLASS; - else if (cn == "double") - id = mxDOUBLE_CLASS; - else if (cn == "single") - id = mxSINGLE_CLASS; + else if (cn == "function_handle") + id = mxFUNCTION_CLASS; else if (cn == "int8") id = mxINT8_CLASS; else if (cn == "uint8") @@ -347,8 +351,6 @@ id = mxINT64_CLASS; else if (cn == "uint64") id = mxUINT64_CLASS; - else if (cn == "function_handle") - id = mxFUNCTION_CLASS; return id; } @@ -376,6 +378,7 @@ // Not allowed. void set_cell (mwIndex /*idx*/, mxArray * /*val*/) { request_mutation (); } + // FIXME: For sparse arrays, this should return the first non-zero value. double get_scalar (void) const { return val.scalar_value (true); } void *get_data (void) const @@ -491,7 +494,7 @@ char *array_to_string (void) const { - // FIXME: this is suposed to handle multi-byte character strings. + // FIXME: this is supposed to handle multi-byte character strings. char *buf = 0; @@ -532,12 +535,13 @@ switch (id) { + case mxDOUBLE_CLASS: return sizeof (double); + case mxSINGLE_CLASS: return sizeof (float); + case mxCHAR_CLASS: return sizeof (mxChar); + case mxLOGICAL_CLASS: return sizeof (mxLogical); case mxCELL_CLASS: return sizeof (mxArray *); case mxSTRUCT_CLASS: return sizeof (mxArray *); - case mxLOGICAL_CLASS: return sizeof (mxLogical); - case mxCHAR_CLASS: return sizeof (mxChar); - case mxDOUBLE_CLASS: return sizeof (double); - case mxSINGLE_CLASS: return sizeof (float); + case mxFUNCTION_CLASS: return 0; case mxINT8_CLASS: return 1; case mxUINT8_CLASS: return 1; case mxINT16_CLASS: return 2; @@ -546,7 +550,8 @@ case mxUINT32_CLASS: return 4; case mxINT64_CLASS: return 8; case mxUINT64_CLASS: return 8; - case mxFUNCTION_CLASS: return 0; + // FIXME: user-defined objects need their own class ID. + // What should they return, size of pointer? default: return 0; } } @@ -743,16 +748,30 @@ void set_n (mwSize n) { dims[1] = n; } - void set_dimensions (mwSize *dims_arg, mwSize ndims_arg) + int set_dimensions (mwSize *dims_arg, mwSize ndims_arg) { ndims = ndims_arg; mxFree (dims); - dims = (ndims > 0 ? static_cast<mwSize *> - (mxArray::malloc (ndims * sizeof (mwSize))) - : 0); - for (int i = 0; i < ndims; i++) - dims[i] = dims_arg[i]; + + if (ndims > 0) + { + dims + = static_cast<mwSize *> (mxArray::malloc (ndims * sizeof (mwSize))); + + if (dims == NULL) + return 1; + + for (int i = 0; i < ndims; i++) + dims[i] = dims_arg[i]; + + return 0; + } + else + { + dims = 0; + return 0; + } } mwSize get_number_of_elements (void) const @@ -778,12 +797,13 @@ { switch (id) { + case mxDOUBLE_CLASS: return "double"; + case mxSINGLE_CLASS: return "single"; + case mxCHAR_CLASS: return "char"; + case mxLOGICAL_CLASS: return "logical"; case mxCELL_CLASS: return "cell"; case mxSTRUCT_CLASS: return "struct"; - case mxLOGICAL_CLASS: return "logical"; - case mxCHAR_CLASS: return "char"; - case mxDOUBLE_CLASS: return "double"; - case mxSINGLE_CLASS: return "single"; + case mxFUNCTION_CLASS: return "function_handle"; case mxINT8_CLASS: return "int8"; case mxUINT8_CLASS: return "uint8"; case mxINT16_CLASS: return "int16"; @@ -792,7 +812,8 @@ case mxUINT32_CLASS: return "uint32"; case mxINT64_CLASS: return "int64"; case mxUINT64_CLASS: return "uint64"; - case mxFUNCTION_CLASS: return "function_handle"; + case mxUNKNOWN_CLASS: return "unknown"; + // FIXME: should return the classname of user-defined objects default: return "unknown"; } } @@ -939,6 +960,8 @@ case mxINT64_CLASS: return 8; case mxUINT64_CLASS: return 8; case mxFUNCTION_CLASS: return 0; + // FIXME: user-defined objects need their own class ID. + // What should they return, size of pointer? default: return 0; } } @@ -1108,20 +1131,20 @@ switch (get_class_id ()) { - case mxLOGICAL_CLASS: - retval = *(static_cast<bool *> (pr)); + case mxDOUBLE_CLASS: + retval = *(static_cast<double *> (pr)); + break; + + case mxSINGLE_CLASS: + retval = *(static_cast<float *> (pr)); break; case mxCHAR_CLASS: retval = *(static_cast<mxChar *> (pr)); break; - case mxSINGLE_CLASS: - retval = *(static_cast<float *> (pr)); - break; - - case mxDOUBLE_CLASS: - retval = *(static_cast<double *> (pr)); + case mxLOGICAL_CLASS: + retval = *(static_cast<bool *> (pr)); break; case mxINT8_CLASS: @@ -1199,7 +1222,7 @@ char *array_to_string (void) const { - // FIXME: this is suposed to handle multi-byte character strings. + // FIXME: this is supposed to handle multi-byte character strings. mwSize nel = get_number_of_elements (); @@ -1226,24 +1249,36 @@ switch (get_class_id ()) { - case mxLOGICAL_CLASS: - retval = int_to_ov<mxLogical, boolNDArray, bool> (dv); - break; - - case mxCHAR_CLASS: + case mxDOUBLE_CLASS: { mwSize nel = get_number_of_elements (); - mxChar *ppr = static_cast<mxChar *> (pr); - - charNDArray val (dv); - - char *ptr = val.fortran_vec (); - - for (mwIndex i = 0; i < nel; i++) - ptr[i] = static_cast<char> (ppr[i]); - - retval = val; + double *ppr = static_cast<double *> (pr); + + if (pi) + { + ComplexNDArray val (dv); + + Complex *ptr = val.fortran_vec (); + + double *ppi = static_cast<double *> (pi); + + for (mwIndex i = 0; i < nel; i++) + ptr[i] = Complex (ppr[i], ppi[i]); + + retval = val; + } + else + { + NDArray val (dv); + + double *ptr = val.fortran_vec (); + + for (mwIndex i = 0; i < nel; i++) + ptr[i] = ppr[i]; + + retval = val; + } } break; @@ -1280,39 +1315,27 @@ } break; - case mxDOUBLE_CLASS: + case mxCHAR_CLASS: { mwSize nel = get_number_of_elements (); - double *ppr = static_cast<double *> (pr); - - if (pi) - { - ComplexNDArray val (dv); - - Complex *ptr = val.fortran_vec (); - - double *ppi = static_cast<double *> (pi); - - for (mwIndex i = 0; i < nel; i++) - ptr[i] = Complex (ppr[i], ppi[i]); - - retval = val; - } - else - { - NDArray val (dv); - - double *ptr = val.fortran_vec (); - - for (mwIndex i = 0; i < nel; i++) - ptr[i] = ppr[i]; - - retval = val; - } + mxChar *ppr = static_cast<mxChar *> (pr); + + charNDArray val (dv); + + char *ptr = val.fortran_vec (); + + for (mwIndex i = 0; i < nel; i++) + ptr[i] = static_cast<char> (ppr[i]); + + retval = val; } break; + case mxLOGICAL_CLASS: + retval = int_to_ov<mxLogical, boolNDArray, bool> (dv); + break; + case mxINT8_CLASS: retval = int_to_ov<int8_t, int8NDArray, octave_int8> (dv); break; @@ -1459,30 +1482,6 @@ switch (get_class_id ()) { - case mxLOGICAL_CLASS: - { - bool *ppr = static_cast<bool *> (pr); - - SparseBoolMatrix val (get_m (), get_n (), - static_cast<octave_idx_type> (nzmax)); - - for (mwIndex i = 0; i < nzmax; i++) - { - val.xdata (i) = ppr[i]; - val.xridx (i) = ir[i]; - } - - for (mwIndex i = 0; i < get_n () + 1; i++) - val.xcidx (i) = jc[i]; - - retval = val; - } - break; - - case mxSINGLE_CLASS: - error ("single precision sparse data type not supported"); - break; - case mxDOUBLE_CLASS: { if (pi) @@ -1525,6 +1524,30 @@ } break; + case mxLOGICAL_CLASS: + { + bool *ppr = static_cast<bool *> (pr); + + SparseBoolMatrix val (get_m (), get_n (), + static_cast<octave_idx_type> (nzmax)); + + for (mwIndex i = 0; i < nzmax; i++) + { + val.xdata (i) = ppr[i]; + val.xridx (i) = ir[i]; + } + + for (mwIndex i = 0; i < get_n () + 1; i++) + val.xcidx (i) = jc[i]; + + retval = val; + } + break; + + case mxSINGLE_CLASS: + error ("single precision sparse data type not supported"); + break; + default: panic_impossible (); } @@ -2759,7 +2782,7 @@ return ptr->get_n (); } -mwSize * +const mwSize * mxGetDimensions (const mxArray *ptr) { return ptr->get_dimensions (); @@ -2790,12 +2813,12 @@ ptr->set_n (n); } -void +int mxSetDimensions (mxArray *ptr, const mwSize *dims, mwSize ndims) { - ptr->set_dimensions (static_cast<mwSize *> - (maybe_unmark (const_cast<mwSize *> (dims))), - ndims); + return (ptr->set_dimensions (static_cast<mwSize *> + (maybe_unmark (const_cast<mwSize *> (dims))), + ndims)); } // Data extractors. @@ -2811,6 +2834,8 @@ return static_cast<double *> (ptr->get_imag_data ()); } +// FIXME: For sparse arrays, mxGetScalar should return the first non-zero +// element, rather than just the first element. double mxGetScalar (const mxArray *ptr) { @@ -2820,7 +2845,10 @@ mxChar * mxGetChars (const mxArray *ptr) { - return static_cast<mxChar *> (ptr->get_data ()); + if (mxIsChar (ptr)) + return static_cast<mxChar *> (ptr->get_data ()); + else + return NULL; } mxLogical *
--- a/libinterp/corefcn/mexproto.h Sun Sep 11 21:08:56 2016 -0700 +++ b/libinterp/corefcn/mexproto.h Mon Sep 12 13:39:32 2016 -0700 @@ -194,6 +194,7 @@ extern OCTINTERP_API bool mxIsClass (const mxArray *ptr, const char *name); extern OCTINTERP_API bool mxIsComplex (const mxArray *ptr); extern OCTINTERP_API bool mxIsDouble (const mxArray *ptr); +/* Matlab seems to have deprecated IsFunctionHandle, but it seems useful */ extern OCTINTERP_API bool mxIsFunctionHandle (const mxArray *ptr); extern OCTINTERP_API bool mxIsInt16 (const mxArray *ptr); extern OCTINTERP_API bool mxIsInt32 (const mxArray *ptr); @@ -225,15 +226,15 @@ /* Dimension extractors. */ extern OCTINTERP_API size_t mxGetM (const mxArray *ptr); extern OCTINTERP_API size_t mxGetN (const mxArray *ptr); -extern OCTINTERP_API mwSize *mxGetDimensions (const mxArray *ptr); +extern OCTINTERP_API const mwSize *mxGetDimensions (const mxArray *ptr); extern OCTINTERP_API mwSize mxGetNumberOfDimensions (const mxArray *ptr); extern OCTINTERP_API size_t mxGetNumberOfElements (const mxArray *ptr); /* Dimension setters. */ extern OCTINTERP_API void mxSetM (mxArray *ptr, mwSize M); extern OCTINTERP_API void mxSetN (mxArray *ptr, mwSize N); -extern OCTINTERP_API void mxSetDimensions (mxArray *ptr, const mwSize *dims, - mwSize ndims); +extern OCTINTERP_API int mxSetDimensions (mxArray *ptr, const mwSize *dims, + mwSize ndims); /* Data extractors. */ extern OCTINTERP_API double *mxGetPi (const mxArray *ptr); @@ -296,8 +297,9 @@ extern OCTINTERP_API char *mxArrayToString (const mxArray *ptr); /* Miscellaneous. */ -extern OCTINTERP_API mwIndex -mxCalcSingleSubscript (const mxArray *ptr, mwSize nsubs, mwIndex *subs); +extern OCTINTERP_API mwIndex mxCalcSingleSubscript (const mxArray *ptr, + mwSize nsubs, + mwIndex *subs); extern OCTINTERP_API size_t mxGetElementSize (const mxArray *ptr);
--- a/libinterp/corefcn/mxarray.in.h Sun Sep 11 21:08:56 2016 -0700 +++ b/libinterp/corefcn/mxarray.in.h Mon Sep 12 13:39:32 2016 -0700 @@ -51,13 +51,6 @@ typedef enum { - mxREAL = 0, - mxCOMPLEX = 1 -} -mxComplexity; - -typedef enum -{ mxUNKNOWN_CLASS = 0, mxCELL_CLASS, mxSTRUCT_CLASS, @@ -78,16 +71,24 @@ } mxClassID; -typedef unsigned char mxLogical; +typedef enum +{ + mxREAL = 0, + mxCOMPLEX = 1 +} +mxComplexity; /* Matlab uses a wide char (uint16) internally, but Octave uses plain char. */ /* typedef Uint16 mxChar; */ typedef char mxChar; +typedef unsigned char mxLogical; + /* - * FIXME: Mathworks says these should be size_t on 64-bit system and when - * mex is used with the -largearraydims flag, but why do that? Its better - * to conform to the same indexing as the rest of Octave. + * FIXME: Mathworks says mwSize, mwIndex should be int generally. + * But on 64-bit systems, or when mex -largeArrayDims is used, it is size_t. + * mwSignedIndex is supposed to be ptrdiff_t. All of this is confusing. + * Its better to conform to the same indexing as the rest of Octave. */ typedef %OCTAVE_IDX_TYPE% mwSize; typedef %OCTAVE_IDX_TYPE% mwIndex; @@ -208,7 +209,7 @@ virtual void set_n (mwSize n) = 0; - virtual void set_dimensions (mwSize *dims_arg, mwSize ndims_arg) = 0; + virtual int set_dimensions (mwSize *dims_arg, mwSize ndims_arg) = 0; virtual mwSize get_number_of_elements (void) const = 0; @@ -416,8 +417,8 @@ void set_n (mwSize n) { DO_VOID_MUTABLE_METHOD (set_n (n)); } - void set_dimensions (mwSize *dims_arg, mwSize ndims_arg) - { DO_VOID_MUTABLE_METHOD (set_dimensions (dims_arg, ndims_arg)); } + int set_dimensions (mwSize *dims_arg, mwSize ndims_arg) + { DO_MUTABLE_METHOD (int, set_dimensions (dims_arg, ndims_arg)); } mwSize get_number_of_elements (void) const { return rep->get_number_of_elements (); }