add support for Enums

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/gsoc2009-sploving@11288 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Baozeng Ding 2009-06-20 02:44:06 +00:00
commit ed84d6b162
19 changed files with 865 additions and 222 deletions

View file

@ -24,6 +24,7 @@
<li><a href="#Scilab_nn9">Functions</a>
<li><a href="#scilab_nn10">Global variables</a>
<li><a href="#Scilab_nn11">Constants</a>
<li><a href="#Scilab_nn12">Enums</a>
</ul>
</ul>
</div>
@ -215,34 +216,85 @@ ans = 4</pre></div>
</p>
<div class="code"><pre>%module example
%constant int ICONST=42;
#define ICONST 42
#define FCONST 2.1828
#define CCONST 'x'
#define CCONST2 '\n'
#define SCONST "Hello World"
#define SCONST2 "\"Hello World\""
</pre></div>
<p>
This is 'effectively' converted into the following code in the wrapper file:
A file called example.sce will be created, which could be interpreted by the scilab. The code in the file is as following:
</p>
<div class="code"><pre>....
const int ICONST=42;
const char * SCONST="Hello World";
....
int ICONST_get (char *fname,unsigned long fname_len) {..}
int SCONST_get (char *fname,unsigned long fname_len) {..}
example.ICONST = 42
example.FCONST = 2.1828
example.CCONST = ascii(120)
example.CCONST2 = ascii(10)
example.SCONST = "Hello World"
example.SCONST2 = """Hello World"""
example.EXPR = 42+3*(2.1828)
example.iconst = 37
example.fconst = 3.14
.... </pre></div>
<p>It is easy to use the C constants as global variables:</p>
<p>It is easy to use the C constants after run the command "exec example.sce":</p>
<div class="targetlang"><pre>
scilab:1&gt; ICONST
ant = 42
scilab:1&gt; exec example.sce;
scilab:2&gt; example.ICONST
ans= 42
scilab:3&gt; example.FCONST
ans= 2.1828
scilab:4&gt; example.CCONST
ans=x
scilab:5&gt; example.CCONST2
ans=
scilab:2&gt; SCONST
ant= Hello world
scilab:6&gt; example.SCONST
ans= Hello World
scilab:7&gt; example.SCONST2
ans= "Hello World"
scilab:8&gt; example.EXPR
ans= 48.5484
scilab:9&gt; example.iconst
ans= 37
scilab:10&gt; example.fconst
ans= 3.14
</pre></div>
scilab:3&gt; c=SCONST()
c = Hello World
<H3><a name="Scilab_nn12"></a>27.3.5 Enums</H3>
<p> The way that deals with the enums is similar to the constants. For example:
</p>
<div class="code"><pre>%module example
typedef enum { RED, BLUE, GREEN } color;
</pre></div>
<p>
A file called example.sce will be created, which could be interpreted by the scilab. The code in the file is as following:
</p>
<div class="code"><pre>....
color.RED=0;
color.BLUE=color.RED + 1;
color.GREEN=color.BLUE + 1;
.... </pre></div>
<p>It is easy to use the enums after run the command "exec example.sce":</p>
<div class="targetlang"><pre>
scilab:1&gt; exec example.sce;
scilab:2&gt; printf(" RED = %i\n", color.RED);
RED = 0
scilab:3&gt; printf(" BLUE = %i\n", color.BLUE);
BLUE = 1
scilab:4&gt; printf(" GREEN = %i\n", color.GREEN);
GREEN = 2
</pre></div>

View file

@ -4,7 +4,7 @@ example
# Call our gcd() function
x = 42;
x = -2;
y = 105;
g = example.gcd(x,y);
printf("The gcd of %d and %d is %d\n",x,y,g);

View file

@ -1,32 +1,22 @@
// builder the *.so
exec builder.sce;
exec example.sce;
//loader the *.so
exec loader.sce;
printf("ICONST = %i (should be 42)\n", ICONST());
printf("FCONST = %f (should be 2.1828)\n", FCONST());
printf("CCONST = %c (should be x)\n", CCONST());
printf("CCONST2 = %s (this should be on a new line)\n", CCONST2());
printf("SCONST = %s (should be Hello World)\n", SCONST());
printf("SCONST2 = %s (should be Hello World)\n", SCONST2());
printf("EXPR = %f (should be 48.5484)\n", EXPR());
printf("iconst = %i (should be 37)\n", iconst());
printf("fconst = %f (should be 3.14)\n", fconst());
printf("ICONST = %i (should be 42)\n", example.ICONST);
printf("FCONST = %f (should be 2.1828)\n",example. FCONST);
printf("CCONST = %c (should be ''x'')\n", example.CCONST);
printf("CCONST2 = %s (this should be on a new line)\n", example.CCONST2);
printf("SCONST = %s (should be ''Hello World'')\n", example.SCONST);
printf("SCONST2 = %s (should be "'""Hello World"""')\n", example.SCONST2);
printf("EXPR = %f (should be 48.5484)\n",example.EXPR);
printf("iconst = %i (should be 37)\n", example.iconst);
printf("fconst = %f (should be 3.14)\n", example.fconst);
try
printf("EXTERN = %s (Arg! This should not printf(anything)\n", EXTERN());
printf("EXTERN = %s (Arg! This should not printf(anything)\n", example.EXTERN);
catch
printf("EXTERN is not defined (good)\n");
printf("EXTERN is not defined (good)\n");
end
try
printf("FOO = %i (Arg! This should not printf(anything)\n", FOO());
printf("FOO = %i (Arg! This should not printf(anything)\n", example.FOO);
catch
printf("FOO is not defined (good)\n");
printf("FOO is not defined (good)\n");
end

View file

@ -0,0 +1,23 @@
/* File : example.c */
/* A global variable */
double Foo = 3.0;
/* Compute the greatest common divisor of positive integers */
int gcd(int x, int y) {
int g;
g = y;
while (x > 0) {
g = x;
x = y % x;
y = g;
}
return g;
}
int fact(int n) {
if (n <= 0) return 1;
return n*fact(n-1);
}

View file

@ -0,0 +1,21 @@
/* File : example.i */
%module example
%contract gcd(int x, int y) {
require:
x >= 0;
y >= 0;
}
%contract fact(int n) {
require:
n >= 0;
ensure:
fact >= 1;
}
%inline %{
extern int gcd(int x, int y);
extern int fact(int n);
extern double Foo;
%}

View file

@ -0,0 +1,15 @@
TOP = ../..
SWIG = $(TOP)/../preinst-swig
SRCS = example.c
TARGET = example
INTERFACE = example.i
all::
$(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \
TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' scilab
clean::
$(MAKE) -f $(TOP)/Makefile scilab_clean
rm -f *.sce *.so lib*lib.c
check: all

View file

@ -0,0 +1,34 @@
// builder the *.so
exec builder.sce;
// loader the *.so
exec loader.sce;
// Call our gcd() function
x = 42;
y = 105;
g = gcd(x,y);
printf("The gcd of %d and %d is %d\n",x,y,g);
// Call our fact() function
x=5;
g=fact(x);
printf("The fact of %d is %d",x,g);
// Manipulate the Foo global variable
// Output its current value
printf("Foo = %f\n",Foo_get());
// Change its value
Foo_set (3.1415926);
// See if the change took effect
printf("Foo = %f\n", Foo_get());
//Call our gcd() function to test the contract conditon
x=-42;
y=105;
g=gcd(x,y);
printf("The gcd of %d and %d is %d\n",x,y,g);

View file

@ -0,0 +1,16 @@
/* File : example.c */
#include "example.h"
#include <stdio.h>
void enum_test(color c) {
if (c == RED) {
sciprint("color = RED, ");
} else if (c == BLUE) {
sciprint("color = BLUE, ");
} else if (c == GREEN) {
sciprint("color = GREEN, ");
} else {
sciprint("color = Unknown color!, ");
}
}

View file

@ -0,0 +1,6 @@
/* File : example.h */
typedef enum { RED, BLUE, GREEN } color;
void enum_test(color c);

View file

@ -0,0 +1,11 @@
/* File : example.i */
%module example
%{
#include "example.h"
%}
/* Let's just grab the original header file here */
%include "example.h"

View file

@ -0,0 +1,15 @@
TOP = ../..
SWIG = $(TOP)/../preinst-swig
SRCS = example.c
TARGET = example
INTERFACE = example.i
all::
$(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \
TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' scilab
clean::
$(MAKE) -f $(TOP)/Makefile scilab_clean
rm -f *.sce *.so lib*lib.c
check: all

View file

@ -0,0 +1,22 @@
// builder the *.so
exec builder.sce;
// loader the *.so
exec loader.sce;
exec example.sce;
// Print out the value of some enums
printf("*** color ***\n");
printf(" RED = %i\n", color.RED);
printf(" BLUE = %i\n", color.BLUE);
printf(" GREEN = %i\n", color.GREEN);
printf("\nTesting use of enums with functions\n");
enum_test(color.RED);
enum_test(color.BLUE);
enum_test(color.GREEN);
enum_test(1234);

View file

@ -1,7 +1,7 @@
// builder the *.so
exec builder.sce;
//loader the *.so
// loader the *.so
exec loader.sce;
// Call our gcd() function
@ -11,7 +11,7 @@ y = 105;
g = gcd(x,y);
printf("The gcd of %d and %d is %d\n",x,y,g);
//Manipulate the Foo global variable
// Manipulate the Foo global variable
// Output its current value
Foo_get()
@ -19,6 +19,6 @@ Foo_get()
// Change its value
Foo_set(3.1415926)
//See if the change took effect
// See if the change took effect
Foo_get()

View file

@ -28,18 +28,18 @@ char *strvar=0;
/* A debugging function to print out their values */
void print_vars() {
sciprint("ivar = %d\n", ivar);
sciprint("svar = %d\n", svar);
sciprint("lvar = %ld\n", lvar);
sciprint("uivar = %u\n", uivar);
sciprint("usvar = %u\n", usvar);
sciprint("ulvar = %lu\n", ulvar);
sciprint("scvar = %d\n", scvar);
sciprint("ucvar = %u\n", ucvar);
sciprint("fvar = %g\n", fvar);
sciprint("dvar = %g\n", dvar);
sciprint("cvar = %c\n", cvar);
sciprint("strvar = %s\n",strvar);
printf("ivar = %d\n", ivar);
printf("svar = %d\n", svar);
printf("lvar = %ld\n", lvar);
printf("uivar = %u\n", uivar);
printf("usvar = %u\n", usvar);
printf("ulvar = %lu\n", ulvar);
printf("scvar = %d\n", scvar);
printf("ucvar = %u\n", ucvar);
printf("fvar = %g\n", fvar);
printf("dvar = %g\n", dvar);
printf("cvar = %c\n", cvar);
printf("strvar = %s\n",strvar);
}

View file

@ -1,5 +1,6 @@
%include <typemaps/swigmacros.swg>
%include <typemaps/fragments.swg>
%include <sciruntime.swg>
%include <sciprimtypes.swg>
%include <scitypemaps.swg>

View file

@ -0,0 +1,9 @@
%insert(runtime) %{
void SWIG_Error(int code, const char *msg) {
Scierror(code,_("%s\n"),msg);
}
#define SWIG_contract_assert(expr, msg) if (!(expr)) { SWIG_Error(999, msg); } else
%}

View file

@ -11,7 +11,11 @@
// Include the unified typemap library
//%include <typemaps/swigtypemaps.swg>
/* -----------------------------------------------------------------------------
* --- Input arguments ---
* ----------------------------------------------------------------------------- */
/* Basic C types */
%typemap(in) signed char (int *piAddrVar, int iRows, int iCols),
unsigned char (int *piAddrVar, int iRows, int iCols),
short (int *piAddrVar, int iRows, int iCols),
@ -44,63 +48,34 @@
}
getMatrixOfString(piAddrVar, &iRows, &iCols,&_piLength, &_pstStrings);
$1=($1_ltype)*_pstStrings;
}
%typemap(out) signed char (int iRowsOut,int iColsOut,int* _piAddress) {
char temp;
temp=(char)$1;
iRowsOut=1;
iColsOut=1;
createMatrixOfInteger8(Rhs+1, iRowsOut, iColsOut, &temp, &_piAddress);
LhsVar(1)=Rhs+1;
}
%typemap(out) short (int iRowsOut,int iColsOut,int* _piAddress),
unsigned char (int iRowsOut,int iColsOut,int* _piAddress) {
short temp;
temp=(short)$1;
iRowsOut=1;
iColsOut=1;
createMatrixOfInteger16(Rhs+1, iRowsOut, iColsOut, &temp, &_piAddress);
LhsVar(1)=Rhs+1;
}
%typemap(out) int (int iRowsOut,int iColsOut,int* _piAddress),
unsigned int (int iRowsOut,int iColsOut,int* _piAddress),
unsigned short (int iRowsOut,int iColsOut,int* _piAddress),
unsigned long (int iRowsOut,int iColsOut,int* _piAddress),
long (int iRowsOut,int iColsOut,int* _piAddress) {
int temp;
temp=(int)$1;
iRowsOut=1;
iColsOut=1;
createMatrixOfInteger32(Rhs+1, iRowsOut, iColsOut, &temp, &_piAddress);
LhsVar(1)=Rhs+1;
}
%typemap(out) double (int iRowsOut,int iColsOut,int* _piAddress),
float (int iRowsOut,int iColsOut,int* _piAddress) {
double temp;
temp=(double)$1;
iRowsOut=1;
iColsOut=1;
createMatrixOfDouble(Rhs+1, iRowsOut, iColsOut, &temp, &_piAddress);
LhsVar(1)=Rhs+1;
}
%typemap(out) char (int iRowsOut,int iColsOut,int* _piAddress) {
char* temp;
temp=(char*)&$1;
iRowsOut=1;
iColsOut=1;
createMatrixOfString(Rhs+1, iRowsOut, iColsOut, &temp, &_piAddress);
LhsVar(1)=Rhs+1;
}
%typemap(out,noblock=1) void {
/* Pointers */
%typemap(in) signed char *(int *piAddrVar, int iRows, int iCols, signed char temp),
unsigned char *(int *piAddrVar, int iRows, int iCols, unsigned char temp),
short *(int *piAddrVar, int iRows, int iCols, short temp),
unsigned short *(int *piAddrVar, int iRows, int iCols, unsigned short temp),
int *(int *piAddrVar, int iRows, int iCols, int temp),
unsigned int *(int *piAddrVar, int iRows, int iCols, unsigned int temp),
long *(int *piAddrVar, int iRows, int iCols, long temp),
unsigned long *(int *piAddrVar, int iRows, int iCols, unsigned long temp),
float *(int *piAddrVar, int iRows, int iCols, float temp),
double *(int *piAddrVar, int iRows, int iCols, double temp) {
double* _piData;
getVarAddressFromNumber($argnum, &piAddrVar);
getVarDimension(piAddrVar, &iRows, &iCols);
if (getVarType(piAddrVar) != sci_matrix || isVarComplex(piAddrVar)) {
Scierror(999, _("%s: Wrong type for input argument #%d: Real scalar expected.\n"), fname, 1);
}
getMatrixOfDouble(piAddrVar, &iRows, &iCols, &_piData);
if($1!=NULL) {
free($1);
}
$1=($1_ltype)malloc(iRows*iCols*sizeof($*1_ltype));
memcpy($1,_piData,iRows*iCols*sizeof($*1_ltype));
//temp=($*1_ltype)*_piData;
//$1=&temp;
}
%typemap(in) char *(int *piAddrVar, int iRows, int iCols) {
@ -116,11 +91,137 @@
$1=strdup(_pstStrings);
}
/* -----------------------------------------------------------------------------
* --- Output arguments ---
* ----------------------------------------------------------------------------- */
/* Basic C types */
%typemap(out) signed char (int iRowsOut,int iColsOut,int* _piAddress) {
char temp;
temp=(char)($result);
iRowsOut=1;
iColsOut=1;
createMatrixOfInteger8(iVarOut, iRowsOut, iColsOut, &temp, &_piAddress);
LhsVar(iOutNum)=iVarOut;
iOutNum++;
iVarOut++;
}
%typemap(out) short (int iRowsOut,int iColsOut,int* _piAddress),
unsigned char (int iRowsOut,int iColsOut,int* _piAddress) {
short temp;
temp=(short)($result);
iRowsOut=1;
iColsOut=1;
createMatrixOfInteger16(iVarOut, iRowsOut, iColsOut, &temp, &_piAddress);
LhsVar(iOutNum)=iVarOut;
iOutNum++;
iVarOut++;
}
%typemap(out) int (int iRowsOut,int iColsOut,int* _piAddress),
unsigned int (int iRowsOut,int iColsOut,int* _piAddress),
unsigned short (int iRowsOut,int iColsOut,int* _piAddress),
unsigned long (int iRowsOut,int iColsOut,int* _piAddress),
long (int iRowsOut,int iColsOut,int* _piAddress) {
int temp;
temp=(int)($result);
iRowsOut=1;
iColsOut=1;
createMatrixOfInteger32(iVarOut, iRowsOut, iColsOut, &temp, &_piAddress);
LhsVar(iOutNum)=iVarOut;
iOutNum++;
iVarOut++;
}
%typemap(out) double (int iRowsOut,int iColsOut,int* _piAddress),
float (int iRowsOut,int iColsOut,int* _piAddress) {
double temp;
temp=(double)($result);
iRowsOut=1;
iColsOut=1;
createMatrixOfDouble(iVarOut, iRowsOut, iColsOut, &temp, &_piAddress);
LhsVar(iOutNum)=iVarOut;
iOutNum++;
iVarOut++;
}
%typemap(out) char (int iRowsOut,int iColsOut,int* _piAddress) {
char* temp;
temp=(char*)&($result);
iRowsOut=1;
iColsOut=1;
createMatrixOfString(iVarOut, iRowsOut, iColsOut, &temp, &_piAddress);
LhsVar(iOutNum)=iVarOut;
iOutNum++;
iVarOut++;
}
%typemap(out,noblock=1) void {
}
/* Pointers */
%typemap(out) signed char *(int iRowsOut,int iColsOut,int* _piAddress) {
char *temp;
temp=(char *)($result);
iRowsOut=1;
iColsOut=1;
createMatrixOfInteger8(iVarOut, iRowsOut, iColsOut, temp, &_piAddress);
LhsVar(iOutNum)=iVarOut;
iOutNum++;
iVarOut++;
}
%typemap(out) short *(int iRowsOut,int iColsOut,int* _piAddress),
unsigned char *(int iRowsOut,int iColsOut,int* _piAddress) {
short *temp;
temp=(short *)($result);
iRowsOut=1;
iColsOut=1;
createMatrixOfInteger16(iVarOut, iRowsOut, iColsOut, temp, &_piAddress);
LhsVar(iOutNum)=iVarOut;
iOutNum++;
iVarOut++;
}
%typemap(out) int *(int iRowsOut,int iColsOut,int* _piAddress),
unsigned int *(int iRowsOut,int iColsOut,int* _piAddress),
unsigned short *(int iRowsOut,int iColsOut,int* _piAddress),
unsigned long *(int iRowsOut,int iColsOut,int* _piAddress),
long *(int iRowsOut,int iColsOut,int* _piAddress) {
int *temp;
temp=(int *)($result);
iRowsOut=1;
iColsOut=1;
createMatrixOfInteger32(iVarOut, iRowsOut, iColsOut, temp, &_piAddress);
LhsVar(iOutNum)=iVarOut;
iOutNum++;
iVarOut++;
}
%typemap(out) double *(int iRowsOut,int iColsOut,int* _piAddress),
float *(int iRowsOut,int iColsOut,int* _piAddress) {
double *temp;
temp=(double *)($result);
iRowsOut=1;
iColsOut=1;
createMatrixOfDouble(iVarOut, iRowsOut, iColsOut, temp, &_piAddress);
LhsVar(iOutNum)=iVarOut;
iOutNum++;
iVarOut++;
}
%typemap(out) char *(int iRowsOut,int iColsOut,int* _piAddress){
iRowsOut=1;
iColsOut=1;
createMatrixOfString(Rhs+1, iRowsOut, iColsOut, &$1, &_piAddress);
LhsVar(1)=Rhs+1;
createMatrixOfString(iVarOut, iRowsOut, iColsOut, &($result), &_piAddress);
LhsVar(iOutNum)=iVarOut;
iOutNum++;
iVarOut++;
}
/* ------------------------------------------------------------
* Enums mapped as integer values
* ------------------------------------------------------------ */
%apply int { enum SWIGTYPE };

258
Lib/scilab/typemaps.i Normal file
View file

@ -0,0 +1,258 @@
/* -----------------------------------------------------------------------------
* See the LICENSE file for information on copyright, usage and redistribution
* of SWIG, and the README file for authors - http://www.swig.org/release.html.
*
* typemaps.i
*
* The SWIG typemap library provides a language independent mechanism for
* supporting output arguments, input values, and other C function
* calling mechanisms. The primary use of the library is to provide a
* better interface to certain C function--especially those involving
* pointers.
* ----------------------------------------------------------------------------- */
// INPUT typemaps.
// These remap a C pointer to be an "INPUT" value which is passed by value
// instead of reference.
/*
The following methods can be applied to turn a pointer into a simple
"input" value. That is, instead of passing a pointer to an object,
you would use a real value instead.
int *INPUT
short *INPUT
long *INPUT
long long *INPUT
unsigned int *INPUT
unsigned short *INPUT
unsigned long *INPUT
unsigned long long *INPUT
unsigned char *INPUT
bool *INPUT
float *INPUT
double *INPUT
To use these, suppose you had a C function like this :
double fadd(double *a, double *b) {
return *a+*b;
}
You could wrap it with SWIG as follows :
%include typemaps.i
double fadd(double *INPUT, double *INPUT);
or you can use the %apply directive :
%include typemaps.i
%apply double *INPUT { double *a, double *b };
double fadd(double *a, double *b);
*/
%typemap(in) signed char *INPUT (int *piAddrVar, int iRows, int iCols, signed char temp),
unsigned char *INPUT (int *piAddrVar, int iRows, int iCols, unsigned char temp),
short *INPUT (int *piAddrVar, int iRows, int iCols, short temp),
unsigned short *INPUT (int *piAddrVar, int iRows, int iCols, unsigned short temp),
int *INPUT (int *piAddrVar, int iRows, int iCols, int temp),
unsigned int *INPUT (int *piAddrVar, int iRows, int iCols, unsigned int temp),
long *INPUT (int *piAddrVar, int iRows, int iCols, long temp),
unsigned long *INPUT (int *piAddrVar, int iRows, int iCols, unsigned long temp),
float *INPUT (int *piAddrVar, int iRows, int iCols, float temp),
double *INPUT (int *piAddrVar, int iRows, int iCols, double temp) {
double* _piData;
getVarAddressFromNumber($argnum, &piAddrVar);
getVarDimension(piAddrVar, &iRows, &iCols);
if (getVarType(piAddrVar) != sci_matrix || iRows != 1 || iCols != 1 || isVarComplex(piAddrVar)) {
Scierror(999, _("%s: Wrong type for input argument #%d: Real scalar expected.\n"), fname, 1);
}
getMatrixOfDouble(piAddrVar, &iRows, &iCols, &_piData);
temp=($*1_ltype)*_piData;
$1=&temp;
}
#undef INPUT_TYPEMAP
// OUTPUT typemaps. These typemaps are used for parameters that
// are output only. The output value is appended to the result as
// a list element.
/*
The following methods can be applied to turn a pointer into an "output"
value. When calling a function, no input value would be given for
a parameter, but an output value would be returned. In the case of
multiple output values, functions will return a Perl array.
int *OUTPUT
short *OUTPUT
long *OUTPUT
long long *OUTPUT
unsigned int *OUTPUT
unsigned short *OUTPUT
unsigned long *OUTPUT
unsigned long long *OUTPUT
unsigned char *OUTPUT
bool *OUTPUT
float *OUTPUT
double *OUTPUT
For example, suppose you were trying to wrap the modf() function in the
C math library which splits x into integral and fractional parts (and
returns the integer part in one of its parameters).:
double modf(double x, double *ip);
You could wrap it with SWIG as follows :
%include typemaps.i
double modf(double x, double *OUTPUT);
or you can use the %apply directive :
%include typemaps.i
%apply double *OUTPUT { double *ip };
double modf(double x, double *ip);
The Perl output of the function would be an array containing both
output values.
*/
// Force the argument to be ignored.
%typemap(in) signed char *OUTPUT (signed temp),
unsigned char *OUTPUT (unsigned temp),
short *OUTPUT (short temp),
unsigned short *OUTPUT (unsigned short temp),
int *OUTPUT (int temp),
unsigned int *OUTPUT (unsigned int temp),
long *OUTPUT (long temp),
unsigned long *OUTPUT (unsigned long temp),
float *OUTPUT (float temp),
double *OUTPUT (double temp) {
$1=($1_ltype)&temp;
}
%typemap(argout) signed char *OUTPUT(int iRowsOut,int iColsOut,int* _piAddress) {
iRowsOut=1;
iColsOut=1;
createMatrixOfInteger8(iVarOut, iRowsOut, iColsOut, &temp$argnum, &_piAddress);
LhsVar(iOutNum)=iVarOut;
iOutNum++;
iVarOut++;
}
%typemap(argout) short *OUTPUT(int iRowsOut,int iColsOut,int* _piAddress),
unsigned char *OUTPUT(int iRowsOut,int iColsOut,int* _piAddress) {
iRowsOut=1;
iColsOut=1;
createMatrixOfInteger16(iVarOut, iRowsOut, iColsOut, &temp$argnum, &_piAddress);
LhsVar(iOutNum)=iVarOut;
iOutNum++;
iVarOut++;
}
%typemap(argout) int *OUTPUT(int iRowsOut,int iColsOut,int* _piAddress),
unsigned int *OUTPUT(int iRowsOut,int iColsOut,int* _piAddress),
unsigned short *OUTPUT(int iRowsOut,int iColsOut,int* _piAddress),
unsigned long *OUTPUT(int iRowsOut,int iColsOut,int* _piAddress),
long *OUTPUT(int iRowsOut,int iColsOut,int* _piAddress) {
iRowsOut=1;
iColsOut=1;
createMatrixOfInteger32(iVarOut, iRowsOut, iColsOut, &temp$argnum, &_piAddress);
LhsVar(iOutNum)=iVarOut;
iOutNum++;
iVarOut++;
}
%typemap(argout) double *OUTPUT(int iRowsOut,int iColsOut,int* _piAddress),
float *OUTPUT(int iRowsOut,int iColsOut,int* _piAddress) {
double temp;
temp=(double)(*$result);
iRowsOut=1;
iColsOut=1;
createMatrixOfDouble(iVarOut, iRowsOut, iColsOut, &temp$argnum, &_piAddress);
LhsVar(iOutNum)=iVarOut;
iOutNum++;
iVarOut++;
}
// INOUT
// Mappings for an argument that is both an input and output
// parameter
/*
The following methods can be applied to make a function parameter both
an input and output value. This combines the behavior of both the
"INPUT" and "OUTPUT" methods described earlier. Output values are
returned in the form of a Perl array.
int *INOUT
short *INOUT
long *INOUT
long long *INOUT
unsigned int *INOUT
unsigned short *INOUT
unsigned long *INOUT
unsigned long long *INOUT
unsigned char *INOUT
bool *INOUT
float *INOUT
double *INOUT
For example, suppose you were trying to wrap the following function :
void neg(double *x) {
*x = -(*x);
}
You could wrap it with SWIG as follows :
%include typemaps.i
void neg(double *INOUT);
or you can use the %apply directive :
%include typemaps.i
%apply double *INOUT { double *x };
void neg(double *x);
Unlike C, this mapping does not directly modify the input value.
Rather, the modified input value shows up as the return value of the
function. Thus, to apply this function to a Perl variable you might
do this :
$x = neg($x);
*/
%typemap(in) int *INOUT = int *INPUT;
%typemap(in) short *INOUT = short *INPUT;
%typemap(in) long *INOUT = long *INPUT;
%typemap(in) unsigned *INOUT = unsigned *INPUT;
%typemap(in) unsigned short *INOUT = unsigned short *INPUT;
%typemap(in) unsigned long *INOUT = unsigned long *INPUT;
%typemap(in) unsigned char *INOUT = unsigned char *INPUT;
%typemap(in) signed char *INOUT = signed char *INPUT;
%typemap(in) float *INOUT = float *INPUT;
%typemap(in) double *INOUT = double *INPUT;
%typemap(in) int *INOUT = int *OUTPUT;
%typemap(in) short *INOUT = short *OUTPUT;
%typemap(in) long *INOUT = long *INPUT;
%typemap(in) unsigned *INOUT = unsigned *OUTPUT;
%typemap(in) unsigned short *INOUT = unsigned short *OUTPUT;
%typemap(in) unsigned long *INOUT = unsigned long *OUTPUT;
%typemap(in) unsigned char *INOUT = unsigned char *OUTPUT;
%typemap(in) signed char *INOUT = signed char *OUTPUT;
%typemap(in) float *INOUT = float *OUTPUT;
%typemap(in) double *INOUT = double *OUTPUT;

View file

@ -17,19 +17,25 @@ Scilab Options (available with -scilab)\n\
class SCILAB:public Language {
private:
private:
File *f_begin;
File *f_runtime;
File *f_header;
File *f_wrappers;
File *f_init;
File *f_builder;
String *f_builder_code;
String *f_example_code;
public:
SCILAB():f_begin(0), f_runtime(0), f_header(0),f_wrappers(0),
f_init(0) {}
bool hasfunction_flag;
bool hasconstant_flag;
public:
SCILAB():
f_builder_code(NewString("")), f_example_code(NewString("")), hasfunction_flag(false), hasconstant_flag(false) {
}
/* ------------------------------------------------------------
* main()
* ------------------------------------------------------------ */
@ -43,16 +49,16 @@ class SCILAB:public Language {
}
}
//Set language-specific subdirectory in SWIG library
/* Set language-specific subdirectory in SWIG library */
SWIG_library_directory("scilab");
// Add a symbol to the parser for conditional compilation
/* Add a symbol to the parser for conditional compilation */
Preprocessor_define("SWIGSCILAB 1", 0);
// Set scilab configuration file
/* Set scilab configuration file */
SWIG_config_file("scilab.swg");
//Set typemap for scilab
/* Set typemap for scilab */
SWIG_typemap_lang("scilab");
}
@ -62,20 +68,14 @@ class SCILAB:public Language {
virtual int top(Node *n) {
Node *mod = Getattr(n, "module");
/*Get the name of the module*/
/* Get the name of the module */
String *module = Getattr(n, "name");
/*One output file for as the wrapper file*/
/* One output file for as the wrapper file */
String *outfile = Getattr(n, "outfile");
f_begin = NewFile(outfile, "w", SWIG_output_files());
/*Another output file to generate the .so or .dll */
String *builder = NewStringf("%sbuilder.sce",SWIG_output_directory());
f_builder=NewFile(builder,"w",SWIG_output_files());
/* Initialize all of the output files */
/* Initialize the output files */
if (!f_begin) {
FileErrorDisplay(outfile);
SWIG_exit(EXIT_FAILURE);
@ -92,32 +92,52 @@ class SCILAB:public Language {
Swig_register_filebyname("wrapper", f_wrappers);
Swig_register_filebyname("init", f_init);
/*Insert the banner at the beginning */
/* Insert the banner at the beginning */
Swig_banner(f_begin);
/*Include some header file of scilab*/
/* Include some header file of scilab */
Printf(f_runtime, "#include \"stack-c.h\"\n");
Printf(f_runtime, "#include \"sciprint.h\"\n");
Printf(f_runtime, "#include \"Scierror.h\"\n");
Printf(f_runtime, "#include \"variable_api.h\"\n");
Printf(f_runtime, "#include \"localization.h\"\n");
/* Initialize the builder.sce file code */
Printf(f_builder_code,"ilib_name = \"%slib\";\n",module);
Printf(f_builder_code,"files = [\"%s\",\"%s.o\"];\n", outfile,module);
Printf(f_builder_code,"libs = [];\n");
Printf(f_builder_code, "table = [");
/*Initialize the builder.sce file*/
Printf(f_builder,"ilib_name = \"%slib\";\n",module);
Printf(f_builder,"files = [\"%s\",\"%s.o\"];\n", outfile,module);
Printf(f_builder,"libs = [];\n");
Printf(f_builder, "table = [");
/*Emit code for children*/
/* Emit code for children */
Language::top(n);
/*Finish off the builder.sce file*/
Printf(f_builder,"];\n");
Printf(f_builder,"ilib_build(ilib_name,table,files,libs);");
/* create the file to generate the module: "builder.sce" */
if(hasfunction_flag) {
Printf(f_builder_code,"];\n");
Printf(f_builder_code,"ilib_build(ilib_name,table,files,libs);");
File *f_builder=NewFile(NewStringf("%sbuilder.sce",SWIG_output_directory()),"w",SWIG_output_files());
Printv(f_builder,f_builder_code,NIL);
Close(f_builder);
Delete(f_builder);
Delete(f_builder_code);
}
else {
Delete(f_builder_code);
}
/*Dump out all the files*/
/* create the file for constants: "module.sce" */
if(hasconstant_flag) {
File *f_example=NewFile(NewStringf("%s%s.sce",SWIG_output_directory(),module),"w",SWIG_output_files());
Printv(f_example,f_example_code,NIL);
Close(f_example);
Delete(f_example);
Delete(f_example_code);
}
else {
Delete(f_example_code);
}
/* Dump out all the files */
Dump(f_runtime, f_begin);
Dump(f_header, f_begin);
Dump(f_wrappers, f_begin);
@ -129,34 +149,32 @@ class SCILAB:public Language {
Delete(f_header);
Delete(f_runtime);
Close(f_begin);
Close(f_builder);
Delete(f_begin);
Delete(f_builder);
return SWIG_OK;
}
/* ----------------------------------------------------------------------
/* ----------------------------------------------------------------------
* functionWrapper()
* ---------------------------------------------------------------------- */
virtual int functionWrapper(Node *n) {
// A new wrapper function object
Wrapper *f = NewWrapper();
hasfunction_flag=true;
/* A new wrapper function object */
Wrapper *f = NewWrapper();
Parm *p;
String *tm;
int j;
//Get the useful information from the node
/* Get the useful information from the node */
String *nodeType = Getattr(n, "nodeType");
int constructor = (!Cmp(nodeType, "constructor"));
int destructor = (!Cmp(nodeType, "destructor"));
// int destructor = (!Cmp(nodeType, "destructor"));
String *storage = Getattr(n, "storage");
bool overloaded = !!Getattr(n, "sym:overloaded");
bool last_overload = overloaded && !Getattr(n, "sym:nextSibling");
//bool last_overload = overloaded && !Getattr(n, "sym:nextSibling");
String *iname = Getattr(n, "sym:name");
String *wname = Swig_name_wrapper(iname);
String *overname = Copy(wname);
@ -169,19 +187,19 @@ class SCILAB:public Language {
if (overloaded)
Append(overname, Getattr(n, "sym:overname"));
Printv(f->def, "int ", overname, " (char *fname,unsigned long fname_len) {", NIL);
Printv(f->def, "int ", overname, " (char *fname,unsigned long fname_len) {\nint iOutNum=1;\nint iVarOut=Rhs+1;", NIL);
// Emit all of the local variables for holding arguments
/* Emit all of the local variables for holding arguments */
emit_parameter_variables(l, f);
//Attach typemaps to the parameter list
/* Attach typemaps to the parameter list */
emit_attach_parmmaps(l, f);
Setattr(n, "wrap:parms", l);
// Get number of required and total arguments
/* Get number of required and total arguments */
int num_arguments = emit_num_arguments(l);
int num_required = emit_num_required(l);
int varargs = emit_isvarargs(l);
//int varargs = emit_isvarargs(l);
if (constructor && num_arguments == 1 && num_required == 1) {
if (Cmp(storage, "explicit") == 0) {
@ -194,7 +212,7 @@ class SCILAB:public Language {
}
}
//Walk the function parameter list and generate code to get arguments
/* Walk the function parameter list and generate code to get arguments */
for (j = 0, p = l; j < num_arguments; ++j) {
while (checkAttribute(p, "tmap:in:numinputs", "0")) {
p = Getattr(p, "tmap:in:next");
@ -202,7 +220,7 @@ class SCILAB:public Language {
SwigType *pt = Getattr(p, "type");
// Get typemap for this argument
/* Get typemap for this argument */
String *tm = Getattr(p, "tmap:in");
if (tm) {
@ -224,15 +242,15 @@ class SCILAB:public Language {
Setattr(n, "wrap:name", overname);
// Now write code to make the function call
/* Now write code to make the function call */
Swig_director_emit_dynamic_cast(n, f);
String *actioncode = emit_action(n);
//Insert the return variable
/* Insert the return variable */
emit_return_variable(n, d, f);
if ((tm = Swig_typemap_lookup_out("out", n, "result", f, actioncode))) {
Replaceall(tm, "$result", "result");
Printf(f->code, "%s\n", tm);
}
@ -261,7 +279,7 @@ class SCILAB:public Language {
/* Dump the wrapper function */
Wrapper_print(f, f_wrappers);
DelWrapper(f);
Printf(f_builder, "\"%s\",\"%s\";",iname,wname);
Printf(f_builder_code, "\"%s\",\"%s\";",iname,wname);
Delete(overname);
Delete(wname);
@ -275,14 +293,18 @@ class SCILAB:public Language {
* ----------------------------------------------------------------------- */
virtual int variableWrapper(Node *n) {
hasfunction_flag=true;
/* Get the useful information from the node */
String *name = Getattr(n, "name");
String *iname = Getattr(n, "sym:name");
SwigType *t = Getattr(n, "type");
if (!addSymbol(iname, n))
return SWIG_ERROR;
/* two wrapper function to get and set the variable */
String *tm;
Wrapper *getf = NewWrapper();
Wrapper *setf = NewWrapper();
@ -290,106 +312,153 @@ class SCILAB:public Language {
String *getname = Swig_name_get(iname);
String *setname = Swig_name_set(iname);
Printv(setf->def, "int ", setname, " (char *fname,unsigned long fname_len) {", NIL);
Printv(setf->def, "int ", setname, " (char *fname,unsigned long fname_len) {\nint iOutNum=1;\nint iVarOut=Rhs+1;", NIL);
/* add the local variable */
Wrapper_add_local(setf, "piAddrVar", "int *piAddrVar");
Wrapper_add_local(setf, "iRows", "int iRows");
Wrapper_add_local(setf, "iCols", "int iCols");
/* deal with the set function */
if (is_assignable(n)) {
Setattr(n, "wrap:name", setname);
if ((tm = Swig_typemap_lookup("in", n, name, 0))) {
Replaceall(tm, "$source", "args(0)");
Replaceall(tm, "$target", name);
Replaceall(tm, "$input", "args(0)");
Replaceall(tm, "$argnum", "1");
//if (Getattr(n, "tmap:varin:implicitconv")) {
//Replaceall(tm, "$implicitconv", get_implicitconv_flag(n));
//}
Replaceall(tm, "$argnum", "1");
emit_action_code(n, setf->code, tm);
Delete(tm);
} else {
Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s.\n", SwigType_str(t, 0));
}
} else {
//Printf(setf->code, "return octave_set_immutable(args,nargout);");
}
else {
}
Append(setf->code, "}\n");
Wrapper_print(setf, f_wrappers);
Printf(f_builder, "\"%s\",\"%s\";",setname,setname);
Printf(f_builder_code, "\"%s\",\"%s\";",setname,setname);
/* deal with the get function */
Setattr(n, "wrap:name", getname);
int addfail = 0;
Printv(getf->def, "int ", getname, " (char *fname,unsigned long fname_len){", NIL);
Printv(getf->def, "int ", getname, " (char *fname,unsigned long fname_len){\nint iOutNum=1;\nint iVarOut=Rhs+1;", NIL);
/* add local variabe */
Wrapper_add_local(getf, "piAddrOut", "int* _piAddress");
Wrapper_add_local(getf, "iRows", "int iRowsOut");
Wrapper_add_local(getf, "iColsOut", "int iColsOut ");
if ((tm = Swig_typemap_lookup("out", n, name, 0))) {
Replaceall(tm, "$source", name);
Replaceall(tm, "$target", "obj");
Replaceall(tm, "$result", "obj");
Replaceall(tm, "$result", name);
addfail = emit_action_code(n, getf->code, tm);
Delete(tm);
} else {
Swig_warning(WARN_TYPEMAP_VAROUT_UNDEF, input_file, line_number, "Unable to read variable of type %s\n", SwigType_str(t, 0));
}
/*Dump the wrapper function */
Append(getf->code, "}\n");
Wrapper_print(getf, f_wrappers);
Printf(f_builder, "\"%s\",\"%s\";",getname,getname);
Printf(f_builder_code, "\"%s\",\"%s\";",getname,getname);
return SWIG_OK;
}
}
/* -----------------------------------------------------------------------
/* -----------------------------------------------------------------------
* constantWrapper()
* ----------------------------------------------------------------------- */
virtual int constantWrapper(Node *n) {
String *name = Getattr(n, "name");
/* set the flag so to generate the example.sce */
hasconstant_flag=true;
/* Get the useful information from the node */
String *iname = Getattr(n, "sym:name");
SwigType *type = Getattr(n, "type");
String *rawval = Getattr(n, "rawval");
String *value = rawval ? rawval : Getattr(n, "value");
String *tm;
if (!addSymbol(iname, n))
return SWIG_ERROR;
Wrapper *getf = NewWrapper();
String *getname = Swig_name_get(iname);
String *tempvalue=NewString("");
Setattr(n, "wrap:name", getname);
Printv(getf->def, "int ", getname, " (char *fname,unsigned long fname_len) {", NIL);
Wrapper_add_local(getf, "piAddrOut", "int* _piAddress");
Wrapper_add_local(getf, "iRows", "int iRowsOut");
Wrapper_add_local(getf, "iColsOut", "int iColsOut ");
if ((tm = Swig_typemap_lookup("out", n, name, 0))) {
Replaceall(tm, "$source", name);
Replaceall(tm, "$target", "obj");
Replaceall(tm, "$result", "obj");
emit_action_code(n, getf->code, tm);
Delete(tm);
} else {
Swig_warning(WARN_TYPEMAP_VAROUT_UNDEF, input_file, line_number, "Unable to read variable of type %s\n", SwigType_str(type, 0));
/* set the value format to be the scilab format */
if(!Strcmp(type,"char")){
value=Getattr(n,"rawvalue");
char *temp=(Char(value));
tempvalue=NewString("ascii");
Printf(tempvalue,"(%i)",(int)*temp);
value=Copy(tempvalue);
}
else{
if(!Strcmp(type,"p.char")){
char *temp=(Char(value));
int len=strlen(temp);
for(int i=0;i<len;++i){
if(temp[i]=='\\'){
temp[i]='"';
++i;
}
}
Printf(tempvalue,"%s",temp);
value=Copy(tempvalue);
}
}
Append(getf->code, "}\n");
Wrapper_print(getf, f_wrappers);
Printf(f_header, "const %s %s=%s;\n",SwigType_str(type,0),iname,value);
Printf(f_builder, "\"%s\",\"%s\";",iname,getname);
/* write into the code string */
Printf(f_example_code, "example.%s = %s\n",iname,value);
return SWIG_OK;
}
/* ---------------------------------------------------------------------
* enumDeclaration()
* --------------------------------------------------------------------- */
virtual int enumDeclaration(Node *n) {
/* set the flag so to generate the example.sce */
hasconstant_flag=true;
return Language::enumDeclaration(n);
}
/* ---------------------------------------------------------------------
* enumvalueDeclaration()
* --------------------------------------------------------------------- */
virtual int enumvalueDeclaration(Node *n) {
/* get the name of the enumvalue */
String *iname = Getattr(n, "sym:name");
/* get the name of the enum name */
String *parentName=Getattr(parentNode(n), "sym:name");
/* set the name to be the enum.enumvalue format */
String *temp=Copy(parentName);
Printf(temp,".%s",iname);
Setattr(n,"sym:name",temp);
/* set the value attribute to be the integer */
String *value;
String *enumvalue=Getattr(n,"enumvalue");
if(enumvalue) {
Setattr(n,"value",enumvalue);
}
else {
if(n!=firstChild(parentNode(n))) {
enumvalue=Getattr(n,"enumvalueex");
value=Copy(parentName);
Printf(value,".%s",enumvalue);
Setattr(n,"value",value);
}
else {
Setattr(n,"value",Getattr(n,"enumvalueex"));
}
}
value=Getattr(n,"value");
/* write into the code string */
Printf(f_example_code, "%s.%s=%s;\n",parentName,iname,value);
return SWIG_OK;
}
};
extern "C" Language *swig_scilab(void) {