|
|
1.1 ! root 1: static char Sccsid[] = "al.c @(#)al.c 1.1 10/1/82 Berkeley "; ! 2: # ! 3: /* ! 4: * monadic epsilon and encode /rww ! 5: */ ! 6: #include "apl.h" ! 7: #include <signal.h> ! 8: ! 9: ex_meps() ! 10: { ! 11: struct item *p; ! 12: register i,j; ! 13: char *a,*b,*c; ! 14: int dim0,dim1; ! 15: char *xpcp; ! 16: ! 17: p = fetch1(); ! 18: if ( p->rank > 2 || p->type != CH ) ! 19: error("execute C"); ! 20: /*get out if nothing to do, apr 2-23-77 */ ! 21: if (p->size == 0){ ! 22: return; ! 23: } ! 24: b = (char *)p->datap; ! 25: dim0 = p->rank < 2 ? 1 : p->dim[0]; ! 26: dim1 = p->rank < 2 ? p->size : p->dim[1]; ! 27: a = alloc ( dim1+1 ); ! 28: xpcp = pcp; ! 29: for ( i=0; i<dim0 ; i++) { ! 30: copy(CH, b, a, dim1); ! 31: a[dim1] = '\n'; ! 32: c = compile(a,1); ! 33: if(c != 0){ ! 34: execute(c); ! 35: free(c); ! 36: } else { ! 37: free(a); ! 38: error(""); ! 39: } ! 40: b += dim1; ! 41: if(i < dim0-1) ! 42: pop(); ! 43: } ! 44: free(a); ! 45: pcp = xpcp; ! 46: p = *--sp; ! 47: pop(); ! 48: *sp++ = p; ! 49: } ! 50: ! 51: ex_menc() ! 52: { ! 53: struct item *p; ! 54: ! 55: p = fetch1(); ! 56: if ( p->type == DA ) ! 57: menc1(); /* ! 58: else ! 59: return (char argument unchanged); */ ! 60: } ! 61: ! 62: ! 63: ex_list() /* List a function on the terminal */ ! 64: { ! 65: register char lastc; ! 66: register struct nlist *n; ! 67: register line; ! 68: char c; ! 69: ! 70: ! 71: /* Check for valid function */ ! 72: ! 73: n = (struct nlist *)*--sp; ! 74: if (n->type != LV) ! 75: error("fnlist B"); ! 76: ! 77: ! 78: /* If a function, locate it in workspace file and ! 79: * print on the terminal in formatted form. ! 80: */ ! 81: ! 82: switch(((struct nlist *)n)->use){ ! 83: default: ! 84: error("fnlist T"); ! 85: ! 86: case NF: ! 87: case MF: ! 88: case DF: ! 89: SEEKF(wfile, (long)n->label, 0); ! 90: line = 0; ! 91: lastc = 0; ! 92: putchar('\n'); ! 93: ! 94: while(READF(wfile, &c, 1) > 0){ ! 95: ! 96: if (!c){ ! 97: putchar('\n'); ! 98: return; ! 99: } ! 100: ! 101: switch(lastc){ ! 102: case '\n': ! 103: printf("[%d]", ++line); ! 104: case 0: ! 105: putchar('\t'); ! 106: } ! 107: putchar(lastc=c); ! 108: } ! 109: error("workspace eof"); ! 110: } ! 111: } ! 112: ! 113: ! 114: ex_crp() /* dredge up a function and put it into an array*/ ! 115: { ! 116: char name[NAMS]; ! 117: char *c, *c2; ! 118: struct nlist *np; ! 119: struct item *p; ! 120: int len, dim0, dim1; ! 121: register i; ! 122: register char *dp; ! 123: ! 124: p = fetch1(); ! 125: if ( p->size == 0 || p->rank >1 || p->size >= NAMS ) ! 126: error("Lcr C"); ! 127: /* set up the name in search format */ ! 128: copy(CH, p->datap, name, p->size); ! 129: name[p->size] = '\0'; ! 130: np = nlook(name); ! 131: /* if not found then domain error */ ! 132: if ( !np->namep ) ! 133: error("Lcr D"); ! 134: switch(np->use){ ! 135: default: ! 136: error("Lcr D"); ! 137: case MF: ! 138: case DF: ! 139: case NF: /* only allow functions */ ! 140: ; ! 141: } ! 142: /* set up new array */ ! 143: dim0 = 0; ! 144: dim1 = 0; ! 145: ifile = DUPF(wfile); ! 146: SEEKF( ifile, (long)np->label, 0); /* look up function */ ! 147: /* compute max width and height */ ! 148: while ( c2 = c = rline(0) ){ ! 149: while ( *c2++ != '\n' ){} ! 150: dim0++; ! 151: len = c2 - c - 1; ! 152: dim1 = dim1 < len ? len : dim1; ! 153: free(c); ! 154: } ! 155: pop(); /* release old variable */ ! 156: /* create new array and put function in */ ! 157: p = newdat ( CH, 2, dim0*dim1 ); ! 158: p->rank = 2; ! 159: p->dim[0] = dim0; ! 160: p->dim[1] = dim1; ! 161: dp = (char *)(p->datap); ! 162: SEEKF( ifile, (long)np->label, 0); ! 163: while ( c2 = c = rline(0) ){ ! 164: for ( i=0; i<dim1; i++) ! 165: if ( *c != '\n' ) ! 166: *dp++ = *c++; ! 167: else ! 168: *dp++ = ' '; /* fill w/blanks*/ ! 169: free(c2); ! 170: } ! 171: /* put the new array on the stack */ ! 172: *sp++ = p; ! 173: /* reset the current file */ ! 174: CLOSEF(ifile); ! 175: ifile = 0; ! 176: } ! 177: ! 178: menc1() /* change numbers into characters */ ! 179: { ! 180: struct item *p, *q; ! 181: register i,j,numsz; ! 182: data *dp; ! 183: int total,param[4]; ! 184: ! 185: /* zeroize size information vector */ ! 186: for ( i=0; i<4; i++ ) ! 187: param[i] = 0; ! 188: /* pick up the argument */ ! 189: p = fetch1(); ! 190: if(p->rank > 2) ! 191: error("format R"); ! 192: dp = p->datap; ! 193: /* find the maximum # of chars in any # */ ! 194: for(i=0; i<p->size; i++) ! 195: epr1(*dp++, param); ! 196: numsz = param[1] + param[2] + !!param[2] + param[3] + 1; ! 197: /* rowsize is max # size x last dim */ ! 198: rowsz = p->rank ? p->dim[p->rank-1] : 1; ! 199: rowsz *= numsz; ! 200: /* row size x # of rows (incl blank) */ ! 201: total = p->size * numsz; ! 202: for( j=i=0; i<p->rank; i++ ) ! 203: if ( p->dim[i] != 1) ! 204: if ( j++ > 1 ) ! 205: total += rowsz; ! 206: /* make new data and fill with blanks */ ! 207: if(p->rank == 2){ ! 208: q = newdat(CH, 2, total); ! 209: q->dim[0] = total/rowsz; ! 210: q->dim[1] = rowsz; ! 211: } else { ! 212: /* rank = 0 or 1 */ ! 213: q = newdat( CH, 1, total); ! 214: q->dim[0] = rowsz; ! 215: } ! 216: mencptr = (char *)(q->datap); ! 217: for ( i=0; i<total; i++) ! 218: *mencptr++ = ' '; ! 219: mencptr = (char *)(q->datap); ! 220: /* use putchar() to fill up the array */ ! 221: mencflg = 2; ! 222: ex_hprint(); ! 223: mencflg = 0; ! 224: /* put it on the stack */ ! 225: /* pop(); /* done by ex_hprint() */ ! 226: *sp++ = q; ! 227: } ! 228: ! 229: ! 230: ex_run() ! 231: { ! 232: register struct item *p; ! 233: register data *dp; ! 234: register int *p2; ! 235: char ebuf[100]; ! 236: int i; ! 237: int *run(); ! 238: ! 239: p = fetch1(); ! 240: if(p->type != CH || p->rank != 1) ! 241: error("Lrun D"); ! 242: copy(CH, p->datap, ebuf, p->size); ! 243: ebuf[p->size] = 0; ! 244: p2 = run(ebuf); ! 245: p = newdat(DA, 1, 0); ! 246: pop(); ! 247: *sp++ = p; ! 248: } ! 249: ! 250: int *run(s) ! 251: char *s; ! 252: { ! 253: register p; ! 254: static int a[3]; ! 255: int (*oldint)(), (*oldquit)(); ! 256: ! 257: oldint = signal(SIGINT, SIG_IGN); ! 258: oldquit = signal(SIGQUIT, 1); ! 259: if(a[0]=FORKF(1)){ ! 260: while((p = wait(a+1)) != -1) ! 261: if(p == a[0]) ! 262: break; ! 263: } else { ! 264: execl("/bin/sh", "-", "-c", s, 0); ! 265: WRITEF(1, "can't find shell\n", 17); ! 266: exit(1); ! 267: } ! 268: a[2] = (a[1]>>8)&0377; ! 269: a[1] &= 0377; ! 270: signal(SIGINT, oldint); ! 271: signal(SIGQUIT, oldquit); ! 272: return(a); ! 273: } ! 274: ! 275: ex_dfmt() ! 276: { ! 277: register char *cp, *ecp; ! 278: register data *fp; ! 279: register j; ! 280: struct item *lp, *rp, *ip; ! 281: data *dp; ! 282: unsigned nrow, ncol, rowlen, inc, wid; ! 283: int i, sign, decpt; ! 284: ! 285: /* Dyadic format. This routine is a little crude and should ! 286: * probably be rewritten to take advantage of other conversion ! 287: * routines. Nonetheless, it does do dyadic formatting for ! 288: * scalars, vectors, and 2-dimensional arrays when the left ! 289: * argument is a 2-element or appropriate-length vector ! 290: * specifying non-exponential ("F format") conversion. ! 291: */ ! 292: ! 293: lp = fetch2(); ! 294: rp = sp[-2]; ! 295: nrow = (rp->rank < 2) ? 1 : rp->dim[0]; ! 296: ncol = rp->rank ? rp->dim[rp->rank-1] : 1; ! 297: inc = (lp->size != 2) * 2; ! 298: ! 299: ! 300: /* Check validity of arguments. */ ! 301: ! 302: if (lp->rank > 1 || lp->size <= 1 || rp->rank > 2 ! 303: || lp->type != DA || rp->type != DA ! 304: || (lp->size != 2 && lp->size != 2*ncol)) ! 305: error("dfmt D"); ! 306: ! 307: for(fp=lp->datap,i=0; i < lp->size; i += 2,fp += 2){ ! 308: if (fp[0] <= 0.0 || fp[1] < 0.0) ! 309: error("dfmt D"); ! 310: fp[0] = (data)((int)(0.5+fp[0])); ! 311: fp[1] = (data)((int)(0.5+fp[1])); ! 312: } ! 313: ! 314: ! 315: /* Allocate result array */ ! 316: ! 317: for(i=rowlen=0,fp=lp->datap; i < ncol; i++, fp += inc) ! 318: rowlen += (int)*fp; ! 319: ! 320: ip = newdat(CH, rp->rank ? rp->rank : 1, rowlen*nrow); ! 321: ! 322: if (rp->rank < 2) ! 323: ip->dim[0] = rowlen; ! 324: else { ! 325: ip->dim[0] = nrow; ! 326: ip->dim[1] = rowlen; ! 327: } ! 328: ! 329: ! 330: /* Fill it up. The special case "fabs(*dp) < 1.0 && !fp[1]" ! 331: * insures that a zero is printed when 0 fractional digits are ! 332: * specified and the number being converted is less than one. ! 333: */ ! 334: ! 335: cp = (char *)ip->datap; ! 336: dp = rp->datap; ! 337: while(nrow--) ! 338: for(i=0,fp=lp->datap; i < ncol; i++, dp++, fp += inc){ ! 339: if (fp[1] == 0.0 && fabs(*dp) < 1.0) ! 340: *dp = 0.0; ! 341: ecp = ecvt(*dp, (int)(0.5+fp[0]), &decpt, &sign); ! 342: decpt += (*dp == 0.0 && fp[1] == 0.0); ! 343: j = fp[0]; ! 344: wid = !!sign + fp[1] + !!fp[1] + ((decpt>0)?decpt:0); ! 345: if (j < wid) ! 346: while(j--) ! 347: *cp++ = '*'; /* not wide enough */ ! 348: else { ! 349: while(j > wid){ /* leading spaces */ ! 350: *cp++ = ' '; ! 351: j--; ! 352: } ! 353: if (sign){ /* possible - sign */ ! 354: *cp++ = '-'; ! 355: j--; ! 356: } ! 357: while(decpt > 0){ /* whole number part */ ! 358: *cp++ = *ecp++; ! 359: j--; ! 360: decpt--; ! 361: } ! 362: if (j--){ /* fraction, if any */ ! 363: *cp++ = '.'; ! 364: while(decpt++ < 0 && j){ ! 365: j--; ! 366: *cp++ = '0'; ! 367: } ! 368: while(j--) ! 369: *cp++ = *ecp++; ! 370: } ! 371: } ! 372: } ! 373: ! 374: pop(); ! 375: pop(); ! 376: *sp++ = ip; ! 377: ! 378: } ! 379: ! 380: ex_mfmt() ! 381: { ! 382: ex_menc(); ! 383: } ! 384: ! 385: ex_nc() ! 386: { ! 387: register struct nlist *np; ! 388: register struct item *p; ! 389: register char *q; ! 390: int i; ! 391: char buf[40]; ! 392: ! 393: p = fetch1(); ! 394: if(p->type != CH) ! 395: error("Lnc T"); ! 396: if(p->size >= 40 || p->rank > 1) ! 397: error("Lnc D"); ! 398: copy(CH, p->datap, buf, p->size); ! 399: buf[p->size] = 0; ! 400: np = nlook(buf); ! 401: i = 0; ! 402: if(np != 0) ! 403: switch(np->use){ ! 404: case 0: ! 405: i = 0; break; ! 406: case MF: ! 407: case NF: ! 408: case DF: ! 409: i = 3; break; ! 410: case DA: ! 411: case CH: ! 412: case LV: ! 413: i = 2; break; ! 414: default: ! 415: printf("unknown Lnc type = %d\n", np->use); ! 416: i = 4; ! 417: } ! 418: p = newdat(DA, 0, 1); ! 419: p->datap[0] = i; ! 420: pop(); ! 421: *sp++ = p; ! 422: } ! 423: ! 424: ex_nl() ! 425: { ! 426: ! 427: struct item *ip; ! 428: struct nlist *np; ! 429: data *dp; ! 430: register char *cp, *cp2; ! 431: register i; ! 432: int count, maxlen; ! 433: char tlist[NTYPES]; ! 434: ! 435: ! 436: /* Namelist quad function. This is monadic (dyadic not ! 437: * implemented). The argument is a list of types: ! 438: * 1: labels ! 439: * 2: variables ! 440: * 3: functions ! 441: * whose names are desired. The result is a character array ! 442: * containing all defined names (in no particular order) of ! 443: * the specified type(s). The number of rows in the matrix ! 444: * is the number of names; the number of columns is the ! 445: * same as the longest name (other names are space-filled). ! 446: */ ! 447: ! 448: ip = fetch1(); ! 449: if (ip->rank > 1 || ip->type != DA) ! 450: error("Lnl D"); ! 451: ! 452: for(i=0; i < NTYPES; i++) tlist[i] = 0; ! 453: for(dp=ip->datap; dp < ip->datap+ip->size; dp++) ! 454: switch((int)*dp){ ! 455: case 1: tlist[LBL] = 1; break; ! 456: case 2: tlist[CH] = tlist[DA] = 1; break; ! 457: case 3: tlist[NF] = tlist[MF] = tlist[DF] = 1; break; ! 458: default:error("Lnl D"); break; ! 459: } ! 460: ! 461: count = maxlen = 0; ! 462: for(np=nlist; np < &nlist[NLS]; np++){ ! 463: if (np->use < NTYPES && tlist[np->use]){ ! 464: count++; ! 465: if ((i=strlen(np->namep)) > maxlen) ! 466: maxlen = i; ! 467: } ! 468: } ! 469: ! 470: ! 471: ip = newdat(CH, 2, count*maxlen); ! 472: ip->dim[0] = count; ! 473: ip->dim[1] = maxlen; ! 474: cp = ip->datap; ! 475: ! 476: for(np=nlist; np < &nlist[NLS]; np++) ! 477: if (np->use < NTYPES && tlist[np->use]) ! 478: for(cp2 = &np->namep[i=0]; i < maxlen; i++) ! 479: if (*cp2) ! 480: *cp++ = *cp2++; ! 481: else ! 482: *cp++ = ' '; ! 483: ! 484: pop(); ! 485: *sp++ = ip; ! 486: } ! 487: ! 488: strlen(p) ! 489: register char *p; ! 490: { ! 491: register i; ! 492: ! 493: for(i=0; *p; i++,p++); ! 494: return(i); ! 495: } ! 496: ! 497: ex_prws(){ ! 498: ! 499: register struct nlist *np; ! 500: register struct item *ip; ! 501: register i; ! 502: ! 503: /* Print workspace in ASCII format */ ! 504: ! 505: printf("origin = %d\nwidth = %d\ndigits = %d\n\n\n", ! 506: thread.iorg, thread.width, thread.digits); ! 507: for(np=nlist; np < &nlist[NLS]; np++) ! 508: switch(np->use){ ! 509: case CH: ! 510: case DA: ! 511: printf("%s { ", np->namep); ! 512: ip = np->itemp; ! 513: if (ip->rank){ ! 514: for(i=0; i < ip->rank; i++) ! 515: printf("%d ", ip->dim[i]); ! 516: printf("R\n"); ! 517: } ! 518: *sp++ = np; ! 519: ex_print(); ! 520: pop(); ! 521: putchar('\n'); ! 522: break; ! 523: ! 524: case NF: ! 525: case MF: ! 526: case DF: ! 527: *sp++ = np; ! 528: ex_list(); ! 529: /* pop(); in ex_list() */ ! 530: putchar('\n'); ! 531: break; ! 532: } ! 533: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.