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