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