xref: /csrg-svn/usr.bin/f77/pass1.tahoe/io.c (revision 47951)
1*47951Sbostic /*-
2*47951Sbostic  * Copyright (c) 1980 The Regents of the University of California.
3*47951Sbostic  * All rights reserved.
4*47951Sbostic  *
5*47951Sbostic  * %sccs.include.proprietary.c%
643213Sbostic  */
743213Sbostic 
843213Sbostic #ifndef lint
9*47951Sbostic static char sccsid[] = "@(#)io.c	5.3 (Berkeley) 04/12/91";
10*47951Sbostic #endif /* not lint */
1143213Sbostic 
1243213Sbostic /*
1343213Sbostic  * io.c
1443213Sbostic  *
1543213Sbostic  * Routines to generate code for I/O statements.
1643213Sbostic  * Some corrections and improvements due to David Wasley, U. C. Berkeley
1743213Sbostic  *
1843213Sbostic  * University of Utah CS Dept modification history:
1943213Sbostic  *
2043213Sbostic  * $Header: io.c,v 2.4 85/02/23 21:09:02 donn Exp $
2143213Sbostic  * $Log:	io.c,v $
2243213Sbostic  * Revision 2.4  85/02/23  21:09:02  donn
2343213Sbostic  * Jerry Berkman's compiled format fixes move setfmt into a separate file.
2443213Sbostic  *
2543213Sbostic  * Revision 2.3  85/01/10  22:33:41  donn
2643213Sbostic  * Added some strategic cpexpr()s to prevent memory management bugs.
2743213Sbostic  *
2843213Sbostic  * Revision 2.2  84/08/04  21:15:47  donn
2943213Sbostic  * Removed code that creates extra statement labels, per Jerry Berkman's
3043213Sbostic  * fixes to make ASSIGNs work right.
3143213Sbostic  *
3243213Sbostic  * Revision 2.1  84/07/19  12:03:33  donn
3343213Sbostic  * Changed comment headers for UofU.
3443213Sbostic  *
3543213Sbostic  * Revision 1.2  84/02/26  06:35:57  donn
3643213Sbostic  * Added Berkeley changes necessary for shortening offsets to data.
3743213Sbostic  *
3843213Sbostic  */
3943213Sbostic 
4043213Sbostic /* TEMPORARY */
4143213Sbostic #define TYIOINT TYLONG
4243213Sbostic #define SZIOINT SZLONG
4343213Sbostic 
4443213Sbostic #include "defs.h"
4543213Sbostic #include "io.h"
4643213Sbostic 
4743213Sbostic 
4843213Sbostic LOCAL char ioroutine[XL+1];
4943213Sbostic 
5043213Sbostic LOCAL int ioendlab;
5143213Sbostic LOCAL int ioerrlab;
5243213Sbostic LOCAL int endbit;
5343213Sbostic LOCAL int errbit;
5443213Sbostic LOCAL int jumplab;
5543213Sbostic LOCAL int skiplab;
5643213Sbostic LOCAL int ioformatted;
5743213Sbostic LOCAL int statstruct = NO;
5843213Sbostic LOCAL ftnint blklen;
5943213Sbostic 
6043213Sbostic LOCAL offsetlist *mkiodata();
6143213Sbostic 
6243213Sbostic 
6343213Sbostic #define UNFORMATTED 0
6443213Sbostic #define FORMATTED 1
6543213Sbostic #define LISTDIRECTED 2
6643213Sbostic #define NAMEDIRECTED 3
6743213Sbostic 
6843213Sbostic #define V(z)	ioc[z].iocval
6943213Sbostic 
7043213Sbostic #define IOALL 07777
7143213Sbostic 
7243213Sbostic LOCAL struct Ioclist
7343213Sbostic 	{
7443213Sbostic 	char *iocname;
7543213Sbostic 	int iotype;
7643213Sbostic 	expptr iocval;
7743213Sbostic 	} ioc[ ] =
7843213Sbostic 	{
7943213Sbostic 		{ "", 0 },
8043213Sbostic 		{ "unit", IOALL },
8143213Sbostic 		{ "fmt", M(IOREAD) | M(IOWRITE) },
8243213Sbostic 		{ "err", IOALL },
8343213Sbostic 		{ "end", M(IOREAD) },
8443213Sbostic 		{ "iostat", IOALL },
8543213Sbostic 		{ "rec", M(IOREAD) | M(IOWRITE) },
8643213Sbostic 		{ "recl", M(IOOPEN) | M(IOINQUIRE) },
8743213Sbostic 		{ "file", M(IOOPEN) | M(IOINQUIRE) },
8843213Sbostic 		{ "status", M(IOOPEN) | M(IOCLOSE) },
8943213Sbostic 		{ "access", M(IOOPEN) | M(IOINQUIRE) },
9043213Sbostic 		{ "form", M(IOOPEN) | M(IOINQUIRE) },
9143213Sbostic 		{ "blank", M(IOOPEN) | M(IOINQUIRE) },
9243213Sbostic 		{ "exist", M(IOINQUIRE) },
9343213Sbostic 		{ "opened", M(IOINQUIRE) },
9443213Sbostic 		{ "number", M(IOINQUIRE) },
9543213Sbostic 		{ "named", M(IOINQUIRE) },
9643213Sbostic 		{ "name", M(IOINQUIRE) },
9743213Sbostic 		{ "sequential", M(IOINQUIRE) },
9843213Sbostic 		{ "direct", M(IOINQUIRE) },
9943213Sbostic 		{ "formatted", M(IOINQUIRE) },
10043213Sbostic 		{ "unformatted", M(IOINQUIRE) },
10143213Sbostic 		{ "nextrec", M(IOINQUIRE) }
10243213Sbostic 	} ;
10343213Sbostic 
10443213Sbostic #define NIOS (sizeof(ioc)/sizeof(struct Ioclist) - 1)
10543213Sbostic #define MAXIO	SZFLAG + 10*SZIOINT + 15*SZADDR
10643213Sbostic 
10743213Sbostic #define IOSUNIT 1
10843213Sbostic #define IOSFMT 2
10943213Sbostic #define IOSERR 3
11043213Sbostic #define IOSEND 4
11143213Sbostic #define IOSIOSTAT 5
11243213Sbostic #define IOSREC 6
11343213Sbostic #define IOSRECL 7
11443213Sbostic #define IOSFILE 8
11543213Sbostic #define IOSSTATUS 9
11643213Sbostic #define IOSACCESS 10
11743213Sbostic #define IOSFORM 11
11843213Sbostic #define IOSBLANK 12
11943213Sbostic #define IOSEXISTS 13
12043213Sbostic #define IOSOPENED 14
12143213Sbostic #define IOSNUMBER 15
12243213Sbostic #define IOSNAMED 16
12343213Sbostic #define IOSNAME 17
12443213Sbostic #define IOSSEQUENTIAL 18
12543213Sbostic #define IOSDIRECT 19
12643213Sbostic #define IOSFORMATTED 20
12743213Sbostic #define IOSUNFORMATTED 21
12843213Sbostic #define IOSNEXTREC 22
12943213Sbostic 
13043213Sbostic #define IOSTP V(IOSIOSTAT)
13143213Sbostic 
13243213Sbostic 
13343213Sbostic /* offsets in generated structures */
13443213Sbostic 
13543213Sbostic #define SZFLAG SZIOINT
13643213Sbostic 
13743213Sbostic /* offsets for external READ and WRITE statements */
13843213Sbostic 
13943213Sbostic #define XERR 0
14043213Sbostic #define XUNIT	SZFLAG
14143213Sbostic #define XEND	SZFLAG + SZIOINT
14243213Sbostic #define XFMT	2*SZFLAG + SZIOINT
14343213Sbostic #define XREC	2*SZFLAG + SZIOINT + SZADDR
14443213Sbostic #define XRLEN	2*SZFLAG + 2*SZADDR
14543213Sbostic #define XRNUM	2*SZFLAG + 2*SZADDR + SZIOINT
14643213Sbostic 
14743213Sbostic /* offsets for internal READ and WRITE statements */
14843213Sbostic 
14943213Sbostic #define XIERR	0
15043213Sbostic #define XIUNIT	SZFLAG
15143213Sbostic #define XIEND	SZFLAG + SZADDR
15243213Sbostic #define XIFMT	2*SZFLAG + SZADDR
15343213Sbostic #define XIRLEN	2*SZFLAG + 2*SZADDR
15443213Sbostic #define XIRNUM	2*SZFLAG + 2*SZADDR + SZIOINT
15543213Sbostic #define XIREC	2*SZFLAG + 2*SZADDR + 2*SZIOINT
15643213Sbostic 
15743213Sbostic /* offsets for OPEN statements */
15843213Sbostic 
15943213Sbostic #define XFNAME	SZFLAG + SZIOINT
16043213Sbostic #define XFNAMELEN	SZFLAG + SZIOINT + SZADDR
16143213Sbostic #define XSTATUS	SZFLAG + 2*SZIOINT + SZADDR
16243213Sbostic #define XACCESS	SZFLAG + 2*SZIOINT + 2*SZADDR
16343213Sbostic #define XFORMATTED	SZFLAG + 2*SZIOINT + 3*SZADDR
16443213Sbostic #define XRECLEN	SZFLAG + 2*SZIOINT + 4*SZADDR
16543213Sbostic #define XBLANK	SZFLAG + 3*SZIOINT + 4*SZADDR
16643213Sbostic 
16743213Sbostic /* offset for CLOSE statement */
16843213Sbostic 
16943213Sbostic #define XCLSTATUS	SZFLAG + SZIOINT
17043213Sbostic 
17143213Sbostic /* offsets for INQUIRE statement */
17243213Sbostic 
17343213Sbostic #define XFILE	SZFLAG + SZIOINT
17443213Sbostic #define XFILELEN	SZFLAG + SZIOINT + SZADDR
17543213Sbostic #define XEXISTS	SZFLAG + 2*SZIOINT + SZADDR
17643213Sbostic #define XOPEN	SZFLAG + 2*SZIOINT + 2*SZADDR
17743213Sbostic #define XNUMBER	SZFLAG + 2*SZIOINT + 3*SZADDR
17843213Sbostic #define XNAMED	SZFLAG + 2*SZIOINT + 4*SZADDR
17943213Sbostic #define XNAME	SZFLAG + 2*SZIOINT + 5*SZADDR
18043213Sbostic #define XNAMELEN	SZFLAG + 2*SZIOINT + 6*SZADDR
18143213Sbostic #define XQACCESS	SZFLAG + 3*SZIOINT + 6*SZADDR
18243213Sbostic #define XQACCLEN	SZFLAG + 3*SZIOINT + 7*SZADDR
18343213Sbostic #define XSEQ	SZFLAG + 4*SZIOINT + 7*SZADDR
18443213Sbostic #define XSEQLEN	SZFLAG + 4*SZIOINT + 8*SZADDR
18543213Sbostic #define XDIRECT	SZFLAG + 5*SZIOINT + 8*SZADDR
18643213Sbostic #define XDIRLEN	SZFLAG + 5*SZIOINT + 9*SZADDR
18743213Sbostic #define XFORM	SZFLAG + 6*SZIOINT + 9*SZADDR
18843213Sbostic #define XFORMLEN	SZFLAG + 6*SZIOINT + 10*SZADDR
18943213Sbostic #define XFMTED	SZFLAG + 7*SZIOINT + 10*SZADDR
19043213Sbostic #define XFMTEDLEN	SZFLAG + 7*SZIOINT + 11*SZADDR
19143213Sbostic #define XUNFMT	SZFLAG + 8*SZIOINT + 11*SZADDR
19243213Sbostic #define XUNFMTLEN	SZFLAG + 8*SZIOINT + 12*SZADDR
19343213Sbostic #define XQRECL	SZFLAG + 9*SZIOINT + 12*SZADDR
19443213Sbostic #define XNEXTREC	SZFLAG + 9*SZIOINT + 13*SZADDR
19543213Sbostic #define XQBLANK	SZFLAG + 9*SZIOINT + 14*SZADDR
19643213Sbostic #define XQBLANKLEN	SZFLAG + 9*SZIOINT + 15*SZADDR
19743213Sbostic 
fmtstmt(lp)19843213Sbostic fmtstmt(lp)
19943213Sbostic register struct Labelblock *lp;
20043213Sbostic {
20143213Sbostic if(lp == NULL)
20243213Sbostic 	{
20343213Sbostic 	execerr("unlabeled format statement" , CNULL);
20443213Sbostic 	return(-1);
20543213Sbostic 	}
20643213Sbostic if(lp->labtype == LABUNKNOWN)
20743213Sbostic 	lp->labtype = LABFORMAT;
20843213Sbostic else if(lp->labtype != LABFORMAT)
20943213Sbostic 	{
21043213Sbostic 	execerr("bad format number", CNULL);
21143213Sbostic 	return(-1);
21243213Sbostic 	}
21343213Sbostic return(lp->labelno);
21443213Sbostic }
21543213Sbostic 
21643213Sbostic 
21743213Sbostic 
startioctl()21843213Sbostic startioctl()
21943213Sbostic {
22043213Sbostic register int i;
22143213Sbostic 
22243213Sbostic inioctl = YES;
22343213Sbostic nioctl = 0;
22443213Sbostic ioformatted = UNFORMATTED;
22543213Sbostic for(i = 1 ; i<=NIOS ; ++i)
22643213Sbostic 	V(i) = NULL;
22743213Sbostic }
22843213Sbostic 
22943213Sbostic 
23043213Sbostic 
endioctl()23143213Sbostic endioctl()
23243213Sbostic {
23343213Sbostic int i;
23443213Sbostic expptr p;
23543213Sbostic 
23643213Sbostic inioctl = NO;
23743213Sbostic 
23843213Sbostic /* set up for error recovery */
23943213Sbostic 
24043213Sbostic ioerrlab = ioendlab = skiplab = jumplab = 0;
24143213Sbostic 
24243213Sbostic if(p = V(IOSEND))
24343213Sbostic 	if(ISICON(p))
24446304Sbostic 		ioendlab = execlab(p->constblock.constant.ci) ->labelno;
24543213Sbostic 	else
24643213Sbostic 		err("bad end= clause");
24743213Sbostic 
24843213Sbostic if(p = V(IOSERR))
24943213Sbostic 	if(ISICON(p))
25046304Sbostic 		ioerrlab = execlab(p->constblock.constant.ci) ->labelno;
25143213Sbostic 	else
25243213Sbostic 		err("bad err= clause");
25343213Sbostic 
25443213Sbostic if(IOSTP)
25543213Sbostic 	if(IOSTP->tag!=TADDR || ! ISINT(IOSTP->addrblock.vtype) )
25643213Sbostic 		{
25743213Sbostic 		err("iostat must be an integer variable");
25843213Sbostic 		frexpr(IOSTP);
25943213Sbostic 		IOSTP = NULL;
26043213Sbostic 		}
26143213Sbostic 
26243213Sbostic if(iostmt == IOREAD)
26343213Sbostic 	{
26443213Sbostic 	if(IOSTP)
26543213Sbostic 		{
26643213Sbostic 		if(ioerrlab && ioendlab && ioerrlab==ioendlab)
26743213Sbostic 			jumplab = ioerrlab;
26843213Sbostic 		else
26943213Sbostic 			skiplab = jumplab = newlabel();
27043213Sbostic 		}
27143213Sbostic 	else	{
27243213Sbostic 		if(ioerrlab && ioendlab && ioerrlab!=ioendlab)
27343213Sbostic 			{
27443213Sbostic 			IOSTP = (expptr) mktemp(TYINT, PNULL);
27543213Sbostic 			skiplab = jumplab = newlabel();
27643213Sbostic 			}
27743213Sbostic 		else
27843213Sbostic 			jumplab = (ioerrlab ? ioerrlab : ioendlab);
27943213Sbostic 		}
28043213Sbostic 	}
28143213Sbostic else if(iostmt == IOWRITE)
28243213Sbostic 	{
28343213Sbostic 	if(IOSTP && !ioerrlab)
28443213Sbostic 		skiplab = jumplab = newlabel();
28543213Sbostic 	else
28643213Sbostic 		jumplab = ioerrlab;
28743213Sbostic 	}
28843213Sbostic else
28943213Sbostic 	jumplab = ioerrlab;
29043213Sbostic 
29143213Sbostic endbit = IOSTP!=NULL || ioendlab!=0;	/* for use in startrw() */
29243213Sbostic errbit = IOSTP!=NULL || ioerrlab!=0;
29343213Sbostic if(iostmt!=IOREAD && iostmt!=IOWRITE)
29443213Sbostic 	{
29543213Sbostic 	if(ioblkp == NULL)
29643213Sbostic 		ioblkp = autovar( (MAXIO+SZIOINT-1)/SZIOINT , TYIOINT, PNULL);
29743213Sbostic 	ioset(TYIOINT, XERR, ICON(errbit));
29843213Sbostic 	}
29943213Sbostic 
30043213Sbostic switch(iostmt)
30143213Sbostic 	{
30243213Sbostic 	case IOOPEN:
30343213Sbostic 		dofopen();  break;
30443213Sbostic 
30543213Sbostic 	case IOCLOSE:
30643213Sbostic 		dofclose();  break;
30743213Sbostic 
30843213Sbostic 	case IOINQUIRE:
30943213Sbostic 		dofinquire();  break;
31043213Sbostic 
31143213Sbostic 	case IOBACKSPACE:
31243213Sbostic 		dofmove("f_back"); break;
31343213Sbostic 
31443213Sbostic 	case IOREWIND:
31543213Sbostic 		dofmove("f_rew");  break;
31643213Sbostic 
31743213Sbostic 	case IOENDFILE:
31843213Sbostic 		dofmove("f_end");  break;
31943213Sbostic 
32043213Sbostic 	case IOREAD:
32143213Sbostic 	case IOWRITE:
32243213Sbostic 		startrw();  break;
32343213Sbostic 
32443213Sbostic 	default:
32543213Sbostic 		fatali("impossible iostmt %d", iostmt);
32643213Sbostic 	}
32743213Sbostic for(i = 1 ; i<=NIOS ; ++i)
32843213Sbostic 	if(i!=IOSIOSTAT && V(i)!=NULL)
32943213Sbostic 		frexpr(V(i));
33043213Sbostic }
33143213Sbostic 
33243213Sbostic 
33343213Sbostic 
iocname()33443213Sbostic iocname()
33543213Sbostic {
33643213Sbostic register int i;
33743213Sbostic int found, mask;
33843213Sbostic 
33943213Sbostic found = 0;
34043213Sbostic mask = M(iostmt);
34143213Sbostic for(i = 1 ; i <= NIOS ; ++i)
34243213Sbostic 	if(toklen==strlen(ioc[i].iocname) && eqn(toklen, token, ioc[i].iocname))
34343213Sbostic 		if(ioc[i].iotype & mask)
34443213Sbostic 			return(i);
34543213Sbostic 		else	found = i;
34643213Sbostic if(found)
34743213Sbostic 	errstr("invalid control %s for statement", ioc[found].iocname);
34843213Sbostic else
34943213Sbostic 	errstr("unknown iocontrol %s", varstr(toklen, token) );
35043213Sbostic return(IOSBAD);
35143213Sbostic }
35243213Sbostic 
35343213Sbostic 
ioclause(n,p)35443213Sbostic ioclause(n, p)
35543213Sbostic register int n;
35643213Sbostic register expptr p;
35743213Sbostic {
35843213Sbostic struct Ioclist *iocp;
35943213Sbostic 
36043213Sbostic ++nioctl;
36143213Sbostic if(n == IOSBAD)
36243213Sbostic 	return;
36343213Sbostic if(n == IOSPOSITIONAL)
36443213Sbostic 	{
36543213Sbostic 	if(nioctl > IOSFMT)
36643213Sbostic 		{
36743213Sbostic 		err("illegal positional iocontrol");
36843213Sbostic 		return;
36943213Sbostic 		}
37043213Sbostic 	n = nioctl;
37143213Sbostic 	}
37243213Sbostic 
37343213Sbostic if(p == NULL)
37443213Sbostic 	{
37543213Sbostic 	if(n == IOSUNIT)
37643213Sbostic 		p = (expptr) (iostmt==IOREAD ? IOSTDIN : IOSTDOUT);
37743213Sbostic 	else if(n != IOSFMT)
37843213Sbostic 		{
37943213Sbostic 		err("illegal * iocontrol");
38043213Sbostic 		return;
38143213Sbostic 		}
38243213Sbostic 	}
38343213Sbostic if(n == IOSFMT)
38443213Sbostic 	ioformatted = (p==NULL ? LISTDIRECTED : FORMATTED);
38543213Sbostic 
38643213Sbostic iocp = & ioc[n];
38743213Sbostic if(iocp->iocval == NULL)
38843213Sbostic 	{
38943213Sbostic 	p = (expptr) cpexpr(p);
39043213Sbostic 	if(n!=IOSFMT && ( n!=IOSUNIT || (p!=NULL && p->headblock.vtype!=TYCHAR) ) )
39143213Sbostic 		p = fixtype(p);
39243213Sbostic 	if(p!=NULL && ISCONST(p) && p->constblock.vtype==TYCHAR)
39343213Sbostic 		p = (expptr) putconst(p);
39443213Sbostic 	iocp->iocval = p;
39543213Sbostic }
39643213Sbostic else
39743213Sbostic 	errstr("iocontrol %s repeated", iocp->iocname);
39843213Sbostic }
39943213Sbostic 
40043213Sbostic /* io list item */
40143213Sbostic 
doio(list)40243213Sbostic doio(list)
40343213Sbostic chainp list;
40443213Sbostic {
40543213Sbostic expptr call0();
40643213Sbostic 
40743213Sbostic if(ioformatted == NAMEDIRECTED)
40843213Sbostic 	{
40943213Sbostic 	if(list)
41043213Sbostic 		err("no I/O list allowed in NAMELIST read/write");
41143213Sbostic 	}
41243213Sbostic else
41343213Sbostic 	{
41443213Sbostic 	doiolist(list);
41543213Sbostic 	ioroutine[0] = 'e';
41643213Sbostic 	putiocall( call0(TYINT, ioroutine) );
41743213Sbostic 	}
41843213Sbostic }
41943213Sbostic 
42043213Sbostic 
42143213Sbostic 
42243213Sbostic 
42343213Sbostic 
doiolist(p0)42443213Sbostic LOCAL doiolist(p0)
42543213Sbostic chainp p0;
42643213Sbostic {
42743213Sbostic chainp p;
42843213Sbostic register tagptr q;
42943213Sbostic register expptr qe;
43043213Sbostic register Namep qn;
43143213Sbostic Addrp tp, mkscalar();
43243213Sbostic int range;
43343213Sbostic expptr expr;
43443213Sbostic 
43543213Sbostic for (p = p0 ; p ; p = p->nextp)
43643213Sbostic 	{
43743213Sbostic 	q = p->datap;
43843213Sbostic 	if(q->tag == TIMPLDO)
43943213Sbostic 		{
44043213Sbostic 		exdo(range=newlabel(), q->impldoblock.impdospec);
44143213Sbostic 		doiolist(q->impldoblock.datalist);
44243213Sbostic 		enddo(range);
44343213Sbostic 		free( (charptr) q);
44443213Sbostic 		}
44543213Sbostic 	else	{
44643213Sbostic 		if(q->tag==TPRIM && q->primblock.argsp==NULL
44743213Sbostic 		    && q->primblock.namep->vdim!=NULL)
44843213Sbostic 			{
44943213Sbostic 			vardcl(qn = q->primblock.namep);
45043213Sbostic 			if(qn->vdim->nelt)
45143213Sbostic 				putio( fixtype(cpexpr(qn->vdim->nelt)),
45243213Sbostic 					mkscalar(qn) );
45343213Sbostic 			else
45443213Sbostic 				err("attempt to i/o array of unknown size");
45543213Sbostic 			}
45643213Sbostic 		else if(q->tag==TPRIM && q->primblock.argsp==NULL &&
45743213Sbostic 		    (qe = (expptr) memversion(q->primblock.namep)) )
45843213Sbostic 			putio(ICON(1),qe);
45943213Sbostic 		else if( (qe = fixtype(cpexpr(q)))->tag==TADDR)
46043213Sbostic 			putio(ICON(1), qe);
46143213Sbostic 		else if(qe->headblock.vtype != TYERROR)
46243213Sbostic 			{
46343213Sbostic 			if(iostmt == IOWRITE)
46443213Sbostic 				{
46543213Sbostic 				ftnint lencat();
46643213Sbostic 				expptr qvl;
46743213Sbostic 				qvl = NULL;
46843213Sbostic 				if( ISCHAR(qe) )
46943213Sbostic 					{
47043213Sbostic 					qvl = (expptr)
47143213Sbostic 						cpexpr(qe->headblock.vleng);
47243213Sbostic 					tp = mkaltemp(qe->headblock.vtype,
47343213Sbostic 						     ICON(lencat(qe)));
47443213Sbostic 					}
47543213Sbostic 				else
47643213Sbostic 					tp = mkaltemp(qe->headblock.vtype,
47743213Sbostic 						qe->headblock.vleng);
47843213Sbostic 				if (optimflag)
47943213Sbostic 					{
48043213Sbostic 					expr = mkexpr(OPASSIGN,cpexpr(tp),qe);
48143213Sbostic 					optbuff (SKEQ,expr,0,0);
48243213Sbostic 					}
48343213Sbostic 				else
48443213Sbostic 					puteq (cpexpr(tp),qe);
48543213Sbostic 				if(qvl)	/* put right length on block */
48643213Sbostic 					{
48743213Sbostic 					frexpr(tp->vleng);
48843213Sbostic 					tp->vleng = qvl;
48943213Sbostic 					}
49043213Sbostic 				putio(ICON(1), tp);
49143213Sbostic 				}
49243213Sbostic 			else
49343213Sbostic 				err("non-left side in READ list");
49443213Sbostic 			}
49543213Sbostic 		frexpr(q);
49643213Sbostic 		}
49743213Sbostic 	}
49843213Sbostic frchain( &p0 );
49943213Sbostic }
50043213Sbostic 
50143213Sbostic 
50243213Sbostic 
50343213Sbostic 
50443213Sbostic 
putio(nelt,addr)50543213Sbostic LOCAL putio(nelt, addr)
50643213Sbostic expptr nelt;
50743213Sbostic register expptr addr;
50843213Sbostic {
50943213Sbostic int type;
51043213Sbostic register expptr q;
51143213Sbostic 
51243213Sbostic type = addr->headblock.vtype;
51343213Sbostic if(ioformatted!=LISTDIRECTED && ISCOMPLEX(type) )
51443213Sbostic 	{
51543213Sbostic 	nelt = mkexpr(OPSTAR, ICON(2), nelt);
51643213Sbostic 	type -= (TYCOMPLEX-TYREAL);
51743213Sbostic 	}
51843213Sbostic 
51943213Sbostic /* pass a length with every item.  for noncharacter data, fake one */
52043213Sbostic if(type != TYCHAR)
52143213Sbostic 	{
52243213Sbostic 	addr->headblock.vtype = TYCHAR;
52343213Sbostic 	addr->headblock.vleng = ICON( typesize[type] );
52443213Sbostic 	}
52543213Sbostic 
52643213Sbostic nelt = fixtype( mkconv(TYLENG,nelt) );
52743213Sbostic if(ioformatted == LISTDIRECTED)
52843213Sbostic 	q = call3(TYINT, "do_lio", mkconv(TYLONG, ICON(type)), nelt, addr);
52943213Sbostic else
53043213Sbostic 	q = call2(TYINT, (ioformatted==FORMATTED ? "do_fio" : "do_uio"),
53143213Sbostic 		nelt, addr);
53243213Sbostic putiocall(q);
53343213Sbostic }
53443213Sbostic 
53543213Sbostic 
53643213Sbostic 
53743213Sbostic 
endio()53843213Sbostic endio()
53943213Sbostic {
54043213Sbostic if(skiplab)
54143213Sbostic 	{
54243213Sbostic 	if (optimflag)
54343213Sbostic 		optbuff (SKLABEL, 0, skiplab, 0);
54443213Sbostic 	else
54543213Sbostic 		putlabel (skiplab);
54643213Sbostic 	if(ioendlab)
54743213Sbostic 		{
54843213Sbostic 		expptr test;
54943213Sbostic 		test = mkexpr(OPGE, cpexpr(IOSTP), ICON(0));
55043213Sbostic 		if (optimflag)
55143213Sbostic 			optbuff (SKIOIFN,test,ioendlab,0);
55243213Sbostic 		else
55343213Sbostic 			putif (test,ioendlab);
55443213Sbostic 		}
55543213Sbostic 	if(ioerrlab)
55643213Sbostic 		{
55743213Sbostic 		expptr test;
55843213Sbostic 		test = mkexpr
55943213Sbostic 			( ((iostmt==IOREAD||iostmt==IOWRITE) ? OPLE : OPEQ),
56043213Sbostic 			cpexpr(IOSTP), ICON(0));
56143213Sbostic 		if (optimflag)
56243213Sbostic 			optbuff (SKIOIFN,test,ioerrlab,0);
56343213Sbostic 		else
56443213Sbostic 			putif (test,ioerrlab);
56543213Sbostic 		}
56643213Sbostic 	}
56743213Sbostic if(IOSTP)
56843213Sbostic 	frexpr(IOSTP);
56943213Sbostic }
57043213Sbostic 
57143213Sbostic 
57243213Sbostic 
putiocall(q)57343213Sbostic LOCAL putiocall(q)
57443213Sbostic register expptr q;
57543213Sbostic {
57643213Sbostic if(IOSTP)
57743213Sbostic 	{
57843213Sbostic 	q->headblock.vtype = TYINT;
57943213Sbostic 	q = fixexpr( mkexpr(OPASSIGN, cpexpr(IOSTP), q));
58043213Sbostic 	}
58143213Sbostic 
58243213Sbostic if(jumplab)
58343213Sbostic 	if (optimflag)
58443213Sbostic 		optbuff (SKIOIFN,mkexpr(OPEQ,q,ICON(0)),jumplab,0);
58543213Sbostic 	else
58643213Sbostic 		putif (mkexpr(OPEQ,q,ICON(0)),jumplab);
58743213Sbostic else
58843213Sbostic 	if (optimflag)
58943213Sbostic 		optbuff (SKEQ, q, 0, 0);
59043213Sbostic 	else
59143213Sbostic 		putexpr(q);
59243213Sbostic }
59343213Sbostic 
startrw()59443213Sbostic startrw()
59543213Sbostic {
59643213Sbostic register expptr p;
59743213Sbostic register Namep np;
59843213Sbostic register Addrp unitp, fmtp, recp, tioblkp;
59943213Sbostic register expptr nump;
60043213Sbostic register ioblock *t;
60143213Sbostic Addrp mkscalar();
60243213Sbostic expptr mkaddcon();
60343213Sbostic int k;
60443213Sbostic flag intfile, sequential, ok, varfmt;
60543213Sbostic 
60643213Sbostic /* First look at all the parameters and determine what is to be done */
60743213Sbostic 
60843213Sbostic ok = YES;
60943213Sbostic statstruct = YES;
61043213Sbostic 
61143213Sbostic intfile = NO;
61243213Sbostic if(p = V(IOSUNIT))
61343213Sbostic 	{
61443213Sbostic 	if( ISINT(p->headblock.vtype) )
61543213Sbostic 		unitp = (Addrp) cpexpr(p);
61643213Sbostic 	else if(p->headblock.vtype == TYCHAR)
61743213Sbostic 		{
61843213Sbostic 		intfile = YES;
61943213Sbostic 		if(p->tag==TPRIM && p->primblock.argsp==NULL &&
62043213Sbostic 		    (np = p->primblock.namep)->vdim!=NULL)
62143213Sbostic 			{
62243213Sbostic 			vardcl(np);
62343213Sbostic 			if(np->vdim->nelt)
62443213Sbostic 				{
62543213Sbostic 				nump = (expptr) cpexpr(np->vdim->nelt);
62643213Sbostic 				if( ! ISCONST(nump) )
62743213Sbostic 					statstruct = NO;
62843213Sbostic 				}
62943213Sbostic 			else
63043213Sbostic 				{
63143213Sbostic 				err("attempt to use internal unit array of unknown size");
63243213Sbostic 				ok = NO;
63343213Sbostic 				nump = ICON(1);
63443213Sbostic 				}
63543213Sbostic 			unitp = mkscalar(np);
63643213Sbostic 			}
63743213Sbostic 		else	{
63843213Sbostic 			nump = ICON(1);
63943213Sbostic 			unitp = (Addrp) fixtype(cpexpr(p));
64043213Sbostic 			}
64143213Sbostic 		if(! isstatic(unitp) )
64243213Sbostic 			statstruct = NO;
64343213Sbostic 		}
64443213Sbostic 	else
64543213Sbostic 		{
64643213Sbostic 		err("bad unit specifier type");
64743213Sbostic 		ok = NO;
64843213Sbostic 		}
64943213Sbostic 	}
65043213Sbostic else
65143213Sbostic 	{
65243213Sbostic 	err("bad unit specifier");
65343213Sbostic 	ok = NO;
65443213Sbostic 	}
65543213Sbostic 
65643213Sbostic sequential = YES;
65743213Sbostic if(p = V(IOSREC))
65843213Sbostic 	if( ISINT(p->headblock.vtype) )
65943213Sbostic 		{
66043213Sbostic 		recp = (Addrp) cpexpr(p);
66143213Sbostic 		sequential = NO;
66243213Sbostic 		}
66343213Sbostic 	else	{
66443213Sbostic 		err("bad REC= clause");
66543213Sbostic 		ok = NO;
66643213Sbostic 		}
66743213Sbostic else
66843213Sbostic 	recp = NULL;
66943213Sbostic 
67043213Sbostic 
67143213Sbostic varfmt = YES;
67243213Sbostic fmtp = NULL;
67343213Sbostic if(p = V(IOSFMT))
67443213Sbostic 	{
67543213Sbostic 	if(p->tag==TPRIM && p->primblock.argsp==NULL)
67643213Sbostic 		{
67743213Sbostic 		np = p->primblock.namep;
67843213Sbostic 		if(np->vclass == CLNAMELIST)
67943213Sbostic 			{
68043213Sbostic 			ioformatted = NAMEDIRECTED;
68143213Sbostic 			fmtp = (Addrp) fixtype(cpexpr(p));
68243213Sbostic 			goto endfmt;
68343213Sbostic 			}
68443213Sbostic 		vardcl(np);
68543213Sbostic 		if(np->vdim)
68643213Sbostic 			{
68743213Sbostic 			if( ! ONEOF(np->vstg, MSKSTATIC) )
68843213Sbostic 				statstruct = NO;
68943213Sbostic 			fmtp = mkscalar(np);
69043213Sbostic 			goto endfmt;
69143213Sbostic 			}
69243213Sbostic 		if( ISINT(np->vtype) )	/* ASSIGNed label */
69343213Sbostic 			{
69443213Sbostic 			statstruct = NO;
69543213Sbostic 			varfmt = NO;
69643213Sbostic 			fmtp = (Addrp) fixtype(cpexpr(p));
69743213Sbostic 			goto endfmt;
69843213Sbostic 			}
69943213Sbostic 		}
70043213Sbostic 	p = V(IOSFMT) = fixtype(p);
70143213Sbostic 	if(p->headblock.vtype == TYCHAR)
70243213Sbostic 		{
70343213Sbostic 		if (p->tag == TCONST) p = (expptr) putconst(p);
70443213Sbostic 		if( ! isstatic(p) )
70543213Sbostic 			statstruct = NO;
70643213Sbostic 		fmtp = (Addrp) cpexpr(p);
70743213Sbostic 		}
70843213Sbostic 	else if( ISICON(p) )
70943213Sbostic 		{
71046304Sbostic 		if( (k = fmtstmt( mklabel(p->constblock.constant.ci) )) > 0 )
71143213Sbostic 			{
71243213Sbostic 			fmtp = (Addrp) mkaddcon(k);
71343213Sbostic 			varfmt = NO;
71443213Sbostic 			}
71543213Sbostic 		else
71643213Sbostic 			ioformatted = UNFORMATTED;
71743213Sbostic 		}
71843213Sbostic 	else	{
71943213Sbostic 		err("bad format descriptor");
72043213Sbostic 		ioformatted = UNFORMATTED;
72143213Sbostic 		ok = NO;
72243213Sbostic 		}
72343213Sbostic 	}
72443213Sbostic else
72543213Sbostic 	fmtp = NULL;
72643213Sbostic 
72743213Sbostic endfmt:
72843213Sbostic 	if(intfile && ioformatted==UNFORMATTED)
72943213Sbostic 		{
73043213Sbostic 		err("unformatted internal I/O not allowed");
73143213Sbostic 		ok = NO;
73243213Sbostic 		}
73343213Sbostic 	if(!sequential && ioformatted==LISTDIRECTED)
73443213Sbostic 		{
73543213Sbostic 		err("direct list-directed I/O not allowed");
73643213Sbostic 		ok = NO;
73743213Sbostic 		}
73843213Sbostic 	if(!sequential && ioformatted==NAMEDIRECTED)
73943213Sbostic 		{
74043213Sbostic 		err("direct namelist I/O not allowed");
74143213Sbostic 		ok = NO;
74243213Sbostic 		}
74343213Sbostic 
74443213Sbostic if( ! ok )
74543213Sbostic 	return;
74643213Sbostic 
74743213Sbostic if (optimflag && ISCONST (fmtp))
74843213Sbostic 	fmtp = putconst ( (expptr) fmtp);
74943213Sbostic 
75043213Sbostic /*
75143213Sbostic    Now put out the I/O structure, statically if all the clauses
75243213Sbostic    are constants, dynamically otherwise
75343213Sbostic */
75443213Sbostic 
75543213Sbostic if(statstruct)
75643213Sbostic 	{
75743213Sbostic 	tioblkp = ioblkp;
75843213Sbostic 	ioblkp = ALLOC(Addrblock);
75943213Sbostic 	ioblkp->tag = TADDR;
76043213Sbostic 	ioblkp->vtype = TYIOINT;
76143213Sbostic 	ioblkp->vclass = CLVAR;
76243213Sbostic 	ioblkp->vstg = STGINIT;
76343213Sbostic 	ioblkp->memno = ++lastvarno;
76443213Sbostic 	ioblkp->memoffset = ICON(0);
76543213Sbostic 	blklen = (intfile ? XIREC+SZIOINT :
76643213Sbostic 			(sequential ? XFMT+SZADDR : XRNUM+SZIOINT) );
76743213Sbostic 	t = ALLOC(IoBlock);
76843213Sbostic 	t->blkno = ioblkp->memno;
76943213Sbostic 	t->len = blklen;
77043213Sbostic 	t->next = iodata;
77143213Sbostic 	iodata = t;
77243213Sbostic 	}
77343213Sbostic else if(ioblkp == NULL)
77443213Sbostic 	ioblkp = autovar( (MAXIO+SZIOINT-1)/SZIOINT , TYIOINT, PNULL);
77543213Sbostic 
77643213Sbostic ioset(TYIOINT, XERR, ICON(errbit));
77743213Sbostic if(iostmt == IOREAD)
77843213Sbostic 	ioset(TYIOINT, (intfile ? XIEND : XEND), ICON(endbit) );
77943213Sbostic 
78043213Sbostic if(intfile)
78143213Sbostic 	{
78243213Sbostic 	ioset(TYIOINT, XIRNUM, nump);
78343213Sbostic 	ioset(TYIOINT, XIRLEN, cpexpr(unitp->vleng) );
78443213Sbostic 	ioseta(XIUNIT, unitp);
78543213Sbostic 	}
78643213Sbostic else
78743213Sbostic 	ioset(TYIOINT, XUNIT, (expptr) unitp);
78843213Sbostic 
78943213Sbostic if(recp)
79043213Sbostic 	ioset(TYIOINT, (intfile ? XIREC : XREC) , (expptr) recp);
79143213Sbostic 
79243213Sbostic if(varfmt)
79343213Sbostic 	ioseta( intfile ? XIFMT : XFMT , fmtp);
79443213Sbostic else
79543213Sbostic 	ioset(TYADDR, intfile ? XIFMT : XFMT, (expptr) fmtp);
79643213Sbostic 
79743213Sbostic ioroutine[0] = 's';
79843213Sbostic ioroutine[1] = '_';
79943213Sbostic ioroutine[2] = (iostmt==IOREAD ? 'r' : 'w');
80043213Sbostic ioroutine[3] = (sequential ? 's' : 'd');
80143213Sbostic ioroutine[4] = "ufln" [ioformatted];
80243213Sbostic ioroutine[5] = (intfile ? 'i' : 'e');
80343213Sbostic ioroutine[6] = '\0';
80443213Sbostic 
80543213Sbostic putiocall( call1(TYINT, ioroutine, cpexpr(ioblkp) ));
80643213Sbostic 
80743213Sbostic if(statstruct)
80843213Sbostic 	{
80943213Sbostic 	frexpr(ioblkp);
81043213Sbostic 	ioblkp = tioblkp;
81143213Sbostic 	statstruct = NO;
81243213Sbostic 	}
81343213Sbostic }
81443213Sbostic 
81543213Sbostic 
81643213Sbostic 
dofopen()81743213Sbostic LOCAL dofopen()
81843213Sbostic {
81943213Sbostic register expptr p;
82043213Sbostic 
82143213Sbostic if( (p = V(IOSUNIT)) && ISINT(p->headblock.vtype) )
82243213Sbostic 	ioset(TYIOINT, XUNIT, cpexpr(p) );
82343213Sbostic else
82443213Sbostic 	err("bad unit in open");
82543213Sbostic if( (p = V(IOSFILE)) )
82643213Sbostic 	if(p->headblock.vtype == TYCHAR)
82743213Sbostic 		ioset(TYIOINT, XFNAMELEN, cpexpr(p->headblock.vleng) );
82843213Sbostic 	else
82943213Sbostic 		err("bad file in open");
83043213Sbostic 
83143213Sbostic iosetc(XFNAME, p);
83243213Sbostic 
83343213Sbostic if(p = V(IOSRECL))
83443213Sbostic 	if( ISINT(p->headblock.vtype) )
83543213Sbostic 		ioset(TYIOINT, XRECLEN, cpexpr(p) );
83643213Sbostic 	else
83743213Sbostic 		err("bad recl");
83843213Sbostic else
83943213Sbostic 	ioset(TYIOINT, XRECLEN, ICON(0) );
84043213Sbostic 
84143213Sbostic iosetc(XSTATUS, V(IOSSTATUS));
84243213Sbostic iosetc(XACCESS, V(IOSACCESS));
84343213Sbostic iosetc(XFORMATTED, V(IOSFORM));
84443213Sbostic iosetc(XBLANK, V(IOSBLANK));
84543213Sbostic 
84643213Sbostic putiocall( call1(TYINT, "f_open", cpexpr(ioblkp) ));
84743213Sbostic }
84843213Sbostic 
84943213Sbostic 
dofclose()85043213Sbostic LOCAL dofclose()
85143213Sbostic {
85243213Sbostic register expptr p;
85343213Sbostic 
85443213Sbostic if( (p = V(IOSUNIT)) && ISINT(p->headblock.vtype) )
85543213Sbostic 	{
85643213Sbostic 	ioset(TYIOINT, XUNIT, cpexpr(p) );
85743213Sbostic 	iosetc(XCLSTATUS, V(IOSSTATUS));
85843213Sbostic 	putiocall( call1(TYINT, "f_clos", cpexpr(ioblkp)) );
85943213Sbostic 	}
86043213Sbostic else
86143213Sbostic 	err("bad unit in close statement");
86243213Sbostic }
86343213Sbostic 
86443213Sbostic 
dofinquire()86543213Sbostic LOCAL dofinquire()
86643213Sbostic {
86743213Sbostic register expptr p;
86843213Sbostic if(p = V(IOSUNIT))
86943213Sbostic 	{
87043213Sbostic 	if( V(IOSFILE) )
87143213Sbostic 		err("inquire by unit or by file, not both");
87243213Sbostic 	ioset(TYIOINT, XUNIT, cpexpr(p) );
87343213Sbostic 	}
87443213Sbostic else if( ! V(IOSFILE) )
87543213Sbostic 	err("must inquire by unit or by file");
87643213Sbostic iosetlc(IOSFILE, XFILE, XFILELEN);
87743213Sbostic iosetip(IOSEXISTS, XEXISTS);
87843213Sbostic iosetip(IOSOPENED, XOPEN);
87943213Sbostic iosetip(IOSNUMBER, XNUMBER);
88043213Sbostic iosetip(IOSNAMED, XNAMED);
88143213Sbostic iosetlc(IOSNAME, XNAME, XNAMELEN);
88243213Sbostic iosetlc(IOSACCESS, XQACCESS, XQACCLEN);
88343213Sbostic iosetlc(IOSSEQUENTIAL, XSEQ, XSEQLEN);
88443213Sbostic iosetlc(IOSDIRECT, XDIRECT, XDIRLEN);
88543213Sbostic iosetlc(IOSFORM, XFORM, XFORMLEN);
88643213Sbostic iosetlc(IOSFORMATTED, XFMTED, XFMTEDLEN);
88743213Sbostic iosetlc(IOSUNFORMATTED, XUNFMT, XUNFMTLEN);
88843213Sbostic iosetip(IOSRECL, XQRECL);
88943213Sbostic iosetip(IOSNEXTREC, XNEXTREC);
89043213Sbostic iosetlc(IOSBLANK, XQBLANK, XQBLANKLEN);
89143213Sbostic 
89243213Sbostic putiocall( call1(TYINT,  "f_inqu", cpexpr(ioblkp) ));
89343213Sbostic }
89443213Sbostic 
89543213Sbostic 
89643213Sbostic 
dofmove(subname)89743213Sbostic LOCAL dofmove(subname)
89843213Sbostic char *subname;
89943213Sbostic {
90043213Sbostic register expptr p;
90143213Sbostic 
90243213Sbostic if( (p = V(IOSUNIT)) && ISINT(p->headblock.vtype) )
90343213Sbostic 	{
90443213Sbostic 	ioset(TYIOINT, XUNIT, cpexpr(p) );
90543213Sbostic 	putiocall( call1(TYINT, subname, cpexpr(ioblkp) ));
90643213Sbostic 	}
90743213Sbostic else
90843213Sbostic 	err("bad unit in I/O motion statement");
90943213Sbostic }
91043213Sbostic 
91143213Sbostic 
91243213Sbostic 
91343213Sbostic LOCAL
ioset(type,offset,p)91443213Sbostic ioset(type, offset, p)
91543213Sbostic int type;
91643213Sbostic int offset;
91743213Sbostic register expptr p;
91843213Sbostic {
91943213Sbostic   static char *badoffset = "badoffset in ioset";
92043213Sbostic 
92143213Sbostic   register Addrp q;
92243213Sbostic   register offsetlist *op;
92343213Sbostic 
92443213Sbostic   q = (Addrp) cpexpr(ioblkp);
92543213Sbostic   q->vtype = type;
92643213Sbostic   q->memoffset = fixtype( mkexpr(OPPLUS, q->memoffset, ICON(offset)) );
92743213Sbostic 
92843213Sbostic   if (statstruct && ISCONST(p))
92943213Sbostic     {
93043213Sbostic       if (!ISICON(q->memoffset))
93143213Sbostic 	fatal(badoffset);
93243213Sbostic 
93346304Sbostic       op = mkiodata(q->memno, q->memoffset->constblock.constant.ci, blklen);
93443213Sbostic       if (op->tag != 0)
93543213Sbostic 	fatal(badoffset);
93643213Sbostic 
93743213Sbostic       if (type == TYADDR)
93843213Sbostic 	{
93943213Sbostic 	  op->tag = NDLABEL;
94046304Sbostic 	  op->val.label = p->constblock.constant.ci;
94143213Sbostic 	}
94243213Sbostic       else
94343213Sbostic 	{
94443213Sbostic 	  op->tag = NDDATA;
94543213Sbostic 	  op->val.cp = (Constp) convconst(type, 0, p);
94643213Sbostic 	}
94743213Sbostic 
94843213Sbostic       frexpr((tagptr) p);
94943213Sbostic       frexpr((tagptr) q);
95043213Sbostic     }
95143213Sbostic   else
95243213Sbostic     if (optimflag)
95343213Sbostic       optbuff (SKEQ, mkexpr(OPASSIGN,q,p), 0,0);
95443213Sbostic     else
95543213Sbostic       puteq (q,p);
95643213Sbostic 
95743213Sbostic   return;
95843213Sbostic }
95943213Sbostic 
96043213Sbostic 
96143213Sbostic 
96243213Sbostic 
iosetc(offset,p)96343213Sbostic LOCAL iosetc(offset, p)
96443213Sbostic int offset;
96543213Sbostic register expptr p;
96643213Sbostic {
96743213Sbostic if(p == NULL)
96843213Sbostic 	ioset(TYADDR, offset, ICON(0) );
96943213Sbostic else if(p->headblock.vtype == TYCHAR)
97043213Sbostic 	ioset(TYADDR, offset, addrof(cpexpr(p) ));
97143213Sbostic else
97243213Sbostic 	err("non-character control clause");
97343213Sbostic }
97443213Sbostic 
97543213Sbostic 
97643213Sbostic 
ioseta(offset,p)97743213Sbostic LOCAL ioseta(offset, p)
97843213Sbostic int offset;
97943213Sbostic register Addrp p;
98043213Sbostic {
98143213Sbostic   static char *badoffset = "bad offset in ioseta";
98243213Sbostic 
98343213Sbostic   int blkno;
98443213Sbostic   register offsetlist *op;
98543213Sbostic 
98643213Sbostic   if(statstruct)
98743213Sbostic     {
98843213Sbostic       blkno = ioblkp->memno;
98943213Sbostic       op = mkiodata(blkno, offset, blklen);
99043213Sbostic       if (op->tag != 0)
99143213Sbostic 	fatal(badoffset);
99243213Sbostic 
99343213Sbostic       if (p == NULL)
99443213Sbostic 	op->tag = NDNULL;
99543213Sbostic       else if (p->tag == TADDR)
99643213Sbostic 	{
99743213Sbostic 	  op->tag = NDADDR;
99843213Sbostic 	  op->val.addr.stg = p->vstg;
99943213Sbostic 	  op->val.addr.memno = p->memno;
100046304Sbostic 	  op->val.addr.offset = p->memoffset->constblock.constant.ci;
100143213Sbostic 	}
100243213Sbostic       else
100343213Sbostic 	badtag("ioseta", p->tag);
100443213Sbostic     }
100543213Sbostic   else
100643213Sbostic     ioset(TYADDR, offset, p ? addrof(p) : ICON(0) );
100743213Sbostic 
100843213Sbostic   return;
100943213Sbostic }
101043213Sbostic 
101143213Sbostic 
101243213Sbostic 
101343213Sbostic 
iosetip(i,offset)101443213Sbostic LOCAL iosetip(i, offset)
101543213Sbostic int i, offset;
101643213Sbostic {
101743213Sbostic register expptr p;
101843213Sbostic 
101943213Sbostic if(p = V(i))
102043213Sbostic 	if(p->tag==TADDR &&
102143213Sbostic 	    ONEOF(p->addrblock.vtype, M(TYLONG)|M(TYLOGICAL)) )
102243213Sbostic 		ioset(TYADDR, offset, addrof(cpexpr(p)) );
102343213Sbostic 	else
102443213Sbostic 		errstr("impossible inquire parameter %s", ioc[i].iocname);
102543213Sbostic else
102643213Sbostic 	ioset(TYADDR, offset, ICON(0) );
102743213Sbostic }
102843213Sbostic 
102943213Sbostic 
103043213Sbostic 
iosetlc(i,offp,offl)103143213Sbostic LOCAL iosetlc(i, offp, offl)
103243213Sbostic int i, offp, offl;
103343213Sbostic {
103443213Sbostic register expptr p;
103543213Sbostic if( (p = V(i)) && p->headblock.vtype==TYCHAR)
103643213Sbostic 	ioset(TYIOINT, offl, cpexpr(p->headblock.vleng) );
103743213Sbostic iosetc(offp, p);
103843213Sbostic }
103943213Sbostic 
104043213Sbostic 
104143213Sbostic LOCAL offsetlist *
mkiodata(blkno,offset,len)104243213Sbostic mkiodata(blkno, offset, len)
104343213Sbostic int blkno;
104443213Sbostic ftnint offset;
104543213Sbostic ftnint len;
104643213Sbostic {
104743213Sbostic   register offsetlist *p, *q;
104843213Sbostic   register ioblock *t;
104943213Sbostic   register int found;
105043213Sbostic 
105143213Sbostic   found = NO;
105243213Sbostic   t = iodata;
105343213Sbostic 
105443213Sbostic   while (found == NO && t != NULL)
105543213Sbostic     {
105643213Sbostic       if (t->blkno == blkno)
105743213Sbostic 	found = YES;
105843213Sbostic       else
105943213Sbostic 	t = t->next;
106043213Sbostic     }
106143213Sbostic 
106243213Sbostic   if (found == NO)
106343213Sbostic     {
106443213Sbostic       t = ALLOC(IoBlock);
106543213Sbostic       t->blkno = blkno;
106643213Sbostic       t->next = iodata;
106743213Sbostic       iodata = t;
106843213Sbostic     }
106943213Sbostic 
107043213Sbostic   if (len > t->len)
107143213Sbostic     t->len = len;
107243213Sbostic 
107343213Sbostic   p = t->olist;
107443213Sbostic 
107543213Sbostic   if (p == NULL)
107643213Sbostic     {
107743213Sbostic       p = ALLOC(OffsetList);
107843213Sbostic       p->next = NULL;
107943213Sbostic       p->offset = offset;
108043213Sbostic       t->olist = p;
108143213Sbostic       return (p);
108243213Sbostic     }
108343213Sbostic 
108443213Sbostic   for (;;)
108543213Sbostic     {
108643213Sbostic       if (p->offset == offset)
108743213Sbostic 	return (p);
108843213Sbostic       else if (p->next != NULL &&
108943213Sbostic 	       p->next->offset <= offset)
109043213Sbostic 	p = p->next;
109143213Sbostic       else
109243213Sbostic 	{
109343213Sbostic 	  q = ALLOC(OffsetList);
109443213Sbostic 	  q->next = p->next;
109543213Sbostic 	  p->next = q;
109643213Sbostic 	  q->offset = offset;
109743213Sbostic 	  return (q);
109843213Sbostic 	}
109943213Sbostic     }
110043213Sbostic }
110143213Sbostic 
110243213Sbostic 
outiodata()110343213Sbostic outiodata()
110443213Sbostic {
110543213Sbostic   static char *varfmt = "\t.align\t2\nv.%d:\n";
110643213Sbostic 
110743213Sbostic   register ioblock *p;
110843213Sbostic   register ioblock *t;
110943213Sbostic 
111043213Sbostic   if (iodata == NULL) return;
111143213Sbostic 
111243213Sbostic   p = iodata;
111343213Sbostic 
111443213Sbostic   while (p != NULL)
111543213Sbostic     {
111643213Sbostic       fprintf(initfile, varfmt, p->blkno);
111743213Sbostic       outolist(p->olist, p->len);
111843213Sbostic 
111943213Sbostic       t = p;
112043213Sbostic       p = t->next;
112143213Sbostic       free((char *) t);
112243213Sbostic     }
112343213Sbostic 
112443213Sbostic   iodata = NULL;
112543213Sbostic   return;
112643213Sbostic }
112743213Sbostic 
112843213Sbostic 
112943213Sbostic 
113043213Sbostic LOCAL
outolist(op,len)113143213Sbostic outolist(op, len)
113243213Sbostic register offsetlist *op;
113343213Sbostic register int len;
113443213Sbostic {
113543213Sbostic   static char *overlap = "overlapping i/o fields in outolist";
113643213Sbostic   static char *toolong = "offset too large in outolist";
113743213Sbostic 
113843213Sbostic   register offsetlist *t;
113943213Sbostic   register ftnint clen;
114043213Sbostic   register Constp cp;
114143213Sbostic   register int type;
114243213Sbostic 
114343213Sbostic   clen = 0;
114443213Sbostic 
114543213Sbostic   while (op != NULL)
114643213Sbostic     {
114743213Sbostic       if (clen > op->offset)
114843213Sbostic 	fatal(overlap);
114943213Sbostic 
115043213Sbostic       if (clen < op->offset)
115143213Sbostic 	{
115243213Sbostic 	  prspace(op->offset - clen);
115343213Sbostic 	  clen = op->offset;
115443213Sbostic 	}
115543213Sbostic 
115643213Sbostic       switch (op->tag)
115743213Sbostic 	{
115843213Sbostic 	default:
115943213Sbostic 	  badtag("outolist", op->tag);
116043213Sbostic 
116143213Sbostic 	case NDDATA:
116243213Sbostic 	  cp = op->val.cp;
116343213Sbostic 	  type = cp->vtype;
116443213Sbostic 	  if (type != TYIOINT)
116543213Sbostic 	    badtype("outolist", type);
116646304Sbostic 	  prconi(initfile, type, cp->constant.ci);
116743213Sbostic 	  clen += typesize[type];
116843213Sbostic 	  frexpr((tagptr) cp);
116943213Sbostic 	  break;
117043213Sbostic 
117143213Sbostic 	case NDLABEL:
117243213Sbostic 	  prcona(initfile, op->val.label);
117343213Sbostic 	  clen += typesize[TYADDR];
117443213Sbostic 	  break;
117543213Sbostic 
117643213Sbostic 	case NDADDR:
117743213Sbostic 	  praddr(initfile, op->val.addr.stg, op->val.addr.memno,
117843213Sbostic 		 op->val.addr.offset);
117943213Sbostic 	  clen += typesize[TYADDR];
118043213Sbostic 	  break;
118143213Sbostic 
118243213Sbostic 	case NDNULL:
118343213Sbostic 	  praddr(initfile, STGNULL, 0, (ftnint) 0);
118443213Sbostic 	  clen += typesize[TYADDR];
118543213Sbostic 	  break;
118643213Sbostic 	}
118743213Sbostic 
118843213Sbostic       t = op;
118943213Sbostic       op = t->next;
119043213Sbostic       free((char *) t);
119143213Sbostic     }
119243213Sbostic 
119343213Sbostic   if (clen > len)
119443213Sbostic     fatal(toolong);
119543213Sbostic 
119643213Sbostic   if (clen < len)
119743213Sbostic     prspace(len - clen);
119843213Sbostic 
119943213Sbostic   return;
120043213Sbostic }
1201