summaryrefslogtreecommitdiff
path: root/Doc/Manual/Contract.html
blob: 660daf9fca67a726e3721cbf84e7a3bfb37a3a44 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Contract Checking</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>

<body bgcolor="#ffffff">
<H1><a name="Contract">13 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">13.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 &gt;= 0;
ensure:
    sqrt &gt;= 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>
&gt;&gt;&gt; example.sqrt(2)
1.4142135623730951
&gt;&gt;&gt; example.sqrt(-2)
Traceback (most recent call last):
  File "&lt;stdin&gt;", line 1, in ?
RuntimeError: Contract violation: require: (arg1&gt;=0)
&gt;&gt;&gt;
</pre>
</div>

<H2><a name="Contract_nn3">13.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 &gt; 0;
ensure:
   bar &gt; 0;
}

%contract Foo::Foo(int a) {
require:
   a &gt; 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 &gt; 0;
}

%contract Spam::bar(int, int y) {
require:
    y &gt; 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">13.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">13.4 Notes</a></H2>


<p>
Contract support was implemented by Songyan (Tiger) Feng and first appeared
in SWIG-1.3.20.
</p>

</body>
</html>