summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTiger Feng <songyanf@cs.uchicago.edu>2003-05-21 21:18:44 +0000
committerTiger Feng <songyanf@cs.uchicago.edu>2003-05-21 21:18:44 +0000
commit0ad9c704425509dd79d435bdf199959c3c116663 (patch)
treea78416f60173dd6da6daca500b63286f3d8f92cd
parent6cdd4ee644c3365b5e4a7f49585434d0cd487fc9 (diff)
downloadswig-0ad9c704425509dd79d435bdf199959c3c116663.tar.gz
wrap by contract work
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@4809 626c5289-ae23-0410-ae9c-e8d60b6d4f22
-rw-r--r--Source/Modules/contract.cxx109
-rw-r--r--Source/Modules/emit.cxx68
-rw-r--r--Source/Modules/main.cxx7
-rw-r--r--Source/Modules/swigmod.h3
4 files changed, 90 insertions, 97 deletions
diff --git a/Source/Modules/contract.cxx b/Source/Modules/contract.cxx
index 5ae4868e4..df2832b6a 100644
--- a/Source/Modules/contract.cxx
+++ b/Source/Modules/contract.cxx
@@ -1,14 +1,14 @@
/* -----------------------------------------------------------------------------
* contract.cxx
*
- * Support for Design by Contract in SWIG
+ * Support for Wrap by Contract in SWIG
*
* Author(s) : Songyan Feng (Tiger) (songyanf@cs.uchicago.edu)
*
* Department of Computer Science
* University of Chicago
*
- * Copyright (C) 1999-2000. The University of Chicago
+ * Copyright (C) 1999-2003. The University of Chicago
* See the file LICENSE for information on usage and redistribution.
* ----------------------------------------------------------------------------- */
@@ -16,17 +16,27 @@ char cvsroot_contract_cxx[] = "$Header$";
#include "swigmod.h"
-#define SWIG_PREASSERT "require:"
-#define SWIG_POSTASSERT "ensure:"
-#define SWIG_INVARIANT "invariant:"
-#define SWIG_BEFORE "swig_before("
-#define SWIG_AFTER "swig_after("
+#define SWIG_PREASSERT "require:"
+#define SWIG_POSTASSERT "ensure:"
+#define SWIG_INVARIANT "invariant:"
+#define SWIG_BEFORE "swig_before("
+#define SWIG_AFTER "swig_after("
+
+static int Contract_Mode = 0; /* contract option */
static int InClass = 0; /* Parsing C++ or not */
static Node *CurrentClass = 0;
static int InConstructor = 0;
static int InDestructor = 0;
+void Swig_contract_mode_set(int flag) {
+ Contract_Mode = flag;
+}
+
+int Swig_contract_mode_get() {
+ return Contract_Mode;
+}
+
class Contracts : public Dispatcher {
public:
@@ -45,24 +55,24 @@ public:
int len_post = Len(SWIG_POSTASSERT);
int len_invar = Len(SWIG_INVARIANT);
- if (!mark_invar) { // No invar-
- if (!mark_post) { // No post-
- if ( !mark_pre ) { // No pre-, default is preassert
+ if (!mark_invar) { /* No invar- */
+ if (!mark_post) { /* No post- */
+ if ( !mark_pre ) { /* No pre-, default is preassert */
preassert = contract;
- } else { // with pre- only
+ } else { /* with pre- only */
mark_pre[len_pre-1]='{';
mark_pre[len_pre]='\n';
preassert = mark_pre+len_pre-1;
}
- } else { // with post-
- if (!mark_pre) { // with post- only, but maybe has preassert
+ } else { /* with post- */
+ if (!mark_pre) { /* with post- only, but maybe has preassert */
preassert = contract;
mark_post[0] = '}';
mark_post[1] = '\0';
mark_post[len_post-2] = '{';
mark_post[len_post-1] = '\n';
postassert = mark_post+len_post-2;
- } else { //with both pre- & post- marks
+ } else { /* with both pre- & post- marks */
mark_pre[len_pre-1]='{';
mark_pre[len_pre]='\n';
preassert = mark_pre+len_pre-1;
@@ -73,16 +83,16 @@ public:
postassert = mark_post+len_post-2;
}
}
- } else { //with invar-mark
- if (!mark_post) { // No post- mark
- if ( !mark_pre ) { // with invar- only, but maybe has pre-
+ } else { /* with invar-mark */
+ if (!mark_post) { /* No post- mark */
+ if ( !mark_pre ) { /* with invar- only, but maybe has pre- */
preassert = contract;
mark_invar[0] = '}';
mark_invar[1] = '\0';
mark_invar[len_invar-2] = '{';
mark_invar[len_invar-1] = '\n';
invariant = mark_invar+len_invar-2;
- } else { // with pre- & invar-, no postassert
+ } else { /* with pre- & invar-, no postassert */
mark_pre[len_pre-1]='{';
mark_pre[len_pre]='\n';
preassert = mark_pre+len_pre-1;
@@ -92,8 +102,8 @@ public:
mark_invar[len_invar-1] = '\n';
invariant = mark_invar+len_invar-2;
}
- } else { // with invar- & post-
- if (!mark_pre) { // with post- & invar- only, but maybe has preassert
+ } else { /* with invar- & post- */
+ if (!mark_pre) { /* with post- & invar- only, but maybe has preassert */
preassert = contract;
mark_post[0] = '}';
mark_post[1] = '\0';
@@ -105,7 +115,7 @@ public:
mark_invar[len_invar-2] = '{';
mark_invar[len_invar-1] = '\n';
invariant = mark_invar+len_invar-2;
- } else { // with pre-, post- & invar-
+ } else { /* with pre-, post- & invar- */
mark_pre[len_pre-1]='{';
mark_pre[len_pre]='\n';
preassert = mark_pre+len_pre-1;
@@ -135,10 +145,10 @@ public:
List *list_assert;
ParmList *list_params;
- if (flag == 1) { // preassert
+ if (flag == 1) { /* preassert */
str_assert = NewString(Getattr(n, "feature:preassert"));
tag = NewString(" SWIG_preassert(");
- } else if (flag == 2){ //postassert
+ } else if (flag == 2){ /* postassert */
str_assert = NewString(Getattr(n, "feature:postassert"));
tag = NewString(" SWIG_postassert(");
} else if (flag == 3){
@@ -147,8 +157,8 @@ public:
} else
return SWIG_ERROR;
- // Modify format into { SWIG_xxxassert(...);\n ...}
- // Omit all unuseful characters and split by ;
+ /* Modify format into { SWIG_xxxassert(...);\n ...}
+ Omit all unuseful characters and split by ; */
Replaceall(str_assert, "\n", "");
Replaceall(str_assert, "{", "");
Replaceall(str_assert, "}", "");
@@ -156,12 +166,11 @@ public:
list_assert = Split(str_assert, ';', -1);
Delete(str_assert);
- // build up new assertion
+ /* build up new assertion */
str_assert = NewString("{");
for (s = Firstitem(list_assert); s; s = Nextitem(list_assert)) {
if (Len(s)) {
- //Printf(stdout, "%s\n", s);
- if (Strstr(s, SWIG_BEFORE)) { //before sync assertion
+ if (Strstr(s, SWIG_BEFORE)) { /* before sync assertion */
tag_sync = NewString(" SWIG_sync(");
Append(tag_sync, Getattr(n, "name"));
Append(tag_sync, ", ");
@@ -169,7 +178,7 @@ public:
Append(str_assert, s);
Append(str_assert, ";\n");
Delete(tag_sync);
- } else if (Strstr(s, SWIG_AFTER)) { //after sync assertion
+ } else if (Strstr(s, SWIG_AFTER)) { /* after sync assertion */
tag_sync = NewString(" SWIG_sync(");
Replaceall(s, SWIG_AFTER, tag_sync);
Replaceall(s, ")", ", ");
@@ -177,7 +186,7 @@ public:
Append(str_assert, Getattr(n,"name"));
Append(str_assert, ");\n");
Delete(tag_sync);
- } else { // no sync assertion
+ } else { /* no sync assertion */
Append(str_assert, tag);
Append(str_assert, s);
Append(str_assert, ");\n");
@@ -186,10 +195,10 @@ public:
}
Append(str_assert, "}");
- // Set the params in preassert & postassert
+ /* Set the params in preassert & postassert */
list_params = Getmeta(Getattr(n, "feature:contract"), "parms");
if ((InClass) && (!InConstructor) && (!InDestructor)){
- // Insert function name as parm for class member functions
+ /* Insert function name as parm for class member functions */
String *type = NewString(Getattr(n,"type"));
String *name = NewString("self");
Parm *p = NewParm(type, name);
@@ -219,44 +228,20 @@ public:
int ret = SWIG_OK;
if (!Getattr(n, "feature:contract"))
return SWIG_ERROR;
- //Printf(stdout, "--------In emit_contract code:\nname is : %s\n",
- // Getattr(n,"name"));
- // Split contract into preassert & postassert
+ /*Printf(stdout, "--------In emit_contract code:\nname is : %s\n",
+ Getattr(n,"name")); */
+
+ /* Split contracqt into preassert & postassert */
if (!SliptContract(n))
return SWIG_ERROR;
- // Modify pre- , post- * invar-
+ /* Modify pre- , post- * invar- */
ret = AssertModify(n, 1);
ret = AssertModify(n, 2);
ret = AssertModify(n, 3);
- /*
- Printf(stdout, "preassert after Setmeta :\n%s\n",
- Getattr(n, "feature:preassert"));
- Printf(stdout, "postassert after Setmeta :\n%s\n",
- Getattr(n, "feature:postassert"));
- Printf(stdout, "invariant after Setmeta :\n%s\n",
- Getattr(n, "feature:invariant"));
- */
return ret;
}
- /*
- virtual int emit_one(Node *n) {
- int ret = SWIG_OK;
- char *tag = Char(nodeType(n));
-
- if (!n) return SWIG_OK;
-
- if (strcmp(tag,"include") == 0)
- ret = emit_children(n);
- else if (strcmp(tag, "top") == 0)
- ret = top(n);
- else if (Getattr(n, "feature:contract")) {
- ret = emit_contract(n);
- }
- return ret;
- }
- */
int cDeclaration(Node *n) {
int ret = SWIG_OK;
if (Getattr(n, "feature:contract"))
@@ -286,6 +271,7 @@ public:
int extendDirective(Node *n) { return emit_children(n); }
int importDirective(Node *n) { return emit_children(n); }
int includeDirective(Node *n) { return emit_children(n); }
+
int classDeclaration(Node *n) {
int ret = SWIG_OK;
InClass = 1;
@@ -295,6 +281,7 @@ public:
CurrentClass = 0;
return ret;
}
+
int classHandler(Node *n) {
emit_children(n);
return SWIG_OK;
diff --git a/Source/Modules/emit.cxx b/Source/Modules/emit.cxx
index 9b0efaf76..c232e44d0 100644
--- a/Source/Modules/emit.cxx
+++ b/Source/Modules/emit.cxx
@@ -364,7 +364,6 @@ void replace_args(Parm *p, String *s) {
/* replace_contract_args. This function replaces argument names in contract
specifications. Used in conjunction with the %contract directive. */
-//replace_contract_args(Getmeta(tm,"parms"), Getattr(n,"parms"),tm);
static
void replace_contract_args(Parm *cp, Parm *rp, String *s) {
while (cp && rp) {
@@ -426,23 +425,25 @@ void emit_action(Node *n, Wrapper *f) {
rt = Getattr(n,"type");
- /* Preassert -- EXPERIMENTAL */
- tm = Getattr(n,"feature:preassert");
- if (tm) {
- replace_contract_args(Getmeta(tm,"parms"), Getattr(n,"parms"),tm);
- /* Printf(stdout, "name: %s, preassert: %s\n", Getattr(n,"name"), tm); */
- Printv(f->code,tm,"\n",NIL);
- }
-
- /* Invariant -- EXPERIMENTAL */
- tm = Getattr(n,"feature:invariant");
- if (tm) {
- replace_contract_args(Getmeta(tm,"parms"), Getattr(n,"parms"),tm);
- Replaceid(tm, "SWIG_invariant", "SWIG_invariant_begin");
- /* Printf(stdout, "name: %s, invarassert: %s\n", Getattr(n,"name"), tm); */
- Printv(f->code,tm,"\n",NIL);
+ /* Emit contract code (if any) */
+ if (Swig_contract_mode_get()) {
+ /* Preassertion */
+ tm = Getattr(n,"feature:preassert");
+ if (tm) {
+ replace_contract_args(Getmeta(tm,"parms"), Getattr(n,"parms"),tm);
+ /* Printf(stdout, "name: %s, preassert: %s\n", Getattr(n,"name"), tm); */
+ Printv(f->code,tm,"\n",NIL);
+ }
+
+ /* Invariant -- EXPERIMENTAL */
+ tm = Getattr(n,"feature:invariant");
+ if (tm) {
+ replace_contract_args(Getmeta(tm,"parms"), Getattr(n,"parms"),tm);
+ Replaceid(tm, "SWIG_invariant", "SWIG_invariant_begin");
+ /* Printf(stdout, "name: %s, invarassert: %s\n", Getattr(n,"name"), tm); */
+ Printv(f->code,tm,"\n",NIL);
+ }
}
-
/* Exception handling code */
/* If we are in C++ mode and there is a throw specifier. We're going to
@@ -487,21 +488,22 @@ void emit_action(Node *n, Wrapper *f) {
Printf(f->code,"catch(...) { throw; }\n");
}
- /* Invariant -- EXPERIMENTAL */
- tm = Getattr(n,"feature:invariant");
- if (tm) {
- replace_contract_args(Getmeta(tm,"parms"), Getattr(n,"parms"),tm);
- Replaceid(tm, "SWIG_invariant", "SWIG_invariant_end");
- /* Printf(stdout, "name: %s, invarassert: %s\n", Getattr(n,"name"), tm); */
- Printv(f->code,tm,"\n",NIL);
- }
- /* Postassert - EXPERIMENTAL */
- tm = Getattr(n,"feature:postassert");
- if (tm) {
- replace_contract_args(Getmeta(tm,"parms"), Getattr(n,"parms"),tm);
- /* Printf(stdout, "name: %s, postassert: %s\n", Getattr(n,"name"), tm); */
- Printv(f->code,tm,"\n",NIL);
+ /* Emit contract code (if any) */
+ if (Swig_contract_mode_get()) {
+ /* Invariant -- EXPERIMENTAL */
+ tm = Getattr(n,"feature:invariant");
+ if (tm) {
+ replace_contract_args(Getmeta(tm,"parms"), Getattr(n,"parms"),tm);
+ Replaceid(tm, "SWIG_invariant", "SWIG_invariant_end");
+ /* Printf(stdout, "name: %s, invarassert: %s\n", Getattr(n,"name"), tm); */
+ Printv(f->code,tm,"\n",NIL);
+ }
+ /* Postassertion - EXPERIMENTAL */
+ tm = Getattr(n,"feature:postassert");
+ if (tm) {
+ replace_contract_args(Getmeta(tm,"parms"), Getattr(n,"parms"),tm);
+ /* Printf(stdout, "name: %s, postassert: %s\n", Getattr(n,"name"), tm); */
+ Printv(f->code,tm,"\n",NIL);
+ }
}
}
-
-
diff --git a/Source/Modules/main.cxx b/Source/Modules/main.cxx
index 1161d5e5d..a8272b9c6 100644
--- a/Source/Modules/main.cxx
+++ b/Source/Modules/main.cxx
@@ -183,7 +183,6 @@ int SWIG_main(int argc, char *argv[], Language *l) {
extern int check_suffix(char *);
int dump_tags = 0;
int dump_tree = 0;
- int contracts = 0;
int browse = 0;
int dump_typedef = 0;
int dump_classes = 0;
@@ -194,6 +193,8 @@ int SWIG_main(int argc, char *argv[], Language *l) {
DOH *libfiles = 0;
DOH *cpps = 0 ;
extern void Swig_contracts(Node *n);
+ extern void Swig_contract_mode_set(int flag);
+ extern int Swig_contract_mode_get();
extern void Swig_browser(Node *n, int);
extern void Swig_default_allocators(Node *n);
extern void Swig_process_types(Node *n);
@@ -418,7 +419,7 @@ int SWIG_main(int argc, char *argv[], Language *l) {
Swig_mark_arg(i);
} else if (strcmp(argv[i],"-contracts") == 0) {
Swig_mark_arg(i);
- contracts = 1;
+ Swig_contract_mode_set(1);
} else if (strcmp(argv[i],"-browse") == 0) {
browse = 1;
Swig_mark_arg(i);
@@ -644,7 +645,7 @@ int SWIG_main(int argc, char *argv[], Language *l) {
Setattr(top,"outfile_h", NewStringf("%s.h", header));
free(header);
}
- if (contracts) {
+ if (Swig_contract_mode_get()) {
Swig_contracts(top);
}
lang->top(top);
diff --git a/Source/Modules/swigmod.h b/Source/Modules/swigmod.h
index 77c6a0c97..21ec1586f 100644
--- a/Source/Modules/swigmod.h
+++ b/Source/Modules/swigmod.h
@@ -265,6 +265,9 @@ extern void emit_action(Node *n, Wrapper *f);
extern List *Swig_overload_rank(Node *n);
extern String *Swig_overload_dispatch(Node *n, const String_or_char *fmt, int *);
+extern void Swig_contracts(Node *n);
+extern void Swig_contract_mode_set(int flag);
+extern int Swig_contract_mode_get();
extern "C" {
typedef Language *(*ModuleFactory)(void);