pangen3.c 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394
  1. /***** spin: pangen3.c *****/
  2. /* Copyright (c) 1989-2003 by Lucent Technologies, Bell Laboratories. */
  3. /* All Rights Reserved. This software is for educational purposes only. */
  4. /* No guarantee whatsoever is expressed or implied by the distribution of */
  5. /* this code. Permission is given to distribute this code provided that */
  6. /* this introductory message is not removed and no monies are exchanged. */
  7. /* Software written by Gerard J. Holzmann. For tool documentation see: */
  8. /* http://spinroot.com/ */
  9. /* Send all bug-reports and/or questions to: bugs@spinroot.com */
  10. #include "spin.h"
  11. #ifdef PC
  12. #include "y_tab.h"
  13. #else
  14. #include "y.tab.h"
  15. #endif
  16. extern FILE *th;
  17. extern int claimnr, eventmapnr;
  18. typedef struct SRC {
  19. short ln, st; /* linenr, statenr */
  20. Symbol *fn; /* filename */
  21. struct SRC *nxt;
  22. } SRC;
  23. static int col;
  24. static Symbol *lastfnm;
  25. static Symbol lastdef;
  26. static int lastfrom;
  27. static SRC *frst = (SRC *) 0;
  28. static SRC *skip = (SRC *) 0;
  29. extern void sr_mesg(FILE *, int, int);
  30. static void
  31. putnr(int n)
  32. {
  33. if (col++ == 8)
  34. { fprintf(th, "\n\t");
  35. col = 1;
  36. }
  37. fprintf(th, "%3d, ", n);
  38. }
  39. static void
  40. putfnm(int j, Symbol *s)
  41. {
  42. if (lastfnm && lastfnm == s && j != -1)
  43. return;
  44. if (lastfnm)
  45. fprintf(th, "{ %s, %d, %d },\n\t",
  46. lastfnm->name,
  47. lastfrom,
  48. j-1);
  49. lastfnm = s;
  50. lastfrom = j;
  51. }
  52. static void
  53. putfnm_flush(int j)
  54. {
  55. fprintf(th, "{ %s, %d, %d }\n",
  56. lastfnm->name,
  57. lastfrom, j);
  58. }
  59. void
  60. putskip(int m) /* states that need not be reached */
  61. { SRC *tmp;
  62. for (tmp = skip; tmp; tmp = tmp->nxt)
  63. if (tmp->st == m)
  64. return;
  65. tmp = (SRC *) emalloc(sizeof(SRC));
  66. tmp->st = (short) m;
  67. tmp->nxt = skip;
  68. skip = tmp;
  69. }
  70. void
  71. unskip(int m) /* a state that needs to be reached after all */
  72. { SRC *tmp, *lst=(SRC *)0;
  73. for (tmp = skip; tmp; lst = tmp, tmp = tmp->nxt)
  74. if (tmp->st == m)
  75. { if (tmp == skip)
  76. skip = skip->nxt;
  77. else
  78. lst->nxt = tmp->nxt;
  79. break;
  80. }
  81. }
  82. void
  83. putsrc(Element *e) /* match states to source lines */
  84. { SRC *tmp;
  85. int n, m;
  86. if (!e || !e->n) return;
  87. n = e->n->ln;
  88. m = e->seqno;
  89. for (tmp = frst; tmp; tmp = tmp->nxt)
  90. if (tmp->st == m)
  91. { if (tmp->ln != n || tmp->fn != e->n->fn)
  92. printf("putsrc mismatch %d - %d, file %s\n", n,
  93. tmp->ln, tmp->fn->name);
  94. return;
  95. }
  96. tmp = (SRC *) emalloc(sizeof(SRC));
  97. tmp->ln = (short) n;
  98. tmp->st = (short) m;
  99. tmp->fn = e->n->fn;
  100. tmp->nxt = frst;
  101. frst = tmp;
  102. }
  103. static void
  104. dumpskip(int n, int m)
  105. { SRC *tmp, *lst;
  106. int j;
  107. fprintf(th, "uchar reached%d [] = {\n\t", m);
  108. for (j = 0, col = 0; j <= n; j++)
  109. { lst = (SRC *) 0;
  110. for (tmp = skip; tmp; lst = tmp, tmp = tmp->nxt)
  111. if (tmp->st == j)
  112. { putnr(1);
  113. if (lst)
  114. lst->nxt = tmp->nxt;
  115. else
  116. skip = tmp->nxt;
  117. break;
  118. }
  119. if (!tmp)
  120. putnr(0);
  121. }
  122. fprintf(th, "};\n");
  123. if (m == claimnr)
  124. fprintf(th, "#define reached_claim reached%d\n", m);
  125. if (m == eventmapnr)
  126. fprintf(th, "#define reached_event reached%d\n", m);
  127. skip = (SRC *) 0;
  128. }
  129. void
  130. dumpsrc(int n, int m)
  131. { SRC *tmp, *lst;
  132. int j;
  133. fprintf(th, "short src_ln%d [] = {\n\t", m);
  134. for (j = 0, col = 0; j <= n; j++)
  135. { lst = (SRC *) 0;
  136. for (tmp = frst; tmp; lst = tmp, tmp = tmp->nxt)
  137. if (tmp->st == j)
  138. { putnr(tmp->ln);
  139. break;
  140. }
  141. if (!tmp)
  142. putnr(0);
  143. }
  144. fprintf(th, "};\n");
  145. lastfnm = (Symbol *) 0;
  146. lastdef.name = "\"-\"";
  147. fprintf(th, "S_F_MAP src_file%d [] = {\n\t", m);
  148. for (j = 0, col = 0; j <= n; j++)
  149. { lst = (SRC *) 0;
  150. for (tmp = frst; tmp; lst = tmp, tmp = tmp->nxt)
  151. if (tmp->st == j)
  152. { putfnm(j, tmp->fn);
  153. if (lst)
  154. lst->nxt = tmp->nxt;
  155. else
  156. frst = tmp->nxt;
  157. break;
  158. }
  159. if (!tmp)
  160. putfnm(j, &lastdef);
  161. }
  162. putfnm_flush(j);
  163. fprintf(th, "};\n");
  164. if (m == claimnr)
  165. fprintf(th, "#define src_claim src_ln%d\n", m);
  166. if (m == eventmapnr)
  167. fprintf(th, "#define src_event src_ln%d\n", m);
  168. frst = (SRC *) 0;
  169. dumpskip(n, m);
  170. }
  171. #define Cat0(x) comwork(fd,now->lft,m); fprintf(fd, x); \
  172. comwork(fd,now->rgt,m)
  173. #define Cat1(x) fprintf(fd,"("); Cat0(x); fprintf(fd,")")
  174. #define Cat2(x,y) fprintf(fd,x); comwork(fd,y,m)
  175. #define Cat3(x,y,z) fprintf(fd,x); comwork(fd,y,m); fprintf(fd,z)
  176. static int
  177. symbolic(FILE *fd, Lextok *tv)
  178. { Lextok *n; extern Lextok *Mtype;
  179. int cnt = 1;
  180. if (tv->ismtyp)
  181. for (n = Mtype; n; n = n->rgt, cnt++)
  182. if (cnt == tv->val)
  183. { fprintf(fd, "%s", n->lft->sym->name);
  184. return 1;
  185. }
  186. return 0;
  187. }
  188. static void
  189. comwork(FILE *fd, Lextok *now, int m)
  190. { Lextok *v;
  191. int i, j;
  192. if (!now) { fprintf(fd, "0"); return; }
  193. switch (now->ntyp) {
  194. case CONST: sr_mesg(fd, now->val, now->ismtyp); break;
  195. case '!': Cat3("!(", now->lft, ")"); break;
  196. case UMIN: Cat3("-(", now->lft, ")"); break;
  197. case '~': Cat3("~(", now->lft, ")"); break;
  198. case '/': Cat1("/"); break;
  199. case '*': Cat1("*"); break;
  200. case '-': Cat1("-"); break;
  201. case '+': Cat1("+"); break;
  202. case '%': Cat1("%%"); break;
  203. case '&': Cat1("&"); break;
  204. case '^': Cat1("^"); break;
  205. case '|': Cat1("|"); break;
  206. case LE: Cat1("<="); break;
  207. case GE: Cat1(">="); break;
  208. case GT: Cat1(">"); break;
  209. case LT: Cat1("<"); break;
  210. case NE: Cat1("!="); break;
  211. case EQ: Cat1("=="); break;
  212. case OR: Cat1("||"); break;
  213. case AND: Cat1("&&"); break;
  214. case LSHIFT: Cat1("<<"); break;
  215. case RSHIFT: Cat1(">>"); break;
  216. case RUN: fprintf(fd, "run %s(", now->sym->name);
  217. for (v = now->lft; v; v = v->rgt)
  218. if (v == now->lft)
  219. { comwork(fd, v->lft, m);
  220. } else
  221. { Cat2(",", v->lft);
  222. }
  223. fprintf(fd, ")");
  224. break;
  225. case LEN: putname(fd, "len(", now->lft, m, ")");
  226. break;
  227. case FULL: putname(fd, "full(", now->lft, m, ")");
  228. break;
  229. case EMPTY: putname(fd, "empty(", now->lft, m, ")");
  230. break;
  231. case NFULL: putname(fd, "nfull(", now->lft, m, ")");
  232. break;
  233. case NEMPTY: putname(fd, "nempty(", now->lft, m, ")");
  234. break;
  235. case 's': putname(fd, "", now->lft, m, now->val?"!!":"!");
  236. for (v = now->rgt, i=0; v; v = v->rgt, i++)
  237. { if (v != now->rgt) fprintf(fd,",");
  238. if (!symbolic(fd, v->lft))
  239. comwork(fd,v->lft,m);
  240. }
  241. break;
  242. case 'r': putname(fd, "", now->lft, m, "?");
  243. switch (now->val) {
  244. case 0: break;
  245. case 1: fprintf(fd, "?"); break;
  246. case 2: fprintf(fd, "<"); break;
  247. case 3: fprintf(fd, "?<"); break;
  248. }
  249. for (v = now->rgt, i=0; v; v = v->rgt, i++)
  250. { if (v != now->rgt) fprintf(fd,",");
  251. if (!symbolic(fd, v->lft))
  252. comwork(fd,v->lft,m);
  253. }
  254. if (now->val >= 2)
  255. fprintf(fd, ">");
  256. break;
  257. case 'R': putname(fd, "", now->lft, m, now->val?"??[":"?[");
  258. for (v = now->rgt, i=0; v; v = v->rgt, i++)
  259. { if (v != now->rgt) fprintf(fd,",");
  260. if (!symbolic(fd, v->lft))
  261. comwork(fd,v->lft,m);
  262. }
  263. fprintf(fd, "]");
  264. break;
  265. case ENABLED: Cat3("enabled(", now->lft, ")");
  266. break;
  267. case EVAL: Cat3("eval(", now->lft, ")");
  268. break;
  269. case NONPROGRESS:
  270. fprintf(fd, "np_");
  271. break;
  272. case PC_VAL: Cat3("pc_value(", now->lft, ")");
  273. break;
  274. case 'c': Cat3("(", now->lft, ")");
  275. break;
  276. case '?': if (now->lft)
  277. { Cat3("( (", now->lft, ") -> ");
  278. }
  279. if (now->rgt)
  280. { Cat3("(", now->rgt->lft, ") : ");
  281. Cat3("(", now->rgt->rgt, ") )");
  282. }
  283. break;
  284. case ASGN: comwork(fd,now->lft,m);
  285. fprintf(fd," = ");
  286. comwork(fd,now->rgt,m);
  287. break;
  288. case PRINT: { char c, buf[512];
  289. strncpy(buf, now->sym->name, 510);
  290. for (i = j = 0; i < 510; i++, j++)
  291. { c = now->sym->name[i];
  292. buf[j] = c;
  293. if (c == '\\') buf[++j] = c;
  294. if (c == '\"') buf[j] = '\'';
  295. if (c == '\0') break;
  296. }
  297. if (now->ntyp == PRINT)
  298. fprintf(fd, "printf");
  299. else
  300. fprintf(fd, "annotate");
  301. fprintf(fd, "(%s", buf);
  302. }
  303. for (v = now->lft; v; v = v->rgt)
  304. { Cat2(",", v->lft);
  305. }
  306. fprintf(fd, ")");
  307. break;
  308. case PRINTM: fprintf(fd, "printm(");
  309. comwork(fd, now->lft, m);
  310. fprintf(fd, ")");
  311. break;
  312. case NAME: putname(fd, "", now, m, "");
  313. break;
  314. case 'p': putremote(fd, now, m);
  315. break;
  316. case 'q': fprintf(fd, "%s", now->sym->name);
  317. break;
  318. case C_EXPR:
  319. case C_CODE: fprintf(fd, "{%s}", now->sym->name);
  320. break;
  321. case ASSERT: Cat3("assert(", now->lft, ")");
  322. break;
  323. case '.': fprintf(fd, ".(goto)"); break;
  324. case GOTO: fprintf(fd, "goto %s", now->sym->name); break;
  325. case BREAK: fprintf(fd, "break"); break;
  326. case ELSE: fprintf(fd, "else"); break;
  327. case '@': fprintf(fd, "-end-"); break;
  328. case D_STEP: fprintf(fd, "D_STEP"); break;
  329. case ATOMIC: fprintf(fd, "ATOMIC"); break;
  330. case NON_ATOMIC: fprintf(fd, "sub-sequence"); break;
  331. case IF: fprintf(fd, "IF"); break;
  332. case DO: fprintf(fd, "DO"); break;
  333. case UNLESS: fprintf(fd, "unless"); break;
  334. case TIMEOUT: fprintf(fd, "timeout"); break;
  335. default: if (isprint(now->ntyp))
  336. fprintf(fd, "'%c'", now->ntyp);
  337. else
  338. fprintf(fd, "%d", now->ntyp);
  339. break;
  340. }
  341. }
  342. void
  343. comment(FILE *fd, Lextok *now, int m)
  344. { extern short terse, nocast;
  345. terse=nocast=1;
  346. comwork(fd, now, m);
  347. terse=nocast=0;
  348. }