diff --git a/Examples/test-suite/scilab/Makefile.in b/Examples/test-suite/scilab/Makefile.in index 198da2e9e..a82f0877d 100644 --- a/Examples/test-suite/scilab/Makefile.in +++ b/Examples/test-suite/scilab/Makefile.in @@ -18,6 +18,7 @@ CPP_TEST_CASES += \ primitive_types \ inout \ scilab_li_matrix \ + scilab_pointer_conversion_functions \ CPP_STD_TEST_CASES += \ li_std_container_typemaps \ diff --git a/Examples/test-suite/scilab/scilab_pointer_conversion_functions_runme.sci b/Examples/test-suite/scilab/scilab_pointer_conversion_functions_runme.sci new file mode 100644 index 000000000..a15e169d3 --- /dev/null +++ b/Examples/test-suite/scilab/scilab_pointer_conversion_functions_runme.sci @@ -0,0 +1,18 @@ +exec("swigtest.start", -1); + +// Test on NULL +null = getNull(); +checkequal(swig_this(null), 0, "swig_this(null)"); + +null = swig_ptr(0); +checkequal(isNull(null), %T, "func(null)"); + +// Test on variable +expected_foo_addr = getFooAddress(); +foo_addr = swig_this(pfoo_get()); +checkequal(uint32(foo_addr), expected_foo_addr, "swig_this(pfoo_get())"); + +pfoo = swig_ptr(foo_addr); +checkequal(equalFooPointer(pfoo), %T, "equalFooPointer(pfoo)"); + +exec("swigtest.quit", -1); diff --git a/Examples/test-suite/scilab_pointer_conversion_functions.i b/Examples/test-suite/scilab_pointer_conversion_functions.i new file mode 100644 index 000000000..58e9b7471 --- /dev/null +++ b/Examples/test-suite/scilab_pointer_conversion_functions.i @@ -0,0 +1,16 @@ +%module scilab_pointer_conversion_functions + +%inline %{ + +void* getNull() { return NULL; } +bool isNull(void *p) { return p == NULL; } + +int foo = 3; +int *pfoo = &foo; + +unsigned long getFooAddress() { return (unsigned long) pfoo; } +bool equalFooPointer(void *p) { return p == pfoo; } + +%} + + diff --git a/Lib/scilab/scirun.swg b/Lib/scilab/scirun.swg index 73e690daa..f6e3c0958 100644 --- a/Lib/scilab/scirun.swg +++ b/Lib/scilab/scirun.swg @@ -115,11 +115,6 @@ SwigScilabPtrToObject(void *_pvApiCtx, int _iVar, void **_pObjValue, swig_type_i return SWIG_ERROR; } } - else if (iType == sci_matrix) { - if (!isEmptyMatrix(_pvApiCtx, piAddrVar)) { - return SWIG_ERROR; - } - } else { return SWIG_ERROR; } @@ -131,7 +126,7 @@ SWIGRUNTIMEINLINE int SwigScilabPtrFromObject(void *_pvApiCtx, int _iVarOut, void *_object, swig_type_info *_descriptor, int _flags) { SciErr sciErr; - sciErr = createPointer(pvApiCtx, SWIG_NbInputArgument(_pvApiCtx) + _iVarOut, (void *)_object); + sciErr = createPointer(_pvApiCtx, SWIG_NbInputArgument(_pvApiCtx) + _iVarOut, (void *)_object); if (sciErr.iErr) { printError(&sciErr, 0); return SWIG_ERROR; @@ -147,7 +142,7 @@ SWIG_Scilab_ConvertPacked(void *_pvApiCtx, int _iVar, void *_ptr, int sz, swig_t char *pstStrings = NULL; SciErr sciErr; - sciErr = getVarAddressFromPosition(pvApiCtx, _iVar, &piAddrVar); + sciErr = getVarAddressFromPosition(_pvApiCtx, _iVar, &piAddrVar); if (sciErr.iErr) { printError(&sciErr, 0); return SWIG_ERROR; @@ -251,3 +246,54 @@ SwigScilabRaise(const char *type) { #define Scilab_Error_Occurred() 0 #define SWIG_Scilab_AddErrorMsg(msg) {;} + +/* + * Helper functions + */ + +#ifdef __cplusplus +extern "C" +#endif +int swig_this(char *fname, unsigned long fname_len) { + void *ptrValue = NULL; + if (SwigScilabPtrToObject(pvApiCtx, 1, &ptrValue, NULL, 0, fname) == SWIG_OK) { + SWIG_Scilab_SetOutputPosition(1); + return SWIG_Scilab_SetOutput(pvApiCtx, + createScalarDouble(pvApiCtx, SWIG_NbInputArgument(_pvApiCtx) + 1, + (double) (unsigned long) ptrValue)); + } + else { + Scierror(999, _("%s: Incorrect value for input argument #%d: The value is not a pointer.\n"), fname, 1); + return SWIG_ERROR; + } +} + +#ifdef __cplusplus +extern "C" +#endif +int swig_ptr(char *fname, unsigned long fname_len) { + double dValue = 0; + int *piAddr; + SciErr sciErr = getVarAddressFromPosition(pvApiCtx, 1, &piAddr); + if(sciErr.iErr) { + printError(&sciErr, 0); + return SWIG_ERROR; + } + if (getScalarDouble(pvApiCtx, piAddr, &dValue) == 0) { + if (dValue != (unsigned long)dValue) { + Scierror(999, _("%s: Incorrect value for input argument #%d: The double value cannot be converted to a pointer.\n"), fname, 1); + return SWIG_ValueError; + } + if ((dValue < LONG_MIN) || (dValue > LONG_MAX)) { + Scierror(999, _("%s: Overflow error for input argument #%d: The double value cannot be converted to a pointer.\n"), fname, 1); + return SWIG_OverflowError; + } + SWIG_Scilab_SetOutputPosition(1); + return SWIG_Scilab_SetOutput(pvApiCtx, + SwigScilabPtrFromObject(pvApiCtx, 1, (void *) (unsigned long) dValue, NULL, 0)); + } + else { + return SWIG_ERROR; + } +} + diff --git a/Source/Modules/scilab.cxx b/Source/Modules/scilab.cxx index 37fc635d4..6f97c861d 100644 --- a/Source/Modules/scilab.cxx +++ b/Source/Modules/scilab.cxx @@ -176,6 +176,9 @@ public: /* Add initialization function to builder table */ addFunctionInBuilder(moduleInitFunctionName, moduleInitFunctionName); + // Add helper functions to builder table + addHelperFunctions(); + // Open Scilab wrapper variables creation function variablesCode = NewString(""); Printf(variablesCode, "int %s() {\n", SWIG_CREATE_VARIABLES_FUNCTION_NAME); @@ -206,6 +209,7 @@ public: /* Write all to the wrapper file */ SwigType_emit_type_table(runtimeSection, wrappersSection); // Declare pointer types, ... (Ex: SWIGTYPE_p_p_double) + Dump(runtimeSection, beginSection); Dump(headerSection, beginSection); Dump(wrappersSection, beginSection); @@ -691,6 +695,11 @@ public: } } + void addHelperFunctions() { + addFunctionInBuilder("swig_this", "swig_this"); + addFunctionInBuilder("swig_ptr", "swig_ptr"); + } + void createBuilderFile() { String *builderFilename = NewStringf("%sbuilder.sce", SWIG_output_directory()); builderFile = NewFile(builderFilename, "w", SWIG_output_files());