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