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