static char Sccsid
[] = "a0.c @(#)a0.c 1.4 6/4/85 Berkeley ";
int mkcore
= 0; /* produce core image upon fatal error */
int edmagic
= 0; /* turn on "ed" magic characters */
struct iobuf iobf
[NBUF
]; /* Actual buffers */
iobuf
= iobf
; /* Set up buffer pointer */
initbuf(); /* Set up to run */
scr_file
= "/tmp/apled.000000";
ws_file
= "/tmp/aplws.000000";
a
= 1; /* catch signals */
/* Check to see if argp[0] is "prws". If so, set prwsflg */
while(p
> argp
[0] && *p
!= '/') p
--;
if (!p
[c
] || p
[c
] != "prws"[c
])
while(argc
> 1 && argp
[1][0] == '-'){
while(*++*argp
) switch(**argp
){
case 'e': echoflg
= 1; break;
case 'q': echoflg
= 0; break;
case 'C': mkcore
= 1; break;
case 'm': apl_term
= 1; break;
case 'r': edmagic
= 1; break;
case 'o': offexit
= 0; break;
echoflg
= mkcore
= a
= 0; /* "prws" settings */
aplmod(1); /* Turn on APL mode */
CLOSEF(opn(WSFILE
,0600));
pi
= 3.141592653589793238462643383;
if((unsigned)signal(SIGINT
, intr
) & 01)
if(argc
> 1 && (a
= opn(argp
[1], 0)) > 0){
printf(" %s\n", argp
[1]);
if((a
=OPENF("continue",0)) < 0) {
evLlx(); /* eval latent expr, if any */
static eotcount
= MAXEOT
; /* maximum eot's on input */
echoflg
= 1; /* enabled echo echo suppress off */
printf("\ruse \')off\' to exit\n");
term(0); /* close down and exit */
/* note that if the execute errors out, then
* the allocated space pointed to by comp is never
* freed. This is hard to fix.
/* "prws" interrupt -- restore old tty modes and exit */
if (p
>= line
+CANBS
-2 || col
> 127)
*p
++ = c
; /* was and'ed with 0177... */
qsort(line
, (p
-line
)/2, 2, rlcmp
);
c
= 1; /* check for blank line */
cp
= (retval
=alloc(c
+3)) - 1;
for(p
=line
; p
[0] != -1; p
+=2) {
if(p
[2] != col
) continue;
i
= ((i
<<8) | *cp
)&0177777;
for(j
=0; chartab
[j
]; j
++){
aplmod(0); /* turn off APL mode */
for(j
=0; j
<NFDS
; j
++) /* Close files */
printf("[dealloc botch: %d]\n", p
->type
);
((struct nlist
*)p
)->use
= 0; /* delete label */
/* Allocate a new data item. I have searched the specifications
* for C and as far as I can tell, it should be legal to
* declare a zero-length array inside a structure. However,
* the VAX C compiler (which I think is a derivative of the
* portable C compiler) does not allow this. The Ritchie
* V7 PDP-11 compiler does. I have redeclared "dim" to
* contain MRANK elements. When the data is allocated,
* space is only allocated for as many dimensions as there
* actually are. Thus, if there are 0 dimensions, no space
* will be allocated for "dim". This had better make the
* VAX happy, since it has sure made me unhappy.
i
= sizeof *p
- SINT
* (MRANK
-rank
);
p
->datap
= (data
*)&p
->dim
[rank
];
register struct item
*p1
, *p2
;
p2
= newdat(p1
->type
, p1
->rank
, p1
->size
);
for(i
=0; i
<p1
->rank
; i
++)
copy(p1
->type
, p1
->datap
, p2
->datap
, p1
->size
);
copy(type
, from
, to
, size
)
register struct item
*p
, *q
;
copy(q
->type
, q
->datap
, p
->datap
, q
->size
);
for(i
=0; cc
->c
[i
] != '\n'; i
++)
copy(CH
, cc
, p
->datap
, i
);
* Currently, if something prevents APL from completing
* execution of line 0 of a function, it leaves with
* the stack in an unknown state and "gsip->oldsp" is
* zero. This is nasty because there is no way to
* reset out of it. The principle cause of error
* exits from line 0 is the fetch of an undefined
* function argument. The following code attempts
* to fix this by setting an error flag and creating
* a dummy variable for the stack if "used before set"
* occurs in the function header. "ex_fun" then will
* note that the flag is high and cause an error exit
* AFTER all header processing has been completed.
if(((struct nlist
*)p
)->use
!= DA
){
printf("%s: used before set",
((struct nlist
*)ip
)->namep
);
if ((!gsip
) || gsip
->funlc
!= 1)
q
= newdat(DA
, 0, 1); /* Dummy */
prolgerr
= 1; /* ERROR flag */
p
= ((struct nlist
*)p
)->itemp
;
i
= DA
; /* treat label as data */
q
= newdat(i
, p
->rank
, p
->size
);
copy(IN
, p
->dim
, q
->dim
, p
->rank
);
copy(i
, p
->datap
, q
->datap
, p
->size
);
if(p
->type
!= DA
|| p
->size
!= 1)
copy(IN
, p
->dim
, idx
.dim
, idx
.rank
);
for(i
=idx
.rank
-1; i
>=0; i
--) {
if(k
< 0 || k
>= idx
.rank
)
for(i
=k
; i
<idx
.rank
; i
++) {
idx
.del
[i
] = idx
.del
[i
+1];
idx
.dim
[i
] = idx
.dim
[i
+1];
return; /* for null items */
while(++idx
.idx
[i
-1] >= idx
.dim
[i
-1])
for(i
=0; i
<idx
.rank
; i
++)
n
+= idx
.idx
[i
] * idx
.del
[i
];
/* Get the data value stored at index p->index. If the
* index is out of range it will be wrapped around. If
* the data item is null, a zero or blank will be returned.
if (p
->size
== 0) /* let the caller beware */
return((p
->type
== DA
) ? zero
: (data
)' ');
d
= ((struct chrstrct
*)p
->datap
)->c
[i
];
((struct chrstrct
*)p
->datap
)->c
[i
] = d
;
/* aplmod has been moved to am.c */
register struct item
*p
, *q
;
q
= newdat(p
->type
, 1, 1);
register struct nlist
*np
;
for(np
= nlist
; np
->namep
; np
++)
if(equal(np
->namep
, name
))
* csize -- return size (in bytes) of a compiled string
while((c
= *p
++) != EOF
){
extern OPENF(), CREATF();
p
= (rw
> 2 ? CREATF
: OPENF
);
if((fd
= (*p
)(file
,rw
)) < 0){
for(fd
=0; file
[fd
]; fd
++)
if((fd
= (*p
)(f2
, rw
)) >= 0){
printf("[using %s]\n", f2
);
printf("can't open file %s\n", file
);
/* signal(SIGFPE, fpe); /* (fppinit called by "main") */
static insane
= 0; /* if != 0, die */
static char *abt_file
= "aplws.abort";
static char *errtbl
[] = {
"segmentation violation",
/* Attempt to save workspace. A signal out of here always
* causes immediate death.
printf("\nfatal signal: %s\n",
errtbl
[(signum
< NSIG
) ? signum
: 0]);
if ((fd
=CREATF(abt_file
, 0644)) >= 0){
printf("[attempting ws dump]\n");
printf(" workspace saved in %s\n", abt_file
);
printf("workspace lost -- sorry\n");
printf("recursive errors: unrecoverable\n");