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