diff options
author | Tiger Feng <songyanf@cs.uchicago.edu> | 2003-05-21 21:18:44 +0000 |
---|---|---|
committer | Tiger Feng <songyanf@cs.uchicago.edu> | 2003-05-21 21:18:44 +0000 |
commit | 0ad9c704425509dd79d435bdf199959c3c116663 (patch) | |
tree | a78416f60173dd6da6daca500b63286f3d8f92cd | |
parent | 6cdd4ee644c3365b5e4a7f49585434d0cd487fc9 (diff) | |
download | swig-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.cxx | 109 | ||||
-rw-r--r-- | Source/Modules/emit.cxx | 68 | ||||
-rw-r--r-- | Source/Modules/main.cxx | 7 | ||||
-rw-r--r-- | Source/Modules/swigmod.h | 3 |
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); |