xref: /csrg-svn/usr.bin/f77/pass1.vax/io.c (revision 25741)
122836Smckusick /*
222836Smckusick  * Copyright (c) 1980 Regents of the University of California.
322836Smckusick  * All rights reserved.  The Berkeley software License Agreement
422836Smckusick  * specifies the terms and conditions for redistribution.
522836Smckusick  */
622836Smckusick 
722836Smckusick #ifndef lint
8*25741Sdonn static	char *sccsid = "@(#)io.c	5.2 (Berkeley) 01/07/86";
922836Smckusick #endif
1022836Smckusick 
1122836Smckusick /*
1222836Smckusick  * io.c
1322836Smckusick  *
1422836Smckusick  * Routines to generate code for I/O statements.
1522836Smckusick  * Some corrections and improvements due to David Wasley, U. C. Berkeley
1622836Smckusick  *
1722836Smckusick  * University of Utah CS Dept modification history:
1822836Smckusick  *
19*25741Sdonn  * $Header: io.c,v 5.2 85/12/19 17:22:35 donn Exp $
2022836Smckusick  * $Log:	io.c,v $
21*25741Sdonn  * Revision 5.2  85/12/19  17:22:35  donn
22*25741Sdonn  * Don't permit more than one 'positional iocontrol' parameter unless we
23*25741Sdonn  * are doing a READ or a WRITE.
24*25741Sdonn  *
25*25741Sdonn  * Revision 5.1  85/08/10  03:47:42  donn
26*25741Sdonn  * 4.3 alpha
27*25741Sdonn  *
2822836Smckusick  * Revision 2.4  85/02/23  21:09:02  donn
2922836Smckusick  * Jerry Berkman's compiled format fixes move setfmt into a separate file.
3022836Smckusick  *
3122836Smckusick  * Revision 2.3  85/01/10  22:33:41  donn
3222836Smckusick  * Added some strategic cpexpr()s to prevent memory management bugs.
3322836Smckusick  *
3422836Smckusick  * Revision 2.2  84/08/04  21:15:47  donn
3522836Smckusick  * Removed code that creates extra statement labels, per Jerry Berkman's
3622836Smckusick  * fixes to make ASSIGNs work right.
3722836Smckusick  *
3822836Smckusick  * Revision 2.1  84/07/19  12:03:33  donn
3922836Smckusick  * Changed comment headers for UofU.
4022836Smckusick  *
4122836Smckusick  * Revision 1.2  84/02/26  06:35:57  donn
4222836Smckusick  * Added Berkeley changes necessary for shortening offsets to data.
4322836Smckusick  *
4422836Smckusick  */
4522836Smckusick 
4622836Smckusick /* TEMPORARY */
4722836Smckusick #define TYIOINT TYLONG
4822836Smckusick #define SZIOINT SZLONG
4922836Smckusick 
5022836Smckusick #include "defs.h"
5122836Smckusick #include "io.h"
5222836Smckusick 
5322836Smckusick 
5422836Smckusick LOCAL char ioroutine[XL+1];
5522836Smckusick 
5622836Smckusick LOCAL int ioendlab;
5722836Smckusick LOCAL int ioerrlab;
5822836Smckusick LOCAL int endbit;
5922836Smckusick LOCAL int errbit;
6022836Smckusick LOCAL int jumplab;
6122836Smckusick LOCAL int skiplab;
6222836Smckusick LOCAL int ioformatted;
6322836Smckusick LOCAL int statstruct = NO;
6422836Smckusick LOCAL ftnint blklen;
6522836Smckusick 
6622836Smckusick LOCAL offsetlist *mkiodata();
6722836Smckusick 
6822836Smckusick 
6922836Smckusick #define UNFORMATTED 0
7022836Smckusick #define FORMATTED 1
7122836Smckusick #define LISTDIRECTED 2
7222836Smckusick #define NAMEDIRECTED 3
7322836Smckusick 
7422836Smckusick #define V(z)	ioc[z].iocval
7522836Smckusick 
7622836Smckusick #define IOALL 07777
7722836Smckusick 
7822836Smckusick LOCAL struct Ioclist
7922836Smckusick 	{
8022836Smckusick 	char *iocname;
8122836Smckusick 	int iotype;
8222836Smckusick 	expptr iocval;
8322836Smckusick 	} ioc[ ] =
8422836Smckusick 	{
8522836Smckusick 		{ "", 0 },
8622836Smckusick 		{ "unit", IOALL },
8722836Smckusick 		{ "fmt", M(IOREAD) | M(IOWRITE) },
8822836Smckusick 		{ "err", IOALL },
8922836Smckusick 		{ "end", M(IOREAD) },
9022836Smckusick 		{ "iostat", IOALL },
9122836Smckusick 		{ "rec", M(IOREAD) | M(IOWRITE) },
9222836Smckusick 		{ "recl", M(IOOPEN) | M(IOINQUIRE) },
9322836Smckusick 		{ "file", M(IOOPEN) | M(IOINQUIRE) },
9422836Smckusick 		{ "status", M(IOOPEN) | M(IOCLOSE) },
9522836Smckusick 		{ "access", M(IOOPEN) | M(IOINQUIRE) },
9622836Smckusick 		{ "form", M(IOOPEN) | M(IOINQUIRE) },
9722836Smckusick 		{ "blank", M(IOOPEN) | M(IOINQUIRE) },
9822836Smckusick 		{ "exist", M(IOINQUIRE) },
9922836Smckusick 		{ "opened", M(IOINQUIRE) },
10022836Smckusick 		{ "number", M(IOINQUIRE) },
10122836Smckusick 		{ "named", M(IOINQUIRE) },
10222836Smckusick 		{ "name", M(IOINQUIRE) },
10322836Smckusick 		{ "sequential", M(IOINQUIRE) },
10422836Smckusick 		{ "direct", M(IOINQUIRE) },
10522836Smckusick 		{ "formatted", M(IOINQUIRE) },
10622836Smckusick 		{ "unformatted", M(IOINQUIRE) },
10722836Smckusick 		{ "nextrec", M(IOINQUIRE) }
10822836Smckusick 	} ;
10922836Smckusick 
11022836Smckusick #define NIOS (sizeof(ioc)/sizeof(struct Ioclist) - 1)
11122836Smckusick #define MAXIO	SZFLAG + 10*SZIOINT + 15*SZADDR
11222836Smckusick 
11322836Smckusick #define IOSUNIT 1
11422836Smckusick #define IOSFMT 2
11522836Smckusick #define IOSERR 3
11622836Smckusick #define IOSEND 4
11722836Smckusick #define IOSIOSTAT 5
11822836Smckusick #define IOSREC 6
11922836Smckusick #define IOSRECL 7
12022836Smckusick #define IOSFILE 8
12122836Smckusick #define IOSSTATUS 9
12222836Smckusick #define IOSACCESS 10
12322836Smckusick #define IOSFORM 11
12422836Smckusick #define IOSBLANK 12
12522836Smckusick #define IOSEXISTS 13
12622836Smckusick #define IOSOPENED 14
12722836Smckusick #define IOSNUMBER 15
12822836Smckusick #define IOSNAMED 16
12922836Smckusick #define IOSNAME 17
13022836Smckusick #define IOSSEQUENTIAL 18
13122836Smckusick #define IOSDIRECT 19
13222836Smckusick #define IOSFORMATTED 20
13322836Smckusick #define IOSUNFORMATTED 21
13422836Smckusick #define IOSNEXTREC 22
13522836Smckusick 
13622836Smckusick #define IOSTP V(IOSIOSTAT)
13722836Smckusick 
13822836Smckusick 
13922836Smckusick /* offsets in generated structures */
14022836Smckusick 
14122836Smckusick #define SZFLAG SZIOINT
14222836Smckusick 
14322836Smckusick /* offsets for external READ and WRITE statements */
14422836Smckusick 
14522836Smckusick #define XERR 0
14622836Smckusick #define XUNIT	SZFLAG
14722836Smckusick #define XEND	SZFLAG + SZIOINT
14822836Smckusick #define XFMT	2*SZFLAG + SZIOINT
14922836Smckusick #define XREC	2*SZFLAG + SZIOINT + SZADDR
15022836Smckusick #define XRLEN	2*SZFLAG + 2*SZADDR
15122836Smckusick #define XRNUM	2*SZFLAG + 2*SZADDR + SZIOINT
15222836Smckusick 
15322836Smckusick /* offsets for internal READ and WRITE statements */
15422836Smckusick 
15522836Smckusick #define XIERR	0
15622836Smckusick #define XIUNIT	SZFLAG
15722836Smckusick #define XIEND	SZFLAG + SZADDR
15822836Smckusick #define XIFMT	2*SZFLAG + SZADDR
15922836Smckusick #define XIRLEN	2*SZFLAG + 2*SZADDR
16022836Smckusick #define XIRNUM	2*SZFLAG + 2*SZADDR + SZIOINT
16122836Smckusick #define XIREC	2*SZFLAG + 2*SZADDR + 2*SZIOINT
16222836Smckusick 
16322836Smckusick /* offsets for OPEN statements */
16422836Smckusick 
16522836Smckusick #define XFNAME	SZFLAG + SZIOINT
16622836Smckusick #define XFNAMELEN	SZFLAG + SZIOINT + SZADDR
16722836Smckusick #define XSTATUS	SZFLAG + 2*SZIOINT + SZADDR
16822836Smckusick #define XACCESS	SZFLAG + 2*SZIOINT + 2*SZADDR
16922836Smckusick #define XFORMATTED	SZFLAG + 2*SZIOINT + 3*SZADDR
17022836Smckusick #define XRECLEN	SZFLAG + 2*SZIOINT + 4*SZADDR
17122836Smckusick #define XBLANK	SZFLAG + 3*SZIOINT + 4*SZADDR
17222836Smckusick 
17322836Smckusick /* offset for CLOSE statement */
17422836Smckusick 
17522836Smckusick #define XCLSTATUS	SZFLAG + SZIOINT
17622836Smckusick 
17722836Smckusick /* offsets for INQUIRE statement */
17822836Smckusick 
17922836Smckusick #define XFILE	SZFLAG + SZIOINT
18022836Smckusick #define XFILELEN	SZFLAG + SZIOINT + SZADDR
18122836Smckusick #define XEXISTS	SZFLAG + 2*SZIOINT + SZADDR
18222836Smckusick #define XOPEN	SZFLAG + 2*SZIOINT + 2*SZADDR
18322836Smckusick #define XNUMBER	SZFLAG + 2*SZIOINT + 3*SZADDR
18422836Smckusick #define XNAMED	SZFLAG + 2*SZIOINT + 4*SZADDR
18522836Smckusick #define XNAME	SZFLAG + 2*SZIOINT + 5*SZADDR
18622836Smckusick #define XNAMELEN	SZFLAG + 2*SZIOINT + 6*SZADDR
18722836Smckusick #define XQACCESS	SZFLAG + 3*SZIOINT + 6*SZADDR
18822836Smckusick #define XQACCLEN	SZFLAG + 3*SZIOINT + 7*SZADDR
18922836Smckusick #define XSEQ	SZFLAG + 4*SZIOINT + 7*SZADDR
19022836Smckusick #define XSEQLEN	SZFLAG + 4*SZIOINT + 8*SZADDR
19122836Smckusick #define XDIRECT	SZFLAG + 5*SZIOINT + 8*SZADDR
19222836Smckusick #define XDIRLEN	SZFLAG + 5*SZIOINT + 9*SZADDR
19322836Smckusick #define XFORM	SZFLAG + 6*SZIOINT + 9*SZADDR
19422836Smckusick #define XFORMLEN	SZFLAG + 6*SZIOINT + 10*SZADDR
19522836Smckusick #define XFMTED	SZFLAG + 7*SZIOINT + 10*SZADDR
19622836Smckusick #define XFMTEDLEN	SZFLAG + 7*SZIOINT + 11*SZADDR
19722836Smckusick #define XUNFMT	SZFLAG + 8*SZIOINT + 11*SZADDR
19822836Smckusick #define XUNFMTLEN	SZFLAG + 8*SZIOINT + 12*SZADDR
19922836Smckusick #define XQRECL	SZFLAG + 9*SZIOINT + 12*SZADDR
20022836Smckusick #define XNEXTREC	SZFLAG + 9*SZIOINT + 13*SZADDR
20122836Smckusick #define XQBLANK	SZFLAG + 9*SZIOINT + 14*SZADDR
20222836Smckusick #define XQBLANKLEN	SZFLAG + 9*SZIOINT + 15*SZADDR
20322836Smckusick 
20422836Smckusick fmtstmt(lp)
20522836Smckusick register struct Labelblock *lp;
20622836Smckusick {
20722836Smckusick if(lp == NULL)
20822836Smckusick 	{
20922836Smckusick 	execerr("unlabeled format statement" , CNULL);
21022836Smckusick 	return(-1);
21122836Smckusick 	}
21222836Smckusick if(lp->labtype == LABUNKNOWN)
21322836Smckusick 	lp->labtype = LABFORMAT;
21422836Smckusick else if(lp->labtype != LABFORMAT)
21522836Smckusick 	{
21622836Smckusick 	execerr("bad format number", CNULL);
21722836Smckusick 	return(-1);
21822836Smckusick 	}
21922836Smckusick return(lp->labelno);
22022836Smckusick }
22122836Smckusick 
22222836Smckusick 
22322836Smckusick 
22422836Smckusick startioctl()
22522836Smckusick {
22622836Smckusick register int i;
22722836Smckusick 
22822836Smckusick inioctl = YES;
22922836Smckusick nioctl = 0;
23022836Smckusick ioformatted = UNFORMATTED;
23122836Smckusick for(i = 1 ; i<=NIOS ; ++i)
23222836Smckusick 	V(i) = NULL;
23322836Smckusick }
23422836Smckusick 
23522836Smckusick 
23622836Smckusick 
23722836Smckusick endioctl()
23822836Smckusick {
23922836Smckusick int i;
24022836Smckusick expptr p;
24122836Smckusick 
24222836Smckusick inioctl = NO;
24322836Smckusick 
24422836Smckusick /* set up for error recovery */
24522836Smckusick 
24622836Smckusick ioerrlab = ioendlab = skiplab = jumplab = 0;
24722836Smckusick 
24822836Smckusick if(p = V(IOSEND))
24922836Smckusick 	if(ISICON(p))
25022836Smckusick 		ioendlab = execlab(p->constblock.const.ci) ->labelno;
25122836Smckusick 	else
25222836Smckusick 		err("bad end= clause");
25322836Smckusick 
25422836Smckusick if(p = V(IOSERR))
25522836Smckusick 	if(ISICON(p))
25622836Smckusick 		ioerrlab = execlab(p->constblock.const.ci) ->labelno;
25722836Smckusick 	else
25822836Smckusick 		err("bad err= clause");
25922836Smckusick 
26022836Smckusick if(IOSTP)
26122836Smckusick 	if(IOSTP->tag!=TADDR || ! ISINT(IOSTP->addrblock.vtype) )
26222836Smckusick 		{
26322836Smckusick 		err("iostat must be an integer variable");
26422836Smckusick 		frexpr(IOSTP);
26522836Smckusick 		IOSTP = NULL;
26622836Smckusick 		}
26722836Smckusick 
26822836Smckusick if(iostmt == IOREAD)
26922836Smckusick 	{
27022836Smckusick 	if(IOSTP)
27122836Smckusick 		{
27222836Smckusick 		if(ioerrlab && ioendlab && ioerrlab==ioendlab)
27322836Smckusick 			jumplab = ioerrlab;
27422836Smckusick 		else
27522836Smckusick 			skiplab = jumplab = newlabel();
27622836Smckusick 		}
27722836Smckusick 	else	{
27822836Smckusick 		if(ioerrlab && ioendlab && ioerrlab!=ioendlab)
27922836Smckusick 			{
28022836Smckusick 			IOSTP = (expptr) mktemp(TYINT, PNULL);
28122836Smckusick 			skiplab = jumplab = newlabel();
28222836Smckusick 			}
28322836Smckusick 		else
28422836Smckusick 			jumplab = (ioerrlab ? ioerrlab : ioendlab);
28522836Smckusick 		}
28622836Smckusick 	}
28722836Smckusick else if(iostmt == IOWRITE)
28822836Smckusick 	{
28922836Smckusick 	if(IOSTP && !ioerrlab)
29022836Smckusick 		skiplab = jumplab = newlabel();
29122836Smckusick 	else
29222836Smckusick 		jumplab = ioerrlab;
29322836Smckusick 	}
29422836Smckusick else
29522836Smckusick 	jumplab = ioerrlab;
29622836Smckusick 
29722836Smckusick endbit = IOSTP!=NULL || ioendlab!=0;	/* for use in startrw() */
29822836Smckusick errbit = IOSTP!=NULL || ioerrlab!=0;
29922836Smckusick if(iostmt!=IOREAD && iostmt!=IOWRITE)
30022836Smckusick 	{
30122836Smckusick 	if(ioblkp == NULL)
30222836Smckusick 		ioblkp = autovar( (MAXIO+SZIOINT-1)/SZIOINT , TYIOINT, PNULL);
30322836Smckusick 	ioset(TYIOINT, XERR, ICON(errbit));
30422836Smckusick 	}
30522836Smckusick 
30622836Smckusick switch(iostmt)
30722836Smckusick 	{
30822836Smckusick 	case IOOPEN:
30922836Smckusick 		dofopen();  break;
31022836Smckusick 
31122836Smckusick 	case IOCLOSE:
31222836Smckusick 		dofclose();  break;
31322836Smckusick 
31422836Smckusick 	case IOINQUIRE:
31522836Smckusick 		dofinquire();  break;
31622836Smckusick 
31722836Smckusick 	case IOBACKSPACE:
31822836Smckusick 		dofmove("f_back"); break;
31922836Smckusick 
32022836Smckusick 	case IOREWIND:
32122836Smckusick 		dofmove("f_rew");  break;
32222836Smckusick 
32322836Smckusick 	case IOENDFILE:
32422836Smckusick 		dofmove("f_end");  break;
32522836Smckusick 
32622836Smckusick 	case IOREAD:
32722836Smckusick 	case IOWRITE:
32822836Smckusick 		startrw();  break;
32922836Smckusick 
33022836Smckusick 	default:
33122836Smckusick 		fatali("impossible iostmt %d", iostmt);
33222836Smckusick 	}
33322836Smckusick for(i = 1 ; i<=NIOS ; ++i)
33422836Smckusick 	if(i!=IOSIOSTAT && V(i)!=NULL)
33522836Smckusick 		frexpr(V(i));
33622836Smckusick }
33722836Smckusick 
33822836Smckusick 
33922836Smckusick 
34022836Smckusick iocname()
34122836Smckusick {
34222836Smckusick register int i;
34322836Smckusick int found, mask;
34422836Smckusick 
34522836Smckusick found = 0;
34622836Smckusick mask = M(iostmt);
34722836Smckusick for(i = 1 ; i <= NIOS ; ++i)
34822836Smckusick 	if(toklen==strlen(ioc[i].iocname) && eqn(toklen, token, ioc[i].iocname))
34922836Smckusick 		if(ioc[i].iotype & mask)
35022836Smckusick 			return(i);
35122836Smckusick 		else	found = i;
35222836Smckusick if(found)
35322836Smckusick 	errstr("invalid control %s for statement", ioc[found].iocname);
35422836Smckusick else
35522836Smckusick 	errstr("unknown iocontrol %s", varstr(toklen, token) );
35622836Smckusick return(IOSBAD);
35722836Smckusick }
35822836Smckusick 
35922836Smckusick 
36022836Smckusick ioclause(n, p)
36122836Smckusick register int n;
36222836Smckusick register expptr p;
36322836Smckusick {
36422836Smckusick struct Ioclist *iocp;
36522836Smckusick 
36622836Smckusick ++nioctl;
36722836Smckusick if(n == IOSBAD)
36822836Smckusick 	return;
36922836Smckusick if(n == IOSPOSITIONAL)
37022836Smckusick 	{
371*25741Sdonn 	if(nioctl > IOSFMT ||
372*25741Sdonn 	   nioctl > IOSUNIT && !(iostmt == IOREAD || iostmt == IOWRITE))
37322836Smckusick 		{
37422836Smckusick 		err("illegal positional iocontrol");
37522836Smckusick 		return;
37622836Smckusick 		}
37722836Smckusick 	n = nioctl;
37822836Smckusick 	}
37922836Smckusick 
38022836Smckusick if(p == NULL)
38122836Smckusick 	{
38222836Smckusick 	if(n == IOSUNIT)
38322836Smckusick 		p = (expptr) (iostmt==IOREAD ? IOSTDIN : IOSTDOUT);
38422836Smckusick 	else if(n != IOSFMT)
38522836Smckusick 		{
38622836Smckusick 		err("illegal * iocontrol");
38722836Smckusick 		return;
38822836Smckusick 		}
38922836Smckusick 	}
39022836Smckusick if(n == IOSFMT)
39122836Smckusick 	ioformatted = (p==NULL ? LISTDIRECTED : FORMATTED);
39222836Smckusick 
39322836Smckusick iocp = & ioc[n];
39422836Smckusick if(iocp->iocval == NULL)
39522836Smckusick 	{
39622836Smckusick 	p = (expptr) cpexpr(p);
39722836Smckusick 	if(n!=IOSFMT && ( n!=IOSUNIT || (p!=NULL && p->headblock.vtype!=TYCHAR) ) )
39822836Smckusick 		p = fixtype(p);
39922836Smckusick 	if(p!=NULL && ISCONST(p) && p->constblock.vtype==TYCHAR)
40022836Smckusick 		p = (expptr) putconst(p);
40122836Smckusick 	iocp->iocval = p;
40222836Smckusick }
40322836Smckusick else
40422836Smckusick 	errstr("iocontrol %s repeated", iocp->iocname);
40522836Smckusick }
40622836Smckusick 
40722836Smckusick /* io list item */
40822836Smckusick 
40922836Smckusick doio(list)
41022836Smckusick chainp list;
41122836Smckusick {
41222836Smckusick expptr call0();
41322836Smckusick 
41422836Smckusick if(ioformatted == NAMEDIRECTED)
41522836Smckusick 	{
41622836Smckusick 	if(list)
41722836Smckusick 		err("no I/O list allowed in NAMELIST read/write");
41822836Smckusick 	}
41922836Smckusick else
42022836Smckusick 	{
42122836Smckusick 	doiolist(list);
42222836Smckusick 	ioroutine[0] = 'e';
42322836Smckusick 	putiocall( call0(TYINT, ioroutine) );
42422836Smckusick 	}
42522836Smckusick }
42622836Smckusick 
42722836Smckusick 
42822836Smckusick 
42922836Smckusick 
43022836Smckusick 
43122836Smckusick LOCAL doiolist(p0)
43222836Smckusick chainp p0;
43322836Smckusick {
43422836Smckusick chainp p;
43522836Smckusick register tagptr q;
43622836Smckusick register expptr qe;
43722836Smckusick register Namep qn;
43822836Smckusick Addrp tp, mkscalar();
43922836Smckusick int range;
44022836Smckusick expptr expr;
44122836Smckusick 
44222836Smckusick for (p = p0 ; p ; p = p->nextp)
44322836Smckusick 	{
44422836Smckusick 	q = p->datap;
44522836Smckusick 	if(q->tag == TIMPLDO)
44622836Smckusick 		{
44722836Smckusick 		exdo(range=newlabel(), q->impldoblock.impdospec);
44822836Smckusick 		doiolist(q->impldoblock.datalist);
44922836Smckusick 		enddo(range);
45022836Smckusick 		free( (charptr) q);
45122836Smckusick 		}
45222836Smckusick 	else	{
45322836Smckusick 		if(q->tag==TPRIM && q->primblock.argsp==NULL
45422836Smckusick 		    && q->primblock.namep->vdim!=NULL)
45522836Smckusick 			{
45622836Smckusick 			vardcl(qn = q->primblock.namep);
45722836Smckusick 			if(qn->vdim->nelt)
45822836Smckusick 				putio( fixtype(cpexpr(qn->vdim->nelt)),
45922836Smckusick 					mkscalar(qn) );
46022836Smckusick 			else
46122836Smckusick 				err("attempt to i/o array of unknown size");
46222836Smckusick 			}
46322836Smckusick 		else if(q->tag==TPRIM && q->primblock.argsp==NULL &&
46422836Smckusick 		    (qe = (expptr) memversion(q->primblock.namep)) )
46522836Smckusick 			putio(ICON(1),qe);
46622836Smckusick 		else if( (qe = fixtype(cpexpr(q)))->tag==TADDR)
46722836Smckusick 			putio(ICON(1), qe);
46822836Smckusick 		else if(qe->headblock.vtype != TYERROR)
46922836Smckusick 			{
47022836Smckusick 			if(iostmt == IOWRITE)
47122836Smckusick 				{
47222836Smckusick 				ftnint lencat();
47322836Smckusick 				expptr qvl;
47422836Smckusick 				qvl = NULL;
47522836Smckusick 				if( ISCHAR(qe) )
47622836Smckusick 					{
47722836Smckusick 					qvl = (expptr)
47822836Smckusick 						cpexpr(qe->headblock.vleng);
47922836Smckusick 					tp = mktemp(qe->headblock.vtype,
48022836Smckusick 						     ICON(lencat(qe)));
48122836Smckusick 					}
48222836Smckusick 				else
48322836Smckusick 					tp = mktemp(qe->headblock.vtype,
48422836Smckusick 						qe->headblock.vleng);
48522836Smckusick 				if (optimflag)
48622836Smckusick 					{
48722836Smckusick 					expr = mkexpr(OPASSIGN,cpexpr(tp),qe);
48822836Smckusick 					optbuff (SKEQ,expr,0,0);
48922836Smckusick 					}
49022836Smckusick 				else
49122836Smckusick 					puteq (cpexpr(tp),qe);
49222836Smckusick 				if(qvl)	/* put right length on block */
49322836Smckusick 					{
49422836Smckusick 					frexpr(tp->vleng);
49522836Smckusick 					tp->vleng = qvl;
49622836Smckusick 					}
49722836Smckusick 				putio(ICON(1), tp);
49822836Smckusick 				}
49922836Smckusick 			else
50022836Smckusick 				err("non-left side in READ list");
50122836Smckusick 			}
50222836Smckusick 		frexpr(q);
50322836Smckusick 		}
50422836Smckusick 	}
50522836Smckusick frchain( &p0 );
50622836Smckusick }
50722836Smckusick 
50822836Smckusick 
50922836Smckusick 
51022836Smckusick 
51122836Smckusick 
51222836Smckusick LOCAL putio(nelt, addr)
51322836Smckusick expptr nelt;
51422836Smckusick register expptr addr;
51522836Smckusick {
51622836Smckusick int type;
51722836Smckusick register expptr q;
51822836Smckusick 
51922836Smckusick type = addr->headblock.vtype;
52022836Smckusick if(ioformatted!=LISTDIRECTED && ISCOMPLEX(type) )
52122836Smckusick 	{
52222836Smckusick 	nelt = mkexpr(OPSTAR, ICON(2), nelt);
52322836Smckusick 	type -= (TYCOMPLEX-TYREAL);
52422836Smckusick 	}
52522836Smckusick 
52622836Smckusick /* pass a length with every item.  for noncharacter data, fake one */
52722836Smckusick if(type != TYCHAR)
52822836Smckusick 	{
52922836Smckusick 	addr->headblock.vtype = TYCHAR;
53022836Smckusick 	addr->headblock.vleng = ICON( typesize[type] );
53122836Smckusick 	}
53222836Smckusick 
53322836Smckusick nelt = fixtype( mkconv(TYLENG,nelt) );
53422836Smckusick if(ioformatted == LISTDIRECTED)
53522836Smckusick 	q = call3(TYINT, "do_lio", mkconv(TYLONG, ICON(type)), nelt, addr);
53622836Smckusick else
53722836Smckusick 	q = call2(TYINT, (ioformatted==FORMATTED ? "do_fio" : "do_uio"),
53822836Smckusick 		nelt, addr);
53922836Smckusick putiocall(q);
54022836Smckusick }
54122836Smckusick 
54222836Smckusick 
54322836Smckusick 
54422836Smckusick 
54522836Smckusick endio()
54622836Smckusick {
54722836Smckusick if(skiplab)
54822836Smckusick 	{
54922836Smckusick 	if (optimflag)
55022836Smckusick 		optbuff (SKLABEL, 0, skiplab, 0);
55122836Smckusick 	else
55222836Smckusick 		putlabel (skiplab);
55322836Smckusick 	if(ioendlab)
55422836Smckusick 		{
55522836Smckusick 		expptr test;
55622836Smckusick 		test = mkexpr(OPGE, cpexpr(IOSTP), ICON(0));
55722836Smckusick 		if (optimflag)
55822836Smckusick 			optbuff (SKIOIFN,test,ioendlab,0);
55922836Smckusick 		else
56022836Smckusick 			putif (test,ioendlab);
56122836Smckusick 		}
56222836Smckusick 	if(ioerrlab)
56322836Smckusick 		{
56422836Smckusick 		expptr test;
56522836Smckusick 		test = mkexpr
56622836Smckusick 			( ((iostmt==IOREAD||iostmt==IOWRITE) ? OPLE : OPEQ),
56722836Smckusick 			cpexpr(IOSTP), ICON(0));
56822836Smckusick 		if (optimflag)
56922836Smckusick 			optbuff (SKIOIFN,test,ioerrlab,0);
57022836Smckusick 		else
57122836Smckusick 			putif (test,ioerrlab);
57222836Smckusick 		}
57322836Smckusick 	}
57422836Smckusick if(IOSTP)
57522836Smckusick 	frexpr(IOSTP);
57622836Smckusick }
57722836Smckusick 
57822836Smckusick 
57922836Smckusick 
58022836Smckusick LOCAL putiocall(q)
58122836Smckusick register expptr q;
58222836Smckusick {
58322836Smckusick if(IOSTP)
58422836Smckusick 	{
58522836Smckusick 	q->headblock.vtype = TYINT;
58622836Smckusick 	q = fixexpr( mkexpr(OPASSIGN, cpexpr(IOSTP), q));
58722836Smckusick 	}
58822836Smckusick 
58922836Smckusick if(jumplab)
59022836Smckusick 	if (optimflag)
59122836Smckusick 		optbuff (SKIOIFN,mkexpr(OPEQ,q,ICON(0)),jumplab,0);
59222836Smckusick 	else
59322836Smckusick 		putif (mkexpr(OPEQ,q,ICON(0)),jumplab);
59422836Smckusick else
59522836Smckusick 	if (optimflag)
59622836Smckusick 		optbuff (SKEQ, q, 0, 0);
59722836Smckusick 	else
59822836Smckusick 		putexpr(q);
59922836Smckusick }
60022836Smckusick 
60122836Smckusick startrw()
60222836Smckusick {
60322836Smckusick register expptr p;
60422836Smckusick register Namep np;
60522836Smckusick register Addrp unitp, fmtp, recp, tioblkp;
60622836Smckusick register expptr nump;
60722836Smckusick register ioblock *t;
60822836Smckusick Addrp mkscalar();
60922836Smckusick expptr mkaddcon();
61022836Smckusick int k;
61122836Smckusick flag intfile, sequential, ok, varfmt;
61222836Smckusick 
61322836Smckusick /* First look at all the parameters and determine what is to be done */
61422836Smckusick 
61522836Smckusick ok = YES;
61622836Smckusick statstruct = YES;
61722836Smckusick 
61822836Smckusick intfile = NO;
61922836Smckusick if(p = V(IOSUNIT))
62022836Smckusick 	{
62122836Smckusick 	if( ISINT(p->headblock.vtype) )
62222836Smckusick 		unitp = (Addrp) cpexpr(p);
62322836Smckusick 	else if(p->headblock.vtype == TYCHAR)
62422836Smckusick 		{
62522836Smckusick 		intfile = YES;
62622836Smckusick 		if(p->tag==TPRIM && p->primblock.argsp==NULL &&
62722836Smckusick 		    (np = p->primblock.namep)->vdim!=NULL)
62822836Smckusick 			{
62922836Smckusick 			vardcl(np);
63022836Smckusick 			if(np->vdim->nelt)
63122836Smckusick 				{
63222836Smckusick 				nump = (expptr) cpexpr(np->vdim->nelt);
63322836Smckusick 				if( ! ISCONST(nump) )
63422836Smckusick 					statstruct = NO;
63522836Smckusick 				}
63622836Smckusick 			else
63722836Smckusick 				{
63822836Smckusick 				err("attempt to use internal unit array of unknown size");
63922836Smckusick 				ok = NO;
64022836Smckusick 				nump = ICON(1);
64122836Smckusick 				}
64222836Smckusick 			unitp = mkscalar(np);
64322836Smckusick 			}
64422836Smckusick 		else	{
64522836Smckusick 			nump = ICON(1);
64622836Smckusick 			unitp = (Addrp) fixtype(cpexpr(p));
64722836Smckusick 			}
64822836Smckusick 		if(! isstatic(unitp) )
64922836Smckusick 			statstruct = NO;
65022836Smckusick 		}
65122836Smckusick 	else
65222836Smckusick 		{
65322836Smckusick 		err("bad unit specifier type");
65422836Smckusick 		ok = NO;
65522836Smckusick 		}
65622836Smckusick 	}
65722836Smckusick else
65822836Smckusick 	{
65922836Smckusick 	err("bad unit specifier");
66022836Smckusick 	ok = NO;
66122836Smckusick 	}
66222836Smckusick 
66322836Smckusick sequential = YES;
66422836Smckusick if(p = V(IOSREC))
66522836Smckusick 	if( ISINT(p->headblock.vtype) )
66622836Smckusick 		{
66722836Smckusick 		recp = (Addrp) cpexpr(p);
66822836Smckusick 		sequential = NO;
66922836Smckusick 		}
67022836Smckusick 	else	{
67122836Smckusick 		err("bad REC= clause");
67222836Smckusick 		ok = NO;
67322836Smckusick 		}
67422836Smckusick else
67522836Smckusick 	recp = NULL;
67622836Smckusick 
67722836Smckusick 
67822836Smckusick varfmt = YES;
67922836Smckusick fmtp = NULL;
68022836Smckusick if(p = V(IOSFMT))
68122836Smckusick 	{
68222836Smckusick 	if(p->tag==TPRIM && p->primblock.argsp==NULL)
68322836Smckusick 		{
68422836Smckusick 		np = p->primblock.namep;
68522836Smckusick 		if(np->vclass == CLNAMELIST)
68622836Smckusick 			{
68722836Smckusick 			ioformatted = NAMEDIRECTED;
68822836Smckusick 			fmtp = (Addrp) fixtype(cpexpr(p));
68922836Smckusick 			goto endfmt;
69022836Smckusick 			}
69122836Smckusick 		vardcl(np);
69222836Smckusick 		if(np->vdim)
69322836Smckusick 			{
69422836Smckusick 			if( ! ONEOF(np->vstg, MSKSTATIC) )
69522836Smckusick 				statstruct = NO;
69622836Smckusick 			fmtp = mkscalar(np);
69722836Smckusick 			goto endfmt;
69822836Smckusick 			}
69922836Smckusick 		if( ISINT(np->vtype) )	/* ASSIGNed label */
70022836Smckusick 			{
70122836Smckusick 			statstruct = NO;
70222836Smckusick 			varfmt = NO;
70322836Smckusick 			fmtp = (Addrp) fixtype(cpexpr(p));
70422836Smckusick 			goto endfmt;
70522836Smckusick 			}
70622836Smckusick 		}
70722836Smckusick 	p = V(IOSFMT) = fixtype(p);
70822836Smckusick 	if(p->headblock.vtype == TYCHAR)
70922836Smckusick 		{
71022836Smckusick 		if (p->tag == TCONST) p = (expptr) putconst(p);
71122836Smckusick 		if( ! isstatic(p) )
71222836Smckusick 			statstruct = NO;
71322836Smckusick 		fmtp = (Addrp) cpexpr(p);
71422836Smckusick 		}
71522836Smckusick 	else if( ISICON(p) )
71622836Smckusick 		{
71722836Smckusick 		if( (k = fmtstmt( mklabel(p->constblock.const.ci) )) > 0 )
71822836Smckusick 			{
71922836Smckusick 			fmtp = (Addrp) mkaddcon(k);
72022836Smckusick 			varfmt = NO;
72122836Smckusick 			}
72222836Smckusick 		else
72322836Smckusick 			ioformatted = UNFORMATTED;
72422836Smckusick 		}
72522836Smckusick 	else	{
72622836Smckusick 		err("bad format descriptor");
72722836Smckusick 		ioformatted = UNFORMATTED;
72822836Smckusick 		ok = NO;
72922836Smckusick 		}
73022836Smckusick 	}
73122836Smckusick else
73222836Smckusick 	fmtp = NULL;
73322836Smckusick 
73422836Smckusick endfmt:
73522836Smckusick 	if(intfile && ioformatted==UNFORMATTED)
73622836Smckusick 		{
73722836Smckusick 		err("unformatted internal I/O not allowed");
73822836Smckusick 		ok = NO;
73922836Smckusick 		}
74022836Smckusick 	if(!sequential && ioformatted==LISTDIRECTED)
74122836Smckusick 		{
74222836Smckusick 		err("direct list-directed I/O not allowed");
74322836Smckusick 		ok = NO;
74422836Smckusick 		}
74522836Smckusick 	if(!sequential && ioformatted==NAMEDIRECTED)
74622836Smckusick 		{
74722836Smckusick 		err("direct namelist I/O not allowed");
74822836Smckusick 		ok = NO;
74922836Smckusick 		}
75022836Smckusick 
75122836Smckusick if( ! ok )
75222836Smckusick 	return;
75322836Smckusick 
75422836Smckusick if (optimflag && ISCONST (fmtp))
75522836Smckusick 	fmtp = putconst ( (expptr) fmtp);
75622836Smckusick 
75722836Smckusick /*
75822836Smckusick    Now put out the I/O structure, statically if all the clauses
75922836Smckusick    are constants, dynamically otherwise
76022836Smckusick */
76122836Smckusick 
76222836Smckusick if(statstruct)
76322836Smckusick 	{
76422836Smckusick 	tioblkp = ioblkp;
76522836Smckusick 	ioblkp = ALLOC(Addrblock);
76622836Smckusick 	ioblkp->tag = TADDR;
76722836Smckusick 	ioblkp->vtype = TYIOINT;
76822836Smckusick 	ioblkp->vclass = CLVAR;
76922836Smckusick 	ioblkp->vstg = STGINIT;
77022836Smckusick 	ioblkp->memno = ++lastvarno;
77122836Smckusick 	ioblkp->memoffset = ICON(0);
77222836Smckusick 	blklen = (intfile ? XIREC+SZIOINT :
77322836Smckusick 			(sequential ? XFMT+SZADDR : XRNUM+SZIOINT) );
77422836Smckusick 	t = ALLOC(IoBlock);
77522836Smckusick 	t->blkno = ioblkp->memno;
77622836Smckusick 	t->len = blklen;
77722836Smckusick 	t->next = iodata;
77822836Smckusick 	iodata = t;
77922836Smckusick 	}
78022836Smckusick else if(ioblkp == NULL)
78122836Smckusick 	ioblkp = autovar( (MAXIO+SZIOINT-1)/SZIOINT , TYIOINT, PNULL);
78222836Smckusick 
78322836Smckusick ioset(TYIOINT, XERR, ICON(errbit));
78422836Smckusick if(iostmt == IOREAD)
78522836Smckusick 	ioset(TYIOINT, (intfile ? XIEND : XEND), ICON(endbit) );
78622836Smckusick 
78722836Smckusick if(intfile)
78822836Smckusick 	{
78922836Smckusick 	ioset(TYIOINT, XIRNUM, nump);
79022836Smckusick 	ioset(TYIOINT, XIRLEN, cpexpr(unitp->vleng) );
79122836Smckusick 	ioseta(XIUNIT, unitp);
79222836Smckusick 	}
79322836Smckusick else
79422836Smckusick 	ioset(TYIOINT, XUNIT, (expptr) unitp);
79522836Smckusick 
79622836Smckusick if(recp)
79722836Smckusick 	ioset(TYIOINT, (intfile ? XIREC : XREC) , (expptr) recp);
79822836Smckusick 
79922836Smckusick if(varfmt)
80022836Smckusick 	ioseta( intfile ? XIFMT : XFMT , fmtp);
80122836Smckusick else
80222836Smckusick 	ioset(TYADDR, intfile ? XIFMT : XFMT, (expptr) fmtp);
80322836Smckusick 
80422836Smckusick ioroutine[0] = 's';
80522836Smckusick ioroutine[1] = '_';
80622836Smckusick ioroutine[2] = (iostmt==IOREAD ? 'r' : 'w');
80722836Smckusick ioroutine[3] = (sequential ? 's' : 'd');
80822836Smckusick ioroutine[4] = "ufln" [ioformatted];
80922836Smckusick ioroutine[5] = (intfile ? 'i' : 'e');
81022836Smckusick ioroutine[6] = '\0';
81122836Smckusick 
81222836Smckusick putiocall( call1(TYINT, ioroutine, cpexpr(ioblkp) ));
81322836Smckusick 
81422836Smckusick if(statstruct)
81522836Smckusick 	{
81622836Smckusick 	frexpr(ioblkp);
81722836Smckusick 	ioblkp = tioblkp;
81822836Smckusick 	statstruct = NO;
81922836Smckusick 	}
82022836Smckusick }
82122836Smckusick 
82222836Smckusick 
82322836Smckusick 
82422836Smckusick LOCAL dofopen()
82522836Smckusick {
82622836Smckusick register expptr p;
82722836Smckusick 
82822836Smckusick if( (p = V(IOSUNIT)) && ISINT(p->headblock.vtype) )
82922836Smckusick 	ioset(TYIOINT, XUNIT, cpexpr(p) );
83022836Smckusick else
83122836Smckusick 	err("bad unit in open");
83222836Smckusick if( (p = V(IOSFILE)) )
83322836Smckusick 	if(p->headblock.vtype == TYCHAR)
83422836Smckusick 		ioset(TYIOINT, XFNAMELEN, cpexpr(p->headblock.vleng) );
83522836Smckusick 	else
83622836Smckusick 		err("bad file in open");
83722836Smckusick 
83822836Smckusick iosetc(XFNAME, p);
83922836Smckusick 
84022836Smckusick if(p = V(IOSRECL))
84122836Smckusick 	if( ISINT(p->headblock.vtype) )
84222836Smckusick 		ioset(TYIOINT, XRECLEN, cpexpr(p) );
84322836Smckusick 	else
84422836Smckusick 		err("bad recl");
84522836Smckusick else
84622836Smckusick 	ioset(TYIOINT, XRECLEN, ICON(0) );
84722836Smckusick 
84822836Smckusick iosetc(XSTATUS, V(IOSSTATUS));
84922836Smckusick iosetc(XACCESS, V(IOSACCESS));
85022836Smckusick iosetc(XFORMATTED, V(IOSFORM));
85122836Smckusick iosetc(XBLANK, V(IOSBLANK));
85222836Smckusick 
85322836Smckusick putiocall( call1(TYINT, "f_open", cpexpr(ioblkp) ));
85422836Smckusick }
85522836Smckusick 
85622836Smckusick 
85722836Smckusick LOCAL dofclose()
85822836Smckusick {
85922836Smckusick register expptr p;
86022836Smckusick 
86122836Smckusick if( (p = V(IOSUNIT)) && ISINT(p->headblock.vtype) )
86222836Smckusick 	{
86322836Smckusick 	ioset(TYIOINT, XUNIT, cpexpr(p) );
86422836Smckusick 	iosetc(XCLSTATUS, V(IOSSTATUS));
86522836Smckusick 	putiocall( call1(TYINT, "f_clos", cpexpr(ioblkp)) );
86622836Smckusick 	}
86722836Smckusick else
86822836Smckusick 	err("bad unit in close statement");
86922836Smckusick }
87022836Smckusick 
87122836Smckusick 
87222836Smckusick LOCAL dofinquire()
87322836Smckusick {
87422836Smckusick register expptr p;
87522836Smckusick if(p = V(IOSUNIT))
87622836Smckusick 	{
87722836Smckusick 	if( V(IOSFILE) )
87822836Smckusick 		err("inquire by unit or by file, not both");
87922836Smckusick 	ioset(TYIOINT, XUNIT, cpexpr(p) );
88022836Smckusick 	}
88122836Smckusick else if( ! V(IOSFILE) )
88222836Smckusick 	err("must inquire by unit or by file");
88322836Smckusick iosetlc(IOSFILE, XFILE, XFILELEN);
88422836Smckusick iosetip(IOSEXISTS, XEXISTS);
88522836Smckusick iosetip(IOSOPENED, XOPEN);
88622836Smckusick iosetip(IOSNUMBER, XNUMBER);
88722836Smckusick iosetip(IOSNAMED, XNAMED);
88822836Smckusick iosetlc(IOSNAME, XNAME, XNAMELEN);
88922836Smckusick iosetlc(IOSACCESS, XQACCESS, XQACCLEN);
89022836Smckusick iosetlc(IOSSEQUENTIAL, XSEQ, XSEQLEN);
89122836Smckusick iosetlc(IOSDIRECT, XDIRECT, XDIRLEN);
89222836Smckusick iosetlc(IOSFORM, XFORM, XFORMLEN);
89322836Smckusick iosetlc(IOSFORMATTED, XFMTED, XFMTEDLEN);
89422836Smckusick iosetlc(IOSUNFORMATTED, XUNFMT, XUNFMTLEN);
89522836Smckusick iosetip(IOSRECL, XQRECL);
89622836Smckusick iosetip(IOSNEXTREC, XNEXTREC);
89722836Smckusick iosetlc(IOSBLANK, XQBLANK, XQBLANKLEN);
89822836Smckusick 
89922836Smckusick putiocall( call1(TYINT,  "f_inqu", cpexpr(ioblkp) ));
90022836Smckusick }
90122836Smckusick 
90222836Smckusick 
90322836Smckusick 
90422836Smckusick LOCAL dofmove(subname)
90522836Smckusick char *subname;
90622836Smckusick {
90722836Smckusick register expptr p;
90822836Smckusick 
90922836Smckusick if( (p = V(IOSUNIT)) && ISINT(p->headblock.vtype) )
91022836Smckusick 	{
91122836Smckusick 	ioset(TYIOINT, XUNIT, cpexpr(p) );
91222836Smckusick 	putiocall( call1(TYINT, subname, cpexpr(ioblkp) ));
91322836Smckusick 	}
91422836Smckusick else
91522836Smckusick 	err("bad unit in I/O motion statement");
91622836Smckusick }
91722836Smckusick 
91822836Smckusick 
91922836Smckusick 
92022836Smckusick LOCAL
92122836Smckusick ioset(type, offset, p)
92222836Smckusick int type;
92322836Smckusick int offset;
92422836Smckusick register expptr p;
92522836Smckusick {
92622836Smckusick   static char *badoffset = "badoffset in ioset";
92722836Smckusick 
92822836Smckusick   register Addrp q;
92922836Smckusick   register offsetlist *op;
93022836Smckusick 
93122836Smckusick   q = (Addrp) cpexpr(ioblkp);
93222836Smckusick   q->vtype = type;
93322836Smckusick   q->memoffset = fixtype( mkexpr(OPPLUS, q->memoffset, ICON(offset)) );
93422836Smckusick 
93522836Smckusick   if (statstruct && ISCONST(p))
93622836Smckusick     {
93722836Smckusick       if (!ISICON(q->memoffset))
93822836Smckusick 	fatal(badoffset);
93922836Smckusick 
94022836Smckusick       op = mkiodata(q->memno, q->memoffset->constblock.const.ci, blklen);
94122836Smckusick       if (op->tag != 0)
94222836Smckusick 	fatal(badoffset);
94322836Smckusick 
94422836Smckusick       if (type == TYADDR)
94522836Smckusick 	{
94622836Smckusick 	  op->tag = NDLABEL;
94722836Smckusick 	  op->val.label = p->constblock.const.ci;
94822836Smckusick 	}
94922836Smckusick       else
95022836Smckusick 	{
95122836Smckusick 	  op->tag = NDDATA;
95222836Smckusick 	  op->val.cp = (Constp) convconst(type, 0, p);
95322836Smckusick 	}
95422836Smckusick 
95522836Smckusick       frexpr((tagptr) p);
95622836Smckusick       frexpr((tagptr) q);
95722836Smckusick     }
95822836Smckusick   else
95922836Smckusick     if (optimflag)
96022836Smckusick       optbuff (SKEQ, mkexpr(OPASSIGN,q,p), 0,0);
96122836Smckusick     else
96222836Smckusick       puteq (q,p);
96322836Smckusick 
96422836Smckusick   return;
96522836Smckusick }
96622836Smckusick 
96722836Smckusick 
96822836Smckusick 
96922836Smckusick 
97022836Smckusick LOCAL iosetc(offset, p)
97122836Smckusick int offset;
97222836Smckusick register expptr p;
97322836Smckusick {
97422836Smckusick if(p == NULL)
97522836Smckusick 	ioset(TYADDR, offset, ICON(0) );
97622836Smckusick else if(p->headblock.vtype == TYCHAR)
97722836Smckusick 	ioset(TYADDR, offset, addrof(cpexpr(p) ));
97822836Smckusick else
97922836Smckusick 	err("non-character control clause");
98022836Smckusick }
98122836Smckusick 
98222836Smckusick 
98322836Smckusick 
98422836Smckusick LOCAL ioseta(offset, p)
98522836Smckusick int offset;
98622836Smckusick register Addrp p;
98722836Smckusick {
98822836Smckusick   static char *badoffset = "bad offset in ioseta";
98922836Smckusick 
99022836Smckusick   int blkno;
99122836Smckusick   register offsetlist *op;
99222836Smckusick 
99322836Smckusick   if(statstruct)
99422836Smckusick     {
99522836Smckusick       blkno = ioblkp->memno;
99622836Smckusick       op = mkiodata(blkno, offset, blklen);
99722836Smckusick       if (op->tag != 0)
99822836Smckusick 	fatal(badoffset);
99922836Smckusick 
100022836Smckusick       if (p == NULL)
100122836Smckusick 	op->tag = NDNULL;
100222836Smckusick       else if (p->tag == TADDR)
100322836Smckusick 	{
100422836Smckusick 	  op->tag = NDADDR;
100522836Smckusick 	  op->val.addr.stg = p->vstg;
100622836Smckusick 	  op->val.addr.memno = p->memno;
100722836Smckusick 	  op->val.addr.offset = p->memoffset->constblock.const.ci;
100822836Smckusick 	}
100922836Smckusick       else
101022836Smckusick 	badtag("ioseta", p->tag);
101122836Smckusick     }
101222836Smckusick   else
101322836Smckusick     ioset(TYADDR, offset, p ? addrof(p) : ICON(0) );
101422836Smckusick 
101522836Smckusick   return;
101622836Smckusick }
101722836Smckusick 
101822836Smckusick 
101922836Smckusick 
102022836Smckusick 
102122836Smckusick LOCAL iosetip(i, offset)
102222836Smckusick int i, offset;
102322836Smckusick {
102422836Smckusick register expptr p;
102522836Smckusick 
102622836Smckusick if(p = V(i))
102722836Smckusick 	if(p->tag==TADDR &&
102822836Smckusick 	    ONEOF(p->addrblock.vtype, M(TYLONG)|M(TYLOGICAL)) )
102922836Smckusick 		ioset(TYADDR, offset, addrof(cpexpr(p)) );
103022836Smckusick 	else
103122836Smckusick 		errstr("impossible inquire parameter %s", ioc[i].iocname);
103222836Smckusick else
103322836Smckusick 	ioset(TYADDR, offset, ICON(0) );
103422836Smckusick }
103522836Smckusick 
103622836Smckusick 
103722836Smckusick 
103822836Smckusick LOCAL iosetlc(i, offp, offl)
103922836Smckusick int i, offp, offl;
104022836Smckusick {
104122836Smckusick register expptr p;
104222836Smckusick if( (p = V(i)) && p->headblock.vtype==TYCHAR)
104322836Smckusick 	ioset(TYIOINT, offl, cpexpr(p->headblock.vleng) );
104422836Smckusick iosetc(offp, p);
104522836Smckusick }
104622836Smckusick 
104722836Smckusick 
104822836Smckusick LOCAL offsetlist *
104922836Smckusick mkiodata(blkno, offset, len)
105022836Smckusick int blkno;
105122836Smckusick ftnint offset;
105222836Smckusick ftnint len;
105322836Smckusick {
105422836Smckusick   register offsetlist *p, *q;
105522836Smckusick   register ioblock *t;
105622836Smckusick   register int found;
105722836Smckusick 
105822836Smckusick   found = NO;
105922836Smckusick   t = iodata;
106022836Smckusick 
106122836Smckusick   while (found == NO && t != NULL)
106222836Smckusick     {
106322836Smckusick       if (t->blkno == blkno)
106422836Smckusick 	found = YES;
106522836Smckusick       else
106622836Smckusick 	t = t->next;
106722836Smckusick     }
106822836Smckusick 
106922836Smckusick   if (found == NO)
107022836Smckusick     {
107122836Smckusick       t = ALLOC(IoBlock);
107222836Smckusick       t->blkno = blkno;
107322836Smckusick       t->next = iodata;
107422836Smckusick       iodata = t;
107522836Smckusick     }
107622836Smckusick 
107722836Smckusick   if (len > t->len)
107822836Smckusick     t->len = len;
107922836Smckusick 
108022836Smckusick   p = t->olist;
108122836Smckusick 
108222836Smckusick   if (p == NULL)
108322836Smckusick     {
108422836Smckusick       p = ALLOC(OffsetList);
108522836Smckusick       p->next = NULL;
108622836Smckusick       p->offset = offset;
108722836Smckusick       t->olist = p;
108822836Smckusick       return (p);
108922836Smckusick     }
109022836Smckusick 
109122836Smckusick   for (;;)
109222836Smckusick     {
109322836Smckusick       if (p->offset == offset)
109422836Smckusick 	return (p);
109522836Smckusick       else if (p->next != NULL &&
109622836Smckusick 	       p->next->offset <= offset)
109722836Smckusick 	p = p->next;
109822836Smckusick       else
109922836Smckusick 	{
110022836Smckusick 	  q = ALLOC(OffsetList);
110122836Smckusick 	  q->next = p->next;
110222836Smckusick 	  p->next = q;
110322836Smckusick 	  q->offset = offset;
110422836Smckusick 	  return (q);
110522836Smckusick 	}
110622836Smckusick     }
110722836Smckusick }
110822836Smckusick 
110922836Smckusick 
111022836Smckusick outiodata()
111122836Smckusick {
111222836Smckusick   static char *varfmt = "v.%d:\n";
111322836Smckusick 
111422836Smckusick   register ioblock *p;
111522836Smckusick   register ioblock *t;
111622836Smckusick 
111722836Smckusick   if (iodata == NULL) return;
111822836Smckusick 
111922836Smckusick   p = iodata;
112022836Smckusick 
112122836Smckusick   while (p != NULL)
112222836Smckusick     {
112322836Smckusick       pralign(ALIDOUBLE);
112422836Smckusick       fprintf(initfile, varfmt, p->blkno);
112522836Smckusick       outolist(p->olist, p->len);
112622836Smckusick 
112722836Smckusick       t = p;
112822836Smckusick       p = t->next;
112922836Smckusick       free((char *) t);
113022836Smckusick     }
113122836Smckusick 
113222836Smckusick   iodata = NULL;
113322836Smckusick   return;
113422836Smckusick }
113522836Smckusick 
113622836Smckusick 
113722836Smckusick 
113822836Smckusick LOCAL
113922836Smckusick outolist(op, len)
114022836Smckusick register offsetlist *op;
114122836Smckusick register int len;
114222836Smckusick {
114322836Smckusick   static char *overlap = "overlapping i/o fields in outolist";
114422836Smckusick   static char *toolong = "offset too large in outolist";
114522836Smckusick 
114622836Smckusick   register offsetlist *t;
114722836Smckusick   register ftnint clen;
114822836Smckusick   register Constp cp;
114922836Smckusick   register int type;
115022836Smckusick 
115122836Smckusick   clen = 0;
115222836Smckusick 
115322836Smckusick   while (op != NULL)
115422836Smckusick     {
115522836Smckusick       if (clen > op->offset)
115622836Smckusick 	fatal(overlap);
115722836Smckusick 
115822836Smckusick       if (clen < op->offset)
115922836Smckusick 	{
116022836Smckusick 	  prspace(op->offset - clen);
116122836Smckusick 	  clen = op->offset;
116222836Smckusick 	}
116322836Smckusick 
116422836Smckusick       switch (op->tag)
116522836Smckusick 	{
116622836Smckusick 	default:
116722836Smckusick 	  badtag("outolist", op->tag);
116822836Smckusick 
116922836Smckusick 	case NDDATA:
117022836Smckusick 	  cp = op->val.cp;
117122836Smckusick 	  type = cp->vtype;
117222836Smckusick 	  if (type != TYIOINT)
117322836Smckusick 	    badtype("outolist", type);
117422836Smckusick 	  prconi(initfile, type, cp->const.ci);
117522836Smckusick 	  clen += typesize[type];
117622836Smckusick 	  frexpr((tagptr) cp);
117722836Smckusick 	  break;
117822836Smckusick 
117922836Smckusick 	case NDLABEL:
118022836Smckusick 	  prcona(initfile, op->val.label);
118122836Smckusick 	  clen += typesize[TYADDR];
118222836Smckusick 	  break;
118322836Smckusick 
118422836Smckusick 	case NDADDR:
118522836Smckusick 	  praddr(initfile, op->val.addr.stg, op->val.addr.memno,
118622836Smckusick 		 op->val.addr.offset);
118722836Smckusick 	  clen += typesize[TYADDR];
118822836Smckusick 	  break;
118922836Smckusick 
119022836Smckusick 	case NDNULL:
119122836Smckusick 	  praddr(initfile, STGNULL, 0, (ftnint) 0);
119222836Smckusick 	  clen += typesize[TYADDR];
119322836Smckusick 	  break;
119422836Smckusick 	}
119522836Smckusick 
119622836Smckusick       t = op;
119722836Smckusick       op = t->next;
119822836Smckusick       free((char *) t);
119922836Smckusick     }
120022836Smckusick 
120122836Smckusick   if (clen > len)
120222836Smckusick     fatal(toolong);
120322836Smckusick 
120422836Smckusick   if (clen < len)
120522836Smckusick     prspace(len - clen);
120622836Smckusick 
120722836Smckusick   return;
120822836Smckusick }
1209