From 2cf606c6389b53417da134fe2bfca69e61605f98 Mon Sep 17 00:00:00 2001 From: Simon Marchetto Date: Wed, 28 Aug 2013 17:00:23 +0200 Subject: [PATCH] Scilab: add %feature scilab:const (constants are wrapped by Scilab variables) --- Examples/scilab/constants/example.i | 12 +++++++++ Examples/scilab/constants/runme.sci | 30 +++++++++++++++------- Lib/scilab/scichar.swg | 34 +++++++++++++++++++++++++ Lib/scilab/scidouble.swg | 12 +++++++++ Lib/scilab/sciint.swg | 12 +++++++++ Lib/scilab/scilab.swg | 1 + Lib/scilab/scimacros.swg | 5 ++++ Lib/scilab/sciruntime.swg | 3 ++- Lib/scilab/scitypemaps.swg | 28 +++++++++++++++++++++ Source/Modules/scilab.cxx | 39 +++++++++++++++++++++++------ 10 files changed, 159 insertions(+), 17 deletions(-) create mode 100644 Lib/scilab/scimacros.swg diff --git a/Examples/scilab/constants/example.i b/Examples/scilab/constants/example.i index a79fb4ed9..fbdea586a 100644 --- a/Examples/scilab/constants/example.i +++ b/Examples/scilab/constants/example.i @@ -24,5 +24,17 @@ %constant int iconst = 37; %constant double fconst = 3.14; +/* Now constants are wrapped to Scilab variables */ +%scilabconst(1); + +#define ICONST2 12 +#define FCONST2 4.60 +#define CCONST3 'a' +#define CCONST4 '\n' +#define SCONST3 "Hello World" +#define SCONST4 "\"Hello World\"" + +%constant int iconst2 = 73; +%constant double fconst2 = 6.28; diff --git a/Examples/scilab/constants/runme.sci b/Examples/scilab/constants/runme.sci index 5109f857e..a1afec976 100644 --- a/Examples/scilab/constants/runme.sci +++ b/Examples/scilab/constants/runme.sci @@ -1,15 +1,17 @@ lines(0); exec loader.sce; +SWIG_Init(); -printf("ICONST = %i (should be 42)\n", ICONST_get()); -printf("FCONST = %f (should be 2.1828)\n", FCONST_get()); -printf("CCONST = %c (should be ''x'')\n", CCONST_get()); -printf("CCONST2 = %s (this should be on a new line)\n", CCONST2_get()); -printf("SCONST = %s (should be ''Hello World'')\n", SCONST_get()); -printf("SCONST2 = %s (should be "'""Hello World"""')\n", SCONST2_get()); -printf("EXPR = %f (should be 48.5484)\n", EXPR_get()); -printf("iconst = %i (should be 37)\n", iconst_get()); -printf("fconst = %f (should be 3.14)\n", fconst_get()); +printf("\nConstants are wrapped by functions:\n"); +printf("ICONST_get() = %i (should be 42)\n", ICONST_get()); +printf("FCONST_get() = %5.4f (should be 2.1828)\n", FCONST_get()); +printf("CCONST_get() = ''%c'' (should be ''x'')\n", CCONST_get()); +printf("CCONST2_get() = %s (this should be on a new line)\n", CCONST2_get()); +printf("SCONST_get() = ''%s'' (should be ''Hello World'')\n", SCONST_get()); +printf("SCONST2_get() = ''%s'' (should be "'""Hello World"""')\n", SCONST2_get()); +printf("EXPR_get() = %5.4f (should be 48.5484)\n", EXPR_get()); +printf("iconst_get() = %i (should be 37)\n", iconst_get()); +printf("fconst_get() = %3.2f (should be 3.14)\n", fconst_get()); try printf("EXTERN = %s (Arg! This should not printf(anything)\n", EXTERN_get()); @@ -22,4 +24,14 @@ catch printf("FOO is not defined (good)\n"); end +printf("\nNow constants are wrapped by Scilab variables (feature scilab:const):\n"); +printf("ICONST2 = %i (should be 12)\n", ICONST2); +printf("FCONST2 = %3.2f (should be 4.60)\n", FCONST2); +printf("CCONST3 = ''%c'' (should be ''a'')\n", CCONST3); +printf("CCONST4 = %s (this should be on a new line)\n", CCONST4); +printf("SCONST3 = ''%s'' (should be ''Hello World'')\n", SCONST3); +printf("SCONST4 = ''%s'' (should be "'""Hello World"""')\n", SCONST4); +printf("iconst2 = %i (should be 73)\n", iconst2); +printf("fconst2 = %3.2f (should be 6.28)\n", fconst2); + exit diff --git a/Lib/scilab/scichar.swg b/Lib/scilab/scichar.swg index 96e855929..e165b66d8 100644 --- a/Lib/scilab/scichar.swg +++ b/Lib/scilab/scichar.swg @@ -252,3 +252,37 @@ SwigScilabStringFromCharPtrArray(void *_pvApiCtx, int _iVarOut, char **_charPtrA return SWIG_NbInputArgument(pvApiCtx) + _iVarOut; } } +%fragment(SWIG_CreateScilabVariable_frag(char), "wrapper") { +SWIGINTERN int +SWIG_CreateScilabVariable_dec(char)(void *_pvApiCtx, const char* _psVariableName, const char _cVariableValue) { + SciErr sciErr; + char sValue[2]; + const char* psStrings[1]; + + sValue[0] = _cVariableValue; + sValue[1] = '\0'; + psStrings[0] = sValue; + + sciErr = createNamedMatrixOfString(_pvApiCtx, _psVariableName, 1, 1, psStrings); + if (sciErr.iErr) { + printError(&sciErr, 0); + return SWIG_ERROR; + } + return SWIG_OK; +} +} +%fragment(SWIG_CreateScilabVariable_frag(charptr), "wrapper") { +SWIGINTERN int +SWIG_CreateScilabVariable_dec(charptr)(void *_pvApiCtx, const char* _psVariableName, const char* _psVariableValue) { + SciErr sciErr; + const char* psStrings[1]; + psStrings[0] = _psVariableValue; + + sciErr = createNamedMatrixOfString(_pvApiCtx, _psVariableName, 1, 1, psStrings); + if (sciErr.iErr) { + printError(&sciErr, 0); + return SWIG_ERROR; + } + return SWIG_OK; +} +} diff --git a/Lib/scilab/scidouble.swg b/Lib/scilab/scidouble.swg index 0eb9d8ae4..94a69671a 100644 --- a/Lib/scilab/scidouble.swg +++ b/Lib/scilab/scidouble.swg @@ -118,3 +118,15 @@ SWIG_SciDouble_FromDoubleArrayAndSize(void *_pvApiCtx, int _iVarOut, int _iRows, return Rhs + _iVarOut; } } +%fragment(SWIG_CreateScilabVariable_frag(double), "wrapper") { +SWIGINTERN int +SWIG_CreateScilabVariable_dec(double)(void *_pvApiCtx, const char* _psVariableName, const double _dVariableValue) { + SciErr sciErr; + sciErr = createNamedMatrixOfDouble(_pvApiCtx, _psVariableName, 1, 1, &_dVariableValue); + if (sciErr.iErr) { + printError(&sciErr, 0); + return SWIG_ERROR; + } + return SWIG_OK; +} +} diff --git a/Lib/scilab/sciint.swg b/Lib/scilab/sciint.swg index f45fb8524..e2758eb74 100644 --- a/Lib/scilab/sciint.swg +++ b/Lib/scilab/sciint.swg @@ -196,3 +196,15 @@ SWIG_SciInt32_FromIntArrayAndSize(void *_pvApiCtx, int _iVarOut, int _iRows, int return Rhs + _iVarOut; } } +%fragment(SWIG_CreateScilabVariable_frag(int), "wrapper") { +SWIGINTERN int +SWIG_CreateScilabVariable_dec(int)(void *_pvApiCtx, const char* _psVariableName, const int _iVariableValue) { + SciErr sciErr; + sciErr = createNamedMatrixOfInteger32(_pvApiCtx, _psVariableName, 1, 1, &_iVariableValue); + if (sciErr.iErr) { + printError(&sciErr, 0); + return SWIG_ERROR; + } + return SWIG_OK; +} +} diff --git a/Lib/scilab/scilab.swg b/Lib/scilab/scilab.swg index ac24d159f..3b5f6e817 100644 --- a/Lib/scilab/scilab.swg +++ b/Lib/scilab/scilab.swg @@ -1,5 +1,6 @@ %include %include +%include %include %include diff --git a/Lib/scilab/scimacros.swg b/Lib/scilab/scimacros.swg new file mode 100644 index 000000000..669ca893f --- /dev/null +++ b/Lib/scilab/scimacros.swg @@ -0,0 +1,5 @@ + #define %scilabconst(flag) %feature("scilab:const","flag") + +// Create Scilab variable +#define SWIG_CreateScilabVariable_frag(Type...) %fragment_name(CreateScilabVariable, Type) +#define SWIG_CreateScilabVariable_dec(Type...) %symbol_name(CreateScilabVariable, Type) diff --git a/Lib/scilab/sciruntime.swg b/Lib/scilab/sciruntime.swg index e8b52b12b..86471bda4 100644 --- a/Lib/scilab/sciruntime.swg +++ b/Lib/scilab/sciruntime.swg @@ -78,7 +78,6 @@ SWIG_Scilab_ErrorMsg(int code, const char *mesg) /* Used for C++ enums */ //#define SWIG_AsVal_int(scilabValue, valuePointer) SWIG_SciDouble_AsInt(pvApiCtx, scilabValue, valuePointer, fname) - #if SCILAB_VERSION_54_OR_HIGHER #define SWIG_CheckInputArgument(pvApiCtx, minInputArgument, maxInputArgument) CheckInputArgument(pvApiCtx, minInputArgument, maxInputArgument) #define SWIG_CheckOutputArgument(pvApiCtx, minOutputArgument, maxOutputArgument) CheckOutputArgument(pvApiCtx, minOutputArgument, maxOutputArgument) @@ -272,6 +271,8 @@ SWIG_Scilab_SetModule(swig_module_info *swig_module) %init %{ #ifdef __cplusplus extern "C" +#endif int SWIG_Init(char *fname, unsigned long fname_len) { SWIG_InitializeModule(NULL); + SWIG_CreateScilabVariables(); %} diff --git a/Lib/scilab/scitypemaps.swg b/Lib/scilab/scitypemaps.swg index 657717cda..f6eeb27aa 100644 --- a/Lib/scilab/scitypemaps.swg +++ b/Lib/scilab/scitypemaps.swg @@ -376,3 +376,31 @@ %typecheck(SWIG_TYPECHECK_STRING_ARRAY) char ** { SCILAB_TYPECHECK(isStringType) } //%apply int { size_t }; + +/* -----------------------------------------------------------------------------*/ +/* Constants +/* -----------------------------------------------------------------------------*/ + +%typemap(scilabconstcode, fragment=SWIG_CreateScilabVariable_frag(int)) int +%{ + if (SWIG_CreateScilabVariable_int(pvApiCtx, "$result", $value) != SWIG_OK) + return SWIG_ERROR; +%} + +%typemap(scilabconstcode, fragment=SWIG_CreateScilabVariable_frag(double)) double +%{ + if (SWIG_CreateScilabVariable_double(pvApiCtx, "$result", $value) != SWIG_OK) + return SWIG_ERROR; +%} + +%typemap(scilabconstcode, fragment=SWIG_CreateScilabVariable_frag(char)) char +%{ + if (SWIG_CreateScilabVariable_char(pvApiCtx, "$result", $value) != SWIG_OK) + return SWIG_ERROR; +%} + +%typemap(scilabconstcode, fragment=SWIG_CreateScilabVariable_frag(charptr)) char * +%{ + if (SWIG_CreateScilabVariable_charptr(pvApiCtx, "$result", $value) != SWIG_OK) + return SWIG_ERROR; +%} diff --git a/Source/Modules/scilab.cxx b/Source/Modules/scilab.cxx index 47322e76b..c2f1b8c8d 100644 --- a/Source/Modules/scilab.cxx +++ b/Source/Modules/scilab.cxx @@ -24,6 +24,7 @@ Scilab options\n\ -vbl sets the build verbose level (default 0)\n\n"; const char *SWIG_INIT_FUNCTION_NAME = "SWIG_Init"; +const char *SWIG_CREATE_VARIABLES_FUNCTION_NAME = "SWIG_CreateScilabVariables"; class SCILAB:public Language { protected: @@ -34,6 +35,8 @@ protected: File *wrappersSection; File *initSection; + String *variablesCode; + File *builderFile; String *builderCode; int builderFunctionCount; @@ -41,9 +44,8 @@ protected: List *sourceFileList; String *cflag; String *ldflag; - + String *verboseBuildLevel; - public: /* ------------------------------------------------------------------------ * main() @@ -180,10 +182,12 @@ public: Printf(builderCode, "table = ["); - /* In C++ mode, add initialization function to builder table */ - if (CPlusPlus) { - Printf(builderCode, "\"%s\",\"%s\";", SWIG_INIT_FUNCTION_NAME, SWIG_INIT_FUNCTION_NAME); - } + /* add initialization function to builder table */ + addFunctionInBuilder(NewString(SWIG_INIT_FUNCTION_NAME), NewString(SWIG_INIT_FUNCTION_NAME)); + + // Open Scilab wrapper variables creation function + variablesCode = NewString(""); + Printf(variablesCode, "int %s() {\n", SWIG_CREATE_VARIABLES_FUNCTION_NAME); /* Emit code for children */ if (CPlusPlus) { @@ -196,6 +200,9 @@ public: Printf(wrappersSection, "}\n"); } + // Close Scilab wrapper variables creation function + Printf(variablesCode, " return SWIG_OK;\n}\n"); + /* Write all to the builder.sce file */ Printf(builderCode, "];\n"); Printf(builderCode, "if ~isempty(table) then\n"); @@ -208,13 +215,14 @@ public: Delete(builderFile); /* Close the init function (opened in sciinit.swg) */ - Printf(initSection, "return 0;\n}\n#endif\n"); + Printf(initSection, "return 0;\n}\n"); /* 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); + Dump(variablesCode, beginSection); Wrapper_pretty_print(initSection, beginSection); /* Cleanup files */ @@ -556,6 +564,23 @@ public: String *constantValue = rawValue ? rawValue : Getattr(node, "value"); String *constantTypemap = NULL; + // Constants of simple type are wrapped to Scilab variables + if (GetFlag(node, "feature:scilab:const")) { + if ((SwigType_issimple(type)) || (SwigType_type(type) == T_STRING)) { + constantTypemap = Swig_typemap_lookup("scilabconstcode", node, nodeName, 0); + if (constantTypemap != NULL) { + //String *wrapName = NewString(""); + //Printf(wrapName, "Swig%s", constantName); + Setattr(node, "wrap:name", constantName); + Replaceall(constantTypemap, "$result", constantName); + Replaceall(constantTypemap, "$value", constantValue); + emit_action_code(node, variablesCode, constantTypemap); + Delete(constantTypemap); + return SWIG_OK; + } + } + } + /* Create variables for member pointer constants, not suppported by typemaps (like Python wrapper does) */ if (SwigType_type(type) == T_MPOINTER) { String *wname = Swig_name_wrapper(constantName);