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