mirror of https://github.com/swig/swig
240 lines
7.9 KiB
OpenEdge ABL
240 lines
7.9 KiB
OpenEdge ABL
%module csharp_exceptions
|
|
|
|
// throw is invalid in C++17 and later, only SWIG to use it
|
|
#define TESTCASE_THROW1(T1) throw(T1)
|
|
%{
|
|
#define TESTCASE_THROW1(T1)
|
|
%}
|
|
|
|
%include <exception.i>
|
|
|
|
%inline %{
|
|
class Ex {
|
|
const char *message;
|
|
public:
|
|
Ex(const char *msg) : message(msg) {}
|
|
const char *what() { return message; }
|
|
};
|
|
%}
|
|
|
|
%exception ThrowByValue() {
|
|
try {
|
|
$action
|
|
} catch(Ex e) {
|
|
SWIG_exception(SWIG_DivisionByZero, e.what());
|
|
}
|
|
}
|
|
|
|
%exception ThrowByReference() {
|
|
try {
|
|
$action
|
|
} catch(Ex &e) {
|
|
SWIG_exception(SWIG_DivisionByZero, e.what());
|
|
}
|
|
}
|
|
|
|
%csnothrowexception NoThrowException() {
|
|
try {
|
|
$action
|
|
} catch(Ex) {
|
|
// swallowed
|
|
}
|
|
}
|
|
|
|
%inline %{
|
|
// %exception tests
|
|
void ThrowByValue() { throw Ex("ThrowByValue"); }
|
|
void ThrowByReference() { throw Ex("ThrowByReference"); }
|
|
// %csnothrowexception
|
|
void NoThrowException() { throw Ex("NoThrowException"); }
|
|
// exception specifications
|
|
void ExceptionSpecificationValue() TESTCASE_THROW1(Ex) { throw Ex("ExceptionSpecificationValue"); }
|
|
void ExceptionSpecificationReference() TESTCASE_THROW1(Ex&) { throw Ex("ExceptionSpecificationReference"); }
|
|
void ExceptionSpecificationString() TESTCASE_THROW1(const char *) { throw "ExceptionSpecificationString"; }
|
|
void ExceptionSpecificationInteger() TESTCASE_THROW1(int) { throw 20; }
|
|
%}
|
|
|
|
// test exceptions in the default typemaps
|
|
|
|
// null reference exceptions
|
|
%inline %{
|
|
void NullReference(Ex& e) {}
|
|
void NullValue(Ex e) {}
|
|
%}
|
|
|
|
// enums
|
|
%inline %{
|
|
enum TestEnum {TestEnumItem};
|
|
void ExceptionSpecificationEnumValue() TESTCASE_THROW1(TestEnum) { throw TestEnumItem; }
|
|
void ExceptionSpecificationEnumReference() TESTCASE_THROW1(TestEnum&) { throw TestEnumItem; }
|
|
%}
|
|
|
|
// std::string
|
|
%include <std_string.i>
|
|
%inline %{
|
|
void ExceptionSpecificationStdStringValue() TESTCASE_THROW1(std::string) { throw std::string("ExceptionSpecificationStdStringValue"); }
|
|
void ExceptionSpecificationStdStringReference() TESTCASE_THROW1(const std::string&) { throw std::string("ExceptionSpecificationStdStringReference"); }
|
|
void NullStdStringValue(std::string s) {}
|
|
void NullStdStringReference(std::string &s) {}
|
|
%}
|
|
|
|
// Memory leak check (The C++ exception stack was never unwound in the original approach to throwing exceptions from unmanaged code)
|
|
%exception MemoryLeakCheck() {
|
|
Counter destructor_should_be_called;
|
|
try {
|
|
$action
|
|
} catch(Ex e) {
|
|
SWIG_exception(SWIG_DivisionByZero, e.what());
|
|
}
|
|
}
|
|
|
|
%inline %{
|
|
struct Counter {
|
|
static int count;
|
|
Counter() { count++; }
|
|
~Counter() { count--; }
|
|
};
|
|
int Counter::count = 0;
|
|
|
|
void MemoryLeakCheck() {
|
|
throw Ex("testing memory leaks when throwing exceptions");
|
|
}
|
|
%}
|
|
|
|
// test exception pending in the csconstruct typemap
|
|
%inline %{
|
|
struct constructor {
|
|
constructor(std::string s) {}
|
|
constructor() TESTCASE_THROW1(int) { throw 10; }
|
|
};
|
|
%}
|
|
|
|
// test exception pending in the csout typemaps
|
|
%typemap(out, canthrow=1) unsigned short ushorttest %{
|
|
$result = $1;
|
|
if ($result == 100) {
|
|
SWIG_CSharpSetPendingException(SWIG_CSharpIndexOutOfRangeException, "don't like 100");
|
|
return $null;
|
|
}
|
|
%}
|
|
%inline %{
|
|
unsigned short ushorttest() { return 100; }
|
|
%}
|
|
|
|
// test exception pending in the csvarout/csvarin typemaps and canthrow attribute in unmanaged code typemaps
|
|
%typemap(check, canthrow=1) int numberin, int InOutStruct::staticnumberin %{
|
|
if ($1 < 0) {
|
|
SWIG_CSharpSetPendingException(SWIG_CSharpIndexOutOfRangeException, "too small");
|
|
return $null;
|
|
}
|
|
%}
|
|
%typemap(out, canthrow=1) int numberout, int InOutStruct::staticnumberout %{
|
|
$result = $1;
|
|
if ($result > 10) {
|
|
SWIG_CSharpSetPendingException(SWIG_CSharpIndexOutOfRangeException, "too big");
|
|
return $null;
|
|
}
|
|
%}
|
|
%inline %{
|
|
int numberin;
|
|
int numberout;
|
|
struct InOutStruct {
|
|
int numberin;
|
|
int numberout;
|
|
static int staticnumberin;
|
|
static int staticnumberout;
|
|
};
|
|
int InOutStruct::staticnumberin;
|
|
int InOutStruct::staticnumberout;
|
|
%}
|
|
|
|
// test SWIG_exception macro - it must return from unmanaged code without executing any further unmanaged code
|
|
%typemap(check, canthrow=1) int macrotest {
|
|
if ($1 < 0) {
|
|
SWIG_exception(SWIG_IndexError, "testing SWIG_exception macro");
|
|
}
|
|
}
|
|
%inline %{
|
|
bool exception_macro_run_flag = false;
|
|
void exceptionmacrotest(int macrotest) {
|
|
exception_macro_run_flag = true;
|
|
}
|
|
%}
|
|
|
|
// test all the types of exceptions
|
|
%typemap(check, canthrow=1) UnmanagedExceptions {
|
|
switch($1) {
|
|
case UnmanagedApplicationException: SWIG_CSharpSetPendingException(SWIG_CSharpApplicationException, "msg"); return $null; break;
|
|
case UnmanagedArithmeticException: SWIG_CSharpSetPendingException(SWIG_CSharpArithmeticException, "msg"); return $null; break;
|
|
case UnmanagedDivideByZeroException: SWIG_CSharpSetPendingException(SWIG_CSharpDivideByZeroException, "msg"); return $null; break;
|
|
case UnmanagedIndexOutOfRangeException: SWIG_CSharpSetPendingException(SWIG_CSharpIndexOutOfRangeException, "msg"); return $null; break;
|
|
case UnmanagedInvalidCastException: SWIG_CSharpSetPendingException(SWIG_CSharpInvalidCastException, "msg"); return $null; break;
|
|
case UnmanagedInvalidOperationException: SWIG_CSharpSetPendingException(SWIG_CSharpInvalidOperationException, "msg"); return $null; break;
|
|
case UnmanagedIOException: SWIG_CSharpSetPendingException(SWIG_CSharpIOException, "msg"); return $null; break;
|
|
case UnmanagedNullReferenceException: SWIG_CSharpSetPendingException(SWIG_CSharpNullReferenceException, "msg"); return $null; break;
|
|
case UnmanagedOutOfMemoryException: SWIG_CSharpSetPendingException(SWIG_CSharpOutOfMemoryException, "msg"); return $null; break;
|
|
case UnmanagedOverflowException: SWIG_CSharpSetPendingException(SWIG_CSharpOverflowException, "msg"); return $null; break;
|
|
case UnmanagedSystemException: SWIG_CSharpSetPendingException(SWIG_CSharpSystemException, "msg"); return $null; break;
|
|
case UnmanagedArgumentException: SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentException, "msg", "parm"); return $null; break;
|
|
case UnmanagedArgumentNullException: SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "msg", "parm"); return $null; break;
|
|
case UnmanagedArgumentOutOfRangeException: SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentOutOfRangeException, "msg", "parm"); return $null; break;
|
|
}
|
|
}
|
|
%inline %{
|
|
enum UnmanagedExceptions {
|
|
UnmanagedApplicationException,
|
|
UnmanagedArithmeticException,
|
|
UnmanagedDivideByZeroException,
|
|
UnmanagedIndexOutOfRangeException,
|
|
UnmanagedInvalidCastException,
|
|
UnmanagedInvalidOperationException,
|
|
UnmanagedIOException,
|
|
UnmanagedNullReferenceException,
|
|
UnmanagedOutOfMemoryException,
|
|
UnmanagedOverflowException,
|
|
UnmanagedSystemException,
|
|
UnmanagedArgumentException,
|
|
UnmanagedArgumentNullException,
|
|
UnmanagedArgumentOutOfRangeException
|
|
};
|
|
|
|
void check_exception(UnmanagedExceptions e) {
|
|
}
|
|
%}
|
|
|
|
// exceptions in multiple threads test
|
|
%exception ThrowsClass::ThrowException(long long input) {
|
|
try {
|
|
$action
|
|
} catch (long long d) {
|
|
char message[64];
|
|
sprintf(message, "caught:%lld", d);
|
|
SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentOutOfRangeException, message, "input");
|
|
}
|
|
}
|
|
%inline %{
|
|
struct ThrowsClass {
|
|
double dub;
|
|
ThrowsClass(double d) : dub(d) {}
|
|
long long ThrowException(long long input) {
|
|
throw input;
|
|
return input;
|
|
}
|
|
};
|
|
%}
|
|
|
|
// test inner exceptions
|
|
%exception InnerExceptionTest() {
|
|
try {
|
|
$action
|
|
} catch(Ex &e) {
|
|
SWIG_CSharpSetPendingException(SWIG_CSharpApplicationException, e.what());
|
|
SWIG_CSharpSetPendingException(SWIG_CSharpInvalidOperationException, "My OuterException message");
|
|
}
|
|
}
|
|
|
|
%inline %{
|
|
void InnerExceptionTest() { throw Ex("My InnerException message"); }
|
|
%}
|
|
|