add the missing file of matrix2 example
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/gsoc2009-sploving@11880 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
215a9c649b
commit
c31100860e
7 changed files with 116 additions and 97 deletions
17
Examples/scilab/matrix2/Makefile
Normal file
17
Examples/scilab/matrix2/Makefile
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
TOP = ../..
|
||||
SWIG = $(TOP)/../preinst-swig
|
||||
SRCS = matrixlib.c
|
||||
TARGET = matrixlib
|
||||
INTERFACE = matrixlib.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 *_wrap.c
|
||||
|
||||
check: all
|
||||
$(MAKE) -f $(TOP)/Makefile scilab_run
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
|
||||
|
||||
files=['matrixlib.c','sci_sumitems.c'];//,'sci_getValues.c'];
|
||||
ilib_build('build_c',['sumitems','sci_sumitems';'generateValues','sci_getValues'],files,[]);
|
||||
|
||||
ilib_name = "matrixliblib";
|
||||
files = ["matrixlib_wrap.c","matrixlib.o"];
|
||||
libs = [];
|
||||
table = ["sumitems","_wrap_sumitems";"getValues","_wrap_getValues";];
|
||||
ilib_build(ilib_name,table,files,libs);
|
||||
exit
|
||||
24
Examples/scilab/matrix2/matrixlib.i
Executable file
24
Examples/scilab/matrix2/matrixlib.i
Executable file
|
|
@ -0,0 +1,24 @@
|
|||
%module matrixlib
|
||||
%typemap (in,noblock=1) (double *first, int nbRow, int nbCol){
|
||||
int *piAddr = NULL;
|
||||
sciErr = getVarAddressFromPosition(pvApiCtx, 1, &piAddr);
|
||||
if (sciErr.iErr) {
|
||||
printError(&sciErr, 0);
|
||||
return 0;
|
||||
}
|
||||
sciErr = getMatrixOfDouble(pvApiCtx, piAddr, &$2, &$3, &$1);
|
||||
if (sciErr.iErr) {
|
||||
printError(&sciErr, 0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
%typemap (in) (int *numberOfRow, int *numberOfCol) {
|
||||
$1 = &iRowsOut;
|
||||
$2 = &iColsOut;
|
||||
}
|
||||
|
||||
%inline {
|
||||
extern double sumitems(double *first, int nbRow, int nbCol);
|
||||
extern double* getValues(int *numberOfRow, int *numberOfCol);
|
||||
}
|
||||
|
||||
|
|
@ -1,28 +1,6 @@
|
|||
// loader the *.so
|
||||
exec loader.sce
|
||||
|
||||
// First create some objects using the pointer library.
|
||||
printf("Testing the pointer library\n");
|
||||
a = new_intp();
|
||||
b = new_intp();
|
||||
c = new_intp();
|
||||
intp_assign(a,37);
|
||||
intp_assign(b,42);
|
||||
|
||||
a,b,c
|
||||
|
||||
// Call the add() function with some pointers
|
||||
add(a,b,c);
|
||||
|
||||
// Now get the result
|
||||
r = intp_value(c);
|
||||
printf(" 37 + 42 = %i\n",r);
|
||||
|
||||
// Clean up the pointers
|
||||
delete_intp(a);
|
||||
delete_intp(b);
|
||||
delete_intp(c);
|
||||
|
||||
//Now try the typemap library
|
||||
//This should be much easier. Now how it is no longer
|
||||
//necessary to manufacture pointers.
|
||||
|
|
|
|||
|
|
@ -765,7 +765,7 @@
|
|||
printError(&sciErr, 0);
|
||||
return 0;
|
||||
}
|
||||
LhsVar(iOutNum) = iVarOut;
|
||||
|
||||
}
|
||||
|
||||
%typemap(out) unsigned char (int iRowsOut, int iColsOut) {
|
||||
|
|
@ -776,7 +776,7 @@
|
|||
printError(&sciErr, 0);
|
||||
return 0;
|
||||
}
|
||||
LhsVar(iOutNum) = iVarOut;
|
||||
|
||||
}
|
||||
|
||||
%typemap(out) short (int iRowsOut, int iColsOut) {
|
||||
|
|
@ -787,7 +787,7 @@
|
|||
printError(&sciErr, 0);
|
||||
return 0;
|
||||
}
|
||||
LhsVar(iOutNum) = iVarOut;
|
||||
|
||||
}
|
||||
|
||||
%typemap(out) unsigned short (int iRowsOut, int iColsOut) {
|
||||
|
|
@ -798,7 +798,7 @@
|
|||
printError(&sciErr, 0);
|
||||
return 0;
|
||||
}
|
||||
LhsVar(iOutNum) = iVarOut;
|
||||
|
||||
}
|
||||
|
||||
%typemap(out) int (int iRowsOut, int iColsOut),
|
||||
|
|
@ -810,7 +810,7 @@
|
|||
printError(&sciErr, 0);
|
||||
return 0;
|
||||
}
|
||||
LhsVar(iOutNum) = iVarOut;
|
||||
|
||||
}
|
||||
|
||||
%typemap(out) unsigned int (int iRowsOut, int iColsOut),
|
||||
|
|
@ -822,7 +822,7 @@
|
|||
printError(&sciErr, 0);
|
||||
return 0;
|
||||
}
|
||||
LhsVar(iOutNum) = iVarOut;
|
||||
|
||||
}
|
||||
|
||||
%typemap(out) double (int iRowsOut, int iColsOut),
|
||||
|
|
@ -834,7 +834,7 @@
|
|||
printError(&sciErr, 0);
|
||||
return 0;
|
||||
}
|
||||
LhsVar(iOutNum) = iVarOut;
|
||||
|
||||
}
|
||||
|
||||
%typemap(out) long long (int iRowsOut, int iColsOut) {
|
||||
|
|
@ -845,7 +845,7 @@
|
|||
printError(&sciErr, 0);
|
||||
return 0;
|
||||
}
|
||||
LhsVar(iOutNum) = iVarOut;
|
||||
|
||||
}
|
||||
|
||||
%typemap(out) unsigned long long (int iRowsOut, int iColsOut) {
|
||||
|
|
@ -856,7 +856,7 @@
|
|||
printError(&sciErr, 0);
|
||||
return 0;
|
||||
}
|
||||
LhsVar(iOutNum) = iVarOut;
|
||||
|
||||
}
|
||||
|
||||
%typemap(out) char (int iRowsOut, int iColsOut) {
|
||||
|
|
@ -869,7 +869,7 @@
|
|||
printError(&sciErr, 0);
|
||||
return 0;
|
||||
}
|
||||
LhsVar(iOutNum) = iVarOut;
|
||||
|
||||
}
|
||||
|
||||
%typemap(out,noblock=1) void {
|
||||
|
|
@ -877,24 +877,24 @@
|
|||
|
||||
|
||||
/* Pointers */
|
||||
%typemap(out) signed char *,
|
||||
short *,
|
||||
unsigned char *,
|
||||
unsigned short *,
|
||||
int *,
|
||||
unsigned int *,
|
||||
long *,
|
||||
unsigned long *,
|
||||
double *,
|
||||
float *,
|
||||
long long,
|
||||
unsigned long long * {
|
||||
sciErr = createPointer(pvApiCtx, iVarOut, (void *)$result);
|
||||
%typemap(out) signed char * (int iRowsOut, int iColsOut),
|
||||
short * (int iRowsOut, int iColsOut),
|
||||
unsigned char * (int iRowsOut, int iColsOut),
|
||||
unsigned short * (int iRowsOut, int iColsOut),
|
||||
int * (int iRowsOut, int iColsOut),
|
||||
unsigned int * (int iRowsOut, int iColsOut),
|
||||
long * (int iRowsOut, int iColsOut),
|
||||
unsigned long * (int iRowsOut, int iColsOut),
|
||||
double * (int iRowsOut, int iColsOut),
|
||||
float * (int iRowsOut, int iColsOut),
|
||||
long long * (int iRowsOut, int iColsOut),
|
||||
unsigned long long * (int iRowsOut, int iColsOut) {
|
||||
sciErr = createMatrixOfDouble(pvApiCtx, iVarOut, iRowsOut, iColsOut, (double *)$result);
|
||||
if (sciErr.iErr) {
|
||||
printError(&sciErr, 0);
|
||||
return 0;
|
||||
}
|
||||
LhsVar(iOutNum) = iVarOut;
|
||||
|
||||
}
|
||||
|
||||
%typemap(out) char * (int iRowsOut, int iColsOut) {
|
||||
|
|
@ -905,7 +905,7 @@
|
|||
printError(&sciErr, 0);
|
||||
return 0;
|
||||
}
|
||||
LhsVar(iOutNum) = iVarOut;
|
||||
|
||||
}
|
||||
|
||||
%typemap(out) enum SWIGTYPE (int iRowsOut, int iColsOut) {
|
||||
|
|
@ -916,7 +916,7 @@
|
|||
printError(&sciErr, 0);
|
||||
return 0;
|
||||
}
|
||||
LhsVar(iOutNum) = iVarOut;
|
||||
|
||||
}
|
||||
|
||||
%typemap(out) SWIGTYPE * {
|
||||
|
|
@ -925,7 +925,7 @@
|
|||
printError(&sciErr, 0);
|
||||
return 0;
|
||||
}
|
||||
LhsVar(iOutNum) = iVarOut;
|
||||
|
||||
}
|
||||
|
||||
%typemap(out) SWIGTYPE {
|
||||
|
|
@ -934,7 +934,7 @@
|
|||
printError(&sciErr, 0);
|
||||
return 0;
|
||||
}
|
||||
LhsVar(iOutNum) = iVarOut;
|
||||
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
|
|
@ -1553,7 +1553,7 @@
|
|||
printError(&sciErr, 0);
|
||||
return 0;
|
||||
}
|
||||
LhsVar(iOutNum) = iVarOut;
|
||||
|
||||
}
|
||||
|
||||
%typemap(varout,noblock=1) unsigned char {
|
||||
|
|
@ -1563,7 +1563,7 @@
|
|||
printError(&sciErr, 0);
|
||||
return 0;
|
||||
}
|
||||
LhsVar(iOutNum) = iVarOut;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -1574,7 +1574,7 @@
|
|||
printError(&sciErr, 0);
|
||||
return 0;
|
||||
}
|
||||
LhsVar(iOutNum) = iVarOut;
|
||||
|
||||
}
|
||||
|
||||
%typemap(varout,noblock=1) unsigned short {
|
||||
|
|
@ -1584,7 +1584,7 @@
|
|||
printError(&sciErr, 0);
|
||||
return 0;
|
||||
}
|
||||
LhsVar(iOutNum) = iVarOut;
|
||||
|
||||
}
|
||||
|
||||
%typemap(varout,noblock=1) int,
|
||||
|
|
@ -1595,7 +1595,7 @@
|
|||
printError(&sciErr, 0);
|
||||
return 0;
|
||||
}
|
||||
LhsVar(iOutNum) = iVarOut;
|
||||
|
||||
}
|
||||
|
||||
%typemap(varout,noblock=1) unsigned int,
|
||||
|
|
@ -1606,7 +1606,7 @@
|
|||
printError(&sciErr, 0);
|
||||
return 0;
|
||||
}
|
||||
LhsVar(iOutNum) = iVarOut;
|
||||
|
||||
}
|
||||
|
||||
%typemap(varout,noblock=1) double,
|
||||
|
|
@ -1617,7 +1617,7 @@
|
|||
printError(&sciErr, 0);
|
||||
return 0;
|
||||
}
|
||||
LhsVar(iOutNum) = iVarOut;
|
||||
|
||||
}
|
||||
|
||||
%typemap(varout,noblock=1) long long {
|
||||
|
|
@ -1627,7 +1627,7 @@
|
|||
printError(&sciErr, 0);
|
||||
return 0;
|
||||
}
|
||||
LhsVar(iOutNum) = iVarOut;
|
||||
|
||||
}
|
||||
|
||||
%typemap(varout,noblock=1) unsigned long long {
|
||||
|
|
@ -1637,7 +1637,7 @@
|
|||
printError(&sciErr, 0);
|
||||
return 0;
|
||||
}
|
||||
LhsVar(iOutNum) = iVarOut;
|
||||
|
||||
}
|
||||
|
||||
%typemap(varout,noblock=1) char {
|
||||
|
|
@ -1649,7 +1649,7 @@
|
|||
printError(&sciErr, 0);
|
||||
return 0;
|
||||
}
|
||||
LhsVar(iOutNum) = iVarOut;
|
||||
|
||||
free(temp);
|
||||
}
|
||||
|
||||
|
|
@ -1660,7 +1660,7 @@
|
|||
printError(&sciErr, 0);
|
||||
return 0;
|
||||
}
|
||||
LhsVar(iOutNum) = iVarOut;
|
||||
|
||||
}
|
||||
|
||||
/* pointer to basic C types */
|
||||
|
|
@ -1681,7 +1681,7 @@
|
|||
printError(&sciErr, 0);
|
||||
return 0;
|
||||
}
|
||||
LhsVar(iOutNum) = iVarOut;
|
||||
|
||||
}
|
||||
|
||||
/* Arrays */
|
||||
|
|
@ -1694,7 +1694,7 @@
|
|||
printError(&sciErr, 0);
|
||||
return 0;
|
||||
}
|
||||
LhsVar(iOutNum) = iVarOut;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -1704,7 +1704,7 @@
|
|||
printError(&sciErr, 0);
|
||||
return 0;
|
||||
}
|
||||
LhsVar(iOutNum) = iVarOut;
|
||||
|
||||
}
|
||||
|
||||
%typemap(varout,noblock=1) unsigned char [ANY] {
|
||||
|
|
@ -1713,7 +1713,7 @@
|
|||
printError(&sciErr, 0);
|
||||
return 0;
|
||||
}
|
||||
LhsVar(iOutNum) = iVarOut;
|
||||
|
||||
}
|
||||
|
||||
%typemap(varout,noblock=1) short [ANY] {
|
||||
|
|
@ -1722,7 +1722,7 @@
|
|||
printError(&sciErr, 0);
|
||||
return 0;
|
||||
}
|
||||
LhsVar(iOutNum) = iVarOut;
|
||||
|
||||
}
|
||||
|
||||
%typemap(varout,noblock=1) unsigned short [ANY] {
|
||||
|
|
@ -1731,7 +1731,7 @@
|
|||
printError(&sciErr, 0);
|
||||
return 0;
|
||||
}
|
||||
LhsVar(iOutNum) = iVarOut;
|
||||
|
||||
}
|
||||
|
||||
%typemap(varout,noblock=1) int [ANY],
|
||||
|
|
@ -1741,7 +1741,7 @@
|
|||
printError(&sciErr, 0);
|
||||
return 0;
|
||||
}
|
||||
LhsVar(iOutNum) = iVarOut;
|
||||
|
||||
}
|
||||
|
||||
%typemap(varout,noblock=1) unsigned int [ANY],
|
||||
|
|
@ -1751,7 +1751,7 @@
|
|||
printError(&sciErr, 0);
|
||||
return 0;
|
||||
}
|
||||
LhsVar(iOutNum) = iVarOut;
|
||||
|
||||
}
|
||||
|
||||
%typemap(varout,noblock=1) double [ANY] {
|
||||
|
|
@ -1760,7 +1760,7 @@
|
|||
printError(&sciErr, 0);
|
||||
return 0;
|
||||
}
|
||||
LhsVar(iOutNum) = iVarOut;
|
||||
|
||||
}
|
||||
|
||||
%typemap(varout,noblock=1) float [ANY] {
|
||||
|
|
@ -1769,7 +1769,7 @@
|
|||
printError(&sciErr, 0);
|
||||
return 0;
|
||||
}
|
||||
LhsVar(iOutNum) = iVarOut;
|
||||
|
||||
}
|
||||
|
||||
%typemap(varout,noblock=1) long long [ANY] {
|
||||
|
|
@ -1778,7 +1778,7 @@
|
|||
printError(&sciErr, 0);
|
||||
return 0;
|
||||
}
|
||||
LhsVar(iOutNum) = iVarOut;
|
||||
|
||||
}
|
||||
|
||||
%typemap(varout,noblock=1) unsigned long long [ANY] {
|
||||
|
|
@ -1787,7 +1787,7 @@
|
|||
printError(&sciErr, 0);
|
||||
return 0;
|
||||
}
|
||||
LhsVar(iOutNum) = iVarOut;
|
||||
|
||||
}
|
||||
|
||||
%typemap(varout,noblock=1) char ** {
|
||||
|
|
@ -1799,7 +1799,7 @@
|
|||
printError(&sciErr, 0);
|
||||
return 0;
|
||||
}
|
||||
LhsVar(iOutNum) = iVarOut;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1810,7 +1810,7 @@
|
|||
printError(&sciErr, 0);
|
||||
return 0;
|
||||
}
|
||||
LhsVar(iOutNum) = iVarOut;
|
||||
|
||||
}
|
||||
|
||||
%typemap(varout,noblock=1) unsigned char [ANY][ANY] {
|
||||
|
|
@ -1819,7 +1819,7 @@
|
|||
printError(&sciErr, 0);
|
||||
return 0;
|
||||
}
|
||||
LhsVar(iOutNum) = iVarOut;
|
||||
|
||||
}
|
||||
|
||||
%typemap(varout,noblock=1) short [ANY][ANY] {
|
||||
|
|
@ -1828,7 +1828,7 @@
|
|||
printError(&sciErr, 0);
|
||||
return 0;
|
||||
}
|
||||
LhsVar(iOutNum) = iVarOut;
|
||||
|
||||
}
|
||||
|
||||
%typemap(varout,noblock=1) unsigned short [ANY][ANY] {
|
||||
|
|
@ -1837,7 +1837,7 @@
|
|||
printError(&sciErr, 0);
|
||||
return 0;
|
||||
}
|
||||
LhsVar(iOutNum) = iVarOut;
|
||||
|
||||
}
|
||||
|
||||
%typemap(varout,noblock=1) int [ANY][ANY],
|
||||
|
|
@ -1847,7 +1847,7 @@
|
|||
printError(&sciErr, 0);
|
||||
return 0;
|
||||
}
|
||||
LhsVar(iOutNum) = iVarOut;
|
||||
|
||||
}
|
||||
|
||||
%typemap(varout,noblock=1) unsigned int [ANY][ANY],
|
||||
|
|
@ -1857,7 +1857,7 @@
|
|||
printError(&sciErr, 0);
|
||||
return 0;
|
||||
}
|
||||
LhsVar(iOutNum) = iVarOut;
|
||||
|
||||
}
|
||||
|
||||
%typemap(varout,noblock=1) double [ANY][ANY] {
|
||||
|
|
@ -1866,7 +1866,7 @@
|
|||
printError(&sciErr, 0);
|
||||
return 0;
|
||||
}
|
||||
LhsVar(iOutNum) = iVarOut;
|
||||
|
||||
}
|
||||
|
||||
%typemap(varout,noblock=1) float [ANY][ANY] {
|
||||
|
|
@ -1875,7 +1875,7 @@
|
|||
printError(&sciErr, 0);
|
||||
return 0;
|
||||
}
|
||||
LhsVar(iOutNum) = iVarOut;
|
||||
|
||||
}
|
||||
|
||||
%typemap(varout,noblock=1) long long [ANY][ANY] {
|
||||
|
|
@ -1884,7 +1884,7 @@
|
|||
printError(&sciErr, 0);
|
||||
return 0;
|
||||
}
|
||||
LhsVar(iOutNum) = iVarOut;
|
||||
|
||||
}
|
||||
|
||||
%typemap(varout,noblock=1) unsigned long long [ANY][ANY] {
|
||||
|
|
@ -1893,7 +1893,7 @@
|
|||
printError(&sciErr, 0);
|
||||
return 0;
|
||||
}
|
||||
LhsVar(iOutNum) = iVarOut;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1904,7 +1904,7 @@
|
|||
printError(&sciErr, 0);
|
||||
return 0;
|
||||
}
|
||||
LhsVar(iOutNum) = iVarOut;
|
||||
|
||||
}
|
||||
|
||||
/* Other types */
|
||||
|
|
@ -1914,7 +1914,7 @@
|
|||
printError(&sciErr, 0);
|
||||
return 0;
|
||||
}
|
||||
LhsVar(iOutNum) = iVarOut;
|
||||
|
||||
}
|
||||
|
||||
%typemap(varout,noblock=1) SWIGTYPE {
|
||||
|
|
@ -1923,7 +1923,7 @@
|
|||
printError(&sciErr, 0);
|
||||
return 0;
|
||||
}
|
||||
LhsVar(iOutNum) = iVarOut;
|
||||
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -149,7 +149,6 @@ output values.
|
|||
printError(&sciErr, 0);
|
||||
return 0;
|
||||
}
|
||||
LhsVar(iOutNum) = iVarOut;
|
||||
}
|
||||
|
||||
%typemap(argout) short *OUTPUT(int iRowsOut, int iColsOut),
|
||||
|
|
@ -161,7 +160,6 @@ output values.
|
|||
printError(&sciErr, 0);
|
||||
return 0;
|
||||
}
|
||||
LhsVar(iOutNum) = iVarOut;
|
||||
}
|
||||
|
||||
%typemap(argout) int *OUTPUT(int iRowsOut,int iColsOut),
|
||||
|
|
@ -176,7 +174,6 @@ output values.
|
|||
printError(&sciErr, 0);
|
||||
return 0;
|
||||
}
|
||||
LhsVar(iOutNum)=iVarOut;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -191,7 +188,6 @@ output values.
|
|||
printError(&sciErr, 0);
|
||||
return 0;
|
||||
}
|
||||
LhsVar(iOutNum) = iVarOut;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -322,6 +322,7 @@ public:
|
|||
Printf(f->def, "\nint iOutNum = 1;\nint iVarOut = Rhs + 1;");
|
||||
|
||||
/* Finish the the code for the function */
|
||||
Printf(f->code, "LhsVar(iOutNum) = iVarOut;\n");
|
||||
Printf(f->code, "return 0;\n");
|
||||
Printf(f->code, "}\n");
|
||||
|
||||
|
|
@ -366,6 +367,7 @@ public:
|
|||
/* Dump the dispatch function */
|
||||
Printv(f->code, dispatch, "\n", NIL);
|
||||
Printf(f->code, "Scierror(999, _(\"No matching function for overload\"));\n");
|
||||
Printf(f->code, "LhsVar(iOutNum) = iVarOut;\n");
|
||||
Printf(f->code, "return 0;\n");
|
||||
Printv(f->code, "}\n", NIL);
|
||||
Wrapper_print(f, f_wrappers);
|
||||
|
|
@ -477,6 +479,7 @@ public:
|
|||
}
|
||||
|
||||
/* Dump the wrapper function */
|
||||
Printf(getf->code, "LhsVar(iOutNum) = iVarOut;\n");
|
||||
Append(getf->code, "}\n");
|
||||
Wrapper_print(getf, f_wrappers);
|
||||
Printf(f_header,"%s", globalVar);
|
||||
|
|
@ -536,6 +539,7 @@ public:
|
|||
}
|
||||
|
||||
/* Dump the wrapper function */
|
||||
Printf(getf->code, "LhsVar(iOutNum) = iVarOut;\n");
|
||||
Append(getf->code, "}\n");
|
||||
Wrapper_print(getf, f_wrappers);
|
||||
Printf(f_builder_code, "\"%s\",\"%s\";", getname, getname);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue