|
|
1.1 root 1: #include "stdio.h"
2: #include "trace.h"
3: #include "trace.d"
4:
5: #define BS(n) ((n) & ~(PASSED))
6:
7: extern struct TBL *tbl;
8: extern struct LBT *lbt;
9: extern struct MBOX *mbox;
10: extern struct MNAME *fullname;
11: extern struct PROCSTACK **procstack;
12:
13: extern struct VARPARS *procpars;
14: extern struct TBLPARS *tblpars;
15:
16: extern struct LOCVARS *tblvars;
17: extern struct TBLPARS *tablpars;
18:
19: extern struct QUEUE **starter, **head, **tail;
20: extern struct QUEUE *s_first, *s_last;
21: extern struct VISIT *lastvisit;
22:
23: extern int *reftasks, *processes, *basics;
24: extern int *globvars, *inits, *state, *qsize;
25: extern int assertbl, abase, errortbl, ebase;
26:
27: extern int nrtbl, nrqs, nrrefs, nrprocs, nrinit;
28: extern int nrvars, nrmesgs, msgbase;
29: extern int maxlevel, maxreached;
30:
31: extern char noshortcut, prbyq, timedd, blast, qandirty, muststore;
32: extern char maxxed, completed, lockplus, firstlock;
33:
34: extern long locksf, normf, loopsf;
35:
36: short lastqueue; /* the last queue addressed */
37: int level = 0;
38: double COUNT = 0;
39:
40: char *emalloc(), *Realloc(), *Emalloc();
41:
42: #include "assert.c"
43:
44: determine(m)
45: {
46: if (m >= 3*MANY)
47: return 0; /* constant */
48: else if (m >= 2*MANY)
49: return 1; /* parameter */
50: else if (m >= MANY)
51: return 2; /* local */
52: else if (m >= 0)
53: return 3; /* global */
54: else if (m < -3*MANY)
55: return 5; /* negative number */
56: else if (m <= -2)
57: return 4; /* expression */
58: else
59: whoops("cannot happen - determine");
60: }
61:
62: convert(m, pr)
63: { int res;
64: int n = m;
65:
66: /* convert a pvar: global, local, parameter, or a constant */
67:
68: switch (determine(n)) {
69: case 5: res = n + 3*MANY;
70: break;
71: case 4: res = evalcond(-(m+2), pr);
72: break;
73: case 0: res = n - 3*MANY;
74: break;
75: case 1: res = wapper(m, pr);
76: break;
77: case 2: n -= MANY;
78: if (n >= 0 && n < (int) procpars[pr].nrlvars)
79: res = (int) procpars[pr].lvarvals[n];
80: else
81: whoops("cannot happen 1 - convert");
82: break;
83: case 3: if (n >= 0 && n < nrvars)
84: res = globvars[n];
85: else
86: whoops("cannot happen 2 - convert");
87: break;
88: default:
89: whoops("cannot happen 3 - convert"); /* a parameter */
90: break;
91: }
92:
93: return res;
94: }
95:
96: wapper(n, pr)
97: { int x = n - 2*MANY;
98: int y;
99: if (x < 0 || x >= MANY)
100: return n; /* not a parameter */
101: if (x >= procpars[pr].nrvs)
102: whoops("cannot happen 1 - wapper");
103:
104: y = (int) procpars[pr].vs[x];
105:
106: if (y >= 2*MANY && y < 3*MANY)
107: whoops("cannot happen 2 - wapper");
108: return y;
109: }
110:
111: mapper(n, pr) /* convert a message parameter */
112: { register int x = n - MANY;
113:
114: if (x < 0 || x >= MANY)
115: return n; /* not a parameter */
116: if (x >= procpars[pr].nrms)
117: whoops("cannot happen - mapper");
118: return ((int)procpars[pr].ms[x]);
119: }
120:
121: matchon(n, m, t, trial, TT, pr)
122: {
123: if (trial == 2)
124: return (TT == TMO && qsize[m] == 0);
125: else
126: {
127: switch (TT) {
128: case FCT :
129: case SPN : return 1;
130: case CND : return (evalcond(n, pr));
131: case DFL : return (qsize[m] > 0 && no_other(t,head[m]->mesg,pr));
132: case INP : return (qsize[m] > 0 && BS(head[m]->mesg) == n);
133: case TMO : return (noshortcut && qsize[m] == 0);
134: case OUTP: return (qsize[m] < mbox[m].limit);
135: default : whoops("cannot happen - matchon");
136: }
137: }
138: }
139:
140: no_other(x, yy, pr)
141: { struct TBL *tmp = &(tbl[x]);
142: int y = BS(yy);
143: int j = tmp->nrcols;
144: int h = state[pr];
145: int i;
146:
147: for (i = 0; i < j; i++)
148: { if (tmp->coltyp[i] == INP
149: && tmp->ptr[h][i].nrpils > 0
150: && y == lbt[pr].mapcol[i])
151: return 0;
152: }
153: return 1;
154: }
155:
156: send(m, to, with, pr)
157: { struct QUEUE *tmp;
158: struct QUEUE *hook = tail[to];
159: int what = NONE;
160:
161: if (with != NONE)
162: { if ((what = convert(with, pr)) >= USED - 1 || what < 0)
163: { fprintf(stderr, "cargo: %d\n", what);
164: whoops("cargo too large or negative");
165: }
166: hook->cargo = (unsigned short) ( what | USED );
167: } else
168: hook->cargo = (unsigned short) 0;
169:
170: if (qsize[to] >= mbox[to].limit)
171: whoops("shouldn't happen - send");
172:
173: tmp = (struct QUEUE *) emalloc(sizeof(struct QUEUE));
174: tmp->last = hook;
175:
176: hook->mesg = (short) m;
177: hook->next = tmp;
178: hook->s_back = s_last;
179: hook->s_forw = NULL;
180: if (s_last == NULL)
181: s_first = hook;
182: else
183: s_last->s_forw = hook;
184:
185: s_last = hook;
186: tail[to] = tmp;
187: qsize[to]++;
188:
189: require(OUTP, m, to, with, pr);
190:
191: return 1;
192: }
193:
194: receive(from, with, pr, ice)
195: struct FREEZE *ice;
196: { struct QUEUE *hook;
197: int what, wither;
198:
199: if (qsize[from] <= 0)
200: whoops("cannot happen - receive");
201:
202: hook = head[from];
203: if (hook->cargo & USED)
204: { what = (int) ((hook->cargo) & (~USED));
205: if (with == NONE)
206: fprintf(stderr, "cargo %d sent but not expected\n", what);
207: else
208: { ice->whichvar = wither = wapper(with, pr);
209: if (wither >= 3*MANY || wither <= -3*MANY)
210: whoops("receiving into a constant...");
211: if (wither < MANY)
212: { ice->oldvalue = globvars[wither];
213: globvars[wither] = what;
214: } else
215: { int n = wither - MANY;
216: if (n >= 0 && n < (int) procpars[pr].nrlvars)
217: { ice->oldvalue = procpars[pr].lvarvals[n];
218: procpars[pr].lvarvals[n] = (short) what;
219: } else
220: whoops("cannot happen 2 - receive");
221: }
222: }
223: } else if (with != NONE)
224: fprintf(stderr, "cargo expected %d but none sent\n", with);
225:
226: hook->mesg |= PASSED;
227:
228: head[from] = hook->next;
229: qsize[from]--;
230:
231: require(INP, (hook->mesg & (~PASSED)), from, what, pr);
232:
233: return 1;
234: }
235:
236: unrecv(from)
237: {
238: if (head[from] == starter[from])
239: whoops("cannot happen - unrecv");
240:
241: head[from] = head[from]->last;
242: head[from]->mesg &= (~PASSED);
243:
244: qsize[from]++;
245: }
246:
247: unsend()
248: { short i = lastqueue;
249: if (tail[i] == starter[i] || (tail[i] = tail[i]->last) != s_last)
250: whoops("cannot happen - unsend");
251:
252: if ((s_last = s_last->s_back) != NULL)
253: s_last->s_forw = NULL;
254: else
255: s_first = NULL;
256: efree(tail[i]->next);
257:
258: qsize[i]--;
259: }
260:
261: output(tag, willabort)
262: char *tag;
263: { struct QUEUE *tmp;
264:
265: printf("%s", tag);
266:
267: if ((tmp = s_first) != NULL)
268: { formatted();
269: if (prbyq != 2)
270: do putname(tmp); while ((tmp = tmp->s_forw) != NULL);
271: putchar('\n');
272: } else
273: printf("null output\n");
274:
275: if (willabort == 2 || (firstlock && willabort == 1))
276: { completed = 1;
277: postlude();
278: }
279: }
280:
281: putname(tmp)
282: struct QUEUE *tmp;
283: { int k = (int) (BS(tmp->mesg)) - msgbase;
284:
285: if (tmp->mesg & PASSED)
286: printf("%s", fullname[k].mname);
287: else
288: printf("[%s]", fullname[k].mname);
289:
290: if (tmp->cargo & USED)
291: printf("(%d),", (tmp->cargo & (~USED)));
292: else
293: putchar(',');
294: }
295:
296: inendstate()
297: { int i, j, k;
298:
299: for (i = 0, k = nrprocs; i < nrprocs; i++)
300: { j = processes[i];
301: if (j != basics[i] || tbl[j].endrow[state[i]] != 1)
302: k--;
303: }
304: return k;
305: }
306:
307: formatted()
308: { struct QUEUE *tmp = s_first;
309: int i;
310:
311: if (tmp == NULL)
312: return;
313:
314: switch((int) prbyq) {
315: case 0: break;
316: case 1:
317: for (i = 0; i < nrqs; i++)
318: { printf("\n\t%s = {", mbox[i].qname);
319: for (tmp = starter[i]; tmp != tail[i]; tmp = tmp->next)
320: putname(tmp);
321: printf("}");
322: }
323: printf("\nexecution sequence:\n\t");
324: break;
325: case 2: putchar('\n');
326: for (i = 0; i < nrqs; i++)
327: printf("%2d = %s\n", i, mbox[i].qname);
328: for (i = 0; i < nrqs; i++)
329: printf("\t%2d", i);
330: putchar('\n');
331: do
332: { for (i = whichq(BS(tmp->mesg)); i >= 0; i--)
333: putchar('\t');
334: putname(tmp);
335: putchar('\n');
336: } while ((tmp = tmp->s_forw) != NULL);
337: break;
338: }
339: }
340:
341: putloop(now, aa)
342: struct STUFF *now; char aa;
343: { register struct QUEUE *tmp = s_first;
344: struct QUEUE *at = now->s;
345:
346: if (aa)
347: printf("loop:\t");
348: else
349: printf("assertion violated: ");
350:
351: if (s_first != NULL)
352: { formatted();
353: if (prbyq != 2)
354: { do
355: { putname(tmp);
356: if (tmp == at)
357: printf("//");
358: } while ((tmp = tmp->s_forw) != NULL);
359: printf("//\n");
360: }
361: } else
362: printf("null output\n");
363: }
364:
365: ppop(pr)
366: { struct PROCSTACK *tmp = procstack[pr];
367: int i = (int) procstack[pr]->uptable;
368:
369: if (procstack[pr] == NULL)
370: whoops("cannot happen - ppop");
371: restorvarpars(tmp->varparsaved, pr);
372:
373: procstack[pr] = procstack[pr]->follow;
374:
375: efree(tmp->varparsaved);
376: efree(tmp);
377:
378: return i; /* we're returing to this table */
379: }
380:
381: ppush(pr, what, tr)
382: { struct PROCSTACK *tmp;
383:
384: tmp = (struct PROCSTACK *)
385: emalloc(sizeof(struct PROCSTACK));
386:
387: tmp->varparsaved = (struct VARPARS *)
388: emalloc(sizeof(struct VARPARS));
389:
390: savevarpars (tmp->varparsaved, pr);
391:
392: tmp->uptable = (short) what;
393: tmp->uptransf = (short) tr;
394: tmp->follow = procstack[pr];
395: procstack[pr] = tmp;
396: }
397:
398: setlvars(to, pr)
399: { register int i;
400: short z = tblvars[to].nrlvars;
401:
402: if (z > tablpars[pr].nrlvars)
403: { if (tablpars[pr].nrlvars > 0)
404: procpars[pr].lvarvals = (short *)
405: Realloc(procpars[pr].lvarvals, z * sizeof(short));
406: else
407: procpars[pr].lvarvals = (short *)
408: Emalloc(z * sizeof(short));
409:
410: tablpars[pr].nrlvars = z;
411: }
412: procpars[pr].nrlvars = z;
413:
414: for (i = 0; i < z; i++)
415: procpars[pr].lvarvals[i] = convert(tblvars[to].lvarvals[i], pr);
416: }
417:
418: setpars(from, to, pr)
419: struct CPARS *from;
420: { struct VARPARS tbuff;
421: register int i;
422: short x = tblpars[to].nrms;
423: short y = tblpars[to].nrvs;
424:
425: savemapped(&tbuff, from, pr); /* mapper() needs old nrms & nrvs */
426:
427: if (x > tablpars[pr].nrms)
428: { if (tablpars[pr].nrms > 0)
429: procpars[pr].ms = (short *)
430: Realloc(procpars[pr].ms, x * sizeof(short));
431: else
432: procpars[pr].ms = (short *)
433: Emalloc(x * sizeof(short));
434:
435: tablpars[pr].nrms = x;
436: }
437: if (y > tablpars[pr].nrvs)
438: { if (tablpars[pr].nrvs > 0)
439: procpars[pr].vs = (short *)
440: Realloc(procpars[pr].vs, y * sizeof(short));
441: else
442: procpars[pr].vs = (short *)
443: Emalloc(y * sizeof(short));
444:
445: tablpars[pr].nrvs = y;
446: }
447:
448: procpars[pr].nrms = tbuff.nrms;
449: procpars[pr].nrvs = tbuff.nrvs;
450:
451: for (i = 0; i < procpars[pr].nrms; i++)
452: procpars[pr].ms[i] = tbuff.ms[i];
453:
454: for (i = 0; i < procpars[pr].nrvs; i++)
455: procpars[pr].vs[i] = tbuff.vs[i];
456:
457: efree(tbuff.ms); efree(tbuff.vs);
458: }
459:
460: retable(prc, ice)
461: struct FREEZE *ice;
462: { struct CUBE *it, *here;
463: int t = processes[prc];
464:
465: if (ice->cube == NULL)
466: { here = ice->cube = (struct CUBE *)
467: emalloc(sizeof(struct CUBE));
468: here->pntr = here->rtnp = NULL;
469: } else
470: { for (it = ice->cube; it->pntr != NULL; it = it->pntr)
471: ;
472: it->pntr = (struct CUBE *)
473: emalloc(sizeof(struct CUBE));
474: it->pntr->rtnp = it;
475: here = it->pntr;
476: here->pntr = NULL;
477: }
478: here->poporpush = POP;
479: here->which = (short) prc;
480: here->procsaved = (short) t;
481: here->transfsaved = procstack[prc]->uptransf;
482: here->varparsaved = (struct VARPARS *) emalloc(sizeof(struct VARPARS));
483:
484: savevarpars(here->varparsaved, prc);
485:
486: processes[prc] = ppop(prc);
487: fiddler(prc);
488: state[prc] = (int) here->transfsaved;
489: muststore = tbl[processes[prc]].labrow[state[prc]];
490:
491: }
492:
493: savevarpars(at, j)
494: struct VARPARS *at;
495: { register int i;
496: struct VARPARS *it;
497:
498: it = &(procpars[j]);
499: at->nrms = it->nrms;
500: at->nrvs = it->nrvs;
501: at->nrlvars = it->nrlvars;
502:
503: at->ms = (short *) emalloc(it->nrms * sizeof(short));
504: at->vs = (short *) emalloc(it->nrvs * sizeof(short));
505: at->lvarvals = (short *) emalloc(it->nrlvars * sizeof(short));
506:
507: for (i = 0; i < at->nrms; i++)
508: at->ms[i] = it->ms[i];
509: for (i = 0; i < at->nrvs; i++)
510: at->vs[i] = it->vs[i];
511: for (i = 0; i < it->nrlvars; i++)
512: at->lvarvals[i] = it->lvarvals[i];
513:
514: }
515:
516: savemapped(at, it, j)
517: struct VARPARS *at;
518: struct CPARS *it;
519: { register int i;
520:
521: at->nrms = it->nrms;
522: at->nrvs = it->nrvs;
523:
524: at->ms = (short *) emalloc(it->nrms * sizeof(short));
525: at->vs = (short *) emalloc(it->nrvs * sizeof(short));
526:
527: for (i = 0; i < at->nrms; i++)
528: at->ms[i] = (short) mapper(it->ms[i], j);
529: for (i = 0; i < at->nrvs; i++)
530: at->vs[i] = (short) convert(it->vs[i], j);
531: }
532:
533: restorvarpars(at, pr)
534: struct VARPARS *at;
535: { register int i;
536:
537: procpars[pr].nrms = at->nrms;
538: procpars[pr].nrvs = at->nrvs;
539: procpars[pr].nrlvars = at->nrlvars;
540:
541: for (i = 0; i < at->nrms; i++)
542: procpars[pr].ms[i] = at->ms[i];
543: for (i = 0; i < at->nrvs; i++)
544: procpars[pr].vs[i] = at->vs[i];
545: for (i = 0; i < at->nrlvars; i++)
546: procpars[pr].lvarvals[i] = at->lvarvals[i];
547:
548: efree(at->ms);
549: efree(at->vs);
550: efree(at->lvarvals);
551:
552: }
553:
554: freeze(icy)
555: struct FREEZE *icy;
556: { register int i;
557: struct FREEZE *ice = icy;
558:
559: ice->statsaved = (short *) emalloc(nrprocs * sizeof(short));
560: ice->varsaved = (short *) emalloc(nrvars * sizeof(short));
561:
562: ice->lastsav = lastqueue;
563: ice->cube = NULL;
564:
565: for (i = 0; i < nrvars; i++)
566: ice->varsaved[i] = (short) globvars[i];
567:
568: for (i = 0; i < nrprocs; i++)
569: { ice->statsaved[i] = (short) state[i];
570:
571: while (tbl[processes[i]].deadrow[state[i]] && procstack[i] != NULL)
572: retable(i, ice);
573: }
574: }
575:
576: unfreeze(ice)
577: struct FREEZE *ice;
578: { struct CUBE *here;
579: register int i;
580:
581: lastqueue = ice->lastsav;
582:
583: for (i = 0; i < nrprocs; i++)
584: state[i] = (int) ice->statsaved[i];
585: for (i = 0; i < nrvars; i++)
586: globvars[i] = (int) ice->varsaved[i];
587:
588: if ((here = ice->cube) != NULL)
589: while (here->pntr != NULL)
590: here = here->pntr;
591:
592: for (; here != NULL;)
593: { i = (int) here->which;
594: if (here->poporpush == PUSH)
595: processes[i] = ppop(i);
596: else
597: { /* use cube to restore the values from before the ppop */
598: ppush(i, processes[i], (int) here->transfsaved);
599: restorvarpars (here->varparsaved, i);
600:
601: processes[i] = (int) here->procsaved;
602: efree(here->varparsaved);
603: }
604: efree(here);
605: fiddler(i);
606:
607: if (here == ice->cube)
608: break;
609: else
610: here = here->rtnp;
611: }
612: efree(ice->statsaved);
613: efree(ice->varsaved);
614: }
615:
616: FSE(I)
617: { short g, h, i, j, k, t, x, y, z, X, Y, how;
618: char progress=0, internal;
619: struct FREEZE delta;
620: struct STATE *inloop(), *iam = NULL;
621: struct VISIT *ticket;
622:
623: if (level >= maxreached)
624: {
625: if (maxxed && level >= maxlevel)
626: return;
627:
628: if (level > maxreached)
629: maxreached = level;
630: }
631: freeze(&delta);
632:
633: if (muststore && (iam = inloop()) == NULL)
634: { unfreeze(&delta);
635: return;
636: }
637:
638: /*
639: * this state has not been seen before; the state
640: * information has now been saved in the structure
641: * `STATE'; queue information has been saved in the
642: * last (iam->nrvisits) `VISIT' template of this state;
643: * we must save a pointer to this template in a local variable:
644: * to be able to mark it `analyzed' when we return
645: * for efficiency a pointer to the last visit is kept in a global `lastvisit'
646: */
647: ticket = lastvisit;
648: level++;
649: COUNT += (double) 1;
650:
651: /* three tries:
652: * 1st try accepts internal moves (no timeouts, no outputs),
653: * 2nd try accepts any moves except timeouts,
654: * 3rd try accepts only timeouts.
655: */
656:
657: for (X = 0; X <= 2; X++)
658: { internal = 0;
659: for (g = 0, i = I; g < nrprocs; g++, i = (i+1)%nrprocs)
660: { t = processes[i];
661: k = state[i];
662:
663: if (X == 0 && tbl[t].badrow[k])
664: continue;
665:
666: for (j = 0; j < tbl[t].nrcols; j++)
667: { if ((z = tbl[t].ptr[k][j].nrpils) == 0)
668: continue;
669:
670: x = lbt[i].mapcol[j];
671: y = lbt[i].orgcol[j];
672: Y = tbl[t].coltyp[j];
673:
674: if (matchon(x, y, t, X, Y, i))
675: { for (h = 0; h < z; h++)
676: { how = forward(t, k, j, h, x, y, i, Y, &delta);
677:
678: if (qandirty || how == 0 || how >= LV || how == TC)
679: internal = 1;
680:
681: progress++;
682: FSE(0);
683: backup(k, how, y, i, &delta);
684: } } /* innermost loop: non-determinism */
685: if (blast && progress > 0)
686: break;
687: } /* inner loop: options per process */
688: if (internal) break;
689: } /* outer loop: parallelism */
690: if (progress) break; /* normal exit */
691: } /* outermost loop: 2 trials */
692: if (progress == 0)
693: {
694: if ((k = inendstate()) == nrprocs)
695: { normf++;
696: if (assertholds())
697: output("endstate: ", 0);
698: else
699: output("assertion violated: ", 0);
700: }
701: else
702: { locksf++;
703: if (k == 0)
704: output("deadlock: ", 1);
705: else
706: output("partial lock: ", 1);
707: }
708: }
709: level--;
710:
711: unfreeze(&delta);
712: if (iam != NULL)
713: { mark(iam, ticket); /* mark visit `analyzed' in hash table */
714: if (progress == 0 || level >= maxlevel-3)
715: swiffle(iam, ticket); /* save pointers in fast lookup table */
716: else
717: addspoke(iam, ticket); /* make hook in 2nd order lookup table */
718: }
719: }
720:
721: forward(tb, k, j, h, m, from, pr, TT, ice)
722: struct FREEZE *ice;
723: { int how = 0, n = m;
724: struct ELM *at;
725:
726: ice->whichvar = NONE;
727:
728: at = &(tbl[tb].ptr[k][j].one[h]);
729:
730: switch (TT) {
731: case SPN: how = evalexpr(at->valtrans, pr, ice);
732: break;
733: case CND: break; /* `matchon()' already checked it */
734: case FCT: m = (int) tbl[tb].calls[n].callwhat;
735: ppush(pr, processes[pr], (int) at->transf);
736: setpars(&(tbl[tb].calls[n]), reftasks[m], pr);
737: setlvars(reftasks[m], pr);
738: processes[pr] = reftasks[m];
739: fiddler(pr);
740: state[pr] = 0;
741: muststore = tbl[processes[pr]].labrow[0];
742: return TC;
743: case TMO: send(m, from, NONE, pr);
744: receive(from, NONE, pr, ice);
745: lastqueue = (short) from;
746: how = TO;
747: break;
748: case DFL:
749: case INP: receive(from, (int) at->valtrans, pr, ice);
750: how = RO;
751: break;
752: case OUTP: send(m, from, (int) at->valtrans, pr);
753: lastqueue = (short) from;
754: how |= SO;
755: break;
756: }
757: state[pr] = (int) at->transf;
758: muststore = tbl[processes[pr]].labrow[state[pr]];
759:
760: return (how);
761: }
762:
763: backup(k, how, bx, i, ice)
764: struct FREEZE *ice;
765: { int u = (int) ice->whichvar;
766:
767: if (u != NONE)
768: { if (u >= MANY)
769: procpars[i].lvarvals[u-MANY] = ice->oldvalue;
770: else
771: globvars[u] = ice->oldvalue;
772: }
773: switch (how) {
774: case TC: u = processes[i];
775: processes[i] = ppop(i);
776: fiddler(i);
777: break;
778: case TO: unrecv(bx);
779: case SO: unsend();
780: peekassert(ice);
781: break;
782: case SR: unsend();
783: case RO: unrecv(bx);
784: peekassert(ice);
785: default: break;
786: } state[i] = k;
787: }
788:
789: fiddler(pr)
790: { register int i;
791: register int t = processes[pr];
792:
793: for (i = 0; i < tbl[t].nrcols; i++)
794: if (tbl[t].colmap[i] >= MANY)
795: { lbt[pr].mapcol[i] = mapper(tbl[t].colmap[i], pr);
796: lbt[pr].orgcol[i] = whichq(lbt[pr].mapcol[i]);
797: } else
798: { lbt[pr].mapcol[i] = tbl[t].colmap[i];
799: lbt[pr].orgcol[i] = tbl[t].colorg[i];
800: }
801:
802: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.