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