PageRenderTime 46ms CodeModel.GetById 14ms app.highlight 14ms RepoModel.GetById 0ms app.codeStats 0ms

/tags/rel-1-3-15/SWIG/Source/Modules1.1/contract.cxx

#
C++ | 118 lines | 82 code | 18 blank | 18 comment | 9 complexity | 7f408ce03cb7abad10faabe1a638bfb3 MD5 | raw file
Possible License(s): LGPL-2.1, Cube, GPL-3.0, 0BSD, GPL-2.0
  1/* ----------------------------------------------------------------------------- 
  2 * contract.cxx
  3 *
  4 *     Experimental support for contracts
  5 * 
  6 * Author(s) : Aquinas Hobor (aahobor@cs.uchicago.edu)
  7 *
  8 * Copyright (C) 1999-2000.  The University of Chicago
  9 * See the file LICENSE for information on usage and redistribution.	
 10 * ----------------------------------------------------------------------------- */
 11
 12static char cvsroot[] = "$Header$";
 13
 14#include "swigmod.h"
 15
 16class Contracts : public Dispatcher {
 17
 18public:
 19  virtual int top(Node *n) {
 20    emit_children(n);
 21    return SWIG_OK;
 22  }
 23
 24  virtual int importDirective(Node *n) { return emit_children(n); }
 25  virtual int includeDirective(Node *n) { return emit_children(n); }  // ?
 26  virtual int externDeclaration(Node *n) { return emit_children(n); }
 27
 28  String * strParms(ParmList *l) {
 29    int comma = 0;
 30    int i = 0;
 31    Parm *p = l;
 32    SwigType *pt;
 33    String * returns = NewString("");
 34    while(p) {
 35      String *pname;
 36      pt = Getattr(p,"type");
 37      if ((SwigType_type(pt) != T_VOID)) {
 38	if (comma) Printf(returns,",");
 39	pname = Swig_cparm_name(p,i);
 40	Printf(returns,"%s",SwigType_rcaststr(pt,pname));
 41	comma = 1;
 42	i++;
 43      }
 44      p = nextSibling(p);
 45    }
 46    return returns;
 47  }
 48
 49  virtual int cDeclaration(Node *n) {
 50    String *name = Getattr(n,"name");
 51    String *k = Getattr(n,"feature:contract");
 52
 53    if(k)
 54    {
 55      /* make the names */
 56      ParmList *l = Getmeta(k,"parms");
 57      String *params = ParmList_str(l);
 58      String *transformed = strParms(l);
 59      if(DohStrcmp(params,"")==0) {
 60	DohDelete(params);
 61	params = DohNewString("void");
 62      }
 63      String *contractName = DohNewStringf("__SWIG_precontract_%s",name);
 64
 65      /* make the contract */
 66      String *contract = DohNewStringf("int %s(%s,int rt[2])\n{\n",contractName,params);
 67      SwigScanner * ss = NewSwigScanner();
 68      SwigScanner_clear(ss);
 69      SwigScanner_push(ss,Copy(k));
 70      SwigScanner_token(ss);  // Get rid of the '{' at the begining
 71
 72      /* loop over the clauses */
 73      int clauseNum = 1;
 74      int token = -1;
 75      while(1) {
 76	String *clause = DohNewString(""); /*BUG -- should free*/
 77	while((token=SwigScanner_token(ss))) {
 78	  if ((token==SWIG_TOKEN_SEMI)||(token==SWIG_TOKEN_RBRACE))
 79	    break;
 80	  //	  if (token != SWIG_TOKEN_ENDLINE)
 81	    Printf(clause,"%s",SwigScanner_text(ss));
 82	}
 83	if (DohStrcmp(clause,"\n") != 0) {
 84	  Printf(contract,"if (!(%s",clause);
 85	  Printf(contract,")) {\nrt[0]=__LINE__;\nrt[1]=%i;\nreturn 1;\n}\n",clauseNum);
 86	}
 87	if(token==SWIG_TOKEN_RBRACE) break;
 88	clauseNum++;
 89      }
 90
 91      /* finish it off and attach it to the main tree */
 92      Printf(contract,"return 0;\n}\n");
 93      Setattr(n,"wrap:code",contract); /*BUG -- WHAT IF SOMETHING IS ALREADY THERE*/
 94      
 95      /*  Generate the calling code */
 96      String * calling = DohNewString("{\nint cfail[2];\nchar message[255];\n");
 97      Printf(calling,"if (%s(%s,cfail)) {\n",contractName,transformed);
 98      Printf(calling,"sprintf(message,\"Contract %s failed on clause %%i (line %%i)!\",cfail[1],cfail[0]);\n",contractName);
 99      Printf(calling,"PyErr_SetString(PyExc_Exception,message);return NULL;\n}\n");
100      Printf(calling,"}\n");
101      /*      Setattr(n,"feature:preassert",calling); */
102    }
103    /*There are two attributes "feature:preassert" and "feature:postassert".*/
104
105    
106    return SWIG_OK;
107  }
108
109};
110
111void Swig_contracts(Node *n) {
112  Printf(stdout,"Applying contracts (experimental v0.09)\n");
113
114  Contracts *a = new Contracts;
115  a->top(n);
116  delete a;
117
118}