pangen1.c 29 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217
  1. /***** spin: pangen1.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. #include "pangen1.h"
  17. #include "pangen3.h"
  18. extern FILE *tc, *th, *tt;
  19. extern Label *labtab;
  20. extern Ordered *all_names;
  21. extern ProcList *rdy;
  22. extern Queue *qtab;
  23. extern Symbol *Fname;
  24. extern int lineno, verbose, Pid, separate;
  25. extern int nrRdy, nqs, mst, Mpars, claimnr, eventmapnr;
  26. extern short has_sorted, has_random, has_provided;
  27. int Npars=0, u_sync=0, u_async=0, hastrack = 1;
  28. short has_io = 0;
  29. short has_state=0; /* code contains c_state */
  30. static Symbol *LstSet=ZS;
  31. static int acceptors=0, progressors=0, nBits=0;
  32. static int Types[] = { UNSIGNED, BIT, BYTE, CHAN, MTYPE, SHORT, INT, STRUCT };
  33. static int doglobal(char *, int);
  34. static void dohidden(void);
  35. static void do_init(FILE *, Symbol *);
  36. static void end_labs(Symbol *, int);
  37. static void put_ptype(char *, int, int, int);
  38. static void tc_predef_np(void);
  39. static void put_pinit(ProcList *);
  40. void walk_struct(FILE *, int, char *, Symbol *, char *, char *, char *);
  41. static void
  42. reverse_names(ProcList *p)
  43. {
  44. if (!p) return;
  45. reverse_names(p->nxt);
  46. fprintf(th, " \"%s\",\n", p->n->name);
  47. }
  48. void
  49. genheader(void)
  50. { ProcList *p; int i;
  51. if (separate == 2)
  52. { putunames(th);
  53. goto here;
  54. }
  55. fprintf(th, "#define SYNC %d\n", u_sync);
  56. fprintf(th, "#define ASYNC %d\n\n", u_async);
  57. putunames(th);
  58. fprintf(tc, "short Air[] = { ");
  59. for (p = rdy, i=0; p; p = p->nxt, i++)
  60. fprintf(tc, "%s (short) Air%d", (p!=rdy)?",":"", i);
  61. fprintf(tc, ", (short) Air%d", i); /* np_ */
  62. fprintf(tc, " };\n");
  63. fprintf(th, "char *procname[] = {\n");
  64. reverse_names(rdy);
  65. fprintf(th, " \":np_:\",\n");
  66. fprintf(th, "};\n\n");
  67. here:
  68. for (p = rdy; p; p = p->nxt)
  69. put_ptype(p->n->name, p->tn, mst, nrRdy+1);
  70. /* +1 for np_ */
  71. put_ptype("np_", nrRdy, mst, nrRdy+1);
  72. ntimes(th, 0, 1, Head0);
  73. if (separate != 2)
  74. { extern void c_add_stack(FILE *);
  75. ntimes(th, 0, 1, Header);
  76. c_add_stack(th);
  77. ntimes(th, 0, 1, Header0);
  78. }
  79. ntimes(th, 0, 1, Head1);
  80. LstSet = ZS;
  81. (void) doglobal("", PUTV);
  82. hastrack = c_add_sv(th);
  83. fprintf(th, " uchar sv[VECTORSZ];\n");
  84. fprintf(th, "} State");
  85. #ifdef SOLARIS
  86. fprintf(th,"\n#ifdef GCC\n");
  87. fprintf(th, "\t__attribute__ ((aligned(8)))");
  88. fprintf(th, "\n#endif\n\t");
  89. #endif
  90. fprintf(th, ";\n\n");
  91. fprintf(th, "#define HAS_TRACK %d\n", hastrack);
  92. if (separate != 2)
  93. dohidden();
  94. }
  95. void
  96. genaddproc(void)
  97. { ProcList *p;
  98. int i = 0;
  99. if (separate ==2) goto shortcut;
  100. fprintf(tc, "int\naddproc(int n");
  101. for (i = 0; i < Npars; i++)
  102. fprintf(tc, ", int par%d", i);
  103. ntimes(tc, 0, 1, Addp0);
  104. ntimes(tc, 1, nrRdy+1, R5); /* +1 for np_ */
  105. ntimes(tc, 0, 1, Addp1);
  106. if (has_provided)
  107. { fprintf(tt, "\nint\nprovided(int II, unsigned char ot, ");
  108. fprintf(tt, "int tt, Trans *t)\n");
  109. fprintf(tt, "{\n\tswitch(ot) {\n");
  110. }
  111. shortcut:
  112. tc_predef_np();
  113. for (p = rdy; p; p = p->nxt)
  114. { Pid = p->tn;
  115. put_pinit(p);
  116. }
  117. if (separate == 2) return;
  118. Pid = 0;
  119. if (has_provided)
  120. { fprintf(tt, "\tdefault: return 1; /* e.g., a claim */\n");
  121. fprintf(tt, "\t}\n\treturn 0;\n}\n");
  122. }
  123. ntimes(tc, i, i+1, R6);
  124. if (separate == 0)
  125. ntimes(tc, 1, nrRdy+1, R5); /* +1 for np_ */
  126. else
  127. ntimes(tc, 1, nrRdy, R5);
  128. ntimes(tc, 0, 1, R8a);
  129. }
  130. void
  131. do_locinits(FILE *fd)
  132. { ProcList *p;
  133. for (p = rdy; p; p = p->nxt)
  134. c_add_locinit(fd, p->tn, p->n->name);
  135. }
  136. void
  137. genother(void)
  138. { ProcList *p;
  139. switch (separate) {
  140. case 2:
  141. if (claimnr >= 0)
  142. ntimes(tc, claimnr, claimnr+1, R0); /* claim only */
  143. break;
  144. case 1:
  145. ntimes(tc, 0, 1, Code0);
  146. ntimes(tc, 0, claimnr, R0); /* all except claim */
  147. ntimes(tc, claimnr+1, nrRdy, R0);
  148. break;
  149. case 0:
  150. ntimes(tc, 0, 1, Code0);
  151. ntimes(tc, 0, nrRdy+1, R0); /* +1 for np_ */
  152. break;
  153. }
  154. for (p = rdy; p; p = p->nxt)
  155. end_labs(p->n, p->tn);
  156. switch (separate) {
  157. case 2:
  158. if (claimnr >= 0)
  159. ntimes(tc, claimnr, claimnr+1, R0a); /* claim only */
  160. return;
  161. case 1:
  162. ntimes(tc, 0, claimnr, R0a); /* all except claim */
  163. ntimes(tc, claimnr+1, nrRdy, R0a);
  164. fprintf(tc, " if (state_tables)\n");
  165. fprintf(tc, " ini_claim(%d, 0);\n", claimnr);
  166. break;
  167. case 0:
  168. ntimes(tc, 0, nrRdy, R0a); /* all */
  169. break;
  170. }
  171. ntimes(tc, 0, 1, R0b);
  172. if (separate == 1 && acceptors == 0)
  173. acceptors = 1; /* assume at least 1 acceptstate */
  174. ntimes(th, acceptors, acceptors+1, Code1);
  175. ntimes(th, progressors, progressors+1, Code3);
  176. ntimes(th, nrRdy+1, nrRdy+2, R2); /* +1 for np_ */
  177. fprintf(tc, " iniglobals();\n");
  178. ntimes(tc, 0, 1, Code2a);
  179. ntimes(tc, 0, 1, Code2b); /* bfs option */
  180. ntimes(tc, 0, 1, Code2c);
  181. ntimes(tc, 0, nrRdy, R4);
  182. fprintf(tc, "}\n\n");
  183. fprintf(tc, "void\n");
  184. fprintf(tc, "iniglobals(void)\n{\n");
  185. if (doglobal("", INIV) > 0)
  186. { fprintf(tc, "#ifdef VAR_RANGES\n");
  187. (void) doglobal("logval(\"", LOGV);
  188. fprintf(tc, "#endif\n");
  189. }
  190. ntimes(tc, 1, nqs+1, R3);
  191. fprintf(tc, "\tMaxbody = max(Maxbody, sizeof(State)-VECTORSZ);");
  192. fprintf(tc, "\n}\n\n");
  193. }
  194. void
  195. gensvmap(void)
  196. {
  197. ntimes(tc, 0, 1, SvMap);
  198. }
  199. static struct {
  200. char *s, *t; int n, m, p;
  201. } ln[] = {
  202. {"end", "stopstate", 3, 0, 0},
  203. {"progress", "progstate", 8, 0, 1},
  204. {"accept", "accpstate", 6, 1, 0},
  205. {0, 0, 0, 0, 0},
  206. };
  207. static void
  208. end_labs(Symbol *s, int i)
  209. { int oln = lineno;
  210. Symbol *ofn = Fname;
  211. Label *l;
  212. int j; char foo[128];
  213. if ((i == claimnr && separate == 1)
  214. || (i != claimnr && separate == 2))
  215. return;
  216. for (l = labtab; l; l = l->nxt)
  217. for (j = 0; ln[j].n; j++)
  218. if (strncmp(l->s->name, ln[j].s, ln[j].n) == 0
  219. && strcmp(l->c->name, s->name) == 0)
  220. { fprintf(tc, "\t%s[%d][%d] = 1;\n",
  221. ln[j].t, i, l->e->seqno);
  222. acceptors += ln[j].m;
  223. progressors += ln[j].p;
  224. if (l->e->status & D_ATOM)
  225. { sprintf(foo, "%s label inside d_step",
  226. ln[j].s);
  227. goto complain;
  228. }
  229. if (j > 0 && (l->e->status & ATOM))
  230. { sprintf(foo, "%s label inside atomic",
  231. ln[j].s);
  232. complain: lineno = l->e->n->ln;
  233. Fname = l->e->n->fn;
  234. printf("spin: %3d:%s, warning, %s - is invisible\n",
  235. lineno, Fname?Fname->name:"-", foo);
  236. }
  237. }
  238. /* visible states -- through remote refs: */
  239. for (l = labtab; l; l = l->nxt)
  240. if (l->visible
  241. && strcmp(l->s->context->name, s->name) == 0)
  242. fprintf(tc, "\tvisstate[%d][%d] = 1;\n",
  243. i, l->e->seqno);
  244. lineno = oln;
  245. Fname = ofn;
  246. }
  247. void
  248. ntimes(FILE *fd, int n, int m, char *c[])
  249. {
  250. int i, j;
  251. for (j = 0; c[j]; j++)
  252. for (i = n; i < m; i++)
  253. { fprintf(fd, c[j], i, i, i, i, i, i);
  254. fprintf(fd, "\n");
  255. }
  256. }
  257. void
  258. prehint(Symbol *s)
  259. { Lextok *n;
  260. printf("spin: warning, ");
  261. if (!s) return;
  262. n = (s->context != ZS)?s->context->ini:s->ini;
  263. if (n)
  264. printf("line %3d %s, ", n->ln, n->fn->name);
  265. }
  266. void
  267. checktype(Symbol *sp, char *s)
  268. { char buf[128]; int i;
  269. if (!s
  270. || (sp->type != BYTE
  271. && sp->type != SHORT
  272. && sp->type != INT))
  273. return;
  274. if (sp->hidden&16) /* formal parameter */
  275. { ProcList *p; Lextok *f, *t;
  276. int posnr = 0;
  277. for (p = rdy; p; p = p->nxt)
  278. if (p->n->name
  279. && strcmp(s, p->n->name) == 0)
  280. break;
  281. if (p)
  282. for (f = p->p; f; f = f->rgt) /* list of types */
  283. for (t = f->lft; t; t = t->rgt, posnr++)
  284. if (t->sym
  285. && strcmp(t->sym->name, sp->name) == 0)
  286. { checkrun(sp, posnr);
  287. return;
  288. }
  289. } else if (!(sp->hidden&4))
  290. { if (!(verbose&32)) return;
  291. sputtype(buf, sp->type);
  292. i = (int) strlen(buf);
  293. while (buf[--i] == ' ') buf[i] = '\0';
  294. prehint(sp);
  295. if (sp->context)
  296. printf("proctype %s:", s);
  297. else
  298. printf("global");
  299. printf(" '%s %s' could be declared 'bit %s'\n",
  300. buf, sp->name, sp->name);
  301. } else if (sp->type != BYTE && !(sp->hidden&8))
  302. { if (!(verbose&32)) return;
  303. sputtype(buf, sp->type);
  304. i = (int) strlen(buf);
  305. while (buf[--i] == ' ') buf[i] = '\0';
  306. prehint(sp);
  307. if (sp->context)
  308. printf("proctype %s:", s);
  309. else
  310. printf("global");
  311. printf(" '%s %s' could be declared 'byte %s'\n",
  312. buf, sp->name, sp->name);
  313. }
  314. }
  315. int
  316. dolocal(FILE *ofd, char *pre, int dowhat, int p, char *s)
  317. { int h, j, k=0; extern int nr_errs;
  318. Ordered *walk;
  319. Symbol *sp;
  320. char buf[64], buf2[128], buf3[128];
  321. for (j = 0; j < 8; j++)
  322. for (h = 0; h <= 1; h++)
  323. for (walk = all_names; walk; walk = walk->next)
  324. { sp = walk->entry;
  325. if (sp->context
  326. && !sp->owner
  327. && sp->type == Types[j]
  328. && ((h == 0 && sp->nel == 1) || (h == 1 && sp->nel > 1))
  329. && strcmp(s, sp->context->name) == 0)
  330. { switch (dowhat) {
  331. case LOGV:
  332. if (sp->type == CHAN
  333. && verbose == 0)
  334. break;
  335. sprintf(buf, "%s%s:", pre, s);
  336. { sprintf(buf2, "\", ((P%d *)pptr(h))->", p);
  337. sprintf(buf3, ");\n");
  338. }
  339. do_var(ofd, dowhat, "", sp, buf, buf2, buf3);
  340. break;
  341. case INIV:
  342. checktype(sp, s); /* fall through */
  343. if (sp->hidden&16) { k++; break; }
  344. case PUTV:
  345. sprintf(buf, "((P%d *)pptr(h))->", p);
  346. do_var(ofd, dowhat, buf, sp, "", " = ", ";\n");
  347. k++;
  348. break;
  349. }
  350. if (strcmp(s, ":never:") == 0)
  351. { printf("error: %s defines local %s\n",
  352. s, sp->name);
  353. nr_errs++;
  354. } } }
  355. return k;
  356. }
  357. void
  358. c_chandump(FILE *fd)
  359. { Queue *q;
  360. char buf[256];
  361. int i;
  362. if (!qtab)
  363. { fprintf(fd, "void\nc_chandump(int unused) ");
  364. fprintf(fd, "{ unused = unused++; /* avoid complaints */ }\n");
  365. return;
  366. }
  367. fprintf(fd, "void\nc_chandump(int from)\n");
  368. fprintf(fd, "{ uchar *z; int slot;\n");
  369. fprintf(fd, " from--;\n");
  370. fprintf(fd, " if (from >= (int) now._nr_qs || from < 0)\n");
  371. fprintf(fd, " { printf(\"pan: bad qid %%d\\n\", from+1);\n");
  372. fprintf(fd, " return;\n");
  373. fprintf(fd, " }\n");
  374. fprintf(fd, " z = qptr(from);\n");
  375. fprintf(fd, " switch (((Q0 *)z)->_t) {\n");
  376. for (q = qtab; q; q = q->nxt)
  377. { fprintf(fd, " case %d:\n\t\t", q->qid);
  378. sprintf(buf, "((Q%d *)z)->", q->qid);
  379. fprintf(fd, "for (slot = 0; slot < %sQlen; slot++)\n\t\t", buf);
  380. fprintf(fd, "{ printf(\" [\");\n\t\t");
  381. for (i = 0; i < q->nflds; i++)
  382. { if (q->fld_width[i] == MTYPE)
  383. { fprintf(fd, "\tprintm(%scontents[slot].fld%d);\n\t\t",
  384. buf, i);
  385. } else
  386. fprintf(fd, "\tprintf(\"%%d,\", %scontents[slot].fld%d);\n\t\t",
  387. buf, i);
  388. }
  389. fprintf(fd, " printf(\"],\");\n\t\t");
  390. fprintf(fd, "}\n\t\t");
  391. fprintf(fd, "break;\n");
  392. }
  393. fprintf(fd, " }\n");
  394. fprintf(fd, " printf(\"\\n\");\n}\n");
  395. }
  396. void
  397. c_var(FILE *fd, char *pref, Symbol *sp)
  398. { char buf[256];
  399. int i;
  400. switch (sp->type) {
  401. case STRUCT:
  402. /* c_struct(fd, pref, sp); */
  403. fprintf(fd, "\t\tprintf(\"\t(struct %s)\\n\");\n",
  404. sp->name);
  405. sprintf(buf, "%s%s.", pref, sp->name);
  406. c_struct(fd, buf, sp);
  407. break;
  408. case BIT: case BYTE:
  409. case SHORT: case INT:
  410. case UNSIGNED:
  411. sputtype(buf, sp->type);
  412. if (sp->nel == 1)
  413. fprintf(fd, "\tprintf(\"\t%s %s:\t%%d\\n\", %s%s);\n",
  414. buf, sp->name, pref, sp->name);
  415. else
  416. for (i = 0; i < sp->nel; i++)
  417. fprintf(fd, "\tprintf(\"\t%s %s[%d]:\t%%d\\n\", %s%s[%d]);\n",
  418. buf, sp->name, i, pref, sp->name, i);
  419. break;
  420. case CHAN:
  421. if (sp->nel == 1)
  422. { fprintf(fd, "\tprintf(\"\tchan %s (=%%d):\tlen %%d:\\t\", ",
  423. sp->name);
  424. fprintf(fd, "%s%s, q_len(%s%s));\n",
  425. pref, sp->name, pref, sp->name);
  426. fprintf(fd, "\tc_chandump(%s%s);\n", pref, sp->name);
  427. } else
  428. for (i = 0; i < sp->nel; i++)
  429. { fprintf(fd, "\tprintf(\"\tchan %s[%d] (=%%d):\tlen %%d:\\t\", ",
  430. sp->name, i);
  431. fprintf(fd, "%s%s[%d], q_len(%s%s[%d]));\n",
  432. pref, sp->name, i, pref, sp->name, i);
  433. fprintf(fd, "\tc_chandump(%s%s[%d]);\n",
  434. pref, sp->name, i);
  435. }
  436. break;
  437. }
  438. }
  439. void
  440. c_splurge(FILE *fd, ProcList *p)
  441. { Ordered *walk;
  442. Symbol *sp;
  443. char pref[64];
  444. if (strcmp(p->n->name, ":never:") != 0
  445. && strcmp(p->n->name, ":trace:") != 0
  446. && strcmp(p->n->name, ":notrace:") != 0)
  447. for (walk = all_names; walk; walk = walk->next)
  448. { sp = walk->entry;
  449. if (!sp->context
  450. || strcmp(sp->context->name, p->n->name) != 0
  451. || sp->owner || (sp->hidden&1)
  452. || (sp->type == MTYPE && ismtype(sp->name)))
  453. continue;
  454. sprintf(pref, "((P%d *)pptr(pid))->", p->tn);
  455. c_var(fd, pref, sp);
  456. }
  457. }
  458. void
  459. c_wrapper(FILE *fd) /* allow pan.c to print out global sv entries */
  460. { Ordered *walk;
  461. ProcList *p;
  462. Symbol *sp;
  463. Lextok *n;
  464. extern Lextok *Mtype;
  465. int j;
  466. fprintf(fd, "void\nc_globals(void)\n{\t/* int i; */\n");
  467. fprintf(fd, " printf(\"global vars:\\n\");\n");
  468. for (walk = all_names; walk; walk = walk->next)
  469. { sp = walk->entry;
  470. if (sp->context || sp->owner || (sp->hidden&1)
  471. || (sp->type == MTYPE && ismtype(sp->name)))
  472. continue;
  473. c_var(fd, "now.", sp);
  474. }
  475. fprintf(fd, "}\n");
  476. fprintf(fd, "void\nc_locals(int pid, int tp)\n{\t/* int i; */\n");
  477. fprintf(fd, " switch(tp) {\n");
  478. for (p = rdy; p; p = p->nxt)
  479. { fprintf(fd, " case %d:\n", p->tn);
  480. fprintf(fd, " \tprintf(\"local vars proc %%d (%s):\\n\", pid);\n",
  481. p->n->name);
  482. c_splurge(fd, p);
  483. fprintf(fd, " \tbreak;\n");
  484. }
  485. fprintf(fd, " }\n}\n");
  486. fprintf(fd, "void\nprintm(int x)\n{\n");
  487. fprintf(fd, " switch (x) {\n");
  488. for (n = Mtype, j = 1; n && j; n = n->rgt, j++)
  489. fprintf(fd, "\tcase %d: Printf(\"%s\"); break;\n",
  490. j, n->lft->sym->name);
  491. fprintf(fd, " default: Printf(\"%%d\", x);\n");
  492. fprintf(fd, " }\n");
  493. fprintf(fd, "}\n");
  494. }
  495. static int
  496. doglobal(char *pre, int dowhat)
  497. { Ordered *walk;
  498. Symbol *sp;
  499. int j, cnt = 0;
  500. for (j = 0; j < 8; j++)
  501. for (walk = all_names; walk; walk = walk->next)
  502. { sp = walk->entry;
  503. if (!sp->context
  504. && !sp->owner
  505. && sp->type == Types[j])
  506. { if (Types[j] != MTYPE || !ismtype(sp->name))
  507. switch (dowhat) {
  508. case LOGV:
  509. if (sp->type == CHAN
  510. && verbose == 0)
  511. break;
  512. if (sp->hidden&1)
  513. break;
  514. do_var(tc, dowhat, "", sp,
  515. pre, "\", now.", ");\n");
  516. break;
  517. case INIV:
  518. checktype(sp, (char *) 0);
  519. cnt++; /* fall through */
  520. case PUTV:
  521. do_var(tc, dowhat, (sp->hidden&1)?"":"now.", sp,
  522. "", " = ", ";\n");
  523. break;
  524. } } }
  525. return cnt;
  526. }
  527. static void
  528. dohidden(void)
  529. { Ordered *walk;
  530. Symbol *sp;
  531. int j;
  532. for (j = 0; j < 8; j++)
  533. for (walk = all_names; walk; walk = walk->next)
  534. { sp = walk->entry;
  535. if ((sp->hidden&1)
  536. && sp->type == Types[j])
  537. { if (sp->context || sp->owner)
  538. fatal("cannot hide non-globals (%s)", sp->name);
  539. if (sp->type == CHAN)
  540. fatal("cannot hide channels (%s)", sp->name);
  541. fprintf(th, "/* hidden variable: */");
  542. typ2c(sp);
  543. } }
  544. fprintf(th, "int _; /* a predefined write-only variable */\n\n");
  545. }
  546. void
  547. do_var(FILE *ofd, int dowhat, char *s, Symbol *sp,
  548. char *pre, char *sep, char *ter)
  549. { int i;
  550. switch(dowhat) {
  551. case PUTV:
  552. if (sp->hidden&1) break;
  553. typ2c(sp);
  554. break;
  555. case LOGV:
  556. case INIV:
  557. if (sp->type == STRUCT)
  558. { /* struct may contain a chan */
  559. walk_struct(ofd, dowhat, s, sp, pre, sep, ter);
  560. break;
  561. }
  562. if (!sp->ini && dowhat != LOGV) /* it defaults to 0 */
  563. break;
  564. if (sp->nel == 1)
  565. { fprintf(ofd, "\t\t%s%s%s%s",
  566. pre, s, sp->name, sep);
  567. if (dowhat == LOGV)
  568. fprintf(ofd, "%s%s", s, sp->name);
  569. else
  570. do_init(ofd, sp);
  571. fprintf(ofd, "%s", ter);
  572. } else
  573. for (i = 0; i < sp->nel; i++)
  574. { fprintf(ofd, "\t\t%s%s%s[%d]%s",
  575. pre, s, sp->name, i, sep);
  576. if (dowhat == LOGV)
  577. fprintf(ofd, "%s%s[%d]",
  578. s, sp->name, i);
  579. else
  580. do_init(ofd, sp);
  581. fprintf(ofd, "%s", ter);
  582. }
  583. break;
  584. }
  585. }
  586. static void
  587. do_init(FILE *ofd, Symbol *sp)
  588. { int i; extern Queue *ltab[];
  589. if (sp->ini
  590. && sp->type == CHAN
  591. && ((i = qmake(sp)) > 0))
  592. { if (sp->ini->ntyp == CHAN)
  593. fprintf(ofd, "addqueue(%d, %d)",
  594. i, ltab[i-1]->nslots == 0);
  595. else
  596. fprintf(ofd, "%d", i);
  597. } else
  598. putstmnt(ofd, sp->ini, 0);
  599. }
  600. static int
  601. blog(int n) /* for small log2 without rounding problems */
  602. { int m=1, r=2;
  603. while (r < n) { m++; r *= 2; }
  604. return 1+m;
  605. }
  606. static void
  607. put_ptype(char *s, int i, int m0, int m1)
  608. { int k;
  609. if (strcmp(s, ":init:") == 0)
  610. fprintf(th, "#define Pinit ((P%d *)this)\n", i);
  611. if (strcmp(s, ":never:") != 0
  612. && strcmp(s, ":trace:") != 0
  613. && strcmp(s, ":notrace:") != 0
  614. && strcmp(s, ":init:") != 0
  615. && strcmp(s, "_:never_template:_") != 0
  616. && strcmp(s, "np_") != 0)
  617. fprintf(th, "#define P%s ((P%d *)this)\n", s, i);
  618. fprintf(th, "typedef struct P%d { /* %s */\n", i, s);
  619. fprintf(th, " unsigned _pid : 8; /* 0..255 */\n");
  620. fprintf(th, " unsigned _t : %d; /* proctype */\n", blog(m1));
  621. fprintf(th, " unsigned _p : %d; /* state */\n", blog(m0));
  622. LstSet = ZS;
  623. nBits = 8 + blog(m1) + blog(m0);
  624. k = dolocal(tc, "", PUTV, i, s); /* includes pars */
  625. c_add_loc(th, s);
  626. fprintf(th, "} P%d;\n", i);
  627. if ((!LstSet && k > 0) || has_state)
  628. fprintf(th, "#define Air%d 0\n", i);
  629. else
  630. { fprintf(th, "#define Air%d (sizeof(P%d) - ", i, i);
  631. if (k == 0)
  632. { fprintf(th, "%d", (nBits+7)/8);
  633. goto done;
  634. }
  635. if ((LstSet->type != BIT && LstSet->type != UNSIGNED)
  636. || LstSet->nel != 1)
  637. { fprintf(th, "Offsetof(P%d, %s) - %d*sizeof(",
  638. i, LstSet->name, LstSet->nel);
  639. }
  640. switch(LstSet->type) {
  641. case UNSIGNED:
  642. fprintf(th, "%d", (nBits+7)/8);
  643. break;
  644. case BIT:
  645. if (LstSet->nel == 1)
  646. { fprintf(th, "%d", (nBits+7)/8);
  647. break;
  648. } /* else fall through */
  649. case MTYPE: case BYTE: case CHAN:
  650. fprintf(th, "uchar)"); break;
  651. case SHORT:
  652. fprintf(th, "short)"); break;
  653. case INT:
  654. fprintf(th, "int)"); break;
  655. default:
  656. fatal("cannot happen Air %s",
  657. LstSet->name);
  658. }
  659. done: fprintf(th, ")\n");
  660. }
  661. }
  662. static void
  663. tc_predef_np(void)
  664. { int i = nrRdy; /* 1+ highest proctype nr */
  665. fprintf(th, "#define _NP_ %d\n", i);
  666. if (separate == 2) fprintf(th, "extern ");
  667. fprintf(th, "uchar reached%d[3]; /* np_ */\n", i);
  668. fprintf(th, "#define nstates%d 3 /* np_ */\n", i);
  669. fprintf(th, "#define endstate%d 2 /* np_ */\n\n", i);
  670. fprintf(th, "#define start%d 0 /* np_ */\n", i);
  671. fprintf(tc, "\tcase %d: /* np_ */\n", i);
  672. if (separate == 1)
  673. { fprintf(tc, "\t\tini_claim(%d, h);\n", i);
  674. } else
  675. { fprintf(tc, "\t\t((P%d *)pptr(h))->_t = %d;\n", i, i);
  676. fprintf(tc, "\t\t((P%d *)pptr(h))->_p = 0;\n", i);
  677. fprintf(tc, "\t\treached%d[0] = 1;\n", i);
  678. fprintf(tc, "\t\taccpstate[%d][1] = 1;\n", i);
  679. }
  680. fprintf(tc, "\t\tbreak;\n");
  681. }
  682. static void
  683. put_pinit(ProcList *P)
  684. { Lextok *fp, *fpt, *t;
  685. Element *e = P->s->frst;
  686. Symbol *s = P->n;
  687. Lextok *p = P->p;
  688. int i = P->tn;
  689. int ini, j, k;
  690. if (i == claimnr
  691. && separate == 1)
  692. { fprintf(tc, "\tcase %d: /* %s */\n", i, s->name);
  693. fprintf(tc, "\t\tini_claim(%d, h);\n", i);
  694. fprintf(tc, "\t\tbreak;\n");
  695. return;
  696. }
  697. if (i != claimnr
  698. && separate == 2)
  699. return;
  700. ini = huntele(e, e->status, -1)->seqno;
  701. fprintf(th, "#define start%d %d\n", i, ini);
  702. if (i == claimnr)
  703. fprintf(th, "#define start_claim %d\n", ini);
  704. if (i == eventmapnr)
  705. fprintf(th, "#define start_event %d\n", ini);
  706. fprintf(tc, "\tcase %d: /* %s */\n", i, s->name);
  707. fprintf(tc, "\t\t((P%d *)pptr(h))->_t = %d;\n", i, i);
  708. fprintf(tc, "\t\t((P%d *)pptr(h))->_p = %d;", i, ini);
  709. fprintf(tc, " reached%d[%d]=1;\n", i, ini);
  710. if (has_provided)
  711. { fprintf(tt, "\tcase %d: /* %s */\n\t\t", i, s->name);
  712. if (P->prov)
  713. { fprintf(tt, "if (");
  714. putstmnt(tt, P->prov, 0);
  715. fprintf(tt, ")\n\t\t\t");
  716. }
  717. fprintf(tt, "return 1;\n");
  718. if (P->prov)
  719. fprintf(tt, "\t\tbreak;\n");
  720. }
  721. fprintf(tc, "\t\t/* params: */\n");
  722. for (fp = p, j=0; fp; fp = fp->rgt)
  723. for (fpt = fp->lft; fpt; fpt = fpt->rgt, j++)
  724. { t = (fpt->ntyp == ',') ? fpt->lft : fpt;
  725. if (t->sym->nel != 1)
  726. { lineno = t->ln;
  727. Fname = t->fn;
  728. fatal("array in parameter list, %s",
  729. t->sym->name);
  730. }
  731. fprintf(tc, "\t\t((P%d *)pptr(h))->", i);
  732. if (t->sym->type == STRUCT)
  733. { if (full_name(tc, t, t->sym, 1))
  734. { lineno = t->ln;
  735. Fname = t->fn;
  736. fatal("hidden array in parameter %s",
  737. t->sym->name);
  738. }
  739. } else
  740. fprintf(tc, "%s", t->sym->name);
  741. fprintf(tc, " = par%d;\n", j);
  742. }
  743. fprintf(tc, "\t\t/* locals: */\n");
  744. k = dolocal(tc, "", INIV, i, s->name);
  745. if (k > 0)
  746. { fprintf(tc, "#ifdef VAR_RANGES\n");
  747. (void) dolocal(tc, "logval(\"", LOGV, i, s->name);
  748. fprintf(tc, "#endif\n");
  749. }
  750. fprintf(tc, "#ifdef HAS_CODE\n");
  751. fprintf(tc, "\t\tlocinit%d(h);\n", i);
  752. fprintf(tc, "#endif\n");
  753. dumpclaims(tc, i, s->name);
  754. fprintf(tc, "\t break;\n");
  755. }
  756. Element *
  757. huntstart(Element *f)
  758. { Element *e = f;
  759. Element *elast = (Element *) 0;
  760. int cnt = 0;
  761. while (elast != e && cnt++ < 20) /* new 4.0.8 */
  762. { elast = e;
  763. if (e->n)
  764. { if (e->n->ntyp == '.' && e->nxt)
  765. e = e->nxt;
  766. else if (e->n->ntyp == UNLESS)
  767. e = e->sub->this->frst;
  768. } }
  769. if (cnt >= 20 || !e)
  770. fatal("confusing control structure", (char *) 0);
  771. return e;
  772. }
  773. Element *
  774. huntele(Element *f, int o, int stopat)
  775. { Element *g, *e = f;
  776. int cnt=0; /* a precaution against loops */
  777. if (e)
  778. for (cnt = 0; cnt < 20 && e->n; cnt++)
  779. {
  780. if (e->seqno == stopat)
  781. break;
  782. switch (e->n->ntyp) {
  783. case GOTO:
  784. g = get_lab(e->n,1);
  785. cross_dsteps(e->n, g->n);
  786. break;
  787. case '.':
  788. case BREAK:
  789. if (!e->nxt)
  790. return e;
  791. g = e->nxt;
  792. break;
  793. case UNLESS:
  794. g = huntele(e->sub->this->frst, o, stopat);
  795. break;
  796. case D_STEP:
  797. case ATOMIC:
  798. case NON_ATOMIC:
  799. default:
  800. return e;
  801. }
  802. if ((o & ATOM) && !(g->status & ATOM))
  803. return e;
  804. e = g;
  805. }
  806. if (cnt >= 20 || !e)
  807. fatal("confusing control structure", (char *) 0);
  808. return e;
  809. }
  810. void
  811. typ2c(Symbol *sp)
  812. { int wsbits = sizeof(long)*8; /* wordsize in bits */
  813. switch (sp->type) {
  814. case UNSIGNED:
  815. if (sp->hidden&1)
  816. fprintf(th, "\tuchar %s;", sp->name);
  817. else
  818. fprintf(th, "\tunsigned %s : %d",
  819. sp->name, sp->nbits);
  820. LstSet = sp;
  821. if (nBits%wsbits > 0
  822. && wsbits - nBits%wsbits < sp->nbits)
  823. { /* must padd to a word-boundary */
  824. nBits += wsbits - nBits%wsbits;
  825. }
  826. nBits += sp->nbits;
  827. break;
  828. case BIT:
  829. if (sp->nel == 1 && !(sp->hidden&1))
  830. { fprintf(th, "\tunsigned %s : 1", sp->name);
  831. LstSet = sp;
  832. nBits++;
  833. break;
  834. } /* else fall through */
  835. if (!(sp->hidden&1) && (verbose&32))
  836. printf("spin: warning: bit-array %s[%d] mapped to byte-array\n",
  837. sp->name, sp->nel);
  838. nBits += 8*sp->nel; /* mapped onto array of uchars */
  839. case MTYPE:
  840. case BYTE:
  841. case CHAN: /* good for up to 255 channels */
  842. fprintf(th, "\tuchar %s", sp->name);
  843. LstSet = sp;
  844. break;
  845. case SHORT:
  846. fprintf(th, "\tshort %s", sp->name);
  847. LstSet = sp;
  848. break;
  849. case INT:
  850. fprintf(th, "\tint %s", sp->name);
  851. LstSet = sp;
  852. break;
  853. case STRUCT:
  854. if (!sp->Snm)
  855. fatal("undeclared structure element %s", sp->name);
  856. fprintf(th, "\tstruct %s %s",
  857. sp->Snm->name,
  858. sp->name);
  859. LstSet = ZS;
  860. break;
  861. case CODE_FRAG:
  862. case PREDEF:
  863. return;
  864. default:
  865. fatal("variable %s undeclared", sp->name);
  866. }
  867. if (sp->nel != 1)
  868. fprintf(th, "[%d]", sp->nel);
  869. fprintf(th, ";\n");
  870. }
  871. static void
  872. ncases(FILE *fd, int p, int n, int m, char *c[])
  873. { int i, j;
  874. for (j = 0; c[j]; j++)
  875. for (i = n; i < m; i++)
  876. { fprintf(fd, c[j], i, p, i);
  877. fprintf(fd, "\n");
  878. }
  879. }
  880. void
  881. qlen_type(int qmax)
  882. {
  883. fprintf(th, "\t");
  884. if (qmax < 256)
  885. fprintf(th, "uchar");
  886. else if (qmax < 65535)
  887. fprintf(th, "ushort");
  888. else
  889. fprintf(th, "uint");
  890. fprintf(th, " Qlen; /* q_size */\n");
  891. }
  892. void
  893. genaddqueue(void)
  894. { char buf0[256];
  895. int j, qmax = 0;
  896. Queue *q;
  897. ntimes(tc, 0, 1, Addq0);
  898. if (has_io && !nqs)
  899. fprintf(th, "#define NQS 1 /* nqs=%d, but has_io */\n", nqs);
  900. else
  901. fprintf(th, "#define NQS %d\n", nqs);
  902. fprintf(th, "short q_flds[%d];\n", nqs+1);
  903. fprintf(th, "short q_max[%d];\n", nqs+1);
  904. for (q = qtab; q; q = q->nxt)
  905. if (q->nslots > qmax)
  906. qmax = q->nslots;
  907. for (q = qtab; q; q = q->nxt)
  908. { j = q->qid;
  909. fprintf(tc, "\tcase %d: j = sizeof(Q%d);", j, j);
  910. fprintf(tc, " q_flds[%d] = %d;", j, q->nflds);
  911. fprintf(tc, " q_max[%d] = %d;", j, max(1,q->nslots));
  912. fprintf(tc, " break;\n");
  913. fprintf(th, "typedef struct Q%d {\n", j);
  914. qlen_type(qmax); /* 4.2.2 */
  915. fprintf(th, " uchar _t; /* q_type */\n");
  916. fprintf(th, " struct {\n");
  917. for (j = 0; j < q->nflds; j++)
  918. { switch (q->fld_width[j]) {
  919. case BIT:
  920. if (q->nflds != 1)
  921. { fprintf(th, "\t\tunsigned");
  922. fprintf(th, " fld%d : 1;\n", j);
  923. break;
  924. } /* else fall through: smaller struct */
  925. case MTYPE:
  926. case CHAN:
  927. case BYTE:
  928. fprintf(th, "\t\tuchar fld%d;\n", j);
  929. break;
  930. case SHORT:
  931. fprintf(th, "\t\tshort fld%d;\n", j);
  932. break;
  933. case INT:
  934. fprintf(th, "\t\tint fld%d;\n", j);
  935. break;
  936. default:
  937. fatal("bad channel spec", "");
  938. }
  939. }
  940. fprintf(th, " } contents[%d];\n", max(1, q->nslots));
  941. fprintf(th, "} Q%d;\n", q->qid);
  942. }
  943. fprintf(th, "typedef struct Q0 {\t/* generic q */\n");
  944. qlen_type(qmax); /* 4.2.2 */
  945. fprintf(th, " uchar _t;\n");
  946. fprintf(th, "} Q0;\n");
  947. ntimes(tc, 0, 1, Addq1);
  948. if (has_random)
  949. { fprintf(th, "int Q_has(int");
  950. for (j = 0; j < Mpars; j++)
  951. fprintf(th, ", int, int");
  952. fprintf(th, ");\n");
  953. fprintf(tc, "int\nQ_has(int into");
  954. for (j = 0; j < Mpars; j++)
  955. fprintf(tc, ", int want%d, int fld%d", j, j);
  956. fprintf(tc, ")\n");
  957. fprintf(tc, "{ int i;\n\n");
  958. fprintf(tc, " if (!into--)\n");
  959. fprintf(tc, " uerror(\"ref to unknown chan ");
  960. fprintf(tc, "(recv-poll)\");\n\n");
  961. fprintf(tc, " if (into >= now._nr_qs || into < 0)\n");
  962. fprintf(tc, " Uerror(\"qrecv bad queue#\");\n\n");
  963. fprintf(tc, " for (i = 0; i < ((Q0 *)qptr(into))->Qlen;");
  964. fprintf(tc, " i++)\n");
  965. fprintf(tc, " {\n");
  966. for (j = 0; j < Mpars; j++)
  967. { fprintf(tc, " if (want%d && ", j);
  968. fprintf(tc, "qrecv(into+1, i, %d, 0) != fld%d)\n",
  969. j, j);
  970. fprintf(tc, " continue;\n");
  971. }
  972. fprintf(tc, " return i+1;\n");
  973. fprintf(tc, " }\n");
  974. fprintf(tc, " return 0;\n");
  975. fprintf(tc, "}\n");
  976. }
  977. fprintf(tc, "#if NQS>0\n");
  978. fprintf(tc, "void\nqsend(int into, int sorted");
  979. for (j = 0; j < Mpars; j++)
  980. fprintf(tc, ", int fld%d", j);
  981. fprintf(tc, ")\n");
  982. ntimes(tc, 0, 1, Addq11);
  983. for (q = qtab; q; q = q->nxt)
  984. { sprintf(buf0, "((Q%d *)z)->", q->qid);
  985. fprintf(tc, "\tcase %d:%s\n", q->qid,
  986. (q->nslots)?"":" /* =rv= */");
  987. if (q->nslots == 0) /* reset handshake point */
  988. fprintf(tc, "\t\t(trpt+2)->o_m = 0;\n");
  989. if (has_sorted)
  990. { fprintf(tc, "\t\tif (!sorted) goto append%d;\n", q->qid);
  991. fprintf(tc, "\t\tfor (j = 0; j < %sQlen; j++)\n", buf0);
  992. fprintf(tc, "\t\t{\t/* find insertion point */\n");
  993. sprintf(buf0, "((Q%d *)z)->contents[j].fld", q->qid);
  994. for (j = 0; j < q->nflds; j++)
  995. { fprintf(tc, "\t\t\tif (fld%d > %s%d) continue;\n",
  996. j, buf0, j);
  997. fprintf(tc, "\t\t\tif (fld%d < %s%d) ", j, buf0, j);
  998. fprintf(tc, "goto found%d;\n\n", q->qid);
  999. }
  1000. fprintf(tc, "\t\t}\n");
  1001. fprintf(tc, "\tfound%d:\n", q->qid);
  1002. sprintf(buf0, "((Q%d *)z)->", q->qid);
  1003. fprintf(tc, "\t\tfor (k = %sQlen - 1; k >= j; k--)\n", buf0);
  1004. fprintf(tc, "\t\t{\t/* shift up */\n");
  1005. for (j = 0; j < q->nflds; j++)
  1006. { fprintf(tc, "\t\t\t%scontents[k+1].fld%d = ",
  1007. buf0, j);
  1008. fprintf(tc, "%scontents[k].fld%d;\n",
  1009. buf0, j);
  1010. }
  1011. fprintf(tc, "\t\t}\n");
  1012. fprintf(tc, "\tappend%d:\t/* insert in slot j */\n", q->qid);
  1013. }
  1014. fprintf(tc, "#ifdef HAS_SORTED\n");
  1015. fprintf(tc, "\t\t(trpt+1)->ipt = j;\n"); /* ipt was bup.oval */
  1016. fprintf(tc, "#endif\n");
  1017. fprintf(tc, "\t\t%sQlen = %sQlen + 1;\n", buf0, buf0);
  1018. sprintf(buf0, "((Q%d *)z)->contents[j].fld", q->qid);
  1019. for (j = 0; j < q->nflds; j++)
  1020. fprintf(tc, "\t\t%s%d = fld%d;\n", buf0, j, j);
  1021. fprintf(tc, "\t\tbreak;\n");
  1022. }
  1023. ntimes(tc, 0, 1, Addq2);
  1024. for (q = qtab; q; q = q->nxt)
  1025. fprintf(tc, "\tcase %d: return %d;\n", q->qid, (!q->nslots));
  1026. ntimes(tc, 0, 1, Addq3);
  1027. for (q = qtab; q; q = q->nxt)
  1028. fprintf(tc, "\tcase %d: return (q_sz(from) == %d);\n",
  1029. q->qid, max(1, q->nslots));
  1030. ntimes(tc, 0, 1, Addq4);
  1031. for (q = qtab; q; q = q->nxt)
  1032. { sprintf(buf0, "((Q%d *)z)->", q->qid);
  1033. fprintf(tc, " case %d:%s\n\t\t",
  1034. q->qid, (q->nslots)?"":" /* =rv= */");
  1035. if (q->nflds == 1)
  1036. { fprintf(tc, "if (fld == 0) r = %s", buf0);
  1037. fprintf(tc, "contents[slot].fld0;\n");
  1038. } else
  1039. { fprintf(tc, "switch (fld) {\n");
  1040. ncases(tc, q->qid, 0, q->nflds, R12);
  1041. fprintf(tc, "\t\tdefault: Uerror");
  1042. fprintf(tc, "(\"too many fields in recv\");\n");
  1043. fprintf(tc, "\t\t}\n");
  1044. }
  1045. fprintf(tc, "\t\tif (done)\n");
  1046. if (q->nslots == 0)
  1047. { fprintf(tc, "\t\t{ j = %sQlen - 1;\n", buf0);
  1048. fprintf(tc, "\t\t %sQlen = 0;\n", buf0);
  1049. sprintf(buf0, "\t\t\t((Q%d *)z)->contents", q->qid);
  1050. } else
  1051. { fprintf(tc, "\t\t{ j = %sQlen;\n", buf0);
  1052. fprintf(tc, "\t\t %sQlen = --j;\n", buf0);
  1053. fprintf(tc, "\t\t for (k=slot; k<j; k++)\n");
  1054. fprintf(tc, "\t\t {\n");
  1055. sprintf(buf0, "\t\t\t((Q%d *)z)->contents", q->qid);
  1056. for (j = 0; j < q->nflds; j++)
  1057. { fprintf(tc, "\t%s[k].fld%d = \n", buf0, j);
  1058. fprintf(tc, "\t\t%s[k+1].fld%d;\n", buf0, j);
  1059. }
  1060. fprintf(tc, "\t\t }\n");
  1061. }
  1062. for (j = 0; j < q->nflds; j++)
  1063. fprintf(tc, "%s[j].fld%d = 0;\n", buf0, j);
  1064. fprintf(tc, "\t\t\tif (fld+1 != %d)\n\t\t\t", q->nflds);
  1065. fprintf(tc, "\tuerror(\"missing pars in receive\");\n");
  1066. /* incompletely received msgs cannot be unrecv'ed */
  1067. fprintf(tc, "\t\t}\n");
  1068. fprintf(tc, "\t\tbreak;\n");
  1069. }
  1070. ntimes(tc, 0, 1, Addq5);
  1071. for (q = qtab; q; q = q->nxt)
  1072. fprintf(tc, " case %d: j = sizeof(Q%d); break;\n",
  1073. q->qid, q->qid);
  1074. ntimes(tc, 0, 1, R8b);
  1075. ntimes(th, 0, 1, Proto); /* tag on function prototypes */
  1076. fprintf(th, "void qsend(int, int");
  1077. for (j = 0; j < Mpars; j++)
  1078. fprintf(th, ", int");
  1079. fprintf(th, ");\n");
  1080. fprintf(th, "#define Addproc(x) addproc(x");
  1081. for (j = 0; j < Npars; j++)
  1082. fprintf(th, ", 0");
  1083. fprintf(th, ")\n");
  1084. }