|
|
1.1 ! root 1: static char Sccsid[] = "a0.c @(#)a0.c 1.5 6/16/87 Berkeley "; ! 2: #include <signal.h> ! 3: #include "apl.h" ! 4: #include <math.h> ! 5: int chartab[]; ! 6: int mkcore = 0; /* produce core image upon fatal error */ ! 7: int edmagic = 0; /* turn on "ed" magic characters */ ! 8: ! 9: main(argc, argp) ! 10: char **argp; ! 11: { ! 12: register char *p; ! 13: register a, b; ! 14: int c; ! 15: int fflag; ! 16: int intr(), intprws(); ! 17: struct tm *localtime(); ! 18: extern headline[]; ! 19: #ifdef NBUF ! 20: struct iobuf iobf[NBUF]; /* Actual buffers */ ! 21: #endif ! 22: ! 23: time(&stime); ! 24: /* ! 25: * kludge to force use of file descriptor in time part ! 26: * of C library; otherwise sbrks are going to die. ! 27: */ ! 28: (void)localtime(&stime); ! 29: #ifdef NBUF ! 30: iobuf = iobf; /* Set up buffer pointer */ ! 31: initbuf(); /* Set up to run */ ! 32: #endif ! 33: /* ! 34: * setup scratch files ! 35: */ ! 36: a = getpid(); ! 37: scr_file = "/tmp/apled.000000"; ! 38: ws_file = "/tmp/aplws.000000"; ! 39: for(c=16; c > 10; c--){ ! 40: b = '0' + a%10; ! 41: scr_file[c] = b; ! 42: ws_file[c] = b; ! 43: a /= 10; ! 44: } ! 45: offexit = isatty(0); ! 46: echoflg = !offexit; ! 47: a = 1; /* catch signals */ ! 48: ! 49: /* Check to see if argp[0] is "prws". If so, set prwsflg */ ! 50: ! 51: for(p=argp[0]; *p; p++); ! 52: while(p > argp[0] && *p != '/') p--; ! 53: if (*p == '/') p++; ! 54: for(c=0; c < 4; c++) ! 55: if (!p[c] || p[c] != "prws"[c]) ! 56: goto notprws; ! 57: prwsflg = 1; ! 58: CLOSEF(0); ! 59: notprws: ! 60: ! 61: /* other flags... */ ! 62: ! 63: while(argc > 1 && argp[1][0] == '-'){ ! 64: argc--; ! 65: argp++; ! 66: while(*++*argp) switch(**argp){ ! 67: case 'e': echoflg = 1; break; ! 68: case 'q': echoflg = 0; break; ! 69: case 'd': ! 70: case 'D': a = 0; ! 71: case 'c': ! 72: case 'C': mkcore = 1; break; ! 73: case 't': scr_file += 5; ! 74: ws_file += 5; ! 75: case 'm': apl_term = 1; break; ! 76: case 'r': edmagic = 1; break; ! 77: case 'o': offexit = 0; break; ! 78: } ! 79: } ! 80: ! 81: if (prwsflg) ! 82: echoflg = mkcore = a = 0; /* "prws" settings */ ! 83: ! 84: thread.iorg = 1; ! 85: srand(thread.rl = 1); ! 86: thread.width = 72; ! 87: thread.digits = 9; ! 88: thread.fuzz = 1.0e-13; ! 89: ! 90: aplmod(1); /* Turn on APL mode */ ! 91: if (a) ! 92: catchsigs(); ! 93: if (prwsflg) ! 94: signal(SIGINT, intprws); ! 95: else ! 96: fppinit(); ! 97: ! 98: /* ! 99: * open ws file ! 100: */ ! 101: ! 102: CLOSEF(opn(WSFILE,0600)); ! 103: wfile = opn(WSFILE,2); ! 104: zero = 0; ! 105: one = 1; ! 106: maxexp = 88; ! 107: pi = 3.141592653589793238462643383; ! 108: ! 109: sp = stack; ! 110: fflag = 1; ! 111: if (!prwsflg){ ! 112: if((unsigned)signal(SIGINT, intr) & 01) ! 113: signal(SIGINT, 1); ! 114: printf(headline); ! 115: } ! 116: setexit(); ! 117: if(fflag) { ! 118: fflag = 0; ! 119: if(argc > 1 && (a = opn(argp[1], 0)) > 0){ ! 120: wsload(a); ! 121: printf(" %s\n", argp[1]); ! 122: CLOSEF(a); ! 123: } else { ! 124: if((a=OPENF("continue",0)) < 0) { ! 125: printf("clear ws\n"); ! 126: } else { ! 127: wsload(a); ! 128: printf(" continue\n"); ! 129: CLOSEF(a); ! 130: } ! 131: } ! 132: if (prwsflg){ ! 133: ex_prws(); ! 134: term(0); ! 135: } ! 136: evLlx(); /* eval latent expr, if any */ ! 137: } ! 138: mainloop(); ! 139: } ! 140: ! 141: mainloop() ! 142: { ! 143: register char *a, *comp; ! 144: static eotcount = MAXEOT; /* maximum eot's on input */ ! 145: ! 146: setexit(); ! 147: while(1){ ! 148: if(echoflg) ! 149: echoflg = 1; /* enabled echo echo suppress off */ ! 150: checksp(); ! 151: if(intflg) ! 152: error("I"); ! 153: putchar('\t'); ! 154: a = rline(8); ! 155: if(a == 0) { ! 156: offexit &= isatty(0); ! 157: if (offexit) { ! 158: if (eotcount-- > 0) ! 159: printf("\ruse \')off\' to exit\n"); ! 160: else ! 161: panic(0); ! 162: continue; ! 163: } else ! 164: term(0); /* close down and exit */ ! 165: } ! 166: comp = compile(a, 0); ! 167: free(a); ! 168: if(comp == 0) ! 169: continue; ! 170: execute(comp); ! 171: free(comp); ! 172: /* note that if the execute errors out, then ! 173: * the allocated space pointed to by comp is never ! 174: * freed. This is hard to fix. ! 175: */ ! 176: } ! 177: } ! 178: ! 179: intr() ! 180: { ! 181: ! 182: intflg = 1; ! 183: signal(SIGINT, intr); ! 184: SEEKF(0, 0L, 2); ! 185: } ! 186: ! 187: intprws() ! 188: { ! 189: /* "prws" interrupt -- restore old tty modes and exit */ ! 190: ! 191: term(0177); ! 192: } ! 193: ! 194: char * ! 195: rline(s) ! 196: { ! 197: int rlcmp(); ! 198: char line[CANBS]; ! 199: register char *p; ! 200: register c, col; ! 201: char *cp, *retval; ! 202: char *dp; ! 203: int i,j; ! 204: ! 205: column = 0; ! 206: col = s; ! 207: p = line; ! 208: loop: ! 209: c = getchar(); ! 210: if(intflg) ! 211: error("I"); ! 212: switch(c) { ! 213: ! 214: case '\0': ! 215: case -1: ! 216: return(0); ! 217: ! 218: case '\b': ! 219: if(col) ! 220: col--; ! 221: goto loop; ! 222: ! 223: case '\t': ! 224: col = (col+8) & ~7; ! 225: goto loop; ! 226: ! 227: case ' ': ! 228: col++; ! 229: goto loop; ! 230: ! 231: case '\r': ! 232: col = 0; ! 233: goto loop; ! 234: ! 235: default: ! 236: if (p >= line+CANBS-2 || col > 127) ! 237: error("line too long"); ! 238: *p++ = col; ! 239: *p++ = c; /* was and'ed with 0177... */ ! 240: col++; ! 241: goto loop; ! 242: ! 243: case '\n': ! 244: ; ! 245: } ! 246: qsort(line, (p-line)/2, 2, rlcmp); ! 247: c = p[-2]; ! 248: if(p == line) ! 249: c = 1; /* check for blank line */ ! 250: *p = -1; ! 251: col = -1; ! 252: cp = (retval=alloc(c+3)) - 1; ! 253: for(p=line; p[0] != -1; p+=2) { ! 254: while(++col != p[0]) ! 255: *++cp = ' '; ! 256: *++cp = p[1]; ! 257: while(p[2] == col) { ! 258: if(p[3] != *cp) { ! 259: i = *cp ; ! 260: *cp = p[3]; ! 261: break; ! 262: } ! 263: p += 2; ! 264: } ! 265: if(p[2] != col) continue; ! 266: while(p[2] == col) { ! 267: if(p[3] != *cp) ! 268: goto yuck; ! 269: p += 2; ! 270: } ! 271: #ifdef vax ! 272: i = ((i<<8) | *cp)&0177777; ! 273: #else ! 274: i |= *cp << 8; ! 275: #endif ! 276: for(j=0; chartab[j]; j++){ ! 277: if(i == chartab[j]) { ! 278: *cp = j | 0200; ! 279: j = 0; ! 280: break; ! 281: } ! 282: } ! 283: if(j) { ! 284: yuck: ! 285: *cp = '\n'; ! 286: pline(cp,++col); ! 287: error("Y error"); ! 288: } ! 289: } ! 290: *++cp = '\n'; ! 291: return(retval); ! 292: } ! 293: ! 294: rlcmp(a, b) ! 295: char *a, *b; ! 296: { ! 297: register c; ! 298: ! 299: if(c = a[0] - b[0]) ! 300: return(c); ! 301: return(a[1] - b[1]); ! 302: } ! 303: ! 304: pline(str, loc) ! 305: char *str; ! 306: { ! 307: register c, l, col; ! 308: ! 309: col = 0; ! 310: l = 0; ! 311: do { ! 312: c = *str++; ! 313: l++; ! 314: if(l == loc) ! 315: col = column; ! 316: putchar(c); ! 317: } while(c != '\n'); ! 318: if(col) { ! 319: putto(col); ! 320: putchar('^'); ! 321: putchar('\n'); ! 322: } ! 323: } ! 324: ! 325: putto(col) ! 326: { ! 327: while(col > column+8) ! 328: putchar('\t'); ! 329: while(col > column) ! 330: putchar(' '); ! 331: } ! 332: ! 333: term(s) ! 334: { ! 335: ! 336: register j; ! 337: ! 338: unlink(WSFILE); ! 339: unlink(scr_file); ! 340: putchar('\n'); ! 341: aplmod(0); /* turn off APL mode */ ! 342: for(j=0; j<NFDS; j++) /* Close files */ ! 343: CLOSEF(j); ! 344: exit(s); ! 345: } ! 346: ! 347: fix(d) ! 348: data d; ! 349: { ! 350: register i; ! 351: ! 352: i = floor(d+0.5); ! 353: return(i); ! 354: } ! 355: ! 356: fuzz(d1, d2) ! 357: data d1, d2; ! 358: { ! 359: double f1, f2; ! 360: ! 361: f1 = d1; ! 362: if(f1 < 0.) ! 363: f1 = -f1; ! 364: f2 = d2; ! 365: if(f2 < 0.) ! 366: f2 = -f2; ! 367: if(f2 > f1) ! 368: f1 = f2; ! 369: f1 *= thread.fuzz; ! 370: if(d1 > d2) { ! 371: if(d2+f1 >= d1) ! 372: return(0); ! 373: return(1); ! 374: } ! 375: if(d1+f1 >= d2) ! 376: return(0); ! 377: return(-1); ! 378: } ! 379: ! 380: pop() ! 381: { ! 382: ! 383: if(sp <= stack) ! 384: error("pop B"); ! 385: dealloc(*--sp); ! 386: } ! 387: ! 388: erase(np) ! 389: struct nlist *np; ! 390: { ! 391: register *p; ! 392: ! 393: p = np->itemp; ! 394: if(p) { ! 395: switch(np->use) { ! 396: case NF: ! 397: case MF: ! 398: case DF: ! 399: for(; *p>0; (*p)--) ! 400: free(p[*p]); ! 401: ! 402: } ! 403: free(p); ! 404: np->itemp = 0; ! 405: } ! 406: np->use = 0; ! 407: } ! 408: ! 409: dealloc(p) ! 410: struct item *p; ! 411: { ! 412: ! 413: switch(p->type) { ! 414: default: ! 415: printf("[dealloc botch: %d]\n", p->type); ! 416: return; ! 417: case LBL: ! 418: ((struct nlist *)p)->use = 0; /* delete label */ ! 419: case LV: ! 420: return; ! 421: ! 422: case DA: ! 423: case CH: ! 424: case QQ: ! 425: case QD: ! 426: case QC: ! 427: case EL: ! 428: case DU: ! 429: case QX: ! 430: free(p); ! 431: } ! 432: } ! 433: ! 434: struct item * ! 435: newdat(type, rank, size) ! 436: { ! 437: register i; ! 438: register struct item *p; ! 439: ! 440: /* Allocate a new data item. I have searched the specifications ! 441: * for C and as far as I can tell, it should be legal to ! 442: * declare a zero-length array inside a structure. However, ! 443: * the VAX C compiler (which I think is a derivative of the ! 444: * portable C compiler) does not allow this. The Ritchie ! 445: * V7 PDP-11 compiler does. I have redeclared "dim" to ! 446: * contain MRANK elements. When the data is allocated, ! 447: * space is only allocated for as many dimensions as there ! 448: * actually are. Thus, if there are 0 dimensions, no space ! 449: * will be allocated for "dim". This had better make the ! 450: * VAX happy, since it has sure made me unhappy. ! 451: * ! 452: * --John Bruner ! 453: */ ! 454: ! 455: ! 456: if(rank > MRANK) ! 457: error("max R"); ! 458: i = sizeof *p - SINT * (MRANK-rank); ! 459: if(type == DA) ! 460: i += size * SDAT; else ! 461: if(type == CH) ! 462: i += size; ! 463: p = alloc(i); ! 464: p->rank = rank; ! 465: p->type = type; ! 466: p->size = size; ! 467: p->index = 0; ! 468: if(rank == 1) ! 469: p->dim[0] = size; ! 470: p->datap = (data *)&p->dim[rank]; ! 471: return(p); ! 472: } ! 473: ! 474: struct item * ! 475: dupdat(ap) ! 476: struct item *ap; ! 477: { ! 478: register struct item *p1, *p2; ! 479: register i; ! 480: ! 481: p1 = ap; ! 482: p2 = newdat(p1->type, p1->rank, p1->size); ! 483: for(i=0; i<p1->rank; i++) ! 484: p2->dim[i] = p1->dim[i]; ! 485: copy(p1->type, p1->datap, p2->datap, p1->size); ! 486: return(p2); ! 487: } ! 488: ! 489: copy(type, from, to, size) ! 490: char *from, *to; ! 491: { ! 492: register i; ! 493: register char *a, *b; ! 494: int s; ! 495: ! 496: if((i = size) == 0) ! 497: return(0); ! 498: a = from; ! 499: b = to; ! 500: if(type == DA) ! 501: i *= SDAT; else ! 502: if(type == IN) ! 503: i *= SINT; ! 504: s = i; ! 505: do ! 506: *b++ = *a++; ! 507: while(--i); ! 508: return(s); ! 509: } ! 510: ! 511: struct item * ! 512: fetch1() ! 513: { ! 514: register struct item *p; ! 515: ! 516: p = fetch(sp[-1]); ! 517: sp[-1] = p; ! 518: return(p); ! 519: } ! 520: ! 521: struct item * ! 522: fetch2() ! 523: { ! 524: register struct item *p; ! 525: ! 526: sp[-2] = fetch(sp[-2]); ! 527: p = fetch(sp[-1]); ! 528: sp[-1] = p; ! 529: return(p); ! 530: } ! 531: ! 532: struct item * ! 533: fetch(ip) ! 534: struct item *ip; ! 535: { ! 536: register struct item *p, *q; ! 537: register i; ! 538: struct nlist *n; ! 539: int c; ! 540: struct chrstrct *cc; ! 541: extern prolgerr; ! 542: ! 543: p = ip; ! 544: ! 545: loop: ! 546: switch(p->type) { ! 547: ! 548: case QX: ! 549: free(p); ! 550: n = nlook("Llx"); ! 551: if(n){ ! 552: q = n->itemp; ! 553: p = dupdat(q); ! 554: copy(q->type, q->datap, p->datap, q->size); ! 555: } else ! 556: p = newdat(CH, 1, 0); ! 557: goto loop; ! 558: ! 559: case QQ: ! 560: free(p); ! 561: cc = rline(0); ! 562: if(cc == 0) ! 563: error("eof"); ! 564: for(i=0; cc->c[i] != '\n'; i++) ! 565: ; ! 566: p = newdat(CH, 1, i); ! 567: copy(CH, cc, p->datap, i); ! 568: goto loop; ! 569: ! 570: case QD: ! 571: case QC: ! 572: printf("L:\n\t"); ! 573: i = rline(8); ! 574: if(i == 0) ! 575: error("eof"); ! 576: c = compile(i, 1); ! 577: free(i); ! 578: if(c == 0) ! 579: goto loop; ! 580: i = pcp; ! 581: execute(c); ! 582: pcp = i; ! 583: free(c); ! 584: free(p); ! 585: p = *--sp; ! 586: goto loop; ! 587: ! 588: case DU: ! 589: if(lastop != PRINT) ! 590: error("no fn result"); ! 591: ! 592: case DA: ! 593: case CH: ! 594: p->index = 0; ! 595: return(p); ! 596: ! 597: case LV: ! 598: ! 599: /* KLUDGE -- ! 600: * ! 601: * Currently, if something prevents APL from completing ! 602: * execution of line 0 of a function, it leaves with ! 603: * the stack in an unknown state and "gsip->oldsp" is ! 604: * zero. This is nasty because there is no way to ! 605: * reset out of it. The principle cause of error ! 606: * exits from line 0 is the fetch of an undefined ! 607: * function argument. The following code attempts ! 608: * to fix this by setting an error flag and creating ! 609: * a dummy variable for the stack if "used before set" ! 610: * occurs in the function header. "ex_fun" then will ! 611: * note that the flag is high and cause an error exit ! 612: * AFTER all header processing has been completed. ! 613: */ ! 614: ! 615: if(((struct nlist *)p)->use != DA){ ! 616: printf("%s: used before set", ! 617: ((struct nlist *)ip)->namep); ! 618: if ((!gsip) || gsip->funlc != 1) ! 619: error(""); ! 620: q = newdat(DA, 0, 1); /* Dummy */ ! 621: q->datap[0] = 0; ! 622: prolgerr = 1; /* ERROR flag */ ! 623: return(q); ! 624: } ! 625: p = ((struct nlist *)p)->itemp; ! 626: i = p->type; ! 627: if(i == LBL) ! 628: i = DA; /* treat label as data */ ! 629: q = newdat(i, p->rank, p->size); ! 630: copy(IN, p->dim, q->dim, p->rank); ! 631: copy(i, p->datap, q->datap, p->size); ! 632: return(q); ! 633: ! 634: default: ! 635: error("fetch B"); ! 636: } ! 637: } ! 638: ! 639: topfix() ! 640: { ! 641: register struct item *p; ! 642: register i; ! 643: ! 644: p = fetch1(); ! 645: if(p->type != DA || p->size != 1) ! 646: error("topval C"); ! 647: i = fix(p->datap[0]); ! 648: pop(); ! 649: return(i); ! 650: } ! 651: ! 652: bidx(ip) ! 653: struct item *ip; ! 654: { ! 655: register struct item *p; ! 656: ! 657: p = ip; ! 658: idx.type = p->type; ! 659: idx.rank = p->rank; ! 660: copy(IN, p->dim, idx.dim, idx.rank); ! 661: size(); ! 662: } ! 663: ! 664: size() ! 665: { ! 666: register i, s; ! 667: ! 668: s = 1; ! 669: for(i=idx.rank-1; i>=0; i--) { ! 670: idx.del[i] = s; ! 671: s *= idx.dim[i]; ! 672: } ! 673: idx.size = s; ! 674: return(s); ! 675: } ! 676: ! 677: colapse(k) ! 678: { ! 679: register i; ! 680: ! 681: if(k < 0 || k >= idx.rank) ! 682: error("collapse X"); ! 683: idx.dimk = idx.dim[k]; ! 684: idx.delk = idx.del[k]; ! 685: for(i=k; i<idx.rank; i++) { ! 686: idx.del[i] = idx.del[i+1]; ! 687: idx.dim[i] = idx.dim[i+1]; ! 688: } ! 689: if (idx.dimk) ! 690: idx.size /= idx.dimk; ! 691: idx.rank--; ! 692: } ! 693: ! 694: forloop(co, arg) ! 695: int (*co)(); ! 696: { ! 697: register i; ! 698: ! 699: if (idx.size == 0) ! 700: return; /* for null items */ ! 701: if(idx.rank == 0) { ! 702: (*co)(arg); ! 703: return; ! 704: } ! 705: for(i=0;;) { ! 706: while(i < idx.rank) ! 707: idx.idx[i++] = 0; ! 708: (*co)(arg); ! 709: while(++idx.idx[i-1] >= idx.dim[i-1]) ! 710: if(--i <= 0) ! 711: return; ! 712: } ! 713: } ! 714: ! 715: access() ! 716: { ! 717: register i, n; ! 718: ! 719: n = 0; ! 720: for(i=0; i<idx.rank; i++) ! 721: n += idx.idx[i] * idx.del[i]; ! 722: return(n); ! 723: } ! 724: ! 725: data ! 726: getdat(ip) ! 727: struct item *ip; ! 728: { ! 729: register struct item *p; ! 730: register i; ! 731: data d; ! 732: ! 733: /* Get the data value stored at index p->index. If the ! 734: * index is out of range it will be wrapped around. If ! 735: * the data item is null, a zero or blank will be returned. ! 736: */ ! 737: ! 738: p = ip; ! 739: i = p->index; ! 740: while(i >= p->size) { ! 741: if (p->size == 0) /* let the caller beware */ ! 742: return((p->type == DA) ? zero : (data)' '); ! 743: /* ! 744: if (i == 0) ! 745: error("getdat B"); ! 746: */ ! 747: i -= p->size; ! 748: } ! 749: if(p->type == DA) { ! 750: d = p->datap[i]; ! 751: } else ! 752: if(p->type == CH) { ! 753: d = ((struct chrstrct *)p->datap)->c[i]; ! 754: } else ! 755: error("getdat B"); ! 756: i++; ! 757: p->index = i; ! 758: return(d); ! 759: } ! 760: ! 761: putdat(ip, d) ! 762: data d; ! 763: struct item *ip; ! 764: { ! 765: register struct item *p; ! 766: register i; ! 767: ! 768: p = ip; ! 769: i = p->index; ! 770: if(i >= p->size) ! 771: error("putdat B"); ! 772: if(p->type == DA) { ! 773: p->datap[i] = d; ! 774: } else ! 775: if(p->type == CH) { ! 776: ((struct chrstrct *)p->datap)->c[i] = d; ! 777: } else ! 778: error("putdat B"); ! 779: i++; ! 780: p->index = i; ! 781: } ! 782: ! 783: /* aplmod has been moved to am.c */ ! 784: ! 785: struct item * ! 786: s2vect(ap) ! 787: struct item *ap; ! 788: { ! 789: register struct item *p, *q; ! 790: ! 791: p = ap; ! 792: q = newdat(p->type, 1, 1); ! 793: q->datap = p->datap; ! 794: q->dim[0] = 1; ! 795: return(q); ! 796: } ! 797: ! 798: struct nlist * ! 799: nlook(name) ! 800: char *name; ! 801: { ! 802: register struct nlist *np; ! 803: ! 804: for(np = nlist; np->namep; np++) ! 805: if(equal(np->namep, name)) ! 806: return(np); ! 807: return(0); ! 808: } ! 809: ! 810: checksp() ! 811: { ! 812: if(sp >= &stack[STKS]) ! 813: error("stack overflow"); ! 814: } ! 815: char * ! 816: concat(s1,s2) ! 817: char *s1, *s2; ! 818: { ! 819: register i,j; ! 820: char *p,*q; ! 821: ! 822: i = lsize(s1) - 1; ! 823: j = lsize(s2) - 1; ! 824: p = q = alloc(i+j); ! 825: p += copy(CH, s1, p, i); ! 826: copy(CH, s2, p, j); ! 827: return(q); ! 828: } ! 829: ! 830: char * ! 831: catcode(s1,s2) ! 832: char *s1, *s2; ! 833: { ! 834: register i,j; ! 835: char *p,*q; ! 836: ! 837: i = csize(s1) - 1; ! 838: j = csize(s2); ! 839: p = q = alloc(i+j); ! 840: p += copy(CH, s1, p, i); ! 841: copy(CH, s2, p, j); ! 842: return(q); ! 843: } ! 844: ! 845: /* ! 846: * csize -- return size (in bytes) of a compiled string ! 847: */ ! 848: csize(s) ! 849: char *s; ! 850: { ! 851: register c,len; ! 852: register char *p; ! 853: int i; ! 854: ! 855: len = 1; ! 856: p = s; ! 857: while((c = *p++) != EOF){ ! 858: len++; ! 859: c &= 0377; ! 860: switch(c){ ! 861: default: ! 862: i = 0; ! 863: break; ! 864: ! 865: case QUOT: ! 866: i = *p++; ! 867: break; ! 868: ! 869: case CONST: ! 870: i = *p++; ! 871: i *= SDAT; ! 872: len++; ! 873: break; ! 874: ! 875: case NAME: ! 876: case FUN: ! 877: case ARG1: ! 878: case ARG2: ! 879: case AUTO: ! 880: case REST: ! 881: case RVAL: ! 882: i = 2; ! 883: break; ! 884: } ! 885: p += i; ! 886: len += i; ! 887: } ! 888: return(len); ! 889: } ! 890: ! 891: opn(file, rw) ! 892: char file[]; ! 893: { ! 894: register fd, (*p)(); ! 895: char f2[100]; ! 896: extern OPENF(), CREATF(); ! 897: ! 898: p = (rw > 2 ? CREATF : OPENF); ! 899: if((fd = (*p)(file,rw)) < 0){ ! 900: for(fd=0; fd<13; fd++) ! 901: f2[fd] = LIBDIR[fd]; ! 902: for(fd=0; file[fd]; fd++) ! 903: f2[fd+13] = file[fd]; ! 904: f2[fd+13] = 0; ! 905: if((fd = (*p)(f2, rw)) >= 0){ ! 906: printf("[using %s]\n", f2); ! 907: return(fd); ! 908: } ! 909: printf("can't open file %s\n", file); ! 910: error(""); ! 911: } ! 912: return(fd); ! 913: } ! 914: ! 915: catchsigs() ! 916: { ! 917: extern panic(); ! 918: ! 919: signal(SIGHUP, panic); ! 920: signal(SIGQUIT, panic); ! 921: signal(SIGILL, panic); ! 922: signal(SIGTRAP, panic); ! 923: signal(SIGEMT, panic); ! 924: /* signal(SIGFPE, fpe); /* (fppinit called by "main") */ ! 925: signal(SIGBUS, panic); ! 926: signal(SIGSEGV, panic); ! 927: signal(SIGSYS, panic); ! 928: signal(SIGPIPE, panic); ! 929: signal(SIGTERM, panic); ! 930: } ! 931: ! 932: panic(signum) ! 933: unsigned signum; ! 934: { ! 935: ! 936: register fd; ! 937: static insane = 0; /* if != 0, die */ ! 938: static char *abt_file = "aplws.abort"; ! 939: static char *errtbl[] = { ! 940: "excessive eofs", ! 941: "hangup", ! 942: "interrupt", ! 943: "quit", ! 944: "illegal instruction", ! 945: "trace trap", ! 946: "i/o trap instruction", ! 947: "emt trap", ! 948: "floating exception", ! 949: "kill", ! 950: "bus error", ! 951: "segmentation violation", ! 952: "bad system call", ! 953: "write no pipe", ! 954: "alarm clock", ! 955: "software termination" ! 956: }; ! 957: ! 958: /* Attempt to save workspace. A signal out of here always ! 959: * causes immediate death. ! 960: */ ! 961: ! 962: mencflg = 0; ! 963: signal(signum, panic); ! 964: printf("\nfatal signal: %s\n", ! 965: errtbl[(signum < NSIG) ? signum : 0]); ! 966: ! 967: if (mkcore) abort(); ! 968: ! 969: if (!insane++){ ! 970: if ((fd=CREATF(abt_file, 0644)) >= 0){ ! 971: printf("[attempting ws dump]\n"); ! 972: wssave(fd); ! 973: printf(" workspace saved in %s\n", abt_file); ! 974: CLOSEF(fd); ! 975: } else ! 976: printf("workspace lost -- sorry\n"); ! 977: } else ! 978: printf("recursive errors: unrecoverable\n"); ! 979: ! 980: term(0); ! 981: } ! 982: #ifdef vax ! 983: abort(){ ! 984: kill(getpid(), SIGIOT); ! 985: exit(1); ! 986: } ! 987: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.