1*219b2ee8SDavid du Colombier /***** spin: run.c *****/ 2*219b2ee8SDavid du Colombier 3*219b2ee8SDavid du Colombier /* Copyright (c) 1991,1995 by AT&T Corporation. All Rights Reserved. */ 4*219b2ee8SDavid du Colombier /* This software is for educational purposes only. */ 5*219b2ee8SDavid du Colombier /* Permission is given to distribute this code provided that this intro- */ 6*219b2ee8SDavid du Colombier /* ductory message is not removed and no monies are exchanged. */ 7*219b2ee8SDavid du Colombier /* No guarantee is expressed or implied by the distribution of this code. */ 8*219b2ee8SDavid du Colombier /* Software written by Gerard J. Holzmann as part of the book: */ 9*219b2ee8SDavid du Colombier /* `Design and Validation of Computer Protocols,' ISBN 0-13-539925-4, */ 10*219b2ee8SDavid du Colombier /* Prentice Hall, Englewood Cliffs, NJ, 07632. */ 11*219b2ee8SDavid du Colombier /* Send bug-reports and/or questions to: gerard@research.att.com */ 12*219b2ee8SDavid du Colombier 13*219b2ee8SDavid du Colombier #include "spin.h" 14*219b2ee8SDavid du Colombier #include "y.tab.h" 15*219b2ee8SDavid du Colombier 16*219b2ee8SDavid du Colombier extern Symbol *Fname; 17*219b2ee8SDavid du Colombier extern Element *LastStep; 18*219b2ee8SDavid du Colombier extern int Rvous, lineno, Tval, Interactive, SubChoice; 19*219b2ee8SDavid du Colombier extern int TstOnly, verbose, s_trail, xspin; 20*219b2ee8SDavid du Colombier 21*219b2ee8SDavid du Colombier static long Seed=1; 22*219b2ee8SDavid du Colombier 23*219b2ee8SDavid du Colombier void 24*219b2ee8SDavid du Colombier Srand(unsigned int s) 25*219b2ee8SDavid du Colombier { Seed = s; 26*219b2ee8SDavid du Colombier } 27*219b2ee8SDavid du Colombier 28*219b2ee8SDavid du Colombier long 29*219b2ee8SDavid du Colombier Rand(void) 30*219b2ee8SDavid du Colombier { /* CACM 31(10), Oct 1988 */ 31*219b2ee8SDavid du Colombier Seed = 16807*(Seed%127773) - 2836*(Seed/127773); 32*219b2ee8SDavid du Colombier if (Seed <= 0) Seed += 2147483647; 33*219b2ee8SDavid du Colombier return Seed; 34*219b2ee8SDavid du Colombier } 35*219b2ee8SDavid du Colombier 36*219b2ee8SDavid du Colombier Element * 37*219b2ee8SDavid du Colombier eval_sub(Element *e) 38*219b2ee8SDavid du Colombier { Element *f, *g; 39*219b2ee8SDavid du Colombier SeqList *z; 40*219b2ee8SDavid du Colombier int i, j, k; 41*219b2ee8SDavid du Colombier 42*219b2ee8SDavid du Colombier if (!e->n) 43*219b2ee8SDavid du Colombier return ZE; 44*219b2ee8SDavid du Colombier #ifdef DEBUG 45*219b2ee8SDavid du Colombier printf("eval_sub(%d) ", e->Seqno); 46*219b2ee8SDavid du Colombier comment(stdout, e->n, 0); 47*219b2ee8SDavid du Colombier printf("\n"); 48*219b2ee8SDavid du Colombier #endif 49*219b2ee8SDavid du Colombier if (e->n->ntyp == GOTO) 50*219b2ee8SDavid du Colombier { if (Rvous) return ZE; 51*219b2ee8SDavid du Colombier f = get_lab(e->n, 1); 52*219b2ee8SDavid du Colombier cross_dsteps(e->n, f->n); 53*219b2ee8SDavid du Colombier return f; 54*219b2ee8SDavid du Colombier } 55*219b2ee8SDavid du Colombier if (e->n->ntyp == UNLESS) 56*219b2ee8SDavid du Colombier { /* escapes were distributed into sequence */ 57*219b2ee8SDavid du Colombier return eval_sub(e->sub->this->frst); 58*219b2ee8SDavid du Colombier } else if (e->sub) /* true for IF, DO, and UNLESS */ 59*219b2ee8SDavid du Colombier { Element *has_else = ZE; 60*219b2ee8SDavid du Colombier 61*219b2ee8SDavid du Colombier if (Interactive && !SubChoice) 62*219b2ee8SDavid du Colombier { printf("Select stmnt ("); 63*219b2ee8SDavid du Colombier whoruns(0); printf(")\n"); 64*219b2ee8SDavid du Colombier printf("\tchoice 0: other process\n"); 65*219b2ee8SDavid du Colombier } 66*219b2ee8SDavid du Colombier for (z = e->sub, j=0; z; z = z->nxt) 67*219b2ee8SDavid du Colombier { j++; 68*219b2ee8SDavid du Colombier if (Interactive 69*219b2ee8SDavid du Colombier && !SubChoice 70*219b2ee8SDavid du Colombier && z->this->frst 71*219b2ee8SDavid du Colombier && (xspin || Enabled0(z->this->frst))) 72*219b2ee8SDavid du Colombier { printf("\tchoice %d: ", j); 73*219b2ee8SDavid du Colombier if (!Enabled0(z->this->frst)) 74*219b2ee8SDavid du Colombier printf("unexecutable, "); 75*219b2ee8SDavid du Colombier comment(stdout, z->this->frst->n, 0); 76*219b2ee8SDavid du Colombier printf("\n"); 77*219b2ee8SDavid du Colombier } } 78*219b2ee8SDavid du Colombier if (Interactive) 79*219b2ee8SDavid du Colombier { if (!SubChoice) 80*219b2ee8SDavid du Colombier { if (xspin) 81*219b2ee8SDavid du Colombier printf("Make Selection %d\n\n", j); 82*219b2ee8SDavid du Colombier else 83*219b2ee8SDavid du Colombier printf("Select [0-%d]: ", j); 84*219b2ee8SDavid du Colombier fflush(stdout); 85*219b2ee8SDavid du Colombier scanf("%d", &k); 86*219b2ee8SDavid du Colombier } else 87*219b2ee8SDavid du Colombier { k = SubChoice; 88*219b2ee8SDavid du Colombier SubChoice = 0; 89*219b2ee8SDavid du Colombier } 90*219b2ee8SDavid du Colombier if (k < 1 || k > j) 91*219b2ee8SDavid du Colombier { printf("\tchoice outside range\n"); 92*219b2ee8SDavid du Colombier return ZE; 93*219b2ee8SDavid du Colombier } 94*219b2ee8SDavid du Colombier k--; 95*219b2ee8SDavid du Colombier } else 96*219b2ee8SDavid du Colombier k = Rand()%j; /* nondeterminism */ 97*219b2ee8SDavid du Colombier for (i = 0, z = e->sub; i < j+k; i++) 98*219b2ee8SDavid du Colombier { if (z->this->frst 99*219b2ee8SDavid du Colombier && z->this->frst->n->ntyp == ELSE) 100*219b2ee8SDavid du Colombier { has_else = z->this->frst->nxt; 101*219b2ee8SDavid du Colombier if (!Interactive) 102*219b2ee8SDavid du Colombier { z = (z->nxt)?z->nxt:e->sub; 103*219b2ee8SDavid du Colombier continue; 104*219b2ee8SDavid du Colombier } } 105*219b2ee8SDavid du Colombier if (i >= k) 106*219b2ee8SDavid du Colombier { if (f = eval_sub(z->this->frst)) 107*219b2ee8SDavid du Colombier return f; 108*219b2ee8SDavid du Colombier else if (Interactive) 109*219b2ee8SDavid du Colombier { printf("\tunexecutable\n"); 110*219b2ee8SDavid du Colombier return ZE; 111*219b2ee8SDavid du Colombier } } 112*219b2ee8SDavid du Colombier z = (z->nxt)?z->nxt:e->sub; 113*219b2ee8SDavid du Colombier } 114*219b2ee8SDavid du Colombier LastStep = z->this->frst; 115*219b2ee8SDavid du Colombier return has_else; 116*219b2ee8SDavid du Colombier } else 117*219b2ee8SDavid du Colombier { if (e->n->ntyp == ATOMIC 118*219b2ee8SDavid du Colombier || e->n->ntyp == D_STEP) 119*219b2ee8SDavid du Colombier { f = e->n->sl->this->frst; 120*219b2ee8SDavid du Colombier g = e->n->sl->this->last; 121*219b2ee8SDavid du Colombier g->nxt = e->nxt; 122*219b2ee8SDavid du Colombier if (!(g = eval_sub(f))) /* atomic guard */ 123*219b2ee8SDavid du Colombier return ZE; 124*219b2ee8SDavid du Colombier /* new implementation of atomic sequences */ 125*219b2ee8SDavid du Colombier return g; 126*219b2ee8SDavid du Colombier } else if (e->n->ntyp == NON_ATOMIC) 127*219b2ee8SDavid du Colombier { f = e->n->sl->this->frst; 128*219b2ee8SDavid du Colombier g = e->n->sl->this->last; 129*219b2ee8SDavid du Colombier g->nxt = e->nxt; /* close it */ 130*219b2ee8SDavid du Colombier return eval_sub(f); 131*219b2ee8SDavid du Colombier } else if (Rvous) 132*219b2ee8SDavid du Colombier { if (eval_sync(e)) 133*219b2ee8SDavid du Colombier return e->nxt; 134*219b2ee8SDavid du Colombier } else if (e->n->ntyp == '.') 135*219b2ee8SDavid du Colombier { return e->nxt; 136*219b2ee8SDavid du Colombier } else 137*219b2ee8SDavid du Colombier { SeqList *x; 138*219b2ee8SDavid du Colombier if (e->esc && verbose&32) 139*219b2ee8SDavid du Colombier { printf("Statement ["); 140*219b2ee8SDavid du Colombier comment(stdout, e->n, 0); 141*219b2ee8SDavid du Colombier printf("] - can be escaped by\n"); 142*219b2ee8SDavid du Colombier for (x = e->esc; x; x = x->nxt) 143*219b2ee8SDavid du Colombier { printf("\t["); 144*219b2ee8SDavid du Colombier comment(stdout, x->this->frst->n, 0); 145*219b2ee8SDavid du Colombier printf("]\n"); 146*219b2ee8SDavid du Colombier } } 147*219b2ee8SDavid du Colombier for (x = e->esc; x; x = x->nxt) 148*219b2ee8SDavid du Colombier { if (g = eval_sub(x->this->frst)) 149*219b2ee8SDavid du Colombier { if (verbose&4) 150*219b2ee8SDavid du Colombier printf("\tEscape taken\n"); 151*219b2ee8SDavid du Colombier return g; 152*219b2ee8SDavid du Colombier } } 153*219b2ee8SDavid du Colombier switch (e->n->ntyp) { 154*219b2ee8SDavid du Colombier case TIMEOUT: case RUN: 155*219b2ee8SDavid du Colombier case PRINT: case ASGN: case ASSERT: 156*219b2ee8SDavid du Colombier case 's': case 'r': case 'c': 157*219b2ee8SDavid du Colombier /* toplevel statements only */ 158*219b2ee8SDavid du Colombier LastStep = e; 159*219b2ee8SDavid du Colombier default: 160*219b2ee8SDavid du Colombier break; 161*219b2ee8SDavid du Colombier } 162*219b2ee8SDavid du Colombier return (eval(e->n))?e->nxt:ZE; 163*219b2ee8SDavid du Colombier } 164*219b2ee8SDavid du Colombier } 165*219b2ee8SDavid du Colombier return ZE; 166*219b2ee8SDavid du Colombier } 167*219b2ee8SDavid du Colombier 168*219b2ee8SDavid du Colombier int 169*219b2ee8SDavid du Colombier eval_sync(Element *e) 170*219b2ee8SDavid du Colombier { /* allow only synchronous receives 171*219b2ee8SDavid du Colombier /* and related node types */ 172*219b2ee8SDavid du Colombier Lextok *now = (e)?e->n:ZN; 173*219b2ee8SDavid du Colombier 174*219b2ee8SDavid du Colombier if (!now 175*219b2ee8SDavid du Colombier || now->ntyp != 'r' 176*219b2ee8SDavid du Colombier || !q_is_sync(now)) 177*219b2ee8SDavid du Colombier return 0; 178*219b2ee8SDavid du Colombier 179*219b2ee8SDavid du Colombier LastStep = e; 180*219b2ee8SDavid du Colombier return eval(now); 181*219b2ee8SDavid du Colombier } 182*219b2ee8SDavid du Colombier 183*219b2ee8SDavid du Colombier int 184*219b2ee8SDavid du Colombier assign(Lextok *now) 185*219b2ee8SDavid du Colombier { int t; 186*219b2ee8SDavid du Colombier 187*219b2ee8SDavid du Colombier if (TstOnly) return 1; 188*219b2ee8SDavid du Colombier 189*219b2ee8SDavid du Colombier switch (now->rgt->ntyp) { 190*219b2ee8SDavid du Colombier case FULL: case NFULL: 191*219b2ee8SDavid du Colombier case EMPTY: case NEMPTY: 192*219b2ee8SDavid du Colombier case RUN: case LEN: 193*219b2ee8SDavid du Colombier t = BYTE; 194*219b2ee8SDavid du Colombier break; 195*219b2ee8SDavid du Colombier default: 196*219b2ee8SDavid du Colombier t = Sym_typ(now->rgt); 197*219b2ee8SDavid du Colombier break; 198*219b2ee8SDavid du Colombier } 199*219b2ee8SDavid du Colombier typ_ck(Sym_typ(now->lft), t, "assignment"); 200*219b2ee8SDavid du Colombier return setval(now->lft, eval(now->rgt)); 201*219b2ee8SDavid du Colombier } 202*219b2ee8SDavid du Colombier 203*219b2ee8SDavid du Colombier int 204*219b2ee8SDavid du Colombier eval(Lextok *now) 205*219b2ee8SDavid du Colombier { 206*219b2ee8SDavid du Colombier if (now) { 207*219b2ee8SDavid du Colombier lineno = now->ln; 208*219b2ee8SDavid du Colombier Fname = now->fn; 209*219b2ee8SDavid du Colombier #ifdef DEBUG 210*219b2ee8SDavid du Colombier printf("eval "); 211*219b2ee8SDavid du Colombier comment(stdout, now, 0); 212*219b2ee8SDavid du Colombier printf("\n"); 213*219b2ee8SDavid du Colombier #endif 214*219b2ee8SDavid du Colombier switch (now->ntyp) { 215*219b2ee8SDavid du Colombier case CONST: return now->val; 216*219b2ee8SDavid du Colombier case '!': return !eval(now->lft); 217*219b2ee8SDavid du Colombier case UMIN: return -eval(now->lft); 218*219b2ee8SDavid du Colombier case '~': return ~eval(now->lft); 219*219b2ee8SDavid du Colombier 220*219b2ee8SDavid du Colombier case '/': return (eval(now->lft) / eval(now->rgt)); 221*219b2ee8SDavid du Colombier case '*': return (eval(now->lft) * eval(now->rgt)); 222*219b2ee8SDavid du Colombier case '-': return (eval(now->lft) - eval(now->rgt)); 223*219b2ee8SDavid du Colombier case '+': return (eval(now->lft) + eval(now->rgt)); 224*219b2ee8SDavid du Colombier case '%': return (eval(now->lft) % eval(now->rgt)); 225*219b2ee8SDavid du Colombier case LT: return (eval(now->lft) < eval(now->rgt)); 226*219b2ee8SDavid du Colombier case GT: return (eval(now->lft) > eval(now->rgt)); 227*219b2ee8SDavid du Colombier case '&': return (eval(now->lft) & eval(now->rgt)); 228*219b2ee8SDavid du Colombier case '|': return (eval(now->lft) | eval(now->rgt)); 229*219b2ee8SDavid du Colombier case LE: return (eval(now->lft) <= eval(now->rgt)); 230*219b2ee8SDavid du Colombier case GE: return (eval(now->lft) >= eval(now->rgt)); 231*219b2ee8SDavid du Colombier case NE: return (eval(now->lft) != eval(now->rgt)); 232*219b2ee8SDavid du Colombier case EQ: return (eval(now->lft) == eval(now->rgt)); 233*219b2ee8SDavid du Colombier case OR: return (eval(now->lft) || eval(now->rgt)); 234*219b2ee8SDavid du Colombier case AND: return (eval(now->lft) && eval(now->rgt)); 235*219b2ee8SDavid du Colombier case LSHIFT: return (eval(now->lft) << eval(now->rgt)); 236*219b2ee8SDavid du Colombier case RSHIFT: return (eval(now->lft) >> eval(now->rgt)); 237*219b2ee8SDavid du Colombier case '?': return (eval(now->lft) ? eval(now->rgt->lft) 238*219b2ee8SDavid du Colombier : eval(now->rgt->rgt)); 239*219b2ee8SDavid du Colombier 240*219b2ee8SDavid du Colombier case 'p': return remotevar(now); /* only _p allowed */ 241*219b2ee8SDavid du Colombier case 'q': return remotelab(now); 242*219b2ee8SDavid du Colombier case 'R': return qrecv(now, 0); /* test only */ 243*219b2ee8SDavid du Colombier case LEN: return qlen(now); 244*219b2ee8SDavid du Colombier case FULL: return (qfull(now)); 245*219b2ee8SDavid du Colombier case EMPTY: return (qlen(now)==0); 246*219b2ee8SDavid du Colombier case NFULL: return (!qfull(now)); 247*219b2ee8SDavid du Colombier case NEMPTY: return (qlen(now)>0); 248*219b2ee8SDavid du Colombier case ENABLED: return 1; /* can only be hit with -t option*/ 249*219b2ee8SDavid du Colombier case PC_VAL: return pc_value(now->lft); 250*219b2ee8SDavid du Colombier case NAME: return getval(now); 251*219b2ee8SDavid du Colombier 252*219b2ee8SDavid du Colombier case TIMEOUT: return Tval; 253*219b2ee8SDavid du Colombier case RUN: return TstOnly?1:enable(now->sym, now->lft); 254*219b2ee8SDavid du Colombier 255*219b2ee8SDavid du Colombier case 's': return qsend(now); /* send */ 256*219b2ee8SDavid du Colombier case 'r': return qrecv(now, 1); /* full-receive */ 257*219b2ee8SDavid du Colombier case 'c': return eval(now->lft); /* condition */ 258*219b2ee8SDavid du Colombier case PRINT: return TstOnly?1:interprint(now); 259*219b2ee8SDavid du Colombier case ASGN: return assign(now); 260*219b2ee8SDavid du Colombier case ASSERT: if (TstOnly || eval(now->lft)) return 1; 261*219b2ee8SDavid du Colombier non_fatal("assertion violated", (char *) 0); 262*219b2ee8SDavid du Colombier if (s_trail) return 1; /* else */ 263*219b2ee8SDavid du Colombier wrapup(1); /* doesn't return */ 264*219b2ee8SDavid du Colombier 265*219b2ee8SDavid du Colombier case IF: case DO: case BREAK: case UNLESS: /* compound structure */ 266*219b2ee8SDavid du Colombier case '.': return 1; /* return label for compound */ 267*219b2ee8SDavid du Colombier case '@': return 0; /* stop state */ 268*219b2ee8SDavid du Colombier case ELSE: return 1; /* only hit here in guided trails */ 269*219b2ee8SDavid du Colombier default : printf("spin: bad node type %d (run)\n", now->ntyp); 270*219b2ee8SDavid du Colombier fatal("aborting", 0); 271*219b2ee8SDavid du Colombier }} 272*219b2ee8SDavid du Colombier return 0; 273*219b2ee8SDavid du Colombier } 274*219b2ee8SDavid du Colombier 275*219b2ee8SDavid du Colombier int 276*219b2ee8SDavid du Colombier interprint(Lextok *n) 277*219b2ee8SDavid du Colombier { Lextok *tmp = n->lft; 278*219b2ee8SDavid du Colombier char c, *s = n->sym->name; 279*219b2ee8SDavid du Colombier int i, j; 280*219b2ee8SDavid du Colombier 281*219b2ee8SDavid du Colombier for (i = 0; i < strlen(s); i++) 282*219b2ee8SDavid du Colombier switch (s[i]) { 283*219b2ee8SDavid du Colombier default: putchar(s[i]); break; 284*219b2ee8SDavid du Colombier case '\"': break; /* ignore */ 285*219b2ee8SDavid du Colombier case '\\': 286*219b2ee8SDavid du Colombier switch(s[++i]) { 287*219b2ee8SDavid du Colombier case 't': putchar('\t'); break; 288*219b2ee8SDavid du Colombier case 'n': putchar('\n'); break; 289*219b2ee8SDavid du Colombier default: putchar(s[i]); break; 290*219b2ee8SDavid du Colombier } 291*219b2ee8SDavid du Colombier break; 292*219b2ee8SDavid du Colombier case '%': 293*219b2ee8SDavid du Colombier if ((c = s[++i]) == '%') 294*219b2ee8SDavid du Colombier { putchar('%'); /* literal */ 295*219b2ee8SDavid du Colombier break; 296*219b2ee8SDavid du Colombier } 297*219b2ee8SDavid du Colombier if (!tmp) 298*219b2ee8SDavid du Colombier { non_fatal("too few print args %s", s); 299*219b2ee8SDavid du Colombier break; 300*219b2ee8SDavid du Colombier } 301*219b2ee8SDavid du Colombier j = eval(tmp->lft); 302*219b2ee8SDavid du Colombier tmp = tmp->rgt; 303*219b2ee8SDavid du Colombier switch(c) { 304*219b2ee8SDavid du Colombier case 'c': printf("%c", j); break; 305*219b2ee8SDavid du Colombier case 'd': printf("%d", j); break; 306*219b2ee8SDavid du Colombier case 'o': printf("%o", j); break; 307*219b2ee8SDavid du Colombier case 'u': printf("%u", (unsigned) j); break; 308*219b2ee8SDavid du Colombier case 'x': printf("%x", j); break; 309*219b2ee8SDavid du Colombier default: non_fatal("unrecognized print cmd: '%s'", &s[i-1]); 310*219b2ee8SDavid du Colombier break; 311*219b2ee8SDavid du Colombier } 312*219b2ee8SDavid du Colombier break; 313*219b2ee8SDavid du Colombier } 314*219b2ee8SDavid du Colombier fflush(stdout); 315*219b2ee8SDavid du Colombier return 1; 316*219b2ee8SDavid du Colombier } 317*219b2ee8SDavid du Colombier 318*219b2ee8SDavid du Colombier /* new */ 319*219b2ee8SDavid du Colombier 320*219b2ee8SDavid du Colombier int 321*219b2ee8SDavid du Colombier Enabled1(Lextok *n) 322*219b2ee8SDavid du Colombier { int i; int v = verbose; 323*219b2ee8SDavid du Colombier 324*219b2ee8SDavid du Colombier if (n) 325*219b2ee8SDavid du Colombier switch (n->ntyp) { 326*219b2ee8SDavid du Colombier default: /* side-effect free */ 327*219b2ee8SDavid du Colombier verbose = 0; 328*219b2ee8SDavid du Colombier i = eval(n); 329*219b2ee8SDavid du Colombier verbose = v; 330*219b2ee8SDavid du Colombier return i; 331*219b2ee8SDavid du Colombier 332*219b2ee8SDavid du Colombier case PRINT: case ASGN: 333*219b2ee8SDavid du Colombier case ASSERT: case RUN: 334*219b2ee8SDavid du Colombier return 1; 335*219b2ee8SDavid du Colombier 336*219b2ee8SDavid du Colombier case 's': /* guesses for rv */ 337*219b2ee8SDavid du Colombier if (q_is_sync(n)) return !Rvous; 338*219b2ee8SDavid du Colombier return (!qfull(n)); 339*219b2ee8SDavid du Colombier case 'r': /* guesses for rv */ 340*219b2ee8SDavid du Colombier if (q_is_sync(n)) return Rvous; 341*219b2ee8SDavid du Colombier n->ntyp = 'R'; verbose = 0; 342*219b2ee8SDavid du Colombier i = eval(n); 343*219b2ee8SDavid du Colombier n->ntyp = 'r'; verbose = v; 344*219b2ee8SDavid du Colombier return i; 345*219b2ee8SDavid du Colombier } 346*219b2ee8SDavid du Colombier return 0; 347*219b2ee8SDavid du Colombier } 348*219b2ee8SDavid du Colombier 349*219b2ee8SDavid du Colombier int 350*219b2ee8SDavid du Colombier Enabled0(Element *e) 351*219b2ee8SDavid du Colombier { SeqList *z; 352*219b2ee8SDavid du Colombier 353*219b2ee8SDavid du Colombier if (!e || !e->n) 354*219b2ee8SDavid du Colombier return 0; 355*219b2ee8SDavid du Colombier 356*219b2ee8SDavid du Colombier switch (e->n->ntyp) { 357*219b2ee8SDavid du Colombier case '.': 358*219b2ee8SDavid du Colombier return 1; 359*219b2ee8SDavid du Colombier case GOTO: 360*219b2ee8SDavid du Colombier if (Rvous) return 0; 361*219b2ee8SDavid du Colombier return 1; 362*219b2ee8SDavid du Colombier case UNLESS: 363*219b2ee8SDavid du Colombier return Enabled0(e->sub->this->frst); 364*219b2ee8SDavid du Colombier case ATOMIC: 365*219b2ee8SDavid du Colombier case D_STEP: 366*219b2ee8SDavid du Colombier case NON_ATOMIC: 367*219b2ee8SDavid du Colombier return Enabled0(e->n->sl->this->frst); 368*219b2ee8SDavid du Colombier } 369*219b2ee8SDavid du Colombier if (e->sub) /* true for IF, DO, and UNLESS */ 370*219b2ee8SDavid du Colombier { for (z = e->sub; z; z = z->nxt) 371*219b2ee8SDavid du Colombier if (Enabled0(z->this->frst)) 372*219b2ee8SDavid du Colombier return 1; 373*219b2ee8SDavid du Colombier return 0; 374*219b2ee8SDavid du Colombier } 375*219b2ee8SDavid du Colombier for (z = e->esc; z; z = z->nxt) 376*219b2ee8SDavid du Colombier { if (Enabled0(z->this->frst)) 377*219b2ee8SDavid du Colombier return 1; 378*219b2ee8SDavid du Colombier } 379*219b2ee8SDavid du Colombier return Enabled1(e->n); 380*219b2ee8SDavid du Colombier } 381