xref: /csrg-svn/usr.bin/f77/pass1.vax/io.c (revision 22836)
1*22836Smckusick /*
2*22836Smckusick  * Copyright (c) 1980 Regents of the University of California.
3*22836Smckusick  * All rights reserved.  The Berkeley software License Agreement
4*22836Smckusick  * specifies the terms and conditions for redistribution.
5*22836Smckusick  */
6*22836Smckusick 
7*22836Smckusick #ifndef lint
8*22836Smckusick static	char *sccsid = "@(#)io.c	5.1 (Berkeley) 85/06/07";
9*22836Smckusick #endif
10*22836Smckusick 
11*22836Smckusick /*
12*22836Smckusick  * io.c
13*22836Smckusick  *
14*22836Smckusick  * Routines to generate code for I/O statements.
15*22836Smckusick  * Some corrections and improvements due to David Wasley, U. C. Berkeley
16*22836Smckusick  *
17*22836Smckusick  * University of Utah CS Dept modification history:
18*22836Smckusick  *
19*22836Smckusick  * $Header: io.c,v 2.4 85/02/23 21:09:02 donn Exp $
20*22836Smckusick  * $Log:	io.c,v $
21*22836Smckusick  * Revision 2.4  85/02/23  21:09:02  donn
22*22836Smckusick  * Jerry Berkman's compiled format fixes move setfmt into a separate file.
23*22836Smckusick  *
24*22836Smckusick  * Revision 2.3  85/01/10  22:33:41  donn
25*22836Smckusick  * Added some strategic cpexpr()s to prevent memory management bugs.
26*22836Smckusick  *
27*22836Smckusick  * Revision 2.2  84/08/04  21:15:47  donn
28*22836Smckusick  * Removed code that creates extra statement labels, per Jerry Berkman's
29*22836Smckusick  * fixes to make ASSIGNs work right.
30*22836Smckusick  *
31*22836Smckusick  * Revision 2.1  84/07/19  12:03:33  donn
32*22836Smckusick  * Changed comment headers for UofU.
33*22836Smckusick  *
34*22836Smckusick  * Revision 1.2  84/02/26  06:35:57  donn
35*22836Smckusick  * Added Berkeley changes necessary for shortening offsets to data.
36*22836Smckusick  *
37*22836Smckusick  */
38*22836Smckusick 
39*22836Smckusick /* TEMPORARY */
40*22836Smckusick #define TYIOINT TYLONG
41*22836Smckusick #define SZIOINT SZLONG
42*22836Smckusick 
43*22836Smckusick #include "defs.h"
44*22836Smckusick #include "io.h"
45*22836Smckusick 
46*22836Smckusick 
47*22836Smckusick LOCAL char ioroutine[XL+1];
48*22836Smckusick 
49*22836Smckusick LOCAL int ioendlab;
50*22836Smckusick LOCAL int ioerrlab;
51*22836Smckusick LOCAL int endbit;
52*22836Smckusick LOCAL int errbit;
53*22836Smckusick LOCAL int jumplab;
54*22836Smckusick LOCAL int skiplab;
55*22836Smckusick LOCAL int ioformatted;
56*22836Smckusick LOCAL int statstruct = NO;
57*22836Smckusick LOCAL ftnint blklen;
58*22836Smckusick 
59*22836Smckusick LOCAL offsetlist *mkiodata();
60*22836Smckusick 
61*22836Smckusick 
62*22836Smckusick #define UNFORMATTED 0
63*22836Smckusick #define FORMATTED 1
64*22836Smckusick #define LISTDIRECTED 2
65*22836Smckusick #define NAMEDIRECTED 3
66*22836Smckusick 
67*22836Smckusick #define V(z)	ioc[z].iocval
68*22836Smckusick 
69*22836Smckusick #define IOALL 07777
70*22836Smckusick 
71*22836Smckusick LOCAL struct Ioclist
72*22836Smckusick 	{
73*22836Smckusick 	char *iocname;
74*22836Smckusick 	int iotype;
75*22836Smckusick 	expptr iocval;
76*22836Smckusick 	} ioc[ ] =
77*22836Smckusick 	{
78*22836Smckusick 		{ "", 0 },
79*22836Smckusick 		{ "unit", IOALL },
80*22836Smckusick 		{ "fmt", M(IOREAD) | M(IOWRITE) },
81*22836Smckusick 		{ "err", IOALL },
82*22836Smckusick 		{ "end", M(IOREAD) },
83*22836Smckusick 		{ "iostat", IOALL },
84*22836Smckusick 		{ "rec", M(IOREAD) | M(IOWRITE) },
85*22836Smckusick 		{ "recl", M(IOOPEN) | M(IOINQUIRE) },
86*22836Smckusick 		{ "file", M(IOOPEN) | M(IOINQUIRE) },
87*22836Smckusick 		{ "status", M(IOOPEN) | M(IOCLOSE) },
88*22836Smckusick 		{ "access", M(IOOPEN) | M(IOINQUIRE) },
89*22836Smckusick 		{ "form", M(IOOPEN) | M(IOINQUIRE) },
90*22836Smckusick 		{ "blank", M(IOOPEN) | M(IOINQUIRE) },
91*22836Smckusick 		{ "exist", M(IOINQUIRE) },
92*22836Smckusick 		{ "opened", M(IOINQUIRE) },
93*22836Smckusick 		{ "number", M(IOINQUIRE) },
94*22836Smckusick 		{ "named", M(IOINQUIRE) },
95*22836Smckusick 		{ "name", M(IOINQUIRE) },
96*22836Smckusick 		{ "sequential", M(IOINQUIRE) },
97*22836Smckusick 		{ "direct", M(IOINQUIRE) },
98*22836Smckusick 		{ "formatted", M(IOINQUIRE) },
99*22836Smckusick 		{ "unformatted", M(IOINQUIRE) },
100*22836Smckusick 		{ "nextrec", M(IOINQUIRE) }
101*22836Smckusick 	} ;
102*22836Smckusick 
103*22836Smckusick #define NIOS (sizeof(ioc)/sizeof(struct Ioclist) - 1)
104*22836Smckusick #define MAXIO	SZFLAG + 10*SZIOINT + 15*SZADDR
105*22836Smckusick 
106*22836Smckusick #define IOSUNIT 1
107*22836Smckusick #define IOSFMT 2
108*22836Smckusick #define IOSERR 3
109*22836Smckusick #define IOSEND 4
110*22836Smckusick #define IOSIOSTAT 5
111*22836Smckusick #define IOSREC 6
112*22836Smckusick #define IOSRECL 7
113*22836Smckusick #define IOSFILE 8
114*22836Smckusick #define IOSSTATUS 9
115*22836Smckusick #define IOSACCESS 10
116*22836Smckusick #define IOSFORM 11
117*22836Smckusick #define IOSBLANK 12
118*22836Smckusick #define IOSEXISTS 13
119*22836Smckusick #define IOSOPENED 14
120*22836Smckusick #define IOSNUMBER 15
121*22836Smckusick #define IOSNAMED 16
122*22836Smckusick #define IOSNAME 17
123*22836Smckusick #define IOSSEQUENTIAL 18
124*22836Smckusick #define IOSDIRECT 19
125*22836Smckusick #define IOSFORMATTED 20
126*22836Smckusick #define IOSUNFORMATTED 21
127*22836Smckusick #define IOSNEXTREC 22
128*22836Smckusick 
129*22836Smckusick #define IOSTP V(IOSIOSTAT)
130*22836Smckusick 
131*22836Smckusick 
132*22836Smckusick /* offsets in generated structures */
133*22836Smckusick 
134*22836Smckusick #define SZFLAG SZIOINT
135*22836Smckusick 
136*22836Smckusick /* offsets for external READ and WRITE statements */
137*22836Smckusick 
138*22836Smckusick #define XERR 0
139*22836Smckusick #define XUNIT	SZFLAG
140*22836Smckusick #define XEND	SZFLAG + SZIOINT
141*22836Smckusick #define XFMT	2*SZFLAG + SZIOINT
142*22836Smckusick #define XREC	2*SZFLAG + SZIOINT + SZADDR
143*22836Smckusick #define XRLEN	2*SZFLAG + 2*SZADDR
144*22836Smckusick #define XRNUM	2*SZFLAG + 2*SZADDR + SZIOINT
145*22836Smckusick 
146*22836Smckusick /* offsets for internal READ and WRITE statements */
147*22836Smckusick 
148*22836Smckusick #define XIERR	0
149*22836Smckusick #define XIUNIT	SZFLAG
150*22836Smckusick #define XIEND	SZFLAG + SZADDR
151*22836Smckusick #define XIFMT	2*SZFLAG + SZADDR
152*22836Smckusick #define XIRLEN	2*SZFLAG + 2*SZADDR
153*22836Smckusick #define XIRNUM	2*SZFLAG + 2*SZADDR + SZIOINT
154*22836Smckusick #define XIREC	2*SZFLAG + 2*SZADDR + 2*SZIOINT
155*22836Smckusick 
156*22836Smckusick /* offsets for OPEN statements */
157*22836Smckusick 
158*22836Smckusick #define XFNAME	SZFLAG + SZIOINT
159*22836Smckusick #define XFNAMELEN	SZFLAG + SZIOINT + SZADDR
160*22836Smckusick #define XSTATUS	SZFLAG + 2*SZIOINT + SZADDR
161*22836Smckusick #define XACCESS	SZFLAG + 2*SZIOINT + 2*SZADDR
162*22836Smckusick #define XFORMATTED	SZFLAG + 2*SZIOINT + 3*SZADDR
163*22836Smckusick #define XRECLEN	SZFLAG + 2*SZIOINT + 4*SZADDR
164*22836Smckusick #define XBLANK	SZFLAG + 3*SZIOINT + 4*SZADDR
165*22836Smckusick 
166*22836Smckusick /* offset for CLOSE statement */
167*22836Smckusick 
168*22836Smckusick #define XCLSTATUS	SZFLAG + SZIOINT
169*22836Smckusick 
170*22836Smckusick /* offsets for INQUIRE statement */
171*22836Smckusick 
172*22836Smckusick #define XFILE	SZFLAG + SZIOINT
173*22836Smckusick #define XFILELEN	SZFLAG + SZIOINT + SZADDR
174*22836Smckusick #define XEXISTS	SZFLAG + 2*SZIOINT + SZADDR
175*22836Smckusick #define XOPEN	SZFLAG + 2*SZIOINT + 2*SZADDR
176*22836Smckusick #define XNUMBER	SZFLAG + 2*SZIOINT + 3*SZADDR
177*22836Smckusick #define XNAMED	SZFLAG + 2*SZIOINT + 4*SZADDR
178*22836Smckusick #define XNAME	SZFLAG + 2*SZIOINT + 5*SZADDR
179*22836Smckusick #define XNAMELEN	SZFLAG + 2*SZIOINT + 6*SZADDR
180*22836Smckusick #define XQACCESS	SZFLAG + 3*SZIOINT + 6*SZADDR
181*22836Smckusick #define XQACCLEN	SZFLAG + 3*SZIOINT + 7*SZADDR
182*22836Smckusick #define XSEQ	SZFLAG + 4*SZIOINT + 7*SZADDR
183*22836Smckusick #define XSEQLEN	SZFLAG + 4*SZIOINT + 8*SZADDR
184*22836Smckusick #define XDIRECT	SZFLAG + 5*SZIOINT + 8*SZADDR
185*22836Smckusick #define XDIRLEN	SZFLAG + 5*SZIOINT + 9*SZADDR
186*22836Smckusick #define XFORM	SZFLAG + 6*SZIOINT + 9*SZADDR
187*22836Smckusick #define XFORMLEN	SZFLAG + 6*SZIOINT + 10*SZADDR
188*22836Smckusick #define XFMTED	SZFLAG + 7*SZIOINT + 10*SZADDR
189*22836Smckusick #define XFMTEDLEN	SZFLAG + 7*SZIOINT + 11*SZADDR
190*22836Smckusick #define XUNFMT	SZFLAG + 8*SZIOINT + 11*SZADDR
191*22836Smckusick #define XUNFMTLEN	SZFLAG + 8*SZIOINT + 12*SZADDR
192*22836Smckusick #define XQRECL	SZFLAG + 9*SZIOINT + 12*SZADDR
193*22836Smckusick #define XNEXTREC	SZFLAG + 9*SZIOINT + 13*SZADDR
194*22836Smckusick #define XQBLANK	SZFLAG + 9*SZIOINT + 14*SZADDR
195*22836Smckusick #define XQBLANKLEN	SZFLAG + 9*SZIOINT + 15*SZADDR
196*22836Smckusick 
197*22836Smckusick fmtstmt(lp)
198*22836Smckusick register struct Labelblock *lp;
199*22836Smckusick {
200*22836Smckusick if(lp == NULL)
201*22836Smckusick 	{
202*22836Smckusick 	execerr("unlabeled format statement" , CNULL);
203*22836Smckusick 	return(-1);
204*22836Smckusick 	}
205*22836Smckusick if(lp->labtype == LABUNKNOWN)
206*22836Smckusick 	lp->labtype = LABFORMAT;
207*22836Smckusick else if(lp->labtype != LABFORMAT)
208*22836Smckusick 	{
209*22836Smckusick 	execerr("bad format number", CNULL);
210*22836Smckusick 	return(-1);
211*22836Smckusick 	}
212*22836Smckusick return(lp->labelno);
213*22836Smckusick }
214*22836Smckusick 
215*22836Smckusick 
216*22836Smckusick 
217*22836Smckusick startioctl()
218*22836Smckusick {
219*22836Smckusick register int i;
220*22836Smckusick 
221*22836Smckusick inioctl = YES;
222*22836Smckusick nioctl = 0;
223*22836Smckusick ioformatted = UNFORMATTED;
224*22836Smckusick for(i = 1 ; i<=NIOS ; ++i)
225*22836Smckusick 	V(i) = NULL;
226*22836Smckusick }
227*22836Smckusick 
228*22836Smckusick 
229*22836Smckusick 
230*22836Smckusick endioctl()
231*22836Smckusick {
232*22836Smckusick int i;
233*22836Smckusick expptr p;
234*22836Smckusick 
235*22836Smckusick inioctl = NO;
236*22836Smckusick 
237*22836Smckusick /* set up for error recovery */
238*22836Smckusick 
239*22836Smckusick ioerrlab = ioendlab = skiplab = jumplab = 0;
240*22836Smckusick 
241*22836Smckusick if(p = V(IOSEND))
242*22836Smckusick 	if(ISICON(p))
243*22836Smckusick 		ioendlab = execlab(p->constblock.const.ci) ->labelno;
244*22836Smckusick 	else
245*22836Smckusick 		err("bad end= clause");
246*22836Smckusick 
247*22836Smckusick if(p = V(IOSERR))
248*22836Smckusick 	if(ISICON(p))
249*22836Smckusick 		ioerrlab = execlab(p->constblock.const.ci) ->labelno;
250*22836Smckusick 	else
251*22836Smckusick 		err("bad err= clause");
252*22836Smckusick 
253*22836Smckusick if(IOSTP)
254*22836Smckusick 	if(IOSTP->tag!=TADDR || ! ISINT(IOSTP->addrblock.vtype) )
255*22836Smckusick 		{
256*22836Smckusick 		err("iostat must be an integer variable");
257*22836Smckusick 		frexpr(IOSTP);
258*22836Smckusick 		IOSTP = NULL;
259*22836Smckusick 		}
260*22836Smckusick 
261*22836Smckusick if(iostmt == IOREAD)
262*22836Smckusick 	{
263*22836Smckusick 	if(IOSTP)
264*22836Smckusick 		{
265*22836Smckusick 		if(ioerrlab && ioendlab && ioerrlab==ioendlab)
266*22836Smckusick 			jumplab = ioerrlab;
267*22836Smckusick 		else
268*22836Smckusick 			skiplab = jumplab = newlabel();
269*22836Smckusick 		}
270*22836Smckusick 	else	{
271*22836Smckusick 		if(ioerrlab && ioendlab && ioerrlab!=ioendlab)
272*22836Smckusick 			{
273*22836Smckusick 			IOSTP = (expptr) mktemp(TYINT, PNULL);
274*22836Smckusick 			skiplab = jumplab = newlabel();
275*22836Smckusick 			}
276*22836Smckusick 		else
277*22836Smckusick 			jumplab = (ioerrlab ? ioerrlab : ioendlab);
278*22836Smckusick 		}
279*22836Smckusick 	}
280*22836Smckusick else if(iostmt == IOWRITE)
281*22836Smckusick 	{
282*22836Smckusick 	if(IOSTP && !ioerrlab)
283*22836Smckusick 		skiplab = jumplab = newlabel();
284*22836Smckusick 	else
285*22836Smckusick 		jumplab = ioerrlab;
286*22836Smckusick 	}
287*22836Smckusick else
288*22836Smckusick 	jumplab = ioerrlab;
289*22836Smckusick 
290*22836Smckusick endbit = IOSTP!=NULL || ioendlab!=0;	/* for use in startrw() */
291*22836Smckusick errbit = IOSTP!=NULL || ioerrlab!=0;
292*22836Smckusick if(iostmt!=IOREAD && iostmt!=IOWRITE)
293*22836Smckusick 	{
294*22836Smckusick 	if(ioblkp == NULL)
295*22836Smckusick 		ioblkp = autovar( (MAXIO+SZIOINT-1)/SZIOINT , TYIOINT, PNULL);
296*22836Smckusick 	ioset(TYIOINT, XERR, ICON(errbit));
297*22836Smckusick 	}
298*22836Smckusick 
299*22836Smckusick switch(iostmt)
300*22836Smckusick 	{
301*22836Smckusick 	case IOOPEN:
302*22836Smckusick 		dofopen();  break;
303*22836Smckusick 
304*22836Smckusick 	case IOCLOSE:
305*22836Smckusick 		dofclose();  break;
306*22836Smckusick 
307*22836Smckusick 	case IOINQUIRE:
308*22836Smckusick 		dofinquire();  break;
309*22836Smckusick 
310*22836Smckusick 	case IOBACKSPACE:
311*22836Smckusick 		dofmove("f_back"); break;
312*22836Smckusick 
313*22836Smckusick 	case IOREWIND:
314*22836Smckusick 		dofmove("f_rew");  break;
315*22836Smckusick 
316*22836Smckusick 	case IOENDFILE:
317*22836Smckusick 		dofmove("f_end");  break;
318*22836Smckusick 
319*22836Smckusick 	case IOREAD:
320*22836Smckusick 	case IOWRITE:
321*22836Smckusick 		startrw();  break;
322*22836Smckusick 
323*22836Smckusick 	default:
324*22836Smckusick 		fatali("impossible iostmt %d", iostmt);
325*22836Smckusick 	}
326*22836Smckusick for(i = 1 ; i<=NIOS ; ++i)
327*22836Smckusick 	if(i!=IOSIOSTAT && V(i)!=NULL)
328*22836Smckusick 		frexpr(V(i));
329*22836Smckusick }
330*22836Smckusick 
331*22836Smckusick 
332*22836Smckusick 
333*22836Smckusick iocname()
334*22836Smckusick {
335*22836Smckusick register int i;
336*22836Smckusick int found, mask;
337*22836Smckusick 
338*22836Smckusick found = 0;
339*22836Smckusick mask = M(iostmt);
340*22836Smckusick for(i = 1 ; i <= NIOS ; ++i)
341*22836Smckusick 	if(toklen==strlen(ioc[i].iocname) && eqn(toklen, token, ioc[i].iocname))
342*22836Smckusick 		if(ioc[i].iotype & mask)
343*22836Smckusick 			return(i);
344*22836Smckusick 		else	found = i;
345*22836Smckusick if(found)
346*22836Smckusick 	errstr("invalid control %s for statement", ioc[found].iocname);
347*22836Smckusick else
348*22836Smckusick 	errstr("unknown iocontrol %s", varstr(toklen, token) );
349*22836Smckusick return(IOSBAD);
350*22836Smckusick }
351*22836Smckusick 
352*22836Smckusick 
353*22836Smckusick ioclause(n, p)
354*22836Smckusick register int n;
355*22836Smckusick register expptr p;
356*22836Smckusick {
357*22836Smckusick struct Ioclist *iocp;
358*22836Smckusick 
359*22836Smckusick ++nioctl;
360*22836Smckusick if(n == IOSBAD)
361*22836Smckusick 	return;
362*22836Smckusick if(n == IOSPOSITIONAL)
363*22836Smckusick 	{
364*22836Smckusick 	if(nioctl > IOSFMT)
365*22836Smckusick 		{
366*22836Smckusick 		err("illegal positional iocontrol");
367*22836Smckusick 		return;
368*22836Smckusick 		}
369*22836Smckusick 	n = nioctl;
370*22836Smckusick 	}
371*22836Smckusick 
372*22836Smckusick if(p == NULL)
373*22836Smckusick 	{
374*22836Smckusick 	if(n == IOSUNIT)
375*22836Smckusick 		p = (expptr) (iostmt==IOREAD ? IOSTDIN : IOSTDOUT);
376*22836Smckusick 	else if(n != IOSFMT)
377*22836Smckusick 		{
378*22836Smckusick 		err("illegal * iocontrol");
379*22836Smckusick 		return;
380*22836Smckusick 		}
381*22836Smckusick 	}
382*22836Smckusick if(n == IOSFMT)
383*22836Smckusick 	ioformatted = (p==NULL ? LISTDIRECTED : FORMATTED);
384*22836Smckusick 
385*22836Smckusick iocp = & ioc[n];
386*22836Smckusick if(iocp->iocval == NULL)
387*22836Smckusick 	{
388*22836Smckusick 	p = (expptr) cpexpr(p);
389*22836Smckusick 	if(n!=IOSFMT && ( n!=IOSUNIT || (p!=NULL && p->headblock.vtype!=TYCHAR) ) )
390*22836Smckusick 		p = fixtype(p);
391*22836Smckusick 	if(p!=NULL && ISCONST(p) && p->constblock.vtype==TYCHAR)
392*22836Smckusick 		p = (expptr) putconst(p);
393*22836Smckusick 	iocp->iocval = p;
394*22836Smckusick }
395*22836Smckusick else
396*22836Smckusick 	errstr("iocontrol %s repeated", iocp->iocname);
397*22836Smckusick }
398*22836Smckusick 
399*22836Smckusick /* io list item */
400*22836Smckusick 
401*22836Smckusick doio(list)
402*22836Smckusick chainp list;
403*22836Smckusick {
404*22836Smckusick expptr call0();
405*22836Smckusick 
406*22836Smckusick if(ioformatted == NAMEDIRECTED)
407*22836Smckusick 	{
408*22836Smckusick 	if(list)
409*22836Smckusick 		err("no I/O list allowed in NAMELIST read/write");
410*22836Smckusick 	}
411*22836Smckusick else
412*22836Smckusick 	{
413*22836Smckusick 	doiolist(list);
414*22836Smckusick 	ioroutine[0] = 'e';
415*22836Smckusick 	putiocall( call0(TYINT, ioroutine) );
416*22836Smckusick 	}
417*22836Smckusick }
418*22836Smckusick 
419*22836Smckusick 
420*22836Smckusick 
421*22836Smckusick 
422*22836Smckusick 
423*22836Smckusick LOCAL doiolist(p0)
424*22836Smckusick chainp p0;
425*22836Smckusick {
426*22836Smckusick chainp p;
427*22836Smckusick register tagptr q;
428*22836Smckusick register expptr qe;
429*22836Smckusick register Namep qn;
430*22836Smckusick Addrp tp, mkscalar();
431*22836Smckusick int range;
432*22836Smckusick expptr expr;
433*22836Smckusick 
434*22836Smckusick for (p = p0 ; p ; p = p->nextp)
435*22836Smckusick 	{
436*22836Smckusick 	q = p->datap;
437*22836Smckusick 	if(q->tag == TIMPLDO)
438*22836Smckusick 		{
439*22836Smckusick 		exdo(range=newlabel(), q->impldoblock.impdospec);
440*22836Smckusick 		doiolist(q->impldoblock.datalist);
441*22836Smckusick 		enddo(range);
442*22836Smckusick 		free( (charptr) q);
443*22836Smckusick 		}
444*22836Smckusick 	else	{
445*22836Smckusick 		if(q->tag==TPRIM && q->primblock.argsp==NULL
446*22836Smckusick 		    && q->primblock.namep->vdim!=NULL)
447*22836Smckusick 			{
448*22836Smckusick 			vardcl(qn = q->primblock.namep);
449*22836Smckusick 			if(qn->vdim->nelt)
450*22836Smckusick 				putio( fixtype(cpexpr(qn->vdim->nelt)),
451*22836Smckusick 					mkscalar(qn) );
452*22836Smckusick 			else
453*22836Smckusick 				err("attempt to i/o array of unknown size");
454*22836Smckusick 			}
455*22836Smckusick 		else if(q->tag==TPRIM && q->primblock.argsp==NULL &&
456*22836Smckusick 		    (qe = (expptr) memversion(q->primblock.namep)) )
457*22836Smckusick 			putio(ICON(1),qe);
458*22836Smckusick 		else if( (qe = fixtype(cpexpr(q)))->tag==TADDR)
459*22836Smckusick 			putio(ICON(1), qe);
460*22836Smckusick 		else if(qe->headblock.vtype != TYERROR)
461*22836Smckusick 			{
462*22836Smckusick 			if(iostmt == IOWRITE)
463*22836Smckusick 				{
464*22836Smckusick 				ftnint lencat();
465*22836Smckusick 				expptr qvl;
466*22836Smckusick 				qvl = NULL;
467*22836Smckusick 				if( ISCHAR(qe) )
468*22836Smckusick 					{
469*22836Smckusick 					qvl = (expptr)
470*22836Smckusick 						cpexpr(qe->headblock.vleng);
471*22836Smckusick 					tp = mktemp(qe->headblock.vtype,
472*22836Smckusick 						     ICON(lencat(qe)));
473*22836Smckusick 					}
474*22836Smckusick 				else
475*22836Smckusick 					tp = mktemp(qe->headblock.vtype,
476*22836Smckusick 						qe->headblock.vleng);
477*22836Smckusick 				if (optimflag)
478*22836Smckusick 					{
479*22836Smckusick 					expr = mkexpr(OPASSIGN,cpexpr(tp),qe);
480*22836Smckusick 					optbuff (SKEQ,expr,0,0);
481*22836Smckusick 					}
482*22836Smckusick 				else
483*22836Smckusick 					puteq (cpexpr(tp),qe);
484*22836Smckusick 				if(qvl)	/* put right length on block */
485*22836Smckusick 					{
486*22836Smckusick 					frexpr(tp->vleng);
487*22836Smckusick 					tp->vleng = qvl;
488*22836Smckusick 					}
489*22836Smckusick 				putio(ICON(1), tp);
490*22836Smckusick 				}
491*22836Smckusick 			else
492*22836Smckusick 				err("non-left side in READ list");
493*22836Smckusick 			}
494*22836Smckusick 		frexpr(q);
495*22836Smckusick 		}
496*22836Smckusick 	}
497*22836Smckusick frchain( &p0 );
498*22836Smckusick }
499*22836Smckusick 
500*22836Smckusick 
501*22836Smckusick 
502*22836Smckusick 
503*22836Smckusick 
504*22836Smckusick LOCAL putio(nelt, addr)
505*22836Smckusick expptr nelt;
506*22836Smckusick register expptr addr;
507*22836Smckusick {
508*22836Smckusick int type;
509*22836Smckusick register expptr q;
510*22836Smckusick 
511*22836Smckusick type = addr->headblock.vtype;
512*22836Smckusick if(ioformatted!=LISTDIRECTED && ISCOMPLEX(type) )
513*22836Smckusick 	{
514*22836Smckusick 	nelt = mkexpr(OPSTAR, ICON(2), nelt);
515*22836Smckusick 	type -= (TYCOMPLEX-TYREAL);
516*22836Smckusick 	}
517*22836Smckusick 
518*22836Smckusick /* pass a length with every item.  for noncharacter data, fake one */
519*22836Smckusick if(type != TYCHAR)
520*22836Smckusick 	{
521*22836Smckusick 	addr->headblock.vtype = TYCHAR;
522*22836Smckusick 	addr->headblock.vleng = ICON( typesize[type] );
523*22836Smckusick 	}
524*22836Smckusick 
525*22836Smckusick nelt = fixtype( mkconv(TYLENG,nelt) );
526*22836Smckusick if(ioformatted == LISTDIRECTED)
527*22836Smckusick 	q = call3(TYINT, "do_lio", mkconv(TYLONG, ICON(type)), nelt, addr);
528*22836Smckusick else
529*22836Smckusick 	q = call2(TYINT, (ioformatted==FORMATTED ? "do_fio" : "do_uio"),
530*22836Smckusick 		nelt, addr);
531*22836Smckusick putiocall(q);
532*22836Smckusick }
533*22836Smckusick 
534*22836Smckusick 
535*22836Smckusick 
536*22836Smckusick 
537*22836Smckusick endio()
538*22836Smckusick {
539*22836Smckusick if(skiplab)
540*22836Smckusick 	{
541*22836Smckusick 	if (optimflag)
542*22836Smckusick 		optbuff (SKLABEL, 0, skiplab, 0);
543*22836Smckusick 	else
544*22836Smckusick 		putlabel (skiplab);
545*22836Smckusick 	if(ioendlab)
546*22836Smckusick 		{
547*22836Smckusick 		expptr test;
548*22836Smckusick 		test = mkexpr(OPGE, cpexpr(IOSTP), ICON(0));
549*22836Smckusick 		if (optimflag)
550*22836Smckusick 			optbuff (SKIOIFN,test,ioendlab,0);
551*22836Smckusick 		else
552*22836Smckusick 			putif (test,ioendlab);
553*22836Smckusick 		}
554*22836Smckusick 	if(ioerrlab)
555*22836Smckusick 		{
556*22836Smckusick 		expptr test;
557*22836Smckusick 		test = mkexpr
558*22836Smckusick 			( ((iostmt==IOREAD||iostmt==IOWRITE) ? OPLE : OPEQ),
559*22836Smckusick 			cpexpr(IOSTP), ICON(0));
560*22836Smckusick 		if (optimflag)
561*22836Smckusick 			optbuff (SKIOIFN,test,ioerrlab,0);
562*22836Smckusick 		else
563*22836Smckusick 			putif (test,ioerrlab);
564*22836Smckusick 		}
565*22836Smckusick 	}
566*22836Smckusick if(IOSTP)
567*22836Smckusick 	frexpr(IOSTP);
568*22836Smckusick }
569*22836Smckusick 
570*22836Smckusick 
571*22836Smckusick 
572*22836Smckusick LOCAL putiocall(q)
573*22836Smckusick register expptr q;
574*22836Smckusick {
575*22836Smckusick if(IOSTP)
576*22836Smckusick 	{
577*22836Smckusick 	q->headblock.vtype = TYINT;
578*22836Smckusick 	q = fixexpr( mkexpr(OPASSIGN, cpexpr(IOSTP), q));
579*22836Smckusick 	}
580*22836Smckusick 
581*22836Smckusick if(jumplab)
582*22836Smckusick 	if (optimflag)
583*22836Smckusick 		optbuff (SKIOIFN,mkexpr(OPEQ,q,ICON(0)),jumplab,0);
584*22836Smckusick 	else
585*22836Smckusick 		putif (mkexpr(OPEQ,q,ICON(0)),jumplab);
586*22836Smckusick else
587*22836Smckusick 	if (optimflag)
588*22836Smckusick 		optbuff (SKEQ, q, 0, 0);
589*22836Smckusick 	else
590*22836Smckusick 		putexpr(q);
591*22836Smckusick }
592*22836Smckusick 
593*22836Smckusick startrw()
594*22836Smckusick {
595*22836Smckusick register expptr p;
596*22836Smckusick register Namep np;
597*22836Smckusick register Addrp unitp, fmtp, recp, tioblkp;
598*22836Smckusick register expptr nump;
599*22836Smckusick register ioblock *t;
600*22836Smckusick Addrp mkscalar();
601*22836Smckusick expptr mkaddcon();
602*22836Smckusick int k;
603*22836Smckusick flag intfile, sequential, ok, varfmt;
604*22836Smckusick 
605*22836Smckusick /* First look at all the parameters and determine what is to be done */
606*22836Smckusick 
607*22836Smckusick ok = YES;
608*22836Smckusick statstruct = YES;
609*22836Smckusick 
610*22836Smckusick intfile = NO;
611*22836Smckusick if(p = V(IOSUNIT))
612*22836Smckusick 	{
613*22836Smckusick 	if( ISINT(p->headblock.vtype) )
614*22836Smckusick 		unitp = (Addrp) cpexpr(p);
615*22836Smckusick 	else if(p->headblock.vtype == TYCHAR)
616*22836Smckusick 		{
617*22836Smckusick 		intfile = YES;
618*22836Smckusick 		if(p->tag==TPRIM && p->primblock.argsp==NULL &&
619*22836Smckusick 		    (np = p->primblock.namep)->vdim!=NULL)
620*22836Smckusick 			{
621*22836Smckusick 			vardcl(np);
622*22836Smckusick 			if(np->vdim->nelt)
623*22836Smckusick 				{
624*22836Smckusick 				nump = (expptr) cpexpr(np->vdim->nelt);
625*22836Smckusick 				if( ! ISCONST(nump) )
626*22836Smckusick 					statstruct = NO;
627*22836Smckusick 				}
628*22836Smckusick 			else
629*22836Smckusick 				{
630*22836Smckusick 				err("attempt to use internal unit array of unknown size");
631*22836Smckusick 				ok = NO;
632*22836Smckusick 				nump = ICON(1);
633*22836Smckusick 				}
634*22836Smckusick 			unitp = mkscalar(np);
635*22836Smckusick 			}
636*22836Smckusick 		else	{
637*22836Smckusick 			nump = ICON(1);
638*22836Smckusick 			unitp = (Addrp) fixtype(cpexpr(p));
639*22836Smckusick 			}
640*22836Smckusick 		if(! isstatic(unitp) )
641*22836Smckusick 			statstruct = NO;
642*22836Smckusick 		}
643*22836Smckusick 	else
644*22836Smckusick 		{
645*22836Smckusick 		err("bad unit specifier type");
646*22836Smckusick 		ok = NO;
647*22836Smckusick 		}
648*22836Smckusick 	}
649*22836Smckusick else
650*22836Smckusick 	{
651*22836Smckusick 	err("bad unit specifier");
652*22836Smckusick 	ok = NO;
653*22836Smckusick 	}
654*22836Smckusick 
655*22836Smckusick sequential = YES;
656*22836Smckusick if(p = V(IOSREC))
657*22836Smckusick 	if( ISINT(p->headblock.vtype) )
658*22836Smckusick 		{
659*22836Smckusick 		recp = (Addrp) cpexpr(p);
660*22836Smckusick 		sequential = NO;
661*22836Smckusick 		}
662*22836Smckusick 	else	{
663*22836Smckusick 		err("bad REC= clause");
664*22836Smckusick 		ok = NO;
665*22836Smckusick 		}
666*22836Smckusick else
667*22836Smckusick 	recp = NULL;
668*22836Smckusick 
669*22836Smckusick 
670*22836Smckusick varfmt = YES;
671*22836Smckusick fmtp = NULL;
672*22836Smckusick if(p = V(IOSFMT))
673*22836Smckusick 	{
674*22836Smckusick 	if(p->tag==TPRIM && p->primblock.argsp==NULL)
675*22836Smckusick 		{
676*22836Smckusick 		np = p->primblock.namep;
677*22836Smckusick 		if(np->vclass == CLNAMELIST)
678*22836Smckusick 			{
679*22836Smckusick 			ioformatted = NAMEDIRECTED;
680*22836Smckusick 			fmtp = (Addrp) fixtype(cpexpr(p));
681*22836Smckusick 			goto endfmt;
682*22836Smckusick 			}
683*22836Smckusick 		vardcl(np);
684*22836Smckusick 		if(np->vdim)
685*22836Smckusick 			{
686*22836Smckusick 			if( ! ONEOF(np->vstg, MSKSTATIC) )
687*22836Smckusick 				statstruct = NO;
688*22836Smckusick 			fmtp = mkscalar(np);
689*22836Smckusick 			goto endfmt;
690*22836Smckusick 			}
691*22836Smckusick 		if( ISINT(np->vtype) )	/* ASSIGNed label */
692*22836Smckusick 			{
693*22836Smckusick 			statstruct = NO;
694*22836Smckusick 			varfmt = NO;
695*22836Smckusick 			fmtp = (Addrp) fixtype(cpexpr(p));
696*22836Smckusick 			goto endfmt;
697*22836Smckusick 			}
698*22836Smckusick 		}
699*22836Smckusick 	p = V(IOSFMT) = fixtype(p);
700*22836Smckusick 	if(p->headblock.vtype == TYCHAR)
701*22836Smckusick 		{
702*22836Smckusick 		if (p->tag == TCONST) p = (expptr) putconst(p);
703*22836Smckusick 		if( ! isstatic(p) )
704*22836Smckusick 			statstruct = NO;
705*22836Smckusick 		fmtp = (Addrp) cpexpr(p);
706*22836Smckusick 		}
707*22836Smckusick 	else if( ISICON(p) )
708*22836Smckusick 		{
709*22836Smckusick 		if( (k = fmtstmt( mklabel(p->constblock.const.ci) )) > 0 )
710*22836Smckusick 			{
711*22836Smckusick 			fmtp = (Addrp) mkaddcon(k);
712*22836Smckusick 			varfmt = NO;
713*22836Smckusick 			}
714*22836Smckusick 		else
715*22836Smckusick 			ioformatted = UNFORMATTED;
716*22836Smckusick 		}
717*22836Smckusick 	else	{
718*22836Smckusick 		err("bad format descriptor");
719*22836Smckusick 		ioformatted = UNFORMATTED;
720*22836Smckusick 		ok = NO;
721*22836Smckusick 		}
722*22836Smckusick 	}
723*22836Smckusick else
724*22836Smckusick 	fmtp = NULL;
725*22836Smckusick 
726*22836Smckusick endfmt:
727*22836Smckusick 	if(intfile && ioformatted==UNFORMATTED)
728*22836Smckusick 		{
729*22836Smckusick 		err("unformatted internal I/O not allowed");
730*22836Smckusick 		ok = NO;
731*22836Smckusick 		}
732*22836Smckusick 	if(!sequential && ioformatted==LISTDIRECTED)
733*22836Smckusick 		{
734*22836Smckusick 		err("direct list-directed I/O not allowed");
735*22836Smckusick 		ok = NO;
736*22836Smckusick 		}
737*22836Smckusick 	if(!sequential && ioformatted==NAMEDIRECTED)
738*22836Smckusick 		{
739*22836Smckusick 		err("direct namelist I/O not allowed");
740*22836Smckusick 		ok = NO;
741*22836Smckusick 		}
742*22836Smckusick 
743*22836Smckusick if( ! ok )
744*22836Smckusick 	return;
745*22836Smckusick 
746*22836Smckusick if (optimflag && ISCONST (fmtp))
747*22836Smckusick 	fmtp = putconst ( (expptr) fmtp);
748*22836Smckusick 
749*22836Smckusick /*
750*22836Smckusick    Now put out the I/O structure, statically if all the clauses
751*22836Smckusick    are constants, dynamically otherwise
752*22836Smckusick */
753*22836Smckusick 
754*22836Smckusick if(statstruct)
755*22836Smckusick 	{
756*22836Smckusick 	tioblkp = ioblkp;
757*22836Smckusick 	ioblkp = ALLOC(Addrblock);
758*22836Smckusick 	ioblkp->tag = TADDR;
759*22836Smckusick 	ioblkp->vtype = TYIOINT;
760*22836Smckusick 	ioblkp->vclass = CLVAR;
761*22836Smckusick 	ioblkp->vstg = STGINIT;
762*22836Smckusick 	ioblkp->memno = ++lastvarno;
763*22836Smckusick 	ioblkp->memoffset = ICON(0);
764*22836Smckusick 	blklen = (intfile ? XIREC+SZIOINT :
765*22836Smckusick 			(sequential ? XFMT+SZADDR : XRNUM+SZIOINT) );
766*22836Smckusick 	t = ALLOC(IoBlock);
767*22836Smckusick 	t->blkno = ioblkp->memno;
768*22836Smckusick 	t->len = blklen;
769*22836Smckusick 	t->next = iodata;
770*22836Smckusick 	iodata = t;
771*22836Smckusick 	}
772*22836Smckusick else if(ioblkp == NULL)
773*22836Smckusick 	ioblkp = autovar( (MAXIO+SZIOINT-1)/SZIOINT , TYIOINT, PNULL);
774*22836Smckusick 
775*22836Smckusick ioset(TYIOINT, XERR, ICON(errbit));
776*22836Smckusick if(iostmt == IOREAD)
777*22836Smckusick 	ioset(TYIOINT, (intfile ? XIEND : XEND), ICON(endbit) );
778*22836Smckusick 
779*22836Smckusick if(intfile)
780*22836Smckusick 	{
781*22836Smckusick 	ioset(TYIOINT, XIRNUM, nump);
782*22836Smckusick 	ioset(TYIOINT, XIRLEN, cpexpr(unitp->vleng) );
783*22836Smckusick 	ioseta(XIUNIT, unitp);
784*22836Smckusick 	}
785*22836Smckusick else
786*22836Smckusick 	ioset(TYIOINT, XUNIT, (expptr) unitp);
787*22836Smckusick 
788*22836Smckusick if(recp)
789*22836Smckusick 	ioset(TYIOINT, (intfile ? XIREC : XREC) , (expptr) recp);
790*22836Smckusick 
791*22836Smckusick if(varfmt)
792*22836Smckusick 	ioseta( intfile ? XIFMT : XFMT , fmtp);
793*22836Smckusick else
794*22836Smckusick 	ioset(TYADDR, intfile ? XIFMT : XFMT, (expptr) fmtp);
795*22836Smckusick 
796*22836Smckusick ioroutine[0] = 's';
797*22836Smckusick ioroutine[1] = '_';
798*22836Smckusick ioroutine[2] = (iostmt==IOREAD ? 'r' : 'w');
799*22836Smckusick ioroutine[3] = (sequential ? 's' : 'd');
800*22836Smckusick ioroutine[4] = "ufln" [ioformatted];
801*22836Smckusick ioroutine[5] = (intfile ? 'i' : 'e');
802*22836Smckusick ioroutine[6] = '\0';
803*22836Smckusick 
804*22836Smckusick putiocall( call1(TYINT, ioroutine, cpexpr(ioblkp) ));
805*22836Smckusick 
806*22836Smckusick if(statstruct)
807*22836Smckusick 	{
808*22836Smckusick 	frexpr(ioblkp);
809*22836Smckusick 	ioblkp = tioblkp;
810*22836Smckusick 	statstruct = NO;
811*22836Smckusick 	}
812*22836Smckusick }
813*22836Smckusick 
814*22836Smckusick 
815*22836Smckusick 
816*22836Smckusick LOCAL dofopen()
817*22836Smckusick {
818*22836Smckusick register expptr p;
819*22836Smckusick 
820*22836Smckusick if( (p = V(IOSUNIT)) && ISINT(p->headblock.vtype) )
821*22836Smckusick 	ioset(TYIOINT, XUNIT, cpexpr(p) );
822*22836Smckusick else
823*22836Smckusick 	err("bad unit in open");
824*22836Smckusick if( (p = V(IOSFILE)) )
825*22836Smckusick 	if(p->headblock.vtype == TYCHAR)
826*22836Smckusick 		ioset(TYIOINT, XFNAMELEN, cpexpr(p->headblock.vleng) );
827*22836Smckusick 	else
828*22836Smckusick 		err("bad file in open");
829*22836Smckusick 
830*22836Smckusick iosetc(XFNAME, p);
831*22836Smckusick 
832*22836Smckusick if(p = V(IOSRECL))
833*22836Smckusick 	if( ISINT(p->headblock.vtype) )
834*22836Smckusick 		ioset(TYIOINT, XRECLEN, cpexpr(p) );
835*22836Smckusick 	else
836*22836Smckusick 		err("bad recl");
837*22836Smckusick else
838*22836Smckusick 	ioset(TYIOINT, XRECLEN, ICON(0) );
839*22836Smckusick 
840*22836Smckusick iosetc(XSTATUS, V(IOSSTATUS));
841*22836Smckusick iosetc(XACCESS, V(IOSACCESS));
842*22836Smckusick iosetc(XFORMATTED, V(IOSFORM));
843*22836Smckusick iosetc(XBLANK, V(IOSBLANK));
844*22836Smckusick 
845*22836Smckusick putiocall( call1(TYINT, "f_open", cpexpr(ioblkp) ));
846*22836Smckusick }
847*22836Smckusick 
848*22836Smckusick 
849*22836Smckusick LOCAL dofclose()
850*22836Smckusick {
851*22836Smckusick register expptr p;
852*22836Smckusick 
853*22836Smckusick if( (p = V(IOSUNIT)) && ISINT(p->headblock.vtype) )
854*22836Smckusick 	{
855*22836Smckusick 	ioset(TYIOINT, XUNIT, cpexpr(p) );
856*22836Smckusick 	iosetc(XCLSTATUS, V(IOSSTATUS));
857*22836Smckusick 	putiocall( call1(TYINT, "f_clos", cpexpr(ioblkp)) );
858*22836Smckusick 	}
859*22836Smckusick else
860*22836Smckusick 	err("bad unit in close statement");
861*22836Smckusick }
862*22836Smckusick 
863*22836Smckusick 
864*22836Smckusick LOCAL dofinquire()
865*22836Smckusick {
866*22836Smckusick register expptr p;
867*22836Smckusick if(p = V(IOSUNIT))
868*22836Smckusick 	{
869*22836Smckusick 	if( V(IOSFILE) )
870*22836Smckusick 		err("inquire by unit or by file, not both");
871*22836Smckusick 	ioset(TYIOINT, XUNIT, cpexpr(p) );
872*22836Smckusick 	}
873*22836Smckusick else if( ! V(IOSFILE) )
874*22836Smckusick 	err("must inquire by unit or by file");
875*22836Smckusick iosetlc(IOSFILE, XFILE, XFILELEN);
876*22836Smckusick iosetip(IOSEXISTS, XEXISTS);
877*22836Smckusick iosetip(IOSOPENED, XOPEN);
878*22836Smckusick iosetip(IOSNUMBER, XNUMBER);
879*22836Smckusick iosetip(IOSNAMED, XNAMED);
880*22836Smckusick iosetlc(IOSNAME, XNAME, XNAMELEN);
881*22836Smckusick iosetlc(IOSACCESS, XQACCESS, XQACCLEN);
882*22836Smckusick iosetlc(IOSSEQUENTIAL, XSEQ, XSEQLEN);
883*22836Smckusick iosetlc(IOSDIRECT, XDIRECT, XDIRLEN);
884*22836Smckusick iosetlc(IOSFORM, XFORM, XFORMLEN);
885*22836Smckusick iosetlc(IOSFORMATTED, XFMTED, XFMTEDLEN);
886*22836Smckusick iosetlc(IOSUNFORMATTED, XUNFMT, XUNFMTLEN);
887*22836Smckusick iosetip(IOSRECL, XQRECL);
888*22836Smckusick iosetip(IOSNEXTREC, XNEXTREC);
889*22836Smckusick iosetlc(IOSBLANK, XQBLANK, XQBLANKLEN);
890*22836Smckusick 
891*22836Smckusick putiocall( call1(TYINT,  "f_inqu", cpexpr(ioblkp) ));
892*22836Smckusick }
893*22836Smckusick 
894*22836Smckusick 
895*22836Smckusick 
896*22836Smckusick LOCAL dofmove(subname)
897*22836Smckusick char *subname;
898*22836Smckusick {
899*22836Smckusick register expptr p;
900*22836Smckusick 
901*22836Smckusick if( (p = V(IOSUNIT)) && ISINT(p->headblock.vtype) )
902*22836Smckusick 	{
903*22836Smckusick 	ioset(TYIOINT, XUNIT, cpexpr(p) );
904*22836Smckusick 	putiocall( call1(TYINT, subname, cpexpr(ioblkp) ));
905*22836Smckusick 	}
906*22836Smckusick else
907*22836Smckusick 	err("bad unit in I/O motion statement");
908*22836Smckusick }
909*22836Smckusick 
910*22836Smckusick 
911*22836Smckusick 
912*22836Smckusick LOCAL
913*22836Smckusick ioset(type, offset, p)
914*22836Smckusick int type;
915*22836Smckusick int offset;
916*22836Smckusick register expptr p;
917*22836Smckusick {
918*22836Smckusick   static char *badoffset = "badoffset in ioset";
919*22836Smckusick 
920*22836Smckusick   register Addrp q;
921*22836Smckusick   register offsetlist *op;
922*22836Smckusick 
923*22836Smckusick   q = (Addrp) cpexpr(ioblkp);
924*22836Smckusick   q->vtype = type;
925*22836Smckusick   q->memoffset = fixtype( mkexpr(OPPLUS, q->memoffset, ICON(offset)) );
926*22836Smckusick 
927*22836Smckusick   if (statstruct && ISCONST(p))
928*22836Smckusick     {
929*22836Smckusick       if (!ISICON(q->memoffset))
930*22836Smckusick 	fatal(badoffset);
931*22836Smckusick 
932*22836Smckusick       op = mkiodata(q->memno, q->memoffset->constblock.const.ci, blklen);
933*22836Smckusick       if (op->tag != 0)
934*22836Smckusick 	fatal(badoffset);
935*22836Smckusick 
936*22836Smckusick       if (type == TYADDR)
937*22836Smckusick 	{
938*22836Smckusick 	  op->tag = NDLABEL;
939*22836Smckusick 	  op->val.label = p->constblock.const.ci;
940*22836Smckusick 	}
941*22836Smckusick       else
942*22836Smckusick 	{
943*22836Smckusick 	  op->tag = NDDATA;
944*22836Smckusick 	  op->val.cp = (Constp) convconst(type, 0, p);
945*22836Smckusick 	}
946*22836Smckusick 
947*22836Smckusick       frexpr((tagptr) p);
948*22836Smckusick       frexpr((tagptr) q);
949*22836Smckusick     }
950*22836Smckusick   else
951*22836Smckusick     if (optimflag)
952*22836Smckusick       optbuff (SKEQ, mkexpr(OPASSIGN,q,p), 0,0);
953*22836Smckusick     else
954*22836Smckusick       puteq (q,p);
955*22836Smckusick 
956*22836Smckusick   return;
957*22836Smckusick }
958*22836Smckusick 
959*22836Smckusick 
960*22836Smckusick 
961*22836Smckusick 
962*22836Smckusick LOCAL iosetc(offset, p)
963*22836Smckusick int offset;
964*22836Smckusick register expptr p;
965*22836Smckusick {
966*22836Smckusick if(p == NULL)
967*22836Smckusick 	ioset(TYADDR, offset, ICON(0) );
968*22836Smckusick else if(p->headblock.vtype == TYCHAR)
969*22836Smckusick 	ioset(TYADDR, offset, addrof(cpexpr(p) ));
970*22836Smckusick else
971*22836Smckusick 	err("non-character control clause");
972*22836Smckusick }
973*22836Smckusick 
974*22836Smckusick 
975*22836Smckusick 
976*22836Smckusick LOCAL ioseta(offset, p)
977*22836Smckusick int offset;
978*22836Smckusick register Addrp p;
979*22836Smckusick {
980*22836Smckusick   static char *badoffset = "bad offset in ioseta";
981*22836Smckusick 
982*22836Smckusick   int blkno;
983*22836Smckusick   register offsetlist *op;
984*22836Smckusick 
985*22836Smckusick   if(statstruct)
986*22836Smckusick     {
987*22836Smckusick       blkno = ioblkp->memno;
988*22836Smckusick       op = mkiodata(blkno, offset, blklen);
989*22836Smckusick       if (op->tag != 0)
990*22836Smckusick 	fatal(badoffset);
991*22836Smckusick 
992*22836Smckusick       if (p == NULL)
993*22836Smckusick 	op->tag = NDNULL;
994*22836Smckusick       else if (p->tag == TADDR)
995*22836Smckusick 	{
996*22836Smckusick 	  op->tag = NDADDR;
997*22836Smckusick 	  op->val.addr.stg = p->vstg;
998*22836Smckusick 	  op->val.addr.memno = p->memno;
999*22836Smckusick 	  op->val.addr.offset = p->memoffset->constblock.const.ci;
1000*22836Smckusick 	}
1001*22836Smckusick       else
1002*22836Smckusick 	badtag("ioseta", p->tag);
1003*22836Smckusick     }
1004*22836Smckusick   else
1005*22836Smckusick     ioset(TYADDR, offset, p ? addrof(p) : ICON(0) );
1006*22836Smckusick 
1007*22836Smckusick   return;
1008*22836Smckusick }
1009*22836Smckusick 
1010*22836Smckusick 
1011*22836Smckusick 
1012*22836Smckusick 
1013*22836Smckusick LOCAL iosetip(i, offset)
1014*22836Smckusick int i, offset;
1015*22836Smckusick {
1016*22836Smckusick register expptr p;
1017*22836Smckusick 
1018*22836Smckusick if(p = V(i))
1019*22836Smckusick 	if(p->tag==TADDR &&
1020*22836Smckusick 	    ONEOF(p->addrblock.vtype, M(TYLONG)|M(TYLOGICAL)) )
1021*22836Smckusick 		ioset(TYADDR, offset, addrof(cpexpr(p)) );
1022*22836Smckusick 	else
1023*22836Smckusick 		errstr("impossible inquire parameter %s", ioc[i].iocname);
1024*22836Smckusick else
1025*22836Smckusick 	ioset(TYADDR, offset, ICON(0) );
1026*22836Smckusick }
1027*22836Smckusick 
1028*22836Smckusick 
1029*22836Smckusick 
1030*22836Smckusick LOCAL iosetlc(i, offp, offl)
1031*22836Smckusick int i, offp, offl;
1032*22836Smckusick {
1033*22836Smckusick register expptr p;
1034*22836Smckusick if( (p = V(i)) && p->headblock.vtype==TYCHAR)
1035*22836Smckusick 	ioset(TYIOINT, offl, cpexpr(p->headblock.vleng) );
1036*22836Smckusick iosetc(offp, p);
1037*22836Smckusick }
1038*22836Smckusick 
1039*22836Smckusick 
1040*22836Smckusick LOCAL offsetlist *
1041*22836Smckusick mkiodata(blkno, offset, len)
1042*22836Smckusick int blkno;
1043*22836Smckusick ftnint offset;
1044*22836Smckusick ftnint len;
1045*22836Smckusick {
1046*22836Smckusick   register offsetlist *p, *q;
1047*22836Smckusick   register ioblock *t;
1048*22836Smckusick   register int found;
1049*22836Smckusick 
1050*22836Smckusick   found = NO;
1051*22836Smckusick   t = iodata;
1052*22836Smckusick 
1053*22836Smckusick   while (found == NO && t != NULL)
1054*22836Smckusick     {
1055*22836Smckusick       if (t->blkno == blkno)
1056*22836Smckusick 	found = YES;
1057*22836Smckusick       else
1058*22836Smckusick 	t = t->next;
1059*22836Smckusick     }
1060*22836Smckusick 
1061*22836Smckusick   if (found == NO)
1062*22836Smckusick     {
1063*22836Smckusick       t = ALLOC(IoBlock);
1064*22836Smckusick       t->blkno = blkno;
1065*22836Smckusick       t->next = iodata;
1066*22836Smckusick       iodata = t;
1067*22836Smckusick     }
1068*22836Smckusick 
1069*22836Smckusick   if (len > t->len)
1070*22836Smckusick     t->len = len;
1071*22836Smckusick 
1072*22836Smckusick   p = t->olist;
1073*22836Smckusick 
1074*22836Smckusick   if (p == NULL)
1075*22836Smckusick     {
1076*22836Smckusick       p = ALLOC(OffsetList);
1077*22836Smckusick       p->next = NULL;
1078*22836Smckusick       p->offset = offset;
1079*22836Smckusick       t->olist = p;
1080*22836Smckusick       return (p);
1081*22836Smckusick     }
1082*22836Smckusick 
1083*22836Smckusick   for (;;)
1084*22836Smckusick     {
1085*22836Smckusick       if (p->offset == offset)
1086*22836Smckusick 	return (p);
1087*22836Smckusick       else if (p->next != NULL &&
1088*22836Smckusick 	       p->next->offset <= offset)
1089*22836Smckusick 	p = p->next;
1090*22836Smckusick       else
1091*22836Smckusick 	{
1092*22836Smckusick 	  q = ALLOC(OffsetList);
1093*22836Smckusick 	  q->next = p->next;
1094*22836Smckusick 	  p->next = q;
1095*22836Smckusick 	  q->offset = offset;
1096*22836Smckusick 	  return (q);
1097*22836Smckusick 	}
1098*22836Smckusick     }
1099*22836Smckusick }
1100*22836Smckusick 
1101*22836Smckusick 
1102*22836Smckusick outiodata()
1103*22836Smckusick {
1104*22836Smckusick   static char *varfmt = "v.%d:\n";
1105*22836Smckusick 
1106*22836Smckusick   register ioblock *p;
1107*22836Smckusick   register ioblock *t;
1108*22836Smckusick 
1109*22836Smckusick   if (iodata == NULL) return;
1110*22836Smckusick 
1111*22836Smckusick   p = iodata;
1112*22836Smckusick 
1113*22836Smckusick   while (p != NULL)
1114*22836Smckusick     {
1115*22836Smckusick       pralign(ALIDOUBLE);
1116*22836Smckusick       fprintf(initfile, varfmt, p->blkno);
1117*22836Smckusick       outolist(p->olist, p->len);
1118*22836Smckusick 
1119*22836Smckusick       t = p;
1120*22836Smckusick       p = t->next;
1121*22836Smckusick       free((char *) t);
1122*22836Smckusick     }
1123*22836Smckusick 
1124*22836Smckusick   iodata = NULL;
1125*22836Smckusick   return;
1126*22836Smckusick }
1127*22836Smckusick 
1128*22836Smckusick 
1129*22836Smckusick 
1130*22836Smckusick LOCAL
1131*22836Smckusick outolist(op, len)
1132*22836Smckusick register offsetlist *op;
1133*22836Smckusick register int len;
1134*22836Smckusick {
1135*22836Smckusick   static char *overlap = "overlapping i/o fields in outolist";
1136*22836Smckusick   static char *toolong = "offset too large in outolist";
1137*22836Smckusick 
1138*22836Smckusick   register offsetlist *t;
1139*22836Smckusick   register ftnint clen;
1140*22836Smckusick   register Constp cp;
1141*22836Smckusick   register int type;
1142*22836Smckusick 
1143*22836Smckusick   clen = 0;
1144*22836Smckusick 
1145*22836Smckusick   while (op != NULL)
1146*22836Smckusick     {
1147*22836Smckusick       if (clen > op->offset)
1148*22836Smckusick 	fatal(overlap);
1149*22836Smckusick 
1150*22836Smckusick       if (clen < op->offset)
1151*22836Smckusick 	{
1152*22836Smckusick 	  prspace(op->offset - clen);
1153*22836Smckusick 	  clen = op->offset;
1154*22836Smckusick 	}
1155*22836Smckusick 
1156*22836Smckusick       switch (op->tag)
1157*22836Smckusick 	{
1158*22836Smckusick 	default:
1159*22836Smckusick 	  badtag("outolist", op->tag);
1160*22836Smckusick 
1161*22836Smckusick 	case NDDATA:
1162*22836Smckusick 	  cp = op->val.cp;
1163*22836Smckusick 	  type = cp->vtype;
1164*22836Smckusick 	  if (type != TYIOINT)
1165*22836Smckusick 	    badtype("outolist", type);
1166*22836Smckusick 	  prconi(initfile, type, cp->const.ci);
1167*22836Smckusick 	  clen += typesize[type];
1168*22836Smckusick 	  frexpr((tagptr) cp);
1169*22836Smckusick 	  break;
1170*22836Smckusick 
1171*22836Smckusick 	case NDLABEL:
1172*22836Smckusick 	  prcona(initfile, op->val.label);
1173*22836Smckusick 	  clen += typesize[TYADDR];
1174*22836Smckusick 	  break;
1175*22836Smckusick 
1176*22836Smckusick 	case NDADDR:
1177*22836Smckusick 	  praddr(initfile, op->val.addr.stg, op->val.addr.memno,
1178*22836Smckusick 		 op->val.addr.offset);
1179*22836Smckusick 	  clen += typesize[TYADDR];
1180*22836Smckusick 	  break;
1181*22836Smckusick 
1182*22836Smckusick 	case NDNULL:
1183*22836Smckusick 	  praddr(initfile, STGNULL, 0, (ftnint) 0);
1184*22836Smckusick 	  clen += typesize[TYADDR];
1185*22836Smckusick 	  break;
1186*22836Smckusick 	}
1187*22836Smckusick 
1188*22836Smckusick       t = op;
1189*22836Smckusick       op = t->next;
1190*22836Smckusick       free((char *) t);
1191*22836Smckusick     }
1192*22836Smckusick 
1193*22836Smckusick   if (clen > len)
1194*22836Smckusick     fatal(toolong);
1195*22836Smckusick 
1196*22836Smckusick   if (clen < len)
1197*22836Smckusick     prspace(len - clen);
1198*22836Smckusick 
1199*22836Smckusick   return;
1200*22836Smckusick }
1201