PageRenderTime 38ms CodeModel.GetById 11ms 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. static char cvsroot[] = "$Header$";
  12. #include "swigmod.h"
  13. class Contracts : public Dispatcher {
  14. public:
  15. virtual int top(Node *n) {
  16. emit_children(n);
  17. return SWIG_OK;
  18. }
  19. virtual int importDirective(Node *n) { return emit_children(n); }
  20. virtual int includeDirective(Node *n) { return emit_children(n); } // ?
  21. virtual int externDeclaration(Node *n) { return emit_children(n); }
  22. String * strParms(ParmList *l) {
  23. int comma = 0;
  24. int i = 0;
  25. Parm *p = l;
  26. SwigType *pt;
  27. String * returns = NewString("");
  28. while(p) {
  29. String *pname;
  30. pt = Getattr(p,"type");
  31. if ((SwigType_type(pt) != T_VOID)) {
  32. if (comma) Printf(returns,",");
  33. pname = Swig_cparm_name(p,i);
  34. Printf(returns,"%s",SwigType_rcaststr(pt,pname));
  35. comma = 1;
  36. i++;
  37. }
  38. p = nextSibling(p);
  39. }
  40. return returns;
  41. }
  42. virtual int cDeclaration(Node *n) {
  43. String *name = Getattr(n,"name");
  44. String *k = Getattr(n,"feature:contract");
  45. if(k)
  46. {
  47. /* make the names */
  48. ParmList *l = Getmeta(k,"parms");
  49. String *params = ParmList_str(l);
  50. String *transformed = strParms(l);
  51. if(DohStrcmp(params,"")==0) {
  52. DohDelete(params);
  53. params = DohNewString("void");
  54. }
  55. String *contractName = DohNewStringf("__SWIG_precontract_%s",name);
  56. /* make the contract */
  57. String *contract = DohNewStringf("int %s(%s,int rt[2])\n{\n",contractName,params);
  58. SwigScanner * ss = NewSwigScanner();
  59. SwigScanner_clear(ss);
  60. SwigScanner_push(ss,Copy(k));
  61. SwigScanner_token(ss); // Get rid of the '{' at the begining
  62. /* loop over the clauses */
  63. int clauseNum = 1;
  64. int token = -1;
  65. while(1) {
  66. String *clause = DohNewString(""); /*BUG -- should free*/
  67. while((token=SwigScanner_token(ss))) {
  68. if ((token==SWIG_TOKEN_SEMI)||(token==SWIG_TOKEN_RBRACE))
  69. break;
  70. // if (token != SWIG_TOKEN_ENDLINE)
  71. Printf(clause,"%s",SwigScanner_text(ss));
  72. }
  73. if (DohStrcmp(clause,"\n") != 0) {
  74. Printf(contract,"if (!(%s",clause);
  75. Printf(contract,")) {\nrt[0]=__LINE__;\nrt[1]=%i;\nreturn 1;\n}\n",clauseNum);
  76. }
  77. if(token==SWIG_TOKEN_RBRACE) break;
  78. clauseNum++;
  79. }
  80. /* finish it off and attach it to the main tree */
  81. Printf(contract,"return 0;\n}\n");
  82. Setattr(n,"wrap:code",contract); /*BUG -- WHAT IF SOMETHING IS ALREADY THERE*/
  83. /* Generate the calling code */
  84. String * calling = DohNewString("{\nint cfail[2];\nchar message[255];\n");
  85. Printf(calling,"if (%s(%s,cfail)) {\n",contractName,transformed);
  86. Printf(calling,"sprintf(message,\"Contract %s failed on clause %%i (line %%i)!\",cfail[1],cfail[0]);\n",contractName);
  87. Printf(calling,"PyErr_SetString(PyExc_Exception,message);return NULL;\n}\n");
  88. Printf(calling,"}\n");
  89. /* Setattr(n,"feature:preassert",calling); */
  90. }
  91. /*There are two attributes "feature:preassert" and "feature:postassert".*/
  92. return SWIG_OK;
  93. }
  94. };
  95. void Swig_contracts(Node *n) {
  96. Printf(stdout,"Applying contracts (experimental v0.09)\n");
  97. Contracts *a = new Contracts;
  98. a->top(n);
  99. delete a;
  100. }