mirror of https://github.com/swig/swig
276 lines
6.4 KiB
HTML
276 lines
6.4 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
|
<html>
|
|
<head>
|
|
<title>Contract Checking</title>
|
|
<link rel="stylesheet" type="text/css" href="style.css">
|
|
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
|
</head>
|
|
|
|
<body bgcolor="#ffffff">
|
|
<H1><a name="Contract">16 Contracts</a></H1>
|
|
<!-- INDEX -->
|
|
<div class="sectiontoc">
|
|
<ul>
|
|
<li><a href="#Contract_nn2">The %contract directive</a>
|
|
<li><a href="#Contract_nn3">%contract and classes</a>
|
|
<li><a href="#Contract_nn4">Constant aggregation and %aggregate_check</a>
|
|
<li><a href="#Contract_nn5">Notes</a>
|
|
</ul>
|
|
</div>
|
|
<!-- INDEX -->
|
|
|
|
|
|
|
|
<p>
|
|
A common problem that arises when wrapping C libraries is that of maintaining
|
|
reliability and checking for errors. The fact of the matter is that many
|
|
C programs are notorious for not providing error checks. Not only that,
|
|
when you expose the internals of an application as a library, it
|
|
often becomes possible to crash it simply by providing bad inputs or
|
|
using it in a way that wasn't intended.
|
|
</p>
|
|
|
|
<p>
|
|
This chapter describes SWIG's support for software contracts. In the context
|
|
of SWIG, a contract can be viewed as a runtime constraint that is attached
|
|
to a declaration. For example, you can easily attach argument checking rules,
|
|
check the output values of a function and more.
|
|
When one of the rules is violated by a script, a runtime exception is
|
|
generated rather than having the program continue to execute.
|
|
</p>
|
|
|
|
<H2><a name="Contract_nn2">16.1 The %contract directive</a></H2>
|
|
|
|
|
|
<p>
|
|
Contracts are added to a declaration using the %contract directive. Here
|
|
is a simple example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%contract sqrt(double x) {
|
|
require:
|
|
x >= 0;
|
|
ensure:
|
|
sqrt >= 0;
|
|
}
|
|
|
|
...
|
|
double sqrt(double);
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
In this case, a contract is being added to the <tt>sqrt()</tt> function.
|
|
The <tt>%contract</tt> directive must always appear before the declaration
|
|
in question. Within the contract there are two sections, both of which
|
|
are optional. The <tt>require:</tt>
|
|
section specifies conditions that must hold before the function is called.
|
|
Typically, this is used to check argument values. The <tt>ensure:</tt> section
|
|
specifies conditions that must hold after the function is called. This is
|
|
often used to check return values or the state of the program. In both
|
|
cases, the conditions that must hold must be specified as boolean expressions.
|
|
</p>
|
|
|
|
<p>
|
|
In the above example, we're simply making sure that sqrt() returns a non-negative
|
|
number (if it didn't, then it would be broken in some way).
|
|
</p>
|
|
|
|
<p>
|
|
Once a contract has been specified, it modifies the behavior of the
|
|
resulting module. For example:
|
|
</p>
|
|
|
|
<div class="shell">
|
|
<pre>
|
|
>>> example.sqrt(2)
|
|
1.4142135623730951
|
|
>>> example.sqrt(-2)
|
|
Traceback (most recent call last):
|
|
File "<stdin>", line 1, in ?
|
|
RuntimeError: Contract violation: require: (arg1>=0)
|
|
>>>
|
|
</pre>
|
|
</div>
|
|
|
|
<H2><a name="Contract_nn3">16.2 %contract and classes</a></H2>
|
|
|
|
|
|
<p>
|
|
The <tt>%contract</tt> directive can also be applied to class methods and constructors. For example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%contract Foo::bar(int x, int y) {
|
|
require:
|
|
x > 0;
|
|
ensure:
|
|
bar > 0;
|
|
}
|
|
|
|
%contract Foo::Foo(int a) {
|
|
require:
|
|
a > 0;
|
|
}
|
|
|
|
class Foo {
|
|
public:
|
|
Foo(int);
|
|
int bar(int, int);
|
|
};
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
The way in which <tt>%contract</tt> is applied is exactly the same as the <tt>%feature</tt> directive.
|
|
Thus, any contract that you specified for a base class will also be attached to inherited methods. For example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
class Spam : public Foo {
|
|
public:
|
|
int bar(int, int); // Gets contract defined for Foo::bar(int, int)
|
|
};
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
In addition to this, separate contracts can be applied to both the base class and a derived class. For example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%contract Foo::bar(int x, int) {
|
|
require:
|
|
x > 0;
|
|
}
|
|
|
|
%contract Spam::bar(int, int y) {
|
|
require:
|
|
y > 0;
|
|
}
|
|
|
|
class Foo {
|
|
public:
|
|
int bar(int, int); // Gets Foo::bar contract.
|
|
};
|
|
|
|
class Spam : public Foo {
|
|
public:
|
|
int bar(int, int); // Gets Foo::bar and Spam::bar contract
|
|
};
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
When more than one contract is applied, the conditions specified in a
|
|
"require:" section are combined together using a logical-AND operation.
|
|
In other words conditions specified for the base class and conditions
|
|
specified for the derived class all must hold. In the above example,
|
|
this means that both the arguments to <tt>Spam::bar</tt> must be positive.
|
|
</p>
|
|
|
|
<H2><a name="Contract_nn4">16.3 Constant aggregation and %aggregate_check</a></H2>
|
|
|
|
|
|
<p>
|
|
Consider an interface file that contains the following code:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
#define UP 1
|
|
#define DOWN 2
|
|
#define RIGHT 3
|
|
#define LEFT 4
|
|
|
|
void move(SomeObject *, int direction, int distance);
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
One thing you might want to do is impose a constraint on the direction parameter to
|
|
make sure it's one of a few accepted values. To do that, SWIG provides an easy to
|
|
use macro %aggregate_check() that works like this:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%aggregate_check(int, check_direction, UP, DOWN, LEFT, RIGHT);
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
This merely defines a utility function of the form
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
int check_direction(int x);
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
That checks the argument x to see if it is one of the values listed. This utility
|
|
function can be used in contracts. For example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%aggregate_check(int, check_direction, UP, DOWN, RIGHT, LEFT);
|
|
|
|
%contract move(SomeObject *, int direction, in) {
|
|
require:
|
|
check_direction(direction);
|
|
}
|
|
|
|
#define UP 1
|
|
#define DOWN 2
|
|
#define RIGHT 3
|
|
#define LEFT 4
|
|
|
|
void move(SomeObject *, int direction, int distance);
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
Alternatively, it can be used in typemaps and other directives. For example:
|
|
</p>
|
|
|
|
<div class="code">
|
|
<pre>
|
|
%aggregate_check(int, check_direction, UP, DOWN, RIGHT, LEFT);
|
|
|
|
%typemap(check) int direction {
|
|
if (!check_direction($1)) SWIG_exception(SWIG_ValueError, "Bad direction");
|
|
}
|
|
|
|
#define UP 1
|
|
#define DOWN 2
|
|
#define RIGHT 3
|
|
#define LEFT 4
|
|
|
|
void move(SomeObject *, int direction, int distance);
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
Regrettably, there is no automatic way to perform similar checks with enums values. Maybe in a future
|
|
release.
|
|
</p>
|
|
|
|
<H2><a name="Contract_nn5">16.4 Notes</a></H2>
|
|
|
|
|
|
<p>
|
|
Contract support was implemented by Songyan (Tiger) Feng and first appeared
|
|
in SWIG-1.3.20.
|
|
</p>
|
|
|
|
</body>
|
|
</html>
|