~ubuntu-branches/ubuntu/hardy/swig1.3/hardy

« back to all changes in this revision

Viewing changes to Doc/Manual/Contract.html

  • Committer: Bazaar Package Importer
  • Author(s): Adam Conrad
  • Date: 2005-12-05 01:16:04 UTC
  • mfrom: (1.2.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20051205011604-ygx904it6413k3go
Tags: 1.3.27-1ubuntu1
Resynchronise with Debian again, for the new subversion packages.

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
<html>
3
3
<head>
4
4
<title>Contract Checking</title>
 
5
<link rel="stylesheet" type="text/css" href="style.css">
5
6
</head>
6
7
 
7
8
<body bgcolor="#ffffff">
8
9
<H1><a name="Contract"></a>12 Contracts</H1>
9
10
<!-- INDEX -->
 
11
<div class="sectiontoc">
10
12
<ul>
11
13
<li><a href="#Contract_nn2">The %contract directive</a>
12
14
<li><a href="#Contract_nn3">%contract and classes</a>
13
15
<li><a href="#Contract_nn4">Constant aggregation and %aggregate_check</a>
14
16
<li><a href="#Contract_nn5">Notes</a>
15
17
</ul>
 
18
</div>
16
19
<!-- INDEX -->
17
20
 
18
21
 
19
22
 
 
23
<p>
20
24
A common problem that arises when wrapping C libraries is that of maintaining
21
25
reliability and checking for errors.  The fact of the matter is that many
22
26
C programs are notorious for not providing error checks.  Not only that, 
23
27
when you expose the internals of an application as a library, it
24
28
often becomes possible to crash it simply by providing bad inputs or
25
29
using it in a way that wasn't intended.
 
30
</p>
26
31
 
27
32
<p>
28
33
This chapter describes SWIG's support for software contracts.  In the context
36
41
<H2><a name="Contract_nn2"></a>12.1 The %contract directive</H2>
37
42
 
38
43
 
 
44
<p>
39
45
Contracts are added to a declaration using the %contract directive.  Here
40
46
is a simple example:
 
47
</p>
41
48
 
42
 
<blockquote>
 
49
<div class="code">
43
50
<pre>
44
51
%contract sqrt(double x) {
45
52
require:
51
58
...
52
59
double sqrt(double);
53
60
</pre>
54
 
</blockquote>
 
61
</div>
55
62
 
 
63
<p>
56
64
In this case, a contract is being added to the <tt>sqrt()</tt> function.
57
65
The <tt>%contract</tt> directive must always appear before the declaration
58
66
in question.  Within the contract there are two sections, both of which
62
70
specifies conditions that must hold after the function is called.  This is
63
71
often used to check return values or the state of the program.  In both
64
72
cases, the conditions that must hold must be specified as boolean expressions.
 
73
</p>
65
74
 
66
75
<p>
67
76
In the above example, we're simply making sure that sqrt() returns a non-negative
73
82
resulting module.  For example:
74
83
</p>
75
84
 
76
 
<blockquote>
 
85
<div class="shell">
77
86
<pre>
78
87
&gt;&gt;&gt; example.sqrt(2)
79
88
1.4142135623730951
83
92
RuntimeError: Contract violation: require: (arg1&gt;=0)
84
93
&gt;&gt;&gt;
85
94
</pre>
86
 
</blockquote>
 
95
</div>
87
96
 
88
97
<H2><a name="Contract_nn3"></a>12.2 %contract and classes</H2>
89
98
 
90
99
 
 
100
<p>
91
101
The <tt>%contract</tt> directive can also be applied to class methods and constructors.  For example:
 
102
</p>
92
103
 
93
 
<blockquote>
 
104
<div class="code">
94
105
<pre>
95
106
%contract Foo::bar(int x, int y) {
96
107
require:
110
121
    int bar(int, int);
111
122
};
112
123
</pre>
113
 
</blockquote>
 
124
</div>
114
125
 
 
126
<p>
115
127
The way in which <tt>%contract</tt> is applied is exactly the same as the <tt>%feature</tt> directive. 
116
128
Thus, any contract that you specified for a base class will also be attached to inherited methods.  For example:
 
129
</p>
117
130
 
118
 
<blockquote>
 
131
<div class="code">
119
132
<pre>
120
133
class Spam : public Foo {
121
134
public:
122
135
   int bar(int,int);    // Gets contract defined for Foo::bar(int,int)
123
136
};
124
137
</pre>
125
 
</blockquote>
 
138
</div>
126
139
 
 
140
<p>
127
141
In addition to this, separate contracts can be applied to both the base class and a derived class.  For example:
 
142
</p>
128
143
 
129
 
<blockquote>
 
144
<div class="code">
130
145
<pre>
131
146
%contract Foo::bar(int x, int) {
132
147
require:
148
163
     int bar(int,int);   // Gets Foo::bar and Spam::bar contract
149
164
};
150
165
</pre>
151
 
</blockquote>
 
166
</div>
152
167
 
 
168
<p>
153
169
When more than one contract is applied, the conditions specified in a
154
170
"require:" section are combined together using a logical-AND operation.
155
171
In other words conditions specified for the base class and conditions
156
172
specified for the derived class all must hold.  In the above example,
157
173
this means that both the arguments to <tt>Spam::bar</tt> must be positive.
 
174
</p>
158
175
 
159
176
<H2><a name="Contract_nn4"></a>12.3 Constant aggregation and %aggregate_check</H2>
160
177
 
161
178
 
 
179
<p>
162
180
Consider an interface file that contains the following code:
 
181
</p>
163
182
 
164
 
<blockquote>
 
183
<div class="code">
165
184
<pre>
166
185
#define  UP     1
167
186
#define  DOWN   2
170
189
 
171
190
void move(SomeObject *, int direction, int distance);
172
191
</pre>
173
 
</blockquote>
 
192
</div>
174
193
 
 
194
<p>
175
195
One thing you might want to do is impose a constraint on the direction parameter to
176
196
make sure it's one of a few accepted values.  To do that, SWIG provides an easy to
177
197
use macro %aggregate_check() that works like this:
 
198
</p>
178
199
 
179
 
<blockquote>
 
200
<div class="code">
180
201
<pre>
181
202
%aggregate_check(int, check_direction, UP, DOWN, LEFT, RIGHT);
182
203
</pre>
183
 
</blockquote>
 
204
</div>
184
205
 
 
206
<p>
185
207
This merely defines a utility function of the form
 
208
</p>
186
209
 
187
 
<blockquote>
 
210
<div class="code">
188
211
<pre>
189
212
int check_direction(int x);
190
213
</pre>
191
 
</blockquote>
 
214
</div>
192
215
 
 
216
<p>
193
217
That checks the argument x to see if it is one of the values listed.   This utility 
194
218
function can be used in contracts.  For example:
 
219
</p>
195
220
 
196
 
<blockquote>
 
221
<div class="code">
197
222
<pre>
198
223
%aggregate_check(int, check_direction, UP, DOWN, RIGHT, LEFT);
199
224
 
209
234
 
210
235
void move(SomeObject *, int direction, int distance);
211
236
</pre>
212
 
</blockquote>
 
237
</div>
213
238
 
 
239
<p>
214
240
Alternatively, it can be used in typemaps and other directives.  For example:
215
 
<blockquote>
 
241
</p>
 
242
 
 
243
<div class="code">
216
244
<pre>
217
245
%aggregate_check(int, check_direction, UP, DOWN, RIGHT, LEFT);
218
246
 
227
255
 
228
256
void move(SomeObject *, int direction, int distance);
229
257
</pre>
230
 
</blockquote>
 
258
</div>
231
259
 
 
260
<p>
232
261
Regrettably, there is no automatic way to perform similar checks with enums values.  Maybe in a future
233
262
release.
 
263
</p>
234
264
 
235
265
<H2><a name="Contract_nn5"></a>12.4 Notes</H2>
236
266
 
237
267
 
 
268
<p>
238
269
Contract support was implemented by Songyan (Tiger) Feng and first appeared
239
270
in SWIG-1.3.20.
 
271
</p>
240
272
 
241
273
</body>
242
274
</html>