1 /***** spin: mesg.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 12 #include "spin.h" 13 #include "y.tab.h" 14 15 #ifndef MAXQ 16 #define MAXQ 2500 /* default max # queues */ 17 #endif 18 19 extern RunList *X; 20 extern Symbol *Fname; 21 extern Lextok *Mtype; 22 extern int verbose, TstOnly, s_trail, analyze, columns; 23 extern int lineno, depth, xspin, m_loss, jumpsteps; 24 extern int nproc, nstop; 25 extern short Have_claim; 26 27 Queue *qtab = (Queue *) 0; /* linked list of queues */ 28 Queue *ltab[MAXQ]; /* linear list of queues */ 29 int nqs = 0, firstrow = 1; 30 char Buf[4096]; 31 32 static Lextok *n_rem = (Lextok *) 0; 33 static Queue *q_rem = (Queue *) 0; 34 35 static int a_rcv(Queue *, Lextok *, int); 36 static int a_snd(Queue *, Lextok *); 37 static int sa_snd(Queue *, Lextok *); 38 static int s_snd(Queue *, Lextok *); 39 extern void sr_buf(int, int); 40 extern void sr_mesg(FILE *, int, int); 41 extern void putarrow(int, int); 42 static void sr_talk(Lextok *, int, char *, char *, int, Queue *); 43 44 int 45 cnt_mpars(Lextok *n) 46 { Lextok *m; 47 int i=0; 48 49 for (m = n; m; m = m->rgt) 50 i += Cnt_flds(m); 51 return i; 52 } 53 54 int 55 qmake(Symbol *s) 56 { Lextok *m; 57 Queue *q; 58 int i; 59 60 if (!s->ini) 61 return 0; 62 63 if (nqs >= MAXQ) 64 { lineno = s->ini->ln; 65 Fname = s->ini->fn; 66 fatal("too many queues (%s)", s->name); 67 } 68 if (analyze && nqs >= 255) 69 { fatal("too many channel types", (char *)0); 70 } 71 72 if (s->ini->ntyp != CHAN) 73 return eval(s->ini); 74 75 q = (Queue *) emalloc(sizeof(Queue)); 76 q->qid = ++nqs; 77 q->nslots = s->ini->val; 78 q->nflds = cnt_mpars(s->ini->rgt); 79 q->setat = depth; 80 81 i = max(1, q->nslots); /* 0-slot qs get 1 slot minimum */ 82 83 q->contents = (int *) emalloc(q->nflds*i*sizeof(int)); 84 q->fld_width = (int *) emalloc(q->nflds*sizeof(int)); 85 q->stepnr = (int *) emalloc(i*sizeof(int)); 86 87 for (m = s->ini->rgt, i = 0; m; m = m->rgt) 88 { if (m->sym && m->ntyp == STRUCT) 89 i = Width_set(q->fld_width, i, getuname(m->sym)); 90 else 91 q->fld_width[i++] = m->ntyp; 92 } 93 q->nxt = qtab; 94 qtab = q; 95 ltab[q->qid-1] = q; 96 97 return q->qid; 98 } 99 100 int 101 qfull(Lextok *n) 102 { int whichq = eval(n->lft)-1; 103 104 if (whichq < MAXQ && whichq >= 0 && ltab[whichq]) 105 return (ltab[whichq]->qlen >= ltab[whichq]->nslots); 106 return 0; 107 } 108 109 int 110 qlen(Lextok *n) 111 { int whichq = eval(n->lft)-1; 112 113 if (whichq < MAXQ && whichq >= 0 && ltab[whichq]) 114 return ltab[whichq]->qlen; 115 return 0; 116 } 117 118 int 119 q_is_sync(Lextok *n) 120 { int whichq = eval(n->lft)-1; 121 122 if (whichq < MAXQ && whichq >= 0 && ltab[whichq]) 123 return (ltab[whichq]->nslots == 0); 124 return 0; 125 } 126 127 int 128 qsend(Lextok *n) 129 { int whichq = eval(n->lft)-1; 130 131 if (whichq == -1) 132 { printf("Error: sending to an uninitialized chan\n"); 133 whichq = 0; 134 return 0; 135 } 136 if (whichq < MAXQ && whichq >= 0 && ltab[whichq]) 137 { ltab[whichq]->setat = depth; 138 if (ltab[whichq]->nslots > 0) 139 return a_snd(ltab[whichq], n); 140 else 141 return s_snd(ltab[whichq], n); 142 } 143 return 0; 144 } 145 146 int 147 qrecv(Lextok *n, int full) 148 { int whichq = eval(n->lft)-1; 149 150 if (whichq == -1) 151 { if (n->sym && !strcmp(n->sym->name, "STDIN")) 152 { Lextok *m; 153 154 if (TstOnly) return 1; 155 156 for (m = n->rgt; m; m = m->rgt) 157 if (m->lft->ntyp != CONST && m->lft->ntyp != EVAL) 158 { int c = getchar(); 159 (void) setval(m->lft, c); 160 } else 161 fatal("invalid use of STDIN", (char *)0); 162 163 whichq = 0; 164 return 1; 165 } 166 printf("Error: receiving from an uninitialized chan %s\n", 167 n->sym?n->sym->name:""); 168 whichq = 0; 169 return 0; 170 } 171 if (whichq < MAXQ && whichq >= 0 && ltab[whichq]) 172 { ltab[whichq]->setat = depth; 173 return a_rcv(ltab[whichq], n, full); 174 } 175 return 0; 176 } 177 178 static int 179 sa_snd(Queue *q, Lextok *n) /* sorted asynchronous */ 180 { Lextok *m; 181 int i, j, k; 182 int New, Old; 183 184 for (i = 0; i < q->qlen; i++) 185 for (j = 0, m = n->rgt; m && j < q->nflds; m = m->rgt, j++) 186 { New = cast_val(q->fld_width[j], eval(m->lft), 0); 187 Old = q->contents[i*q->nflds+j]; 188 if (New == Old) 189 continue; 190 if (New > Old) 191 break; /* inner loop */ 192 goto found; /* New < Old */ 193 } 194 found: 195 for (j = q->qlen-1; j >= i; j--) 196 for (k = 0; k < q->nflds; k++) 197 { q->contents[(j+1)*q->nflds+k] = 198 q->contents[j*q->nflds+k]; /* shift up */ 199 if (k == 0) 200 q->stepnr[j+1] = q->stepnr[j]; 201 } 202 return i*q->nflds; /* new q offset */ 203 } 204 205 void 206 typ_ck(int ft, int at, char *s) 207 { 208 if ((verbose&32) && ft != at 209 && (ft == CHAN || at == CHAN)) 210 { char buf[128], tag1[64], tag2[64]; 211 (void) sputtype(tag1, ft); 212 (void) sputtype(tag2, at); 213 sprintf(buf, "type-clash in %s, (%s<-> %s)", s, tag1, tag2); 214 non_fatal("%s", buf); 215 } 216 } 217 218 static int 219 a_snd(Queue *q, Lextok *n) 220 { Lextok *m; 221 int i = q->qlen*q->nflds; /* q offset */ 222 int j = 0; /* q field# */ 223 224 if (q->nslots > 0 && q->qlen >= q->nslots) 225 return m_loss; /* q is full */ 226 227 if (TstOnly) return 1; 228 229 if (n->val) i = sa_snd(q, n); /* sorted insert */ 230 231 q->stepnr[i/q->nflds] = depth; 232 233 for (m = n->rgt; m && j < q->nflds; m = m->rgt, j++) 234 { int New = eval(m->lft); 235 q->contents[i+j] = cast_val(q->fld_width[j], New, 0); 236 if ((verbose&16) && depth >= jumpsteps) 237 sr_talk(n, New, "Send ", "->", j, q); 238 typ_ck(q->fld_width[j], Sym_typ(m->lft), "send"); 239 } 240 if ((verbose&16) && depth >= jumpsteps) 241 { for (i = j; i < q->nflds; i++) 242 sr_talk(n, 0, "Send ", "->", i, q); 243 if (j < q->nflds) 244 printf("%3d: warning: missing params in send\n", 245 depth); 246 if (m) 247 printf("%3d: warning: too many params in send\n", 248 depth); 249 } 250 q->qlen++; 251 return 1; 252 } 253 254 static int 255 a_rcv(Queue *q, Lextok *n, int full) 256 { Lextok *m; 257 int i=0, oi, j, k; 258 extern int Rvous; 259 260 if (q->qlen == 0) 261 return 0; /* q is empty */ 262 try_slot: 263 /* test executability */ 264 for (m = n->rgt, j=0; m && j < q->nflds; m = m->rgt, j++) 265 if ((m->lft->ntyp == CONST 266 && q->contents[i*q->nflds+j] != m->lft->val) 267 || (m->lft->ntyp == EVAL 268 && q->contents[i*q->nflds+j] != eval(m->lft->lft))) 269 { if (n->val == 0 /* fifo recv */ 270 || n->val == 2 /* fifo poll */ 271 || ++i >= q->qlen) /* last slot */ 272 return 0; /* no match */ 273 goto try_slot; 274 } 275 if (TstOnly) return 1; 276 277 if (verbose&8) 278 { if (j < q->nflds) 279 printf("%3d: warning: missing params in next recv\n", 280 depth); 281 else if (m) 282 printf("%3d: warning: too many params in next recv\n", 283 depth); 284 } 285 286 /* set the fields */ 287 if (Rvous) 288 { n_rem = n; 289 q_rem = q; 290 } 291 292 oi = q->stepnr[i]; 293 for (m = n->rgt, j = 0; m && j < q->nflds; m = m->rgt, j++) 294 { if (columns && !full) /* was columns == 1 */ 295 continue; 296 if ((verbose&8) && !Rvous && depth >= jumpsteps) 297 { sr_talk(n, q->contents[i*q->nflds+j], 298 (full && n->val < 2)?"Recv ":"[Recv] ", "<-", j, q); 299 } 300 if (!full) 301 continue; /* test */ 302 if (m && m->lft->ntyp != CONST && m->lft->ntyp != EVAL) 303 { (void) setval(m->lft, q->contents[i*q->nflds+j]); 304 typ_ck(q->fld_width[j], Sym_typ(m->lft), "recv"); 305 } 306 if (n->val < 2) /* not a poll */ 307 for (k = i; k < q->qlen-1; k++) 308 { q->contents[k*q->nflds+j] = 309 q->contents[(k+1)*q->nflds+j]; 310 if (j == 0) 311 q->stepnr[k] = q->stepnr[k+1]; 312 } 313 } 314 315 if ((!columns || full) 316 && (verbose&8) && !Rvous && depth >= jumpsteps) 317 for (i = j; i < q->nflds; i++) 318 { sr_talk(n, 0, 319 (full && n->val < 2)?"Recv ":"[Recv] ", "<-", i, q); 320 } 321 if (columns == 2 && full && !Rvous && depth >= jumpsteps) 322 putarrow(oi, depth); 323 324 if (full && n->val < 2) 325 q->qlen--; 326 return 1; 327 } 328 329 static int 330 s_snd(Queue *q, Lextok *n) 331 { Lextok *m; 332 RunList *rX, *sX = X; /* rX=recvr, sX=sendr */ 333 int i, j = 0; /* q field# */ 334 335 for (m = n->rgt; m && j < q->nflds; m = m->rgt, j++) 336 { q->contents[j] = cast_val(q->fld_width[j], eval(m->lft), 0); 337 typ_ck(q->fld_width[j], Sym_typ(m->lft), "rv-send"); 338 } 339 q->qlen = 1; 340 if (!complete_rendez()) 341 { q->qlen = 0; 342 return 0; 343 } 344 if (TstOnly) 345 { q->qlen = 0; 346 return 1; 347 } 348 q->stepnr[0] = depth; 349 if ((verbose&16) && depth >= jumpsteps) 350 { m = n->rgt; 351 rX = X; X = sX; 352 for (j = 0; m && j < q->nflds; m = m->rgt, j++) 353 sr_talk(n, eval(m->lft), "Sent ", "->", j, q); 354 for (i = j; i < q->nflds; i++) 355 sr_talk(n, 0, "Sent ", "->", i, q); 356 if (j < q->nflds) 357 printf("%3d: warning: missing params in rv-send\n", 358 depth); 359 else if (m) 360 printf("%3d: warning: too many params in rv-send\n", 361 depth); 362 X = rX; /* restore receiver's context */ 363 if (!s_trail) 364 { if (!n_rem || !q_rem) 365 fatal("cannot happen, s_snd", (char *) 0); 366 m = n_rem->rgt; 367 for (j = 0; m && j < q->nflds; m = m->rgt, j++) 368 { if (m->lft->ntyp != NAME 369 || strcmp(m->lft->sym->name, "_") != 0) 370 i = eval(m->lft); 371 else i = 0; 372 373 if (verbose&8) 374 sr_talk(n_rem,i,"Recv ","<-",j,q_rem); 375 } 376 if (verbose&8) 377 for (i = j; i < q->nflds; i++) 378 sr_talk(n_rem, 0, "Recv ", "<-", j, q_rem); 379 if (columns == 2) 380 putarrow(depth, depth); 381 } 382 n_rem = (Lextok *) 0; 383 q_rem = (Queue *) 0; 384 } 385 return 1; 386 } 387 388 static void 389 channm(Lextok *n) 390 { char lbuf[512]; 391 392 if (n->sym->type == CHAN) 393 strcat(Buf, n->sym->name); 394 else if (n->sym->type == NAME) 395 strcat(Buf, lookup(n->sym->name)->name); 396 else if (n->sym->type == STRUCT) 397 { Symbol *r = n->sym; 398 if (r->context) 399 { r = findloc(r); 400 if (!r) 401 { strcat(Buf, "*?*"); 402 return; 403 } } 404 ini_struct(r); 405 printf("%s", r->name); 406 strcpy(lbuf, ""); 407 struct_name(n->lft, r, 1, lbuf); 408 strcat(Buf, lbuf); 409 } else 410 strcat(Buf, "-"); 411 if (n->lft->lft) 412 { sprintf(lbuf, "[%d]", eval(n->lft->lft)); 413 strcat(Buf, lbuf); 414 } 415 } 416 417 static void 418 difcolumns(Lextok *n, char *tr, int v, int j, Queue *q) 419 { extern int pno; 420 421 if (j == 0) 422 { Buf[0] = '\0'; 423 channm(n); 424 strcat(Buf, (strncmp(tr, "Sen", 3))?"?":"!"); 425 } else 426 strcat(Buf, ","); 427 if (tr[0] == '[') strcat(Buf, "["); 428 sr_buf(v, q->fld_width[j] == MTYPE); 429 if (j == q->nflds - 1) 430 { int cnr; 431 if (s_trail) cnr = pno; else cnr = X?X->pid - Have_claim:0; 432 if (tr[0] == '[') strcat(Buf, "]"); 433 pstext(cnr, Buf); 434 } 435 } 436 437 static void 438 docolumns(Lextok *n, char *tr, int v, int j, Queue *q) 439 { int i; 440 441 if (firstrow) 442 { printf("q\\p"); 443 for (i = 0; i < nproc-nstop - Have_claim; i++) 444 printf(" %3d", i); 445 printf("\n"); 446 firstrow = 0; 447 } 448 if (j == 0) 449 { printf("%3d", q->qid); 450 if (X) 451 for (i = 0; i < X->pid - Have_claim; i++) 452 printf(" ."); 453 printf(" "); 454 Buf[0] = '\0'; 455 channm(n); 456 printf("%s%c", Buf, (strncmp(tr, "Sen", 3))?'?':'!'); 457 } else 458 printf(","); 459 if (tr[0] == '[') printf("["); 460 sr_mesg(stdout, v, q->fld_width[j] == MTYPE); 461 if (j == q->nflds - 1) 462 { if (tr[0] == '[') printf("]"); 463 printf("\n"); 464 } 465 } 466 467 typedef struct QH { 468 int n; 469 struct QH *nxt; 470 } QH; 471 static QH *qh; 472 473 void 474 qhide(int q) 475 { QH *p = (QH *) emalloc(sizeof(QH)); 476 p->n = q; 477 p->nxt = qh; 478 qh = p; 479 } 480 481 int 482 qishidden(int q) 483 { QH *p; 484 for (p = qh; p; p = p->nxt) 485 if (p->n == q) 486 return 1; 487 return 0; 488 } 489 490 static void 491 sr_talk(Lextok *n, int v, char *tr, char *a, int j, Queue *q) 492 { char s[128]; 493 494 if (qishidden(eval(n->lft))) 495 return; 496 497 if (columns) 498 { if (columns == 2) 499 difcolumns(n, tr, v, j, q); 500 else 501 docolumns(n, tr, v, j, q); 502 return; 503 } 504 if (xspin) 505 { if ((verbose&4) && tr[0] != '[') 506 sprintf(s, "(state -)\t[values: %d", 507 eval(n->lft)); 508 else 509 sprintf(s, "(state -)\t[%d", eval(n->lft)); 510 if (strncmp(tr, "Sen", 3) == 0) 511 strcat(s, "!"); 512 else 513 strcat(s, "?"); 514 } else 515 { strcpy(s, tr); 516 } 517 518 if (j == 0) 519 { char snm[128]; 520 whoruns(1); 521 { char *ptr = n->fn->name; 522 char *qtr = snm; 523 while (*ptr != '\0') 524 { if (*ptr != '\"') 525 { *qtr++ = *ptr; 526 } 527 ptr++; 528 } 529 *qtr = '\0'; 530 printf("%s:%d %s", 531 snm, n->ln, s); 532 } 533 } else 534 printf(","); 535 sr_mesg(stdout, v, q->fld_width[j] == MTYPE); 536 537 if (j == q->nflds - 1) 538 { if (xspin) 539 { printf("]\n"); 540 if (!(verbose&4)) printf("\n"); 541 return; 542 } 543 printf("\t%s queue %d (", a, eval(n->lft)); 544 Buf[0] = '\0'; 545 channm(n); 546 printf("%s)\n", Buf); 547 } 548 fflush(stdout); 549 } 550 551 void 552 sr_buf(int v, int j) 553 { int cnt = 1; Lextok *n; 554 char lbuf[512]; 555 556 for (n = Mtype; n && j; n = n->rgt, cnt++) 557 if (cnt == v) 558 { if(strlen(n->lft->sym->name) >= sizeof(lbuf)) 559 { non_fatal("mtype name %s too long", n->lft->sym->name); 560 break; 561 } 562 sprintf(lbuf, "%s", n->lft->sym->name); 563 strcat(Buf, lbuf); 564 return; 565 } 566 sprintf(lbuf, "%d", v); 567 strcat(Buf, lbuf); 568 } 569 570 void 571 sr_mesg(FILE *fd, int v, int j) 572 { Buf[0] ='\0'; 573 sr_buf(v, j); 574 fprintf(fd, Buf); 575 } 576 577 void 578 doq(Symbol *s, int n, RunList *r) 579 { Queue *q; 580 int j, k; 581 582 if (!s->val) /* uninitialized queue */ 583 return; 584 for (q = qtab; q; q = q->nxt) 585 if (q->qid == s->val[n]) 586 { if (xspin > 0 587 && (verbose&4) 588 && q->setat < depth) 589 continue; 590 if (q->nslots == 0) 591 continue; /* rv q always empty */ 592 #if 0 593 if (q->qlen == 0) /* new 7/10 -- dont show if queue is empty */ 594 { continue; 595 } 596 #endif 597 printf("\t\tqueue %d (", q->qid); 598 if (r) 599 printf("%s(%d):", r->n->name, r->pid - Have_claim); 600 if (s->nel > 1 || s->isarray) 601 printf("%s[%d]): ", s->name, n); 602 else 603 printf("%s): ", s->name); 604 for (k = 0; k < q->qlen; k++) 605 { printf("["); 606 for (j = 0; j < q->nflds; j++) 607 { if (j > 0) printf(","); 608 sr_mesg(stdout, q->contents[k*q->nflds+j], 609 q->fld_width[j] == MTYPE); 610 } 611 printf("]"); 612 } 613 printf("\n"); 614 break; 615 } 616 } 617 618 void 619 nochan_manip(Lextok *p, Lextok *n, int d) 620 { int e = 1; 621 622 if (d == 0 && p->sym && p->sym->type == CHAN) 623 { setaccess(p->sym, ZS, 0, 'L'); 624 625 if (n && n->ntyp == CONST) 626 fatal("invalid asgn to chan", (char *) 0); 627 628 if (n && n->sym && n->sym->type == CHAN) 629 { setaccess(n->sym, ZS, 0, 'V'); 630 return; 631 } 632 } 633 634 /* ok on the rhs of an assignment: */ 635 if (!n || n->ntyp == LEN || n->ntyp == RUN 636 || n->ntyp == FULL || n->ntyp == NFULL 637 || n->ntyp == EMPTY || n->ntyp == NEMPTY) 638 return; 639 640 if (n->sym && n->sym->type == CHAN) 641 { if (d == 1) 642 fatal("invalid use of chan name", (char *) 0); 643 else 644 setaccess(n->sym, ZS, 0, 'V'); 645 } 646 647 if (n->ntyp == NAME 648 || n->ntyp == '.') 649 e = 0; /* array index or struct element */ 650 651 nochan_manip(p, n->lft, e); 652 nochan_manip(p, n->rgt, 1); 653 } 654 655 typedef struct BaseName { 656 char *str; 657 int cnt; 658 struct BaseName *nxt; 659 } BaseName; 660 BaseName *bsn; 661 662 void 663 newbasename(char *s) 664 { BaseName *b; 665 666 /* printf("+++++++++%s\n", s); */ 667 for (b = bsn; b; b = b->nxt) 668 if (strcmp(b->str, s) == 0) 669 { b->cnt++; 670 return; 671 } 672 b = (BaseName *) emalloc(sizeof(BaseName)); 673 b->str = emalloc(strlen(s)+1); 674 b->cnt = 1; 675 strcpy(b->str, s); 676 b->nxt = bsn; 677 bsn = b; 678 } 679 680 void 681 delbasename(char *s) 682 { BaseName *b, *prv = (BaseName *) 0; 683 684 for (b = bsn; b; prv = b, b = b->nxt) 685 { if (strcmp(b->str, s) == 0) 686 { b->cnt--; 687 if (b->cnt == 0) 688 { if (prv) 689 { prv->nxt = b->nxt; 690 } else 691 { bsn = b->nxt; 692 } } 693 /* printf("---------%s\n", s); */ 694 break; 695 } } 696 } 697 698 void 699 checkindex(char *s, char *t) 700 { BaseName *b; 701 702 /* printf("xxx Check %s (%s)\n", s, t); */ 703 for (b = bsn; b; b = b->nxt) 704 { 705 /* printf(" %s\n", b->str); */ 706 if (strcmp(b->str, s) == 0) 707 { non_fatal("do not index an array with itself (%s)", t); 708 break; 709 } } 710 } 711 712 void 713 scan_tree(Lextok *t, char *mn, char *mx) 714 { char sv[512]; 715 char tmp[32]; 716 int oln = lineno; 717 718 if (!t) return; 719 720 lineno = t->ln; 721 722 if (t->ntyp == NAME) 723 { strcat(mn, t->sym->name); 724 strcat(mx, t->sym->name); 725 if (t->lft) /* array index */ 726 { strcat(mn, "[]"); 727 newbasename(mn); 728 strcpy(sv, mn); /* save */ 729 strcpy(mn, ""); /* clear */ 730 strcat(mx, "["); 731 scan_tree(t->lft, mn, mx); /* index */ 732 strcat(mx, "]"); 733 checkindex(mn, mx); /* match against basenames */ 734 strcpy(mn, sv); /* restore */ 735 delbasename(mn); 736 } 737 if (t->rgt) /* structure element */ 738 { scan_tree(t->rgt, mn, mx); 739 } 740 } else if (t->ntyp == CONST) 741 { strcat(mn, "1"); /* really: t->val */ 742 sprintf(tmp, "%d", t->val); 743 strcat(mx, tmp); 744 } else if (t->ntyp == '.') 745 { strcat(mn, "."); 746 strcat(mx, "."); 747 scan_tree(t->lft, mn, mx); 748 } else 749 { strcat(mn, "??"); 750 strcat(mx, "??"); 751 } 752 lineno = oln; 753 } 754 755 void 756 no_nested_array_refs(Lextok *n) /* a [ a[1] ] with a[1] = 1, causes trouble in pan.b */ 757 { char mn[512]; 758 char mx[512]; 759 760 /* printf("==================================ZAP\n"); */ 761 bsn = (BaseName *) 0; /* start new list */ 762 strcpy(mn, ""); 763 strcpy(mx, ""); 764 765 scan_tree(n, mn, mx); 766 /* printf("==> %s\n", mn); */ 767 } 768 769 void 770 no_internals(Lextok *n) 771 { char *sp; 772 773 if (!n->sym 774 || !n->sym->name) 775 return; 776 777 sp = n->sym->name; 778 779 if ((strlen(sp) == strlen("_nr_pr") && strcmp(sp, "_nr_pr") == 0) 780 || (strlen(sp) == strlen("_p") && strcmp(sp, "_p") == 0)) 781 { fatal("attempt to assign value to system variable %s", sp); 782 } 783 784 no_nested_array_refs(n); 785 } 786