"Fossies" - the Fresh Open Source Software Archive

Member "swig-4.1.1/Doc/Manual/Contract.html" (30 Nov 2022, 6544 Bytes) of package /linux/misc/swig-4.1.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) HTML source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file.

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